25 #include <sys/types.h>
30 #include "kfileitem.h"
35 #include <tqstylesheet.h>
38 #include <kfilemetainfo.h>
39 #include <ksambashare.h>
40 #include <knfsshare.h>
42 #include <kglobalsettings.h>
43 #include <kiconloader.h>
44 #include <klargefile.h>
46 #include <kmimetype.h>
49 class KFileItem::KFileItemPrivate {
55 bool _determineMimeTypeOnDemand,
bool _urlIsDirectory ) :
63 m_bIsLocalURL( _url.isLocalFile() ),
64 m_bMimeTypeKnown( false ),
69 init( _determineMimeTypeOnDemand );
72 KFileItem::KFileItem( mode_t _mode, mode_t _permissions,
const KURL& _url,
bool _determineMimeTypeOnDemand ) :
75 m_strName( _url.fileName() ),
76 m_strText( KIO::decodeFileName( m_strName ) ),
79 m_permissions( _permissions ),
82 m_bIsLocalURL( _url.isLocalFile() ),
83 m_bMimeTypeKnown( false ),
87 init( _determineMimeTypeOnDemand );
92 m_strName( url.fileName() ),
93 m_strText( KIO::decodeFileName( m_strName ) ),
99 m_bIsLocalURL( url.isLocalFile() ),
100 m_bMimeTypeKnown( !mimeType.isEmpty() ),
104 if (m_bMimeTypeKnown)
129 m_access = TQString::null;
132 for (
int i = 0; i < NumFlags; i++ )
133 m_time[i] = (time_t) -1;
136 if ( m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown )
139 if ( m_url.isLocalFile() )
149 TQCString path = TQFile::encodeName(m_url.path( -1 ));
150 if ( KDE_lstat( path.data(), &buf ) == 0 )
153 if ( S_ISLNK( mode ) )
156 if ( KDE_stat( path.data(), &buf ) == 0 )
159 mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO;
162 m_time[ Modification ] = buf.st_mtime;
163 m_time[ Access ] = buf.st_atime;
164 if ( m_fileMode == KFileItem::Unknown )
165 m_fileMode = mode & S_IFMT;
166 if ( m_permissions == KFileItem::Unknown )
167 m_permissions = mode & 07777;
173 if (!m_pMimeType && !m_url.isEmpty())
175 bool accurate =
false;
181 _determineMimeTypeOnDemand, &accurate );
185 m_bMimeTypeKnown = (!_determineMimeTypeOnDemand) || accurate;
192 bool UDS_URL_seen =
false;
194 if (&m_entry == NULL)
return;
196 KIO::UDSEntry::ConstIterator it = m_entry.begin();
197 for( ; it != m_entry.end(); ++it ) {
198 switch ((*it).m_uds) {
201 m_fileMode = (mode_t)((*it).m_long);
205 m_permissions = (mode_t)((*it).m_long);
209 m_user = ((*it).m_str);
213 m_group = ((*it).m_str);
217 m_strName = (*it).m_str;
223 m_url = KURL((*it).m_str);
224 if ( m_url.isLocalFile() )
225 m_bIsLocalURL =
true;
230 m_bMimeTypeKnown =
true;
234 m_guessedMimeType = (*it).m_str;
238 m_bLink = !(*it).m_str.isEmpty();
243 d =
new KFileItemPrivate();
244 d->iconName = (*it).m_str;
257 static const TQString& dot = KGlobal::staticQString(
".");
258 if ( _urlIsDirectory && !UDS_URL_seen && !m_strName.isEmpty() && m_strName != dot )
259 m_url.addPath( m_strName );
264 m_fileMode = KFileItem::Unknown;
265 m_permissions = KFileItem::Unknown;
267 m_user = TQString::null;
268 m_group = TQString::null;
300 if (&m_entry == NULL)
return TQString::null;
303 KIO::UDSEntry::ConstIterator it = m_entry.begin();
304 for( ; it != m_entry.end(); ++it )
311 int n = readlink( TQFile::encodeName(m_url.path( -1 )), buf,
sizeof(buf)-1 );
315 return TQFile::decodeName( buf );
318 return TQString::null;
329 if (&m_entry == NULL)
return TQString::null;
332 KIO::UDSEntry::ConstIterator it = m_entry.begin();
333 const KIO::UDSEntry::ConstIterator end = m_entry.end();
334 for( ; it != end; ++it )
339 return TQString::null;
348 if (&m_entry == NULL)
return 0L;
351 KIO::UDSEntry::ConstIterator it = m_entry.begin();
352 for( ; it != m_entry.end(); ++it )
354 m_size = (*it).m_long;
361 if ( KDE_stat( TQFile::encodeName(m_url.path( -1 )), &buf ) == 0 )
370 if (&m_entry == NULL)
return false;
371 KIO::UDSEntry::ConstIterator it = m_entry.begin();
372 for( ; it != m_entry.end(); it++ )
382 if (&m_entry == NULL)
return KACL( m_permissions );
385 KIO::UDSEntry::ConstIterator it = m_entry.begin();
386 for( ; it != m_entry.end(); ++it )
388 return KACL((*it).m_str);
391 return KACL( m_permissions );
396 if (&m_entry == NULL)
return KACL();
399 KIO::UDSEntry::ConstIterator it = m_entry.begin();
400 for( ; it != m_entry.end(); ++it )
402 return KACL((*it).m_str);
415 return time(which, hasTime);
420 unsigned int mappedWhich = 0;
424 mappedWhich = Modification;
427 mappedWhich = Access;
430 mappedWhich = Creation;
434 if ( m_time[mappedWhich] != (time_t) -1 )
435 return m_time[mappedWhich];
437 if (&m_entry == NULL)
return static_cast<time_t
>(0);
440 KIO::UDSEntry::ConstIterator it = m_entry.begin();
441 for( ; it != m_entry.end(); ++it )
442 if ( (*it).m_uds == which ) {
443 m_time[mappedWhich] =
static_cast<time_t
>((*it).m_long);
444 return m_time[mappedWhich];
451 if ( KDE_stat( TQFile::encodeName(m_url.path(-1)), &buf ) == 0 )
456 m_time[mappedWhich] =
static_cast<time_t
>(0);
457 return m_time[mappedWhich];
463 return m_time[mappedWhich];
467 return static_cast<time_t
>(0);
473 if ( m_user.isEmpty() && m_bIsLocalURL )
475 KDE_struct_stat buff;
476 if ( KDE_lstat( TQFile::encodeName(m_url.path( -1 )), &buff ) == 0)
478 struct passwd *
user = getpwuid( buff.st_uid );
480 m_user = TQString::fromLocal8Bit(user->pw_name);
489 if (m_group.isEmpty() && m_bIsLocalURL )
491 KDE_struct_stat buff;
492 if ( KDE_lstat( TQFile::encodeName(m_url.path( -1 )), &buff ) == 0)
494 struct group *ge = getgrgid( buff.st_gid );
496 m_group = TQString::fromLocal8Bit(ge->gr_name);
497 if (m_group.isEmpty())
498 m_group.sprintf(
"%d",ge->gr_gid);
500 m_group.sprintf(
"%d",buff.st_gid);
515 if ( !m_pMimeType || !m_bMimeTypeKnown )
522 m_bMimeTypeKnown =
true;
528 bool KFileItem::isMimeTypeKnown()
const
533 return m_bMimeTypeKnown && m_guessedMimeType.isEmpty();
543 TQString comment = mType->comment( url, isLocalURL );
545 if (!comment.isEmpty())
548 return mType->name();
553 if (d && (!d->iconName.isEmpty()))
return d->iconName;
566 _state |= KIcon::LinkOverlay;
568 if ( !S_ISDIR( m_fileMode )
570 _state |= KIcon::LockOverlay;
573 _state |= KIcon::HiddenOverlay;
575 if( S_ISDIR( m_fileMode ) && m_bIsLocalURL)
581 _state |= KIcon::ShareOverlay;
585 if ( m_pMimeType->name() ==
"application/x-gzip" && m_url.fileName().right(3) ==
".gz" )
586 _state |= KIcon::ZipOverlay;
592 if (d && (!d->iconName.isEmpty()))
593 return DesktopIcon(d->iconName,_size,_state);
597 static const TQString & defaultFolderIcon =
600 if ( S_ISDIR( m_fileMode ) )
601 return DesktopIcon( defaultFolderIcon, _size, _state );
603 return DesktopIcon(
"unknown", _size, _state );
610 if ( !m_bMimeTypeKnown && !m_guessedMimeType.isEmpty() )
617 if ( mime->name() ==
"application/x-gzip" && m_url.fileName().right(3) ==
".gz" )
620 sf.setPath( m_url.path().left( m_url.path().length() - 3 ) );
628 TQPixmap p = mime->pixmap( url, KIcon::Desktop, _size, _state );
631 kdWarning() <<
"Pixmap not found for mimetype " << m_pMimeType->name() << endl;
646 if ( m_permissions != KFileItem::Unknown ) {
648 if ( !(S_IRUSR & m_permissions) && !(S_IRGRP & m_permissions) && !(S_IROTH & m_permissions) )
652 if ( (S_IRUSR|S_IRGRP|S_IROTH) & m_permissions )
657 if ( m_bIsLocalURL && ::access( TQFile::encodeName(m_url.path()), R_OK ) == -1 )
673 if ( m_permissions != KFileItem::Unknown ) {
675 if ( !(S_IWUSR & m_permissions) && !(S_IWGRP & m_permissions) && !(S_IWOTH & m_permissions) )
680 if ( m_bIsLocalURL && ::access( TQFile::encodeName(m_url.path()), W_OK ) == -1 )
688 if ( m_hidden != Auto )
689 return m_hidden == Hidden;
691 if ( !m_url.isEmpty() )
692 return m_url.fileName()[0] ==
'.';
694 return m_strName[0] ==
'.';
699 if ( m_fileMode == KFileItem::Unknown )
701 kdDebug() <<
" KFileItem::isDir can't say -> false " << endl;
704 return (S_ISDIR(m_fileMode));
718 if ( S_ISDIR(
mode() ) ) {
723 if ( !m_bIsLocalURL )
726 if ((
mimetype() ==
"application/x-desktop") ||
727 (
mimetype() ==
"media/builtin-mydocuments") ||
728 (
mimetype() ==
"media/builtin-mycomputer") ||
729 (
mimetype() ==
"media/builtin-mynetworkplaces") ||
730 (
mimetype() ==
"media/builtin-printers") ||
731 (
mimetype() ==
"media/builtin-trash") ||
732 (
mimetype() ==
"media/builtin-webbrowser"))
736 if ( ::access( TQFile::encodeName(m_url.path()), X_OK ) == 0 )
744 TQString
text = m_strText;
750 if ( comment.isEmpty() )
751 tmp = i18n (
"Symbolic Link" );
753 tmp = i18n(
"%1 (Link)").arg(comment);
759 else if ( S_ISREG( m_fileMode ) )
767 else if ( S_ISDIR ( m_fileMode ) )
777 text.replace(
'\n',
" ");
789 const char* start =
"<tr><td><nobr><font color=\"black\">";
790 const char* mid =
"</font></nobr></td><td><nobr><font color=\"black\">";
791 const char* end =
"</font></nobr></td></tr>";
793 tip =
"<table cellspacing=0 cellpadding=0>";
795 tip += start + i18n(
"Name:") + mid +
text() + end;
796 tip += start + i18n(
"Type:") + mid;
798 TQString type = TQStyleSheet::escape(
mimeComment());
800 tip += i18n(
"Link to %1 (%2)").arg(
linkDest(), type) + end;
804 if ( !S_ISDIR ( m_fileMode ) ) {
808 tip += start + i18n(
"Size:") + mid +
812 if(!timeStr.isEmpty())
813 tip += start + i18n(
"Modified:") + mid +
815 #ifndef Q_WS_WIN //TODO: show win32-specific permissions
816 TQString userStr =
user();
817 TQString groupStr =
group();
818 if(!userStr.isEmpty() || !groupStr.isEmpty())
819 tip += start + i18n(
"Owner:") + mid + userStr +
" - " + groupStr + end +
820 start + i18n(
"Permissions:") + mid +
826 tip +=
"<tr><td colspan=2><center><s> </s></center></td></tr>";
830 TQStringList::Iterator it = keys.begin();
831 for (
int count = 0; count<maxcount && it!=keys.end() ; ++it)
836 TQString s = item.
string();
838 && s.length() > 50) {
848 TQStyleSheet::escape( s ) +
868 (void)
new KRun( m_url, m_fileMode, m_bIsLocalURL );
873 bool hasSize1,hasSize2,hasTime1,hasTime2;
874 hasSize1 = hasSize2 = hasTime1 = hasTime2 =
false;
875 return ( m_strName == item.m_strName
876 && m_bIsLocalURL == item.m_bIsLocalURL
877 && m_fileMode == item.m_fileMode
878 && m_permissions == item.m_permissions
879 && m_user == item.m_user
880 && m_group == item.m_group
881 && m_bLink == item.m_bLink
882 && m_hidden == item.m_hidden
883 &&
size(hasSize1) == item.
size(hasSize2)
884 && hasSize1 == hasSize2
886 && hasTime1 == hasTime2
887 && (!d || !item.d || d->iconName == item.d->iconName) );
897 m_entry = item.m_entry;
899 m_bIsLocalURL = item.m_bIsLocalURL;
900 m_strName = item.m_strName;
901 m_strText = item.m_strText;
902 m_fileMode = item.m_fileMode;
903 m_permissions = item.m_permissions;
904 m_user = item.m_user;
905 m_group = item.m_group;
906 m_bLink = item.m_bLink;
907 m_pMimeType = item.m_pMimeType;
908 m_strLowerCaseName = item.m_strLowerCaseName;
909 m_bMimeTypeKnown = item.m_bMimeTypeKnown;
910 m_hidden = item.m_hidden;
911 m_guessedMimeType = item.m_guessedMimeType;
912 m_access = item.m_access;
913 m_metaInfo = item.m_metaInfo;
914 for (
int i = 0; i < NumFlags; i++ )
915 m_time[i] = item.m_time[i];
916 m_size = item.m_size;
925 d =
new KFileItemPrivate;
926 d->iconName = item.d->iconName;
934 bool _determineMimeTypeOnDemand,
bool _urlIsDirectory )
938 m_strName = TQString::null;
939 m_strText = TQString::null;
940 m_user = TQString::null;
941 m_group = TQString::null;
942 m_strLowerCaseName = TQString::null;
944 m_fileMode = KFileItem::Unknown;
945 m_permissions = KFileItem::Unknown;
948 m_bIsLocalURL = _url.isLocalFile();
949 m_bMimeTypeKnown =
false;
951 m_guessedMimeType = TQString::null;
955 d->iconName = TQString::null;
958 init( _determineMimeTypeOnDemand );
976 m_extra.replace( key, value );
981 TQMapConstIterator<const void*,void*> it = m_extra.find( key );
982 if ( it != m_extra.end() )
989 TQMapIterator<const void*,void*> it = m_extra.find( key );
990 if ( it != m_extra.end() )
997 m_extra.remove( key );
1002 if (m_access.isNull())
1010 char p[] =
"---------- ";
1017 if (perm & TQFileInfo::ReadUser)
1019 if (perm & TQFileInfo::WriteUser)
1021 if ((perm & TQFileInfo::ExeUser) && !(perm & S_ISUID)) p[3]=
'x';
1022 else if ((perm & TQFileInfo::ExeUser) && (perm & S_ISUID)) p[3]=
's';
1023 else if (!(perm & TQFileInfo::ExeUser) && (perm & S_ISUID)) p[3]=
'S';
1025 if (perm & TQFileInfo::ReadGroup)
1027 if (perm & TQFileInfo::WriteGroup)
1029 if ((perm & TQFileInfo::ExeGroup) && !(perm & S_ISGID)) p[6]=
'x';
1030 else if ((perm & TQFileInfo::ExeGroup) && (perm & S_ISGID)) p[6]=
's';
1031 else if (!(perm & TQFileInfo::ExeGroup) && (perm & S_ISGID)) p[6]=
'S';
1033 if (perm & TQFileInfo::ReadOther)
1035 if (perm & TQFileInfo::WriteOther)
1037 if ((perm & TQFileInfo::ExeOther) && !(perm & S_ISVTX)) p[9]=
'x';
1038 else if ((perm & TQFileInfo::ExeOther) && (perm & S_ISVTX)) p[9]=
't';
1039 else if (!(perm & TQFileInfo::ExeOther) && (perm & S_ISVTX)) p[9]=
'T';
1044 return TQString::fromLatin1(p);
1051 time_t time_ =
time(which, hasTime);
1052 if(!hasTime)
return TQString::null;
1055 t.setTime_t( time_);
1056 return KGlobal::locale()->formatDateTime( t );
1069 if ( autoget && !m_metaInfo.
isValid() &&
1070 KGlobalSettings::showFilePreview(url) )
1082 if ( !local_path.isEmpty() )
1086 url.setPath(local_path);
1091 local = m_bIsLocalURL;
1096 void KFileItem::virtual_hook(
int,
void* )
1099 TQDataStream & operator<< ( TQDataStream & s,
const KFileItem & a )
1109 TQDataStream & operator>> ( TQDataStream & s,
KFileItem & a )
1114 a.m_bIsLocalURL = a.m_url.isLocalFile();
1115 a.m_bMimeTypeKnown =
false;