• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kio

kfileitem.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002    Copyright (C) 1999 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 // $Id: kfileitem.cpp 717004 2007-09-25 20:52:46Z dfaure $
00021 
00022 #include <sys/time.h>
00023 #include <pwd.h>
00024 #include <grp.h>
00025 #include <sys/types.h>
00026 
00027 #include <assert.h>
00028 #include <unistd.h>
00029 
00030 #include "kfileitem.h"
00031 
00032 #include <qdir.h>
00033 #include <qfile.h>
00034 #include <qmap.h>
00035 #include <qstylesheet.h>
00036 
00037 #include <kdebug.h>
00038 #include <kfilemetainfo.h>
00039 #include <ksambashare.h>
00040 #include <knfsshare.h>
00041 #include <kglobal.h>
00042 #include <kglobalsettings.h>
00043 #include <kiconloader.h>
00044 #include <klargefile.h>
00045 #include <klocale.h>
00046 #include <kmimetype.h>
00047 #include <krun.h>
00048 
00049 class KFileItem::KFileItemPrivate {
00050     public:
00051         QString iconName;
00052 };
00053 
00054 KFileItem::KFileItem( const KIO::UDSEntry& _entry, const KURL& _url,
00055                       bool _determineMimeTypeOnDemand, bool _urlIsDirectory ) :
00056   m_entry( _entry ),
00057   m_url( _url ),
00058   m_pMimeType( 0 ),
00059   m_fileMode( KFileItem::Unknown ),
00060   m_permissions( KFileItem::Unknown ),
00061   m_bMarked( false ),
00062   m_bLink( false ),
00063   m_bIsLocalURL( _url.isLocalFile() ),
00064   m_bMimeTypeKnown( false ),
00065   m_hidden( Auto ),
00066   d(0)
00067 {
00068   readUDSEntry( _urlIsDirectory );
00069   init( _determineMimeTypeOnDemand );
00070 }
00071 
00072 KFileItem::KFileItem( mode_t _mode, mode_t _permissions, const KURL& _url, bool _determineMimeTypeOnDemand ) :
00073   m_entry(), // warning !
00074   m_url( _url ),
00075   m_strName( _url.fileName() ),
00076   m_strText( KIO::decodeFileName( m_strName ) ),
00077   m_pMimeType( 0 ),
00078   m_fileMode ( _mode ),
00079   m_permissions( _permissions ),
00080   m_bMarked( false ),
00081   m_bLink( false ),
00082   m_bIsLocalURL( _url.isLocalFile() ),
00083   m_bMimeTypeKnown( false ),
00084   m_hidden( Auto ),
00085   d(0)
00086 {
00087   init( _determineMimeTypeOnDemand );
00088 }
00089 
00090 KFileItem::KFileItem( const KURL &url, const QString &mimeType, mode_t mode )
00091 :  m_url( url ),
00092   m_strName( url.fileName() ),
00093   m_strText( KIO::decodeFileName( m_strName ) ),
00094   m_pMimeType( 0 ),
00095   m_fileMode( mode ),
00096   m_permissions( KFileItem::Unknown ),
00097   m_bMarked( false ),
00098   m_bLink( false ),
00099   m_bIsLocalURL( url.isLocalFile() ),
00100   m_bMimeTypeKnown( !mimeType.isEmpty() ),
00101   m_hidden( Auto ),
00102   d(0)
00103 {
00104   if (m_bMimeTypeKnown)
00105     m_pMimeType = KMimeType::mimeType( mimeType );
00106 
00107   init( false );
00108 }
00109 
00110 KFileItem::KFileItem( const KFileItem & item ) :
00111   d(0)
00112 {
00113     assign( item );
00114 }
00115 
00116 KFileItem& KFileItem::operator=( const KFileItem & item )
00117 {
00118     assign( item );
00119     return *this;
00120 }
00121 
00122 KFileItem::~KFileItem()
00123 {
00124   delete d;
00125 }
00126 
00127 void KFileItem::init( bool _determineMimeTypeOnDemand )
00128 {
00129   m_access = QString::null;
00130   m_size = (KIO::filesize_t) -1;
00131   //  metaInfo = KFileMetaInfo();
00132   for ( int i = 0; i < NumFlags; i++ )
00133       m_time[i] = (time_t) -1;
00134 
00135   // determine mode and/or permissions if unknown
00136   if ( m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown )
00137   {
00138     mode_t mode = 0;
00139     if ( m_url.isLocalFile() )
00140     {
00141       /* directories may not have a slash at the end if
00142        * we want to stat() them; it requires that we
00143        * change into it .. which may not be allowed
00144        * stat("/is/unaccessible")  -> rwx------
00145        * stat("/is/unaccessible/") -> EPERM            H.Z.
00146        * This is the reason for the -1
00147        */
00148       KDE_struct_stat buf;
00149       QCString path = QFile::encodeName(m_url.path( -1 ));
00150       if ( KDE_lstat( path.data(), &buf ) == 0 )
00151       {
00152         mode = buf.st_mode;
00153         if ( S_ISLNK( mode ) )
00154         {
00155           m_bLink = true;
00156           if ( KDE_stat( path.data(), &buf ) == 0 )
00157               mode = buf.st_mode;
00158           else // link pointing to nowhere (see kio/file/file.cc)
00159               mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO;
00160         }
00161         // While we're at it, store the times
00162         m_time[ Modification ] = buf.st_mtime;
00163         m_time[ Access ] = buf.st_atime;
00164         if ( m_fileMode == KFileItem::Unknown )
00165           m_fileMode = mode & S_IFMT; // extract file type
00166         if ( m_permissions == KFileItem::Unknown )
00167           m_permissions = mode & 07777; // extract permissions
00168       }
00169     }
00170   }
00171 
00172   // determine the mimetype
00173   if (!m_pMimeType && !m_url.isEmpty())
00174   {
00175       bool accurate = false;
00176       bool isLocalURL;
00177       KURL url = mostLocalURL(isLocalURL);
00178 
00179       m_pMimeType = KMimeType::findByURL( url, m_fileMode, isLocalURL,
00180                                           // use fast mode if not mimetype on demand
00181                                           _determineMimeTypeOnDemand, &accurate );
00182       //kdDebug() << "finding mimetype for " << url.url() << " : " << m_pMimeType->name() << endl;
00183       // if we didn't use fast mode, or if we got a result, then this is the mimetype
00184       // otherwise, determineMimeType will be able to do better.
00185       m_bMimeTypeKnown = (!_determineMimeTypeOnDemand) || accurate;
00186   }
00187 }
00188 
00189 void KFileItem::readUDSEntry( bool _urlIsDirectory )
00190 {
00191   // extract the mode and the filename from the KIO::UDS Entry
00192   bool UDS_URL_seen = false;
00193 
00194   KIO::UDSEntry::ConstIterator it = m_entry.begin();
00195   for( ; it != m_entry.end(); ++it ) {
00196     switch ((*it).m_uds) {
00197 
00198       case KIO::UDS_FILE_TYPE:
00199         m_fileMode = (mode_t)((*it).m_long);
00200         break;
00201 
00202       case KIO::UDS_ACCESS:
00203         m_permissions = (mode_t)((*it).m_long);
00204         break;
00205 
00206       case KIO::UDS_USER:
00207         m_user = ((*it).m_str);
00208         break;
00209 
00210       case KIO::UDS_GROUP:
00211         m_group = ((*it).m_str);
00212         break;
00213 
00214       case KIO::UDS_NAME:
00215         m_strName = (*it).m_str;
00216         m_strText = KIO::decodeFileName( m_strName );
00217         break;
00218 
00219       case KIO::UDS_URL:
00220         UDS_URL_seen = true;
00221         m_url = KURL((*it).m_str);
00222         if ( m_url.isLocalFile() )
00223            m_bIsLocalURL = true;
00224         break;
00225 
00226       case KIO::UDS_MIME_TYPE:
00227         m_pMimeType = KMimeType::mimeType((*it).m_str);
00228         m_bMimeTypeKnown = true;
00229         break;
00230 
00231       case KIO::UDS_GUESSED_MIME_TYPE:
00232         m_guessedMimeType = (*it).m_str;
00233         break;
00234 
00235       case KIO::UDS_LINK_DEST:
00236         m_bLink = !(*it).m_str.isEmpty(); // we don't store the link dest
00237         break;
00238 
00239       case KIO::UDS_ICON_NAME:
00240         if ( !d )
00241           d = new KFileItemPrivate();
00242         d->iconName = (*it).m_str;
00243         break;
00244 
00245       case KIO::UDS_HIDDEN:
00246         if ( (*it).m_long )
00247           m_hidden = Hidden;
00248         else
00249           m_hidden = Shown;
00250         break;
00251     }
00252   }
00253 
00254   // avoid creating these QStrings again and again
00255   static const QString& dot = KGlobal::staticQString(".");
00256   if ( _urlIsDirectory && !UDS_URL_seen && !m_strName.isEmpty() && m_strName != dot )
00257     m_url.addPath( m_strName );
00258 }
00259 
00260 void KFileItem::refresh()
00261 {
00262   m_fileMode = KFileItem::Unknown;
00263   m_permissions = KFileItem::Unknown;
00264   m_pMimeType = 0L;
00265   m_user = QString::null;
00266   m_group = QString::null;
00267   m_metaInfo = KFileMetaInfo();
00268   m_hidden = Auto;
00269 
00270   // Basically, we can't trust any information we got while listing.
00271   // Everything could have changed...
00272   // Clearing m_entry makes it possible to detect changes in the size of the file,
00273   // the time information, etc.
00274   m_entry = KIO::UDSEntry();
00275   init( false );
00276 }
00277 
00278 void KFileItem::refreshMimeType()
00279 {
00280   m_pMimeType = 0L;
00281   init( false ); // Will determine the mimetype
00282 }
00283 
00284 void KFileItem::setURL( const KURL &url )
00285 {
00286   m_url = url;
00287   setName( url.fileName() );
00288 }
00289 
00290 void KFileItem::setName( const QString& name )
00291 {
00292   m_strName = name;
00293   m_strText = KIO::decodeFileName( m_strName );
00294 }
00295 
00296 QString KFileItem::linkDest() const
00297 {
00298   // Extract it from the KIO::UDSEntry
00299   KIO::UDSEntry::ConstIterator it = m_entry.begin();
00300   for( ; it != m_entry.end(); ++it )
00301     if ( (*it).m_uds == KIO::UDS_LINK_DEST )
00302       return (*it).m_str;
00303   // If not in the KIO::UDSEntry, or if UDSEntry empty, use readlink() [if local URL]
00304   if ( m_bIsLocalURL )
00305   {
00306     char buf[1000];
00307     int n = readlink( QFile::encodeName(m_url.path( -1 )), buf, sizeof(buf)-1 );
00308     if ( n != -1 )
00309     {
00310       buf[ n ] = 0;
00311       return QFile::decodeName( buf );
00312     }
00313   }
00314   return QString::null;
00315 }
00316 
00317 QString KFileItem::localPath() const
00318 {
00319   if ( m_bIsLocalURL )
00320   {
00321     return m_url.path();
00322   }
00323   else
00324   {
00325     // Extract the local path from the KIO::UDSEntry
00326     KIO::UDSEntry::ConstIterator it = m_entry.begin();
00327     const KIO::UDSEntry::ConstIterator end = m_entry.end();
00328     for( ; it != end; ++it )
00329       if ( (*it).m_uds == KIO::UDS_LOCAL_PATH )
00330         return (*it).m_str;
00331   }
00332 
00333   return QString::null;
00334 }
00335 
00336 KIO::filesize_t KFileItem::size(bool &exists) const
00337 {
00338   exists = true;
00339   if ( m_size != (KIO::filesize_t) -1 )
00340     return m_size;
00341 
00342   // Extract it from the KIO::UDSEntry
00343   KIO::UDSEntry::ConstIterator it = m_entry.begin();
00344   for( ; it != m_entry.end(); ++it )
00345     if ( (*it).m_uds == KIO::UDS_SIZE ) {
00346       m_size = (*it).m_long;
00347       return m_size;
00348     }
00349   // If not in the KIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL]
00350   if ( m_bIsLocalURL )
00351   {
00352     KDE_struct_stat buf;
00353     if ( KDE_stat( QFile::encodeName(m_url.path( -1 )), &buf ) == 0 )
00354         return buf.st_size;
00355   }
00356   exists = false;
00357   return 0L;
00358 }
00359 
00360 bool KFileItem::hasExtendedACL() const
00361 {
00362   KIO::UDSEntry::ConstIterator it = m_entry.begin();
00363   for( ; it != m_entry.end(); it++ )
00364     if ( (*it).m_uds == KIO::UDS_EXTENDED_ACL ) {
00365       return true;
00366     }
00367   return false;
00368 }
00369 
00370 KACL KFileItem::ACL() const
00371 {
00372   if ( hasExtendedACL() ) {
00373     // Extract it from the KIO::UDSEntry
00374     KIO::UDSEntry::ConstIterator it = m_entry.begin();
00375     for( ; it != m_entry.end(); ++it )
00376       if ( (*it).m_uds == KIO::UDS_ACL_STRING )
00377         return KACL((*it).m_str);
00378   }
00379   // create one from the basic permissions
00380   return KACL( m_permissions );
00381 }
00382 
00383 KACL KFileItem::defaultACL() const
00384 {
00385   // Extract it from the KIO::UDSEntry
00386   KIO::UDSEntry::ConstIterator it = m_entry.begin();
00387   for( ; it != m_entry.end(); ++it )
00388     if ( (*it).m_uds == KIO::UDS_DEFAULT_ACL_STRING )
00389       return KACL((*it).m_str);
00390   return KACL();
00391 }
00392 
00393 KIO::filesize_t KFileItem::size() const
00394 {
00395   bool exists;
00396   return size(exists);
00397 }
00398 
00399 time_t KFileItem::time( unsigned int which ) const
00400 {
00401   bool hasTime;
00402   return time(which, hasTime);
00403 }
00404 time_t KFileItem::time( unsigned int which, bool &hasTime ) const
00405 {
00406   hasTime = true;
00407   unsigned int mappedWhich = 0;
00408 
00409   switch( which ) {
00410     case KIO::UDS_MODIFICATION_TIME:
00411       mappedWhich = Modification;
00412       break;
00413     case KIO::UDS_ACCESS_TIME:
00414       mappedWhich = Access;
00415       break;
00416     case KIO::UDS_CREATION_TIME:
00417       mappedWhich = Creation;
00418       break;
00419   }
00420 
00421   if ( m_time[mappedWhich] != (time_t) -1 )
00422     return m_time[mappedWhich];
00423 
00424   // Extract it from the KIO::UDSEntry
00425   KIO::UDSEntry::ConstIterator it = m_entry.begin();
00426   for( ; it != m_entry.end(); ++it )
00427     if ( (*it).m_uds == which ) {
00428       m_time[mappedWhich] = static_cast<time_t>((*it).m_long);
00429       return m_time[mappedWhich];
00430     }
00431 
00432   // If not in the KIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL]
00433   if ( m_bIsLocalURL )
00434   {
00435     KDE_struct_stat buf;
00436     if ( KDE_stat( QFile::encodeName(m_url.path(-1)), &buf ) == 0 )
00437     {
00438     if(which == KIO::UDS_CREATION_TIME) {
00439         // We can't determine creation time for local files
00440         hasTime = false;
00441             m_time[mappedWhich] = static_cast<time_t>(0);
00442         return m_time[mappedWhich];
00443     }
00444         m_time[mappedWhich] = (which == KIO::UDS_MODIFICATION_TIME) ?
00445                                buf.st_mtime :
00446                                /* which == KIO::UDS_ACCESS_TIME)*/
00447                    buf.st_atime;
00448         return m_time[mappedWhich];
00449     }
00450   }
00451   hasTime = false;
00452   return static_cast<time_t>(0);
00453 }
00454 
00455 
00456 QString KFileItem::user() const
00457 {
00458   if ( m_user.isEmpty() && m_bIsLocalURL )
00459   {
00460     KDE_struct_stat buff;
00461     if ( KDE_lstat( QFile::encodeName(m_url.path( -1 )), &buff ) == 0) // get uid/gid of the link, if it's a link
00462     {
00463       struct passwd *user = getpwuid( buff.st_uid );
00464       if ( user != 0L )
00465         m_user = QString::fromLocal8Bit(user->pw_name);
00466     }
00467   }
00468   return m_user;
00469 }
00470 
00471 QString KFileItem::group() const
00472 {
00473 #ifdef Q_OS_UNIX
00474   if (m_group.isEmpty() && m_bIsLocalURL )
00475   {
00476     KDE_struct_stat buff;
00477     if ( KDE_lstat( QFile::encodeName(m_url.path( -1 )), &buff ) == 0) // get uid/gid of the link, if it's a link
00478     {
00479       struct group *ge = getgrgid( buff.st_gid );
00480       if ( ge != 0L ) {
00481         m_group = QString::fromLocal8Bit(ge->gr_name);
00482         if (m_group.isEmpty())
00483           m_group.sprintf("%d",ge->gr_gid);
00484       } else
00485         m_group.sprintf("%d",buff.st_gid);
00486     }
00487   }
00488 #endif
00489   return m_group;
00490 }
00491 
00492 QString KFileItem::mimetype() const
00493 {
00494   KFileItem * that = const_cast<KFileItem *>(this);
00495   return that->determineMimeType()->name();
00496 }
00497 
00498 KMimeType::Ptr KFileItem::determineMimeType()
00499 {
00500   if ( !m_pMimeType || !m_bMimeTypeKnown )
00501   {
00502     bool isLocalURL;
00503     KURL url = mostLocalURL(isLocalURL);
00504 
00505     m_pMimeType = KMimeType::findByURL( url, m_fileMode, isLocalURL );
00506     //kdDebug() << "finding mimetype for " << url.url() << " : " << m_pMimeType->name() << endl;
00507     m_bMimeTypeKnown = true;
00508   }
00509 
00510   return m_pMimeType;
00511 }
00512 
00513 bool KFileItem::isMimeTypeKnown() const
00514 {
00515   // The mimetype isn't known if determineMimeType was never called (on-demand determination)
00516   // or if this fileitem has a guessed mimetype (e.g. ftp symlink) - in which case
00517   // it always remains "not fully determined"
00518   return m_bMimeTypeKnown && m_guessedMimeType.isEmpty();
00519 }
00520 
00521 QString KFileItem::mimeComment()
00522 {
00523  KMimeType::Ptr mType = determineMimeType();
00524 
00525  bool isLocalURL;
00526  KURL url = mostLocalURL(isLocalURL);
00527 
00528  QString comment = mType->comment( url, isLocalURL );
00529  //kdDebug() << "finding comment for " << url.url() << " : " << m_pMimeType->name() << endl;
00530   if (!comment.isEmpty())
00531     return comment;
00532   else
00533     return mType->name();
00534 }
00535 
00536 QString KFileItem::iconName()
00537 {
00538   if (d && (!d->iconName.isEmpty())) return d->iconName;
00539 
00540   bool isLocalURL;
00541   KURL url = mostLocalURL(isLocalURL);
00542 
00543   //kdDebug() << "finding icon for " << url.url() << " : " << m_pMimeType->name() << endl;
00544   return determineMimeType()->icon(url, isLocalURL);
00545 }
00546 
00547 int KFileItem::overlays() const
00548 {
00549   int _state = 0;
00550   if ( m_bLink )
00551       _state |= KIcon::LinkOverlay;
00552 
00553   if ( !S_ISDIR( m_fileMode ) // Locked dirs have a special icon, use the overlay for files only
00554        && !isReadable())
00555      _state |= KIcon::LockOverlay;
00556 
00557   if ( isHidden() )
00558      _state |= KIcon::HiddenOverlay;
00559 
00560   if( S_ISDIR( m_fileMode ) && m_bIsLocalURL)
00561   {
00562     if (KSambaShare::instance()->isDirectoryShared( m_url.path() ) ||
00563         KNFSShare::instance()->isDirectoryShared( m_url.path() ))
00564     {
00565       //kdDebug()<<"KFileShare::isDirectoryShared : "<<m_url.path()<<endl;
00566       _state |= KIcon::ShareOverlay;
00567     }
00568   }
00569 
00570   if ( m_pMimeType->name() == "application/x-gzip" && m_url.fileName().right(3) == ".gz" )
00571      _state |= KIcon::ZipOverlay;
00572   return _state;
00573 }
00574 
00575 QPixmap KFileItem::pixmap( int _size, int _state ) const
00576 {
00577   if (d && (!d->iconName.isEmpty()))
00578      return DesktopIcon(d->iconName,_size,_state);
00579 
00580   if ( !m_pMimeType )
00581   {
00582     static const QString & defaultFolderIcon =
00583        KGlobal::staticQString(KMimeType::mimeType( "inode/directory" )->KServiceType::icon());
00584 
00585     if ( S_ISDIR( m_fileMode ) )
00586      return DesktopIcon( defaultFolderIcon, _size, _state );
00587 
00588     return DesktopIcon( "unknown", _size, _state );
00589   }
00590 
00591   _state |= overlays();
00592 
00593   KMimeType::Ptr mime;
00594   // Use guessed mimetype if the main one hasn't been determined for sure
00595   if ( !m_bMimeTypeKnown && !m_guessedMimeType.isEmpty() )
00596       mime = KMimeType::mimeType( m_guessedMimeType );
00597   else
00598       mime = m_pMimeType;
00599 
00600   // Support for gzipped files: extract mimetype of contained file
00601   // See also the relevant code in overlays, which adds the zip overlay.
00602   if ( mime->name() == "application/x-gzip" && m_url.fileName().right(3) == ".gz" )
00603   {
00604       KURL sf;
00605       sf.setPath( m_url.path().left( m_url.path().length() - 3 ) );
00606       //kdDebug() << "KFileItem::pixmap subFileName=" << subFileName << endl;
00607       mime = KMimeType::findByURL( sf, 0, m_bIsLocalURL );
00608   }
00609 
00610   bool isLocalURL;
00611   KURL url = mostLocalURL(isLocalURL);
00612 
00613   QPixmap p = mime->pixmap( url, KIcon::Desktop, _size, _state );
00614   //kdDebug() << "finding pixmap for " << url.url() << " : " << mime->name() << endl;
00615   if (p.isNull())
00616       kdWarning() << "Pixmap not found for mimetype " << m_pMimeType->name() << endl;
00617 
00618   return p;
00619 }
00620 
00621 bool KFileItem::isReadable() const
00622 {
00623   /*
00624   struct passwd * user = getpwuid( geteuid() );
00625   bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == m_user);
00626   // This gets ugly for the group....
00627   // Maybe we want a static QString for the user and a static QStringList
00628   // for the groups... then we need to handle the deletion properly...
00629   */
00630 
00631   if ( m_permissions != KFileItem::Unknown ) {
00632     // No read permission at all
00633     if ( !(S_IRUSR & m_permissions) && !(S_IRGRP & m_permissions) && !(S_IROTH & m_permissions) )
00634         return false;
00635 
00636     // Read permissions for all: save a stat call
00637     if ( (S_IRUSR|S_IRGRP|S_IROTH) & m_permissions )
00638         return true;
00639   }
00640 
00641   // Or if we can't read it [using ::access()] - not network transparent
00642   if ( m_bIsLocalURL && ::access( QFile::encodeName(m_url.path()), R_OK ) == -1 )
00643       return false;
00644 
00645   return true;
00646 }
00647 
00648 bool KFileItem::isWritable() const
00649 {
00650   /*
00651   struct passwd * user = getpwuid( geteuid() );
00652   bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == m_user);
00653   // This gets ugly for the group....
00654   // Maybe we want a static QString for the user and a static QStringList
00655   // for the groups... then we need to handle the deletion properly...
00656   */
00657 
00658   if ( m_permissions != KFileItem::Unknown ) {
00659     // No write permission at all
00660     if ( !(S_IWUSR & m_permissions) && !(S_IWGRP & m_permissions) && !(S_IWOTH & m_permissions) )
00661         return false;
00662   }
00663 
00664   // Or if we can't read it [using ::access()] - not network transparent
00665  if ( m_bIsLocalURL && ::access( QFile::encodeName(m_url.path()), W_OK ) == -1 )
00666       return false;
00667 
00668   return true;
00669 }
00670 
00671 bool KFileItem::isHidden() const
00672 {
00673   if ( m_hidden != Auto )
00674       return m_hidden == Hidden;
00675 
00676   if ( !m_url.isEmpty() )
00677       return m_url.fileName()[0] == '.';
00678   else // should never happen
00679       return m_strName[0] == '.';
00680 }
00681 
00682 bool KFileItem::isDir() const
00683 {
00684   if ( m_fileMode == KFileItem::Unknown )
00685   {
00686     kdDebug() << " KFileItem::isDir can't say -> false " << endl;
00687     return false; // can't say for sure, so no
00688   }
00689   return (S_ISDIR(m_fileMode));
00690 /*
00691   if  (!S_ISDIR(m_fileMode)) {
00692     if (m_url.isLocalFile()) {
00693         KMimeType::Ptr ptr=KMimeType::findByURL(m_url,0,true,true);
00694         if ((ptr!=0) && (ptr->is("directory/inode"))) return true;
00695     }
00696     return false
00697   } else return true;*/
00698 }
00699 
00700 bool KFileItem::acceptsDrops()
00701 {
00702   // A directory ?
00703   if ( S_ISDIR( mode() ) ) {
00704       return isWritable();
00705   }
00706 
00707   // But only local .desktop files and executables
00708   if ( !m_bIsLocalURL )
00709     return false;
00710 
00711   if ( mimetype() == "application/x-desktop")
00712     return true;
00713 
00714   // Executable, shell script ... ?
00715   if ( ::access( QFile::encodeName(m_url.path()), X_OK ) == 0 )
00716     return true;
00717 
00718   return false;
00719 }
00720 
00721 QString KFileItem::getStatusBarInfo()
00722 {
00723   QString text = m_strText;
00724 
00725   if ( m_bLink )
00726   {
00727       QString comment = determineMimeType()->comment( m_url, m_bIsLocalURL );
00728       QString tmp;
00729       if ( comment.isEmpty() )
00730         tmp = i18n ( "Symbolic Link" );
00731       else
00732         tmp = i18n("%1 (Link)").arg(comment);
00733       text += "->";
00734       text += linkDest();
00735       text += "  ";
00736       text += tmp;
00737   }
00738   else if ( S_ISREG( m_fileMode ) )
00739   {
00740       bool hasSize;
00741       KIO::filesize_t sizeValue = size(hasSize);
00742       if(hasSize)
00743         text += QString(" (%1)  ").arg( KIO::convertSize( sizeValue ) );
00744       text += mimeComment();
00745   }
00746   else if ( S_ISDIR ( m_fileMode ) )
00747   {
00748       text += "/  ";
00749       text += mimeComment();
00750   }
00751   else
00752   {
00753       text += "  ";
00754       text += mimeComment();
00755   }
00756   text.replace('\n', " "); // replace any newlines with a space, so the statusbar doesn't get a two-line string which messes the display up, Alex
00757   return text;
00758 }
00759 
00760 QString KFileItem::getToolTipText(int maxcount)
00761 {
00762   // we can return QString::null if no tool tip should be shown
00763   QString tip;
00764   KFileMetaInfo info = metaInfo();
00765 
00766   // the font tags are a workaround for the fact that the tool tip gets
00767   // screwed if the color scheme uses white as default text color
00768   const char* start = "<tr><td><nobr><font color=\"black\">";
00769   const char* mid   = "</font></nobr></td><td><nobr><font color=\"black\">";
00770   const char* end   = "</font></nobr></td></tr>";
00771 
00772   tip = "<table cellspacing=0 cellpadding=0>";
00773 
00774   tip += start + i18n("Name:") + mid + text() + end;
00775   tip += start + i18n("Type:") + mid;
00776 
00777   QString type = QStyleSheet::escape(mimeComment());
00778   if ( m_bLink ) {
00779    tip += i18n("Link to %1 (%2)").arg(linkDest(), type) + end;
00780   } else
00781     tip += type + end;
00782 
00783   if ( !S_ISDIR ( m_fileMode ) ) {
00784     bool hasSize;
00785     KIO::filesize_t sizeValue = size(hasSize);
00786     if(hasSize)
00787       tip += start + i18n("Size:") + mid +
00788              KIO::convertSizeWithBytes(sizeValue) + end;
00789   }
00790   QString timeStr = timeString( KIO::UDS_MODIFICATION_TIME);
00791   if(!timeStr.isEmpty())
00792     tip += start + i18n("Modified:") + mid +
00793            timeStr + end;
00794 #ifndef Q_WS_WIN //TODO: show win32-specific permissions
00795   QString userStr = user();
00796   QString groupStr = group();
00797   if(!userStr.isEmpty() || !groupStr.isEmpty())
00798     tip += start + i18n("Owner:") + mid + userStr + " - " + groupStr + end +
00799            start + i18n("Permissions:") + mid +
00800            parsePermissions(m_permissions) + end;
00801 #endif
00802 
00803   if (info.isValid() && !info.isEmpty() )
00804   {
00805     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>";
00806     QStringList keys = info.preferredKeys();
00807 
00808     // now the rest
00809     QStringList::Iterator it = keys.begin();
00810     for (int count = 0; count<maxcount && it!=keys.end() ; ++it)
00811     {
00812       KFileMetaInfoItem item = info.item( *it );
00813       if ( item.isValid() )
00814       {
00815         QString s = item.string();
00816         if ( ( item.attributes() & KFileMimeTypeInfo::SqueezeText )
00817              && s.length() > 50) {
00818             s.truncate(47);
00819             s.append("...");
00820         }
00821         if ( !s.isEmpty() )
00822         {
00823           count++;
00824           tip += start +
00825                    QStyleSheet::escape( item.translatedKey() ) + ":" +
00826                  mid +
00827                    QStyleSheet::escape( s ) +
00828                  end;
00829         }
00830 
00831       }
00832     }
00833   }
00834   tip += "</table>";
00835 
00836   //kdDebug() << "making this the tool tip rich text:\n";
00837   //kdDebug() << tip << endl;
00838 
00839   return tip;
00840 }
00841 
00842 void KFileItem::run()
00843 {
00844   // It might be faster to pass skip that when we know the mimetype,
00845   // and just call KRun::runURL. But then we need to use mostLocalURL()
00846   // for application/x-desktop files, to be able to execute them.
00847   (void) new KRun( m_url, m_fileMode, m_bIsLocalURL );
00848 }
00849 
00850 bool KFileItem::cmp( const KFileItem & item )
00851 {
00852     bool hasSize1,hasSize2,hasTime1,hasTime2;
00853     hasSize1 = hasSize2 = hasTime1 = hasTime2 = false;
00854     return ( m_strName == item.m_strName
00855              && m_bIsLocalURL == item.m_bIsLocalURL
00856              && m_fileMode == item.m_fileMode
00857              && m_permissions == item.m_permissions
00858              && m_user == item.m_user
00859              && m_group == item.m_group
00860              && m_bLink == item.m_bLink
00861              && m_hidden == item.m_hidden
00862              && size(hasSize1) == item.size(hasSize2)
00863          && hasSize1 == hasSize2
00864              && time(KIO::UDS_MODIFICATION_TIME, hasTime1) == item.time(KIO::UDS_MODIFICATION_TIME, hasTime2)
00865          && hasTime1 == hasTime2
00866              && (!d || !item.d || d->iconName == item.d->iconName) );
00867 
00868     // Don't compare the mimetypes here. They might not be known, and we don't want to
00869     // do the slow operation of determining them here.
00870 }
00871 
00872 void KFileItem::assign( const KFileItem & item )
00873 {
00874     if ( this == &item )
00875         return;
00876     m_entry = item.m_entry;
00877     m_url = item.m_url;
00878     m_bIsLocalURL = item.m_bIsLocalURL;
00879     m_strName = item.m_strName;
00880     m_strText = item.m_strText;
00881     m_fileMode = item.m_fileMode;
00882     m_permissions = item.m_permissions;
00883     m_user = item.m_user;
00884     m_group = item.m_group;
00885     m_bLink = item.m_bLink;
00886     m_pMimeType = item.m_pMimeType;
00887     m_strLowerCaseName = item.m_strLowerCaseName;
00888     m_bMimeTypeKnown = item.m_bMimeTypeKnown;
00889     m_hidden = item.m_hidden;
00890     m_guessedMimeType   = item.m_guessedMimeType;
00891     m_access            = item.m_access;
00892     m_metaInfo          = item.m_metaInfo;
00893     for ( int i = 0; i < NumFlags; i++ )
00894         m_time[i] = item.m_time[i];
00895     m_size = item.m_size;
00896     // note: m_extra is NOT copied, as we'd have no control over who is
00897     // deleting the data or not.
00898 
00899     // We had a mimetype previously (probably), so we need to re-determine it
00900     determineMimeType();
00901 
00902     if ( item.d ) {
00903         if ( !d )
00904             d = new KFileItemPrivate;
00905         d->iconName = item.d->iconName;
00906     } else {
00907         delete d;
00908         d = 0;
00909     }
00910 }
00911 
00912 void KFileItem::setUDSEntry( const KIO::UDSEntry& _entry, const KURL& _url,
00913     bool _determineMimeTypeOnDemand, bool _urlIsDirectory )
00914 {
00915   m_entry = _entry;
00916   m_url = _url;
00917   m_strName = QString::null;
00918   m_strText = QString::null;
00919   m_user = QString::null;
00920   m_group = QString::null;
00921   m_strLowerCaseName = QString::null;
00922   m_pMimeType = 0;
00923   m_fileMode = KFileItem::Unknown;
00924   m_permissions = KFileItem::Unknown;
00925   m_bMarked = false;
00926   m_bLink = false;
00927   m_bIsLocalURL = _url.isLocalFile();
00928   m_bMimeTypeKnown = false;
00929   m_hidden = Auto;
00930   m_guessedMimeType = QString::null;
00931   m_metaInfo = KFileMetaInfo();
00932 
00933   if ( d )
00934     d->iconName = QString::null;
00935 
00936   readUDSEntry( _urlIsDirectory );
00937   init( _determineMimeTypeOnDemand );
00938 }
00939 
00940 void KFileItem::setFileMode( mode_t m )
00941 {
00942   m_fileMode = m;
00943 }
00944 
00945 void KFileItem::setMimeType( const QString& mimetype )
00946 {
00947     m_pMimeType = KMimeType::mimeType( mimetype );
00948 }
00949 
00950 void KFileItem::setExtraData( const void *key, void *value )
00951 {
00952     if ( !key )
00953         return;
00954 
00955     m_extra.replace( key, value );
00956 }
00957 
00958 const void * KFileItem::extraData( const void *key ) const
00959 {
00960     QMapConstIterator<const void*,void*> it = m_extra.find( key );
00961     if ( it != m_extra.end() )
00962         return it.data();
00963     return 0L;
00964 }
00965 
00966 void * KFileItem::extraData( const void *key )
00967 {
00968     QMapIterator<const void*,void*> it = m_extra.find( key );
00969     if ( it != m_extra.end() )
00970         return it.data();
00971     return 0L;
00972 }
00973 
00974 void KFileItem::removeExtraData( const void *key )
00975 {
00976     m_extra.remove( key );
00977 }
00978 
00979 QString KFileItem::permissionsString() const
00980 {
00981     if (m_access.isNull())
00982       m_access = parsePermissions( m_permissions );
00983 
00984     return m_access;
00985 }
00986 
00987 QString KFileItem::parsePermissions(mode_t perm) const
00988 {
00989     char p[] = "---------- ";
00990 
00991     if (isDir())
00992     p[0]='d';
00993     else if (isLink())
00994     p[0]='l';
00995 
00996     if (perm & QFileInfo::ReadUser)
00997     p[1]='r';
00998     if (perm & QFileInfo::WriteUser)
00999         p[2]='w';
01000     if ((perm & QFileInfo::ExeUser) && !(perm & S_ISUID)) p[3]='x';
01001     else if ((perm & QFileInfo::ExeUser) && (perm & S_ISUID)) p[3]='s';
01002     else if (!(perm & QFileInfo::ExeUser) && (perm & S_ISUID)) p[3]='S';
01003 
01004     if (perm & QFileInfo::ReadGroup)
01005     p[4]='r';
01006     if (perm & QFileInfo::WriteGroup)
01007         p[5]='w';
01008     if ((perm & QFileInfo::ExeGroup) && !(perm & S_ISGID)) p[6]='x';
01009     else if ((perm & QFileInfo::ExeGroup) && (perm & S_ISGID)) p[6]='s';
01010     else if (!(perm & QFileInfo::ExeGroup) && (perm & S_ISGID)) p[6]='S';
01011 
01012     if (perm & QFileInfo::ReadOther)
01013     p[7]='r';
01014     if (perm & QFileInfo::WriteOther)
01015         p[8]='w';
01016     if ((perm & QFileInfo::ExeOther) && !(perm & S_ISVTX)) p[9]='x';
01017     else if ((perm & QFileInfo::ExeOther) && (perm & S_ISVTX)) p[9]='t';
01018     else if (!(perm & QFileInfo::ExeOther) && (perm & S_ISVTX)) p[9]='T';
01019 
01020     if (hasExtendedACL())
01021         p[10]='+';
01022 
01023     return QString::fromLatin1(p);
01024 }
01025 
01026 // check if we need to cache this
01027 QString KFileItem::timeString( unsigned int which ) const
01028 {
01029     bool hasTime;
01030     time_t time_ = time(which, hasTime);
01031     if(!hasTime) return QString::null;
01032 
01033     QDateTime t;
01034     t.setTime_t( time_);
01035     return KGlobal::locale()->formatDateTime( t );
01036 }
01037 
01038 void KFileItem::setMetaInfo( const KFileMetaInfo & info )
01039 {
01040     m_metaInfo = info;
01041 }
01042 
01043 const KFileMetaInfo & KFileItem::metaInfo(bool autoget, int) const
01044 {
01045     bool isLocalURL;
01046     KURL url = mostLocalURL(isLocalURL);
01047 
01048     if ( autoget && !m_metaInfo.isValid() &&
01049          KGlobalSettings::showFilePreview(url) )
01050     {
01051         m_metaInfo = KFileMetaInfo( url, mimetype() );
01052     }
01053 
01054     return m_metaInfo;
01055 }
01056 
01057 KURL KFileItem::mostLocalURL(bool &local) const
01058 {
01059     QString local_path = localPath();
01060 
01061     if ( !local_path.isEmpty() )
01062     {
01063         local = true;
01064         KURL url;
01065         url.setPath(local_path);
01066         return url;
01067     }
01068     else
01069     {
01070         local = m_bIsLocalURL;
01071         return m_url;
01072     }
01073 }
01074 
01075 void KFileItem::virtual_hook( int, void* )
01076 { /*BASE::virtual_hook( id, data );*/ }
01077 
01078 QDataStream & operator<< ( QDataStream & s, const KFileItem & a )
01079 {
01080     // We don't need to save/restore anything that refresh() invalidates,
01081     // since that means we can re-determine those by ourselves.
01082     s << a.m_url;
01083     s << a.m_strName;
01084     s << a.m_strText;
01085     return s;
01086 }
01087 
01088 QDataStream & operator>> ( QDataStream & s, KFileItem & a )
01089 {
01090     s >> a.m_url;
01091     s >> a.m_strName;
01092     s >> a.m_strText;
01093     a.m_bIsLocalURL = a.m_url.isLocalFile();
01094     a.m_bMimeTypeKnown = false;
01095     a.refresh();
01096     return s;
01097 }

kio

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

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
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