00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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(),
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
00147 for ( int i = 0; i < NumFlags; i++ ) {
00148 m_time[i] = (time_t) -1;
00149 }
00150
00151
00152 if ( m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown )
00153 {
00154 mode_t mode = 0;
00155 if ( m_url.isLocalFile() )
00156 {
00157
00158
00159
00160
00161
00162
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 {
00176 mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO;
00177 }
00178 }
00179
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;
00184 }
00185 if ( m_permissions == KFileItem::Unknown ) {
00186 m_permissions = mode & 07777;
00187 }
00188 }
00189 }
00190 }
00191
00192
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
00201 _determineMimeTypeOnDemand, &accurate );
00202
00203
00204
00205 m_bMimeTypeKnown = (!_determineMimeTypeOnDemand) || accurate;
00206 }
00207 }
00208
00209 void KFileItem::readUDSEntry( bool _urlIsDirectory )
00210 {
00211
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();
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
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
00296
00297
00298
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 );
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
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
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
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
00376
00377 if ((!m_url.isLocalFile())) {
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
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
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
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
00435 return KACL( m_permissions );
00436 }
00437
00438 KACL KFileItem::defaultACL() const
00439 {
00440 if (&m_entry == NULL) return KACL();
00441
00442
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
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
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
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
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)
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)
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
00581 m_bMimeTypeKnown = true;
00582 }
00583
00584 return m_pMimeType;
00585 }
00586
00587 bool KFileItem::isMimeTypeKnown() const
00588 {
00589
00590
00591
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
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
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 )
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
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
00680 if ( !m_bMimeTypeKnown && !m_guessedMimeType.isEmpty() )
00681 mime = KMimeType::mimeType( m_guessedMimeType );
00682 else
00683 mime = m_pMimeType;
00684
00685
00686
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
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
00700 if (p.isNull())
00701 kdWarning() << "Pixmap not found for mimetype " << m_pMimeType->name() << endl;
00702
00703 if ( mime->name() == "application/x-executable" ) {
00704
00705
00706
00707
00708
00709 #ifdef HAVE_ELFICON
00710
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
00726
00727 int iconresnamefound = 0;
00728 iconentry *entry = NULL;
00729 iconlist icons;
00730 if(!get_iconlist(handle, &icons))
00731 {
00732
00733 kdDebug() << "failed to obtain ELF icon from " << url.path() << ": " << libr_errmsg() << endl;
00734
00735
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
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
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);
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
00787
00788
00789
00790
00791
00792
00793 if ( m_permissions != KFileItem::Unknown ) {
00794
00795 if ( !(S_IRUSR & m_permissions) && !(S_IRGRP & m_permissions) && !(S_IROTH & m_permissions) )
00796 return false;
00797
00798
00799 if ( (S_IRUSR|S_IRGRP|S_IROTH) & m_permissions )
00800 return true;
00801 }
00802
00803
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
00814
00815
00816
00817
00818
00819
00820 if ( m_permissions != KFileItem::Unknown ) {
00821
00822 if ( !(S_IWUSR & m_permissions) && !(S_IWGRP & m_permissions) && !(S_IWOTH & m_permissions) )
00823 return false;
00824 }
00825
00826
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
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;
00850 }
00851 return (S_ISDIR(m_fileMode));
00852
00853
00854
00855
00856
00857
00858
00859
00860 }
00861
00862 bool KFileItem::acceptsDrops()
00863 {
00864
00865 if ( S_ISDIR( mode() ) ) {
00866 return isWritable();
00867 }
00868
00869
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
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', " ");
00931 return text;
00932 }
00933
00934 TQString KFileItem::getToolTipText(int maxcount)
00935 {
00936
00937 TQString tip;
00938 KFileMetaInfo info = metaInfo();
00939
00940
00941
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> </s></center></td></tr>";
00980 TQStringList keys = info.preferredKeys();
00981
00982
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
01011
01012
01013 return tip;
01014 }
01015
01016 void KFileItem::run()
01017 {
01018
01019
01020
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
01043
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
01071
01072
01073
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
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 { }
01255
01256 TQDataStream & operator<< ( TQDataStream & s, const KFileItem & a )
01257 {
01258
01259
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 }