• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeio/tdeio
 

tdeio/tdeio

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

tdeio/tdeio

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

tdeio/tdeio

Skip menu "tdeio/tdeio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeio/tdeio by doxygen 1.7.1
This website is maintained by Timothy Pearson.