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 {
51 KFileItemPrivate() : commentCached(false) {}
60 bool _determineMimeTypeOnDemand,
bool _urlIsDirectory ) :
68 m_bIsLocalURL( _url.isLocalFile() ),
69 m_bMimeTypeKnown( false ),
74 init( _determineMimeTypeOnDemand );
77 KFileItem::KFileItem( mode_t _mode, mode_t _permissions,
const KURL& _url,
bool _determineMimeTypeOnDemand ) :
80 m_strName( _url.fileName() ),
81 m_strText( KIO::decodeFileName( m_strName ) ),
84 m_permissions( _permissions ),
87 m_bIsLocalURL( _url.isLocalFile() ),
88 m_bMimeTypeKnown( false ),
92 init( _determineMimeTypeOnDemand );
97 m_strName( url.fileName() ),
98 m_strText( KIO::decodeFileName( m_strName ) ),
104 m_bIsLocalURL( url.isLocalFile() ),
105 m_bMimeTypeKnown( !mimeType.isEmpty() ),
109 if (m_bMimeTypeKnown)
134 m_access = TQString::null;
137 for (
int i = 0; i < NumFlags; i++ )
138 m_time[i] = (time_t) -1;
141 if ( m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown )
144 if ( m_url.isLocalFile() )
154 TQCString path = TQFile::encodeName(m_url.path( -1 ));
155 if ( KDE_lstat( path.data(), &buf ) == 0 )
158 if ( S_ISLNK( mode ) )
161 if ( KDE_stat( path.data(), &buf ) == 0 )
164 mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO;
167 m_time[ Modification ] = buf.st_mtime;
168 m_time[ Access ] = buf.st_atime;
169 if ( m_fileMode == KFileItem::Unknown )
170 m_fileMode = mode & S_IFMT;
171 if ( m_permissions == KFileItem::Unknown )
172 m_permissions = mode & 07777;
178 if (!m_pMimeType && !m_url.isEmpty())
180 bool accurate =
false;
186 _determineMimeTypeOnDemand, &accurate );
190 m_bMimeTypeKnown = (!_determineMimeTypeOnDemand) || accurate;
197 bool UDS_URL_seen =
false;
199 if (&m_entry == NULL)
return;
201 KIO::UDSEntry::ConstIterator it = m_entry.begin();
202 for( ; it != m_entry.end(); ++it ) {
203 switch ((*it).m_uds) {
206 m_fileMode = (mode_t)((*it).m_long);
210 m_permissions = (mode_t)((*it).m_long);
214 m_user = ((*it).m_str);
218 m_group = ((*it).m_str);
222 m_strName = (*it).m_str;
228 m_url = KURL((*it).m_str);
229 if ( m_url.isLocalFile() )
230 m_bIsLocalURL =
true;
235 m_bMimeTypeKnown =
true;
239 m_guessedMimeType = (*it).m_str;
243 m_bLink = !(*it).m_str.isEmpty();
248 d =
new KFileItemPrivate();
250 d->iconName = (*it).m_str;
263 static const TQString& dot = KGlobal::staticQString(
".");
264 if ( _urlIsDirectory && !UDS_URL_seen && !m_strName.isEmpty() && m_strName != dot )
265 m_url.addPath( m_strName );
270 m_fileMode = KFileItem::Unknown;
271 m_permissions = KFileItem::Unknown;
273 m_user = TQString::null;
274 m_group = TQString::null;
289 d->iconName = TQString::null;
290 d->comment = TQString::null;
291 d->commentCached =
false;
311 if (&m_entry == NULL)
return TQString::null;
314 KIO::UDSEntry::ConstIterator it = m_entry.begin();
315 for( ; it != m_entry.end(); ++it )
322 int n = readlink( TQFile::encodeName(m_url.path( -1 )), buf,
sizeof(buf)-1 );
326 return TQFile::decodeName( buf );
329 return TQString::null;
340 if (&m_entry == NULL)
return TQString::null;
343 KIO::UDSEntry::ConstIterator it = m_entry.begin();
344 const KIO::UDSEntry::ConstIterator end = m_entry.end();
345 for( ; it != end; ++it )
350 return TQString::null;
359 if (&m_entry == NULL)
return 0L;
362 KIO::UDSEntry::ConstIterator it = m_entry.begin();
363 for( ; it != m_entry.end(); ++it )
365 m_size = (*it).m_long;
372 if ( KDE_stat( TQFile::encodeName(m_url.path( -1 )), &buf ) == 0 )
381 if (&m_entry == NULL)
return false;
382 KIO::UDSEntry::ConstIterator it = m_entry.begin();
383 for( ; it != m_entry.end(); it++ )
393 if (&m_entry == NULL)
return KACL( m_permissions );
396 KIO::UDSEntry::ConstIterator it = m_entry.begin();
397 for( ; it != m_entry.end(); ++it )
399 return KACL((*it).m_str);
402 return KACL( m_permissions );
407 if (&m_entry == NULL)
return KACL();
410 KIO::UDSEntry::ConstIterator it = m_entry.begin();
411 for( ; it != m_entry.end(); ++it )
413 return KACL((*it).m_str);
426 return time(which, hasTime);
431 unsigned int mappedWhich = 0;
435 mappedWhich = Modification;
438 mappedWhich = Access;
441 mappedWhich = Creation;
445 if ( m_time[mappedWhich] != (time_t) -1 )
446 return m_time[mappedWhich];
448 if (&m_entry == NULL)
return static_cast<time_t
>(0);
451 KIO::UDSEntry::ConstIterator it = m_entry.begin();
452 for( ; it != m_entry.end(); ++it )
453 if ( (*it).m_uds == which ) {
454 m_time[mappedWhich] =
static_cast<time_t
>((*it).m_long);
455 return m_time[mappedWhich];
462 if ( KDE_stat( TQFile::encodeName(m_url.path(-1)), &buf ) == 0 )
467 m_time[mappedWhich] =
static_cast<time_t
>(0);
468 return m_time[mappedWhich];
474 return m_time[mappedWhich];
478 return static_cast<time_t
>(0);
484 if ( m_user.isEmpty() && m_bIsLocalURL )
486 KDE_struct_stat buff;
487 if ( KDE_lstat( TQFile::encodeName(m_url.path( -1 )), &buff ) == 0)
489 struct passwd *
user = getpwuid( buff.st_uid );
491 m_user = TQString::fromLocal8Bit(user->pw_name);
500 if (m_group.isEmpty() && m_bIsLocalURL )
502 KDE_struct_stat buff;
503 if ( KDE_lstat( TQFile::encodeName(m_url.path( -1 )), &buff ) == 0)
505 struct group *ge = getgrgid( buff.st_gid );
507 m_group = TQString::fromLocal8Bit(ge->gr_name);
508 if (m_group.isEmpty())
509 m_group.sprintf(
"%d",ge->gr_gid);
511 m_group.sprintf(
"%d",buff.st_gid);
526 if (isMimeTypeKnown()) {
530 return m_pMimeType->name();
541 if ( !m_pMimeType || !m_bMimeTypeKnown )
548 m_bMimeTypeKnown =
true;
554 bool KFileItem::isMimeTypeKnown()
const
559 return m_bMimeTypeKnown && m_guessedMimeType.isEmpty();
564 if (d && (d->commentCached))
return d->comment;
571 TQString comment = mType->comment( url, isLocalURL );
574 d =
new KFileItemPrivate();
576 if (!comment.isEmpty()) {
577 d->comment = comment;
578 d->commentCached =
true;
581 d->comment = mType->name();
582 d->commentCached =
true;
590 if (d && (!d->iconName.isEmpty()))
return d->iconName;
603 _state |= KIcon::LinkOverlay;
605 if ( !S_ISDIR( m_fileMode )
607 _state |= KIcon::LockOverlay;
610 _state |= KIcon::HiddenOverlay;
612 if( S_ISDIR( m_fileMode ) && m_bIsLocalURL)
618 _state |= KIcon::ShareOverlay;
622 if ( m_pMimeType->name() ==
"application/x-gzip" && m_url.fileName().right(3) ==
".gz" )
623 _state |= KIcon::ZipOverlay;
629 if (d && (!d->iconName.isEmpty()))
630 return DesktopIcon(d->iconName,_size,_state);
634 static const TQString & defaultFolderIcon =
637 if ( S_ISDIR( m_fileMode ) )
638 return DesktopIcon( defaultFolderIcon, _size, _state );
640 return DesktopIcon(
"unknown", _size, _state );
647 if ( !m_bMimeTypeKnown && !m_guessedMimeType.isEmpty() )
654 if ( mime->name() ==
"application/x-gzip" && m_url.fileName().right(3) ==
".gz" )
657 sf.setPath( m_url.path().left( m_url.path().length() - 3 ) );
665 TQPixmap p = mime->pixmap( url, KIcon::Desktop, _size, _state );
668 kdWarning() <<
"Pixmap not found for mimetype " << m_pMimeType->name() << endl;
683 if ( m_permissions != KFileItem::Unknown ) {
685 if ( !(S_IRUSR & m_permissions) && !(S_IRGRP & m_permissions) && !(S_IROTH & m_permissions) )
689 if ( (S_IRUSR|S_IRGRP|S_IROTH) & m_permissions )
694 if ( m_bIsLocalURL && ::access( TQFile::encodeName(m_url.path()), R_OK ) == -1 )
710 if ( m_permissions != KFileItem::Unknown ) {
712 if ( !(S_IWUSR & m_permissions) && !(S_IWGRP & m_permissions) && !(S_IWOTH & m_permissions) )
717 if ( m_bIsLocalURL && ::access( TQFile::encodeName(m_url.path()), W_OK ) == -1 )
725 if ( m_hidden != Auto )
726 return m_hidden == Hidden;
728 if ( !m_url.isEmpty() )
729 return m_url.fileName()[0] ==
'.';
731 return m_strName[0] ==
'.';
736 if ( m_fileMode == KFileItem::Unknown )
738 kdDebug() <<
" KFileItem::isDir can't say -> false " << endl;
741 return (S_ISDIR(m_fileMode));
755 if ( S_ISDIR(
mode() ) ) {
760 if ( !m_bIsLocalURL )
763 if ((
mimetype() ==
"application/x-desktop") ||
764 (
mimetype() ==
"media/builtin-mydocuments") ||
765 (
mimetype() ==
"media/builtin-mycomputer") ||
766 (
mimetype() ==
"media/builtin-mynetworkplaces") ||
767 (
mimetype() ==
"media/builtin-printers") ||
768 (
mimetype() ==
"media/builtin-trash") ||
769 (
mimetype() ==
"media/builtin-webbrowser"))
773 if ( ::access( TQFile::encodeName(m_url.path()), X_OK ) == 0 )
781 TQString
text = m_strText;
786 d =
new KFileItemPrivate();
788 if (!d->commentCached) {
790 d->commentCached =
true;
793 if ( d->comment.isEmpty() )
794 tmp = i18n (
"Symbolic Link" );
796 tmp = i18n(
"%1 (Link)").arg(d->comment);
802 else if ( S_ISREG( m_fileMode ) )
810 else if ( S_ISDIR ( m_fileMode ) )
820 text.replace(
'\n',
" ");
832 const char* start =
"<tr><td><nobr><font color=\"black\">";
833 const char* mid =
"</font></nobr></td><td><nobr><font color=\"black\">";
834 const char* end =
"</font></nobr></td></tr>";
836 tip =
"<table cellspacing=0 cellpadding=0>";
838 tip += start + i18n(
"Name:") + mid +
text() + end;
839 tip += start + i18n(
"Type:") + mid;
841 TQString type = TQStyleSheet::escape(
mimeComment());
843 tip += i18n(
"Link to %1 (%2)").arg(
linkDest(), type) + end;
847 if ( !S_ISDIR ( m_fileMode ) ) {
851 tip += start + i18n(
"Size:") + mid +
855 if(!timeStr.isEmpty())
856 tip += start + i18n(
"Modified:") + mid +
858 #ifndef Q_WS_WIN //TODO: show win32-specific permissions
859 TQString userStr =
user();
860 TQString groupStr =
group();
861 if(!userStr.isEmpty() || !groupStr.isEmpty())
862 tip += start + i18n(
"Owner:") + mid + userStr +
" - " + groupStr + end +
863 start + i18n(
"Permissions:") + mid +
869 tip +=
"<tr><td colspan=2><center><s> </s></center></td></tr>";
873 TQStringList::Iterator it = keys.begin();
874 for (
int count = 0; count<maxcount && it!=keys.end() ; ++it)
879 TQString s = item.
string();
881 && s.length() > 50) {
891 TQStyleSheet::escape( s ) +
911 (void)
new KRun( m_url, m_fileMode, m_bIsLocalURL );
916 bool hasSize1,hasSize2,hasTime1,hasTime2;
917 hasSize1 = hasSize2 = hasTime1 = hasTime2 =
false;
918 return ( m_strName == item.m_strName
919 && m_bIsLocalURL == item.m_bIsLocalURL
920 && m_fileMode == item.m_fileMode
921 && m_permissions == item.m_permissions
922 && m_user == item.m_user
923 && m_group == item.m_group
924 && m_bLink == item.m_bLink
925 && m_hidden == item.m_hidden
926 &&
size(hasSize1) == item.
size(hasSize2)
927 && hasSize1 == hasSize2
929 && hasTime1 == hasTime2
930 && (!d || !item.d || d->iconName == item.d->iconName) );
940 m_entry = item.m_entry;
942 m_bIsLocalURL = item.m_bIsLocalURL;
943 m_strName = item.m_strName;
944 m_strText = item.m_strText;
945 m_fileMode = item.m_fileMode;
946 m_permissions = item.m_permissions;
947 m_user = item.m_user;
948 m_group = item.m_group;
949 m_bLink = item.m_bLink;
950 m_pMimeType = item.m_pMimeType;
951 m_strLowerCaseName = item.m_strLowerCaseName;
952 m_bMimeTypeKnown = item.m_bMimeTypeKnown;
953 m_hidden = item.m_hidden;
954 m_guessedMimeType = item.m_guessedMimeType;
955 m_access = item.m_access;
956 m_metaInfo = item.m_metaInfo;
957 for (
int i = 0; i < NumFlags; i++ )
958 m_time[i] = item.m_time[i];
959 m_size = item.m_size;
968 d =
new KFileItemPrivate;
970 d->iconName = item.d->iconName;
978 bool _determineMimeTypeOnDemand,
bool _urlIsDirectory )
982 m_strName = TQString::null;
983 m_strText = TQString::null;
984 m_user = TQString::null;
985 m_group = TQString::null;
986 m_strLowerCaseName = TQString::null;
988 m_fileMode = KFileItem::Unknown;
989 m_permissions = KFileItem::Unknown;
992 m_bIsLocalURL = _url.isLocalFile();
993 m_bMimeTypeKnown =
false;
995 m_guessedMimeType = TQString::null;
999 d->iconName = TQString::null;
1000 d->comment = TQString::null;
1001 d->commentCached =
false;
1005 init( _determineMimeTypeOnDemand );
1023 m_extra.replace( key, value );
1028 TQMapConstIterator<const void*,void*> it = m_extra.find( key );
1029 if ( it != m_extra.end() )
1036 TQMapIterator<const void*,void*> it = m_extra.find( key );
1037 if ( it != m_extra.end() )
1044 m_extra.remove( key );
1049 if (m_access.isNull())
1057 char p[] =
"---------- ";
1064 if (perm & TQFileInfo::ReadUser)
1066 if (perm & TQFileInfo::WriteUser)
1068 if ((perm & TQFileInfo::ExeUser) && !(perm & S_ISUID)) p[3]=
'x';
1069 else if ((perm & TQFileInfo::ExeUser) && (perm & S_ISUID)) p[3]=
's';
1070 else if (!(perm & TQFileInfo::ExeUser) && (perm & S_ISUID)) p[3]=
'S';
1072 if (perm & TQFileInfo::ReadGroup)
1074 if (perm & TQFileInfo::WriteGroup)
1076 if ((perm & TQFileInfo::ExeGroup) && !(perm & S_ISGID)) p[6]=
'x';
1077 else if ((perm & TQFileInfo::ExeGroup) && (perm & S_ISGID)) p[6]=
's';
1078 else if (!(perm & TQFileInfo::ExeGroup) && (perm & S_ISGID)) p[6]=
'S';
1080 if (perm & TQFileInfo::ReadOther)
1082 if (perm & TQFileInfo::WriteOther)
1084 if ((perm & TQFileInfo::ExeOther) && !(perm & S_ISVTX)) p[9]=
'x';
1085 else if ((perm & TQFileInfo::ExeOther) && (perm & S_ISVTX)) p[9]=
't';
1086 else if (!(perm & TQFileInfo::ExeOther) && (perm & S_ISVTX)) p[9]=
'T';
1091 return TQString::fromLatin1(p);
1098 time_t time_ =
time(which, hasTime);
1099 if(!hasTime)
return TQString::null;
1102 t.setTime_t( time_);
1103 return KGlobal::locale()->formatDateTime( t );
1116 if ( autoget && !m_metaInfo.
isValid() &&
1117 KGlobalSettings::showFilePreview(url) )
1129 if ( !local_path.isEmpty() )
1133 url.setPath(local_path);
1138 local = m_bIsLocalURL;
1143 void KFileItem::virtual_hook(
int,
void* )
1146 TQDataStream & operator<< ( TQDataStream & s,
const KFileItem & a )
1156 TQDataStream & operator>> ( TQDataStream & s,
KFileItem & a )
1161 a.m_bIsLocalURL = a.m_url.isLocalFile();
1162 a.m_bMimeTypeKnown =
false;