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