27 #include <sys/types.h>
32 #include "tdefileitem.h"
37 #include <tqstylesheet.h>
41 #include <tdefilemetainfo.h>
42 #include <ksambashare.h>
43 #include <knfsshare.h>
44 #include <tdeglobal.h>
45 #include <tdeglobalsettings.h>
46 #include <kiconloader.h>
47 #include <klargefile.h>
48 #include <tdelocale.h>
49 #include <kmimetype.h>
52 #include "netaccess.h"
55 #include "tdelficon.h"
56 #endif // HAVE_ELFICON
58 class KFileItem::KFileItemPrivate {
60 KFileItemPrivate() : commentCached(false) {}
69 bool _determineMimeTypeOnDemand,
bool _urlIsDirectory ) :
77 m_bIsLocalURL( _url.isLocalFile() ),
78 m_bMimeTypeKnown( false ),
83 init( _determineMimeTypeOnDemand );
86 KFileItem::KFileItem( mode_t _mode, mode_t _permissions,
const KURL& _url,
bool _determineMimeTypeOnDemand ) :
89 m_strName( _url.fileName() ),
90 m_strText( TDEIO::decodeFileName( m_strName ) ),
93 m_permissions( _permissions ),
96 m_bIsLocalURL( _url.isLocalFile() ),
97 m_bMimeTypeKnown( false ),
101 init( _determineMimeTypeOnDemand );
106 m_strName( url.fileName() ),
107 m_strText( TDEIO::decodeFileName( m_strName ) ),
113 m_bIsLocalURL( url.isLocalFile() ),
114 m_bMimeTypeKnown( !mimeType.isEmpty() ),
118 if (m_bMimeTypeKnown) {
144 m_access = TQString::null;
147 for (
int i = 0; i < NumFlags; i++ ) {
148 m_time[i] = (time_t) -1;
152 if ( m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown )
155 if ( m_url.isLocalFile() )
165 TQCString path = TQFile::encodeName(m_url.path( -1 ));
166 if ( KDE_lstat( path.data(), &buf ) == 0 )
169 if ( S_ISLNK( mode ) )
172 if ( KDE_stat( path.data(), &buf ) == 0 ) {
176 mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO;
180 m_time[ Modification ] = buf.st_mtime;
181 m_time[ Access ] = buf.st_atime;
182 if ( m_fileMode == KFileItem::Unknown ) {
183 m_fileMode = mode & S_IFMT;
185 if ( m_permissions == KFileItem::Unknown ) {
186 m_permissions = mode & 07777;
193 if (!m_pMimeType && !m_url.isEmpty())
195 bool accurate =
false;
201 _determineMimeTypeOnDemand, &accurate );
205 m_bMimeTypeKnown = (!_determineMimeTypeOnDemand) || accurate;
212 bool UDS_URL_seen =
false;
214 if (&m_entry == NULL)
return;
216 TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
217 for( ; it != m_entry.end(); ++it ) {
218 switch ((*it).m_uds) {
221 m_fileMode = (mode_t)((*it).m_long);
225 m_permissions = (mode_t)((*it).m_long);
229 m_user = ((*it).m_str);
233 m_group = ((*it).m_str);
237 m_strName = (*it).m_str;
243 m_url = KURL((*it).m_str);
244 if ( m_url.isLocalFile() ) {
245 m_bIsLocalURL =
true;
251 m_bMimeTypeKnown =
true;
255 m_guessedMimeType = (*it).m_str;
259 m_bLink = !(*it).m_str.isEmpty();
264 d =
new KFileItemPrivate();
266 d->iconName = (*it).m_str;
279 static const TQString& dot = TDEGlobal::staticQString(
".");
280 if ( _urlIsDirectory && !UDS_URL_seen && !m_strName.isEmpty() && m_strName != dot ) {
281 m_url.addPath( m_strName );
287 m_fileMode = KFileItem::Unknown;
288 m_permissions = KFileItem::Unknown;
290 m_user = TQString::null;
291 m_group = TQString::null;
306 d->iconName = TQString::null;
307 d->comment = TQString::null;
308 d->commentCached =
false;
318 m_bIsLocalURL = m_url.isLocalFile();
334 if (&m_entry == NULL)
return TQString::null;
337 TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
338 for( ; it != m_entry.end(); ++it )
345 int n = readlink( TQFile::encodeName(m_url.path( -1 )), buf,
sizeof(buf)-1 );
349 return TQFile::decodeName( buf );
352 return TQString::null;
357 if ( m_bIsLocalURL ) {
361 if (&m_entry == NULL) {
362 return TQString::null;
366 TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
367 const TDEIO::UDSEntry::ConstIterator end = m_entry.end();
368 for( ; it != end; ++it ) {
377 if ((!m_url.isLocalFile())) {
378 if (m_listerURL.isLocalFile()) {
379 return m_listerURL.path();
383 return TQString::null;
392 if (&m_entry == NULL)
return 0L;
395 TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
396 for( ; it != m_entry.end(); ++it )
398 m_size = (*it).m_long;
405 if ( KDE_stat( TQFile::encodeName(m_url.path( -1 )), &buf ) == 0 )
414 if (&m_entry == NULL)
return false;
415 TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
416 for( ; it != m_entry.end(); it++ )
426 if (&m_entry == NULL)
return KACL( m_permissions );
429 TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
430 for( ; it != m_entry.end(); ++it )
432 return KACL((*it).m_str);
435 return KACL( m_permissions );
440 if (&m_entry == NULL)
return KACL();
443 TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
444 for( ; it != m_entry.end(); ++it )
446 return KACL((*it).m_str);
459 return time(which, hasTime);
464 unsigned int mappedWhich = 0;
468 mappedWhich = Modification;
471 mappedWhich = Access;
474 mappedWhich = Creation;
478 if ( m_time[mappedWhich] != (time_t) -1 )
479 return m_time[mappedWhich];
481 if (&m_entry == NULL)
return static_cast<time_t
>(0);
484 TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
485 for( ; it != m_entry.end(); ++it )
486 if ( (*it).m_uds == which ) {
487 m_time[mappedWhich] =
static_cast<time_t
>((*it).m_long);
488 return m_time[mappedWhich];
495 if ( KDE_stat( TQFile::encodeName(m_url.path(-1)), &buf ) == 0 )
500 m_time[mappedWhich] =
static_cast<time_t
>(0);
501 return m_time[mappedWhich];
507 return m_time[mappedWhich];
511 return static_cast<time_t
>(0);
517 if ( m_user.isEmpty() && m_bIsLocalURL )
519 KDE_struct_stat buff;
520 if ( KDE_lstat( TQFile::encodeName(m_url.path( -1 )), &buff ) == 0)
522 struct passwd *
user = getpwuid( buff.st_uid );
524 m_user = TQString::fromLocal8Bit(user->pw_name);
533 if (m_group.isEmpty() && m_bIsLocalURL )
535 KDE_struct_stat buff;
536 if ( KDE_lstat( TQFile::encodeName(m_url.path( -1 )), &buff ) == 0)
538 struct group *ge = getgrgid( buff.st_gid );
540 m_group = TQString::fromLocal8Bit(ge->gr_name);
541 if (m_group.isEmpty())
542 m_group.sprintf(
"%d",ge->gr_gid);
544 m_group.sprintf(
"%d",buff.st_gid);
559 if (isMimeTypeKnown()) {
563 return m_pMimeType->name();
574 if ( !m_pMimeType || !m_bMimeTypeKnown )
581 m_bMimeTypeKnown =
true;
587 bool KFileItem::isMimeTypeKnown()
const
592 return m_bMimeTypeKnown && m_guessedMimeType.isEmpty();
597 if (d && (d->commentCached))
return d->comment;
604 TQString comment = mType->comment( url, isLocalURL );
607 d =
new KFileItemPrivate();
609 if (!comment.isEmpty()) {
610 d->comment = comment;
611 d->commentCached =
true;
614 d->comment = mType->name();
615 d->commentCached =
true;
623 if (d && (!d->iconName.isEmpty()))
return d->iconName;
636 _state |= TDEIcon::LinkOverlay;
638 if ( !S_ISDIR( m_fileMode )
640 _state |= TDEIcon::LockOverlay;
643 _state |= TDEIcon::HiddenOverlay;
645 if( S_ISDIR( m_fileMode ) && m_bIsLocalURL)
651 _state |= TDEIcon::ShareOverlay;
655 if ( m_pMimeType->name() ==
"application/x-gzip" && m_url.fileName().right(3) ==
".gz" )
656 _state |= TDEIcon::ZipOverlay;
662 if (d && (!d->iconName.isEmpty()))
663 return DesktopIcon(d->iconName,_size,_state);
667 static const TQString & defaultFolderIcon =
670 if ( S_ISDIR( m_fileMode ) )
671 return DesktopIcon( defaultFolderIcon, _size, _state );
673 return DesktopIcon(
"unknown", _size, _state );
680 if ( !m_bMimeTypeKnown && !m_guessedMimeType.isEmpty() )
687 if ( mime->name() ==
"application/x-gzip" && m_url.fileName().right(3) ==
".gz" )
690 sf.setPath( m_url.path().left( m_url.path().length() - 3 ) );
698 TQPixmap p = mime->pixmap( url, TDEIcon::Desktop, _size, _state );
701 kdWarning() <<
"Pixmap not found for mimetype " << m_pMimeType->name() << endl;
703 if ( mime->name() ==
"application/x-executable" ) {
711 unsigned int icon_size;
712 libr_icon *icon = NULL;
713 libr_file *handle = NULL;
714 libr_access_t access = LIBR_READ;
716 if((handle = libr_open(const_cast<char*>(url.path().ascii()), access)) == NULL)
718 kdWarning() <<
"failed to open file" << url.path() << endl;
723 icon = libr_icon_geticon_bysize(handle, icon_size);
727 int iconresnamefound = 0;
728 iconentry *
entry = NULL;
730 if(!get_iconlist(handle, &icons))
733 kdDebug() <<
"failed to obtain ELF icon from " << url.path() <<
": " << libr_errmsg() << endl;
736 TQString sysIconName = elf_get_resource(handle,
".metadata_sysicon");
737 if (!sysIconName.isEmpty()) {
738 if (TDEGlobal::iconLoader()->iconPath(sysIconName.ascii(), 0,
true) !=
"") {
739 p = DesktopIcon( sysIconName.ascii(), _size, _state );
747 while((entry = get_nexticon(&icons, entry)) != NULL)
752 icon = libr_icon_geticon_byname(handle, entry->name);
754 if (TDEGlobal::iconLoader()->iconPath(entry->name, 0,
true) !=
"") {
755 iconresnamefound = 1;
756 p = DesktopIcon( entry->name, _size, _state );
762 if ((iconresnamefound == 0) && (icon)) {
764 size_t icon_data_length;
765 char* icondata = libr_icon_malloc(icon, &icon_data_length);
766 p.loadFromData(static_cast<uchar*>(static_cast<void*>(icondata)), icon_data_length);
767 if (icon_size != 0) {
768 TQImage ip = p.convertToImage();
769 ip = ip.smoothScale(icon_size, icon_size);
770 p.convertFromImage(ip);
773 libr_icon_close(icon);
777 #endif // HAVE_ELFICON
793 if ( m_permissions != KFileItem::Unknown ) {
795 if ( !(S_IRUSR & m_permissions) && !(S_IRGRP & m_permissions) && !(S_IROTH & m_permissions) )
799 if ( (S_IRUSR|S_IRGRP|S_IROTH) & m_permissions )
804 if ( m_bIsLocalURL && ::access( TQFile::encodeName(m_url.path()), R_OK ) == -1 )
820 if ( m_permissions != KFileItem::Unknown ) {
822 if ( !(S_IWUSR & m_permissions) && !(S_IWGRP & m_permissions) && !(S_IWOTH & m_permissions) )
827 if ( m_bIsLocalURL && ::access( TQFile::encodeName(m_url.path()), W_OK ) == -1 )
835 if ( m_hidden != Auto )
836 return m_hidden == Hidden;
838 if ( !m_url.isEmpty() )
839 return m_url.fileName()[0] ==
'.';
841 return m_strName[0] ==
'.';
846 if ( m_fileMode == KFileItem::Unknown )
848 kdDebug() <<
" KFileItem::isDir can't say -> false " << endl;
851 return (S_ISDIR(m_fileMode));
865 if ( S_ISDIR(
mode() ) ) {
870 if ( !m_bIsLocalURL )
873 if ((
mimetype() ==
"application/x-desktop") ||
874 (
mimetype() ==
"media/builtin-mydocuments") ||
875 (
mimetype() ==
"media/builtin-mycomputer") ||
876 (
mimetype() ==
"media/builtin-mynetworkplaces") ||
877 (
mimetype() ==
"media/builtin-printers") ||
878 (
mimetype() ==
"media/builtin-trash") ||
879 (
mimetype() ==
"media/builtin-webbrowser"))
883 if ( ::access( TQFile::encodeName(m_url.path()), X_OK ) == 0 )
891 TQString
text = m_strText;
896 d =
new KFileItemPrivate();
898 if (!d->commentCached) {
900 d->commentCached =
true;
903 if ( d->comment.isEmpty() )
904 tmp = i18n (
"Symbolic Link" );
906 tmp = i18n(
"%1 (Link)").arg(d->comment);
912 else if ( S_ISREG( m_fileMode ) )
920 else if ( S_ISDIR ( m_fileMode ) )
930 text.replace(
'\n',
" ");
942 const char* start =
"<tr><td><nobr><font color=\"black\">";
943 const char* mid =
"</font></nobr></td><td><nobr><font color=\"black\">";
944 const char* end =
"</font></nobr></td></tr>";
946 tip =
"<table cellspacing=0 cellpadding=0>";
948 tip += start + i18n(
"Name:") + mid +
text() + end;
949 tip += start + i18n(
"Type:") + mid;
951 TQString type = TQStyleSheet::escape(
mimeComment());
953 tip += i18n(
"Link to %1 (%2)").arg(
linkDest(), type) + end;
957 if ( !S_ISDIR ( m_fileMode ) ) {
961 tip += start + i18n(
"Size:") + mid +
965 if(!timeStr.isEmpty())
966 tip += start + i18n(
"Modified:") + mid +
968 #ifndef Q_WS_WIN //TODO: show win32-specific permissions
969 TQString userStr =
user();
970 TQString groupStr =
group();
971 if(!userStr.isEmpty() || !groupStr.isEmpty())
972 tip += start + i18n(
"Owner:") + mid + userStr +
" - " + groupStr + end +
973 start + i18n(
"Permissions:") + mid +
979 tip +=
"<tr><td colspan=2><center><s> </s></center></td></tr>";
983 TQStringList::Iterator it = keys.begin();
984 for (
int count = 0; count<maxcount && it!=keys.end() ; ++it)
989 TQString s = item.
string();
991 && s.length() > 50) {
1001 TQStyleSheet::escape( s ) +
1021 (void)
new KRun( m_url, m_fileMode, m_bIsLocalURL );
1026 bool hasSize1,hasSize2,hasTime1,hasTime2;
1027 hasSize1 = hasSize2 = hasTime1 = hasTime2 =
false;
1028 return ( m_strName == item.m_strName
1029 && m_bIsLocalURL == item.m_bIsLocalURL
1030 && m_fileMode == item.m_fileMode
1031 && m_permissions == item.m_permissions
1032 && m_user == item.m_user
1033 && m_group == item.m_group
1034 && m_bLink == item.m_bLink
1035 && m_hidden == item.m_hidden
1036 &&
size(hasSize1) == item.
size(hasSize2)
1037 && hasSize1 == hasSize2
1039 && hasTime1 == hasTime2
1040 && (!d || !item.d || d->iconName == item.d->iconName) );
1048 if (
this == &item )
1050 m_entry = item.m_entry;
1052 m_bIsLocalURL = item.m_bIsLocalURL;
1053 m_strName = item.m_strName;
1054 m_strText = item.m_strText;
1055 m_fileMode = item.m_fileMode;
1056 m_permissions = item.m_permissions;
1057 m_user = item.m_user;
1058 m_group = item.m_group;
1059 m_bLink = item.m_bLink;
1060 m_pMimeType = item.m_pMimeType;
1061 m_strLowerCaseName = item.m_strLowerCaseName;
1062 m_bMimeTypeKnown = item.m_bMimeTypeKnown;
1063 m_hidden = item.m_hidden;
1064 m_guessedMimeType = item.m_guessedMimeType;
1065 m_access = item.m_access;
1066 m_metaInfo = item.m_metaInfo;
1067 for (
int i = 0; i < NumFlags; i++ )
1068 m_time[i] = item.m_time[i];
1069 m_size = item.m_size;
1078 d =
new KFileItemPrivate;
1080 d->iconName = item.d->iconName;
1088 bool _determineMimeTypeOnDemand,
bool _urlIsDirectory )
1092 m_strName = TQString::null;
1093 m_strText = TQString::null;
1094 m_user = TQString::null;
1095 m_group = TQString::null;
1096 m_strLowerCaseName = TQString::null;
1098 m_fileMode = KFileItem::Unknown;
1099 m_permissions = KFileItem::Unknown;
1102 m_bIsLocalURL = _url.isLocalFile();
1103 m_bMimeTypeKnown =
false;
1105 m_guessedMimeType = TQString::null;
1109 d->iconName = TQString::null;
1110 d->comment = TQString::null;
1111 d->commentCached =
false;
1115 init( _determineMimeTypeOnDemand );
1133 m_extra.replace( key, value );
1138 TQMapConstIterator<const void*,void*> it = m_extra.find( key );
1139 if ( it != m_extra.end() )
1146 TQMapIterator<const void*,void*> it = m_extra.find( key );
1147 if ( it != m_extra.end() )
1154 m_extra.remove( key );
1159 if (m_access.isNull())
1167 char p[] =
"---------- ";
1174 if (perm & TQFileInfo::ReadUser)
1176 if (perm & TQFileInfo::WriteUser)
1178 if ((perm & TQFileInfo::ExeUser) && !(perm & S_ISUID)) p[3]=
'x';
1179 else if ((perm & TQFileInfo::ExeUser) && (perm & S_ISUID)) p[3]=
's';
1180 else if (!(perm & TQFileInfo::ExeUser) && (perm & S_ISUID)) p[3]=
'S';
1182 if (perm & TQFileInfo::ReadGroup)
1184 if (perm & TQFileInfo::WriteGroup)
1186 if ((perm & TQFileInfo::ExeGroup) && !(perm & S_ISGID)) p[6]=
'x';
1187 else if ((perm & TQFileInfo::ExeGroup) && (perm & S_ISGID)) p[6]=
's';
1188 else if (!(perm & TQFileInfo::ExeGroup) && (perm & S_ISGID)) p[6]=
'S';
1190 if (perm & TQFileInfo::ReadOther)
1192 if (perm & TQFileInfo::WriteOther)
1194 if ((perm & TQFileInfo::ExeOther) && !(perm & S_ISVTX)) p[9]=
'x';
1195 else if ((perm & TQFileInfo::ExeOther) && (perm & S_ISVTX)) p[9]=
't';
1196 else if (!(perm & TQFileInfo::ExeOther) && (perm & S_ISVTX)) p[9]=
'T';
1201 return TQString::fromLatin1(p);
1208 time_t time_ =
time(which, hasTime);
1209 if(!hasTime)
return TQString::null;
1212 t.setTime_t( time_);
1213 return TDEGlobal::locale()->formatDateTime( t );
1226 if ( autoget && !m_metaInfo.
isValid() &&
1227 TDEGlobalSettings::showFilePreview(url) )
1239 if ( !local_path.isEmpty() )
1243 url.setPath(local_path);
1248 local = m_bIsLocalURL;
1253 void KFileItem::virtual_hook(
int,
void* )
1256 TQDataStream & operator<< ( TQDataStream & s,
const KFileItem & a )
1266 TQDataStream & operator>> ( TQDataStream & s,
KFileItem & a )
1271 a.m_bIsLocalURL = a.m_url.isLocalFile();
1272 a.m_bMimeTypeKnown =
false;