kio Library API Documentation

kfileitem.cpp

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