24 #include <config-kio.h>
29 #include <sys/types.h>
35 #include <QtCore/QDate>
36 #include <QtCore/QDir>
37 #include <QtCore/QFile>
38 #include <QtCore/QMap>
39 #include <QtGui/QApplication>
40 #include <QtGui/QPalette>
41 #include <QTextDocument>
64 mode_t mode, mode_t permissions,
65 const KUrl& itemOrDirUrl,
67 bool delayedMimeTypes)
76 m_permissions( permissions ),
79 m_bIsLocalUrl(itemOrDirUrl.isLocalFile()),
80 m_bMimeTypeKnown( false ),
81 m_delayedMimeTypes( delayedMimeTypes ),
82 m_useIconNameCache(false),
86 if (entry.
count() != 0) {
87 readUDSEntry( urlIsDirectory );
89 Q_ASSERT(!urlIsDirectory);
112 bool cmp(
const KFileItemPrivate & item )
const;
121 void readUDSEntry(
bool _urlIsDirectory );
126 QString parsePermissions( mode_t perm )
const;
156 mutable QString m_strLowerCaseName;
170 mode_t m_permissions;
183 bool m_bIsLocalUrl:1;
185 mutable bool m_bMimeTypeKnown:1;
186 bool m_delayedMimeTypes:1;
189 mutable bool m_useIconNameCache:1;
192 enum { Auto, Hidden, Shown } m_hidden:3;
195 mutable enum { SlowUnknown, Fast, Slow } m_slow:3;
200 #ifndef KDE_NO_DEPRECATED
209 void KFileItemPrivate::init()
219 if ( m_url.isLocalFile() )
233 if ( S_ISLNK( mode ) )
239 mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO;
245 m_fileMode = mode & S_IFMT;
247 m_permissions = mode & 07777;
249 kDebug() << path <<
"does not exist anymore";
255 void KFileItemPrivate::readUDSEntry(
bool _urlIsDirectory )
264 if (!displayName.isEmpty())
265 m_strText = displayName;
270 const bool UDS_URL_seen = !urlStr.isEmpty();
271 if ( UDS_URL_seen ) {
272 m_url =
KUrl( urlStr );
273 if ( m_url.isLocalFile() )
274 m_bIsLocalUrl =
true;
277 m_bMimeTypeKnown = !mimeTypeStr.isEmpty();
278 if ( m_bMimeTypeKnown )
285 m_hidden = hiddenVal == 1 ? Hidden : ( hiddenVal == 0 ? Shown : Auto );
289 if ( _urlIsDirectory && !UDS_URL_seen && !m_strName.isEmpty() && m_strName != dot )
290 m_url.addPath( m_strName );
300 if ( fieldVal != -1 ) {
305 if ( m_bIsLocalUrl ) {
315 m_time[mappedWhich].setTime_t(time_t_val);
316 m_time[mappedWhich] = m_time[mappedWhich].toLocalZone();
321 if ( !m_time[mappedWhich].isNull() )
322 return m_time[mappedWhich];
325 long long fieldVal = -1;
326 switch ( mappedWhich ) {
337 if ( fieldVal != -1 ) {
338 setTime(mappedWhich, fieldVal);
339 return m_time[mappedWhich];
351 return m_time[mappedWhich];
358 bool KFileItemPrivate::cmp(
const KFileItemPrivate & item )
const
361 kDebug() <<
"Comparing" << m_url <<
"and" << item.m_url;
362 kDebug() <<
" name" << (m_strName == item.m_strName);
363 kDebug() <<
" local" << (m_bIsLocalUrl == item.m_bIsLocalUrl);
364 kDebug() <<
" mode" << (m_fileMode == item.m_fileMode);
365 kDebug() <<
" perm" << (m_permissions == item.m_permissions);
366 kDebug() <<
" UDS_USER" << (user() == item.user());
367 kDebug() <<
" UDS_GROUP" << (
group() == item.group());
371 kDebug() <<
" m_bLink" << (m_bLink == item.m_bLink);
372 kDebug() <<
" m_hidden" << (m_hidden == item.m_hidden);
373 kDebug() <<
" size" << (size() == item.size());
377 return ( m_strName == item.m_strName
378 && m_bIsLocalUrl == item.m_bIsLocalUrl
379 && m_fileMode == item.m_fileMode
380 && m_permissions == item.m_permissions
381 && user() == item.user()
382 &&
group() == item.group()
386 && m_bLink == item.m_bLink
387 && m_hidden == item.m_hidden
388 && size() == item.size()
398 QString KFileItemPrivate::parsePermissions(mode_t perm)
const
400 static char buffer[ 12 ];
402 char uxbit,gxbit,oxbit;
404 if ( (perm & (S_IXUSR|S_ISUID)) == (S_IXUSR|S_ISUID) )
406 else if ( (perm & (S_IXUSR|S_ISUID)) == S_ISUID )
408 else if ( (perm & (S_IXUSR|S_ISUID)) == S_IXUSR )
413 if ( (perm & (S_IXGRP|S_ISGID)) == (S_IXGRP|S_ISGID) )
415 else if ( (perm & (S_IXGRP|S_ISGID)) == S_ISGID )
417 else if ( (perm & (S_IXGRP|S_ISGID)) == S_IXGRP )
422 if ( (perm & (S_IXOTH|S_ISVTX)) == (S_IXOTH|S_ISVTX) )
424 else if ( (perm & (S_IXOTH|S_ISVTX)) == S_ISVTX )
426 else if ( (perm & (S_IXOTH|S_ISVTX)) == S_IXOTH )
436 if (S_ISDIR(m_fileMode))
438 else if (S_ISSOCK(m_fileMode))
440 else if (S_ISCHR(m_fileMode))
442 else if (S_ISBLK(m_fileMode))
444 else if (S_ISFIFO(m_fileMode))
452 buffer[1] = ((( perm & S_IRUSR ) == S_IRUSR ) ?
'r' :
'-' );
453 buffer[2] = ((( perm & S_IWUSR ) == S_IWUSR ) ?
'w' :
'-' );
455 buffer[4] = ((( perm & S_IRGRP ) == S_IRGRP ) ?
'r' :
'-' );
456 buffer[5] = ((( perm & S_IWGRP ) == S_IWGRP ) ?
'w' :
'-' );
458 buffer[7] = ((( perm & S_IROTH ) == S_IROTH ) ?
'r' :
'-' );
459 buffer[8] = ((( perm & S_IWOTH ) == S_IWOTH ) ?
'w' :
'-' );
469 return QString::fromLatin1(buffer);
481 bool delayedMimeTypes,
bool urlIsDirectory )
483 itemOrDirUrl, urlIsDirectory, delayedMimeTypes))
488 : d(new KFileItemPrivate(KIO::UDSEntry(), mode, permissions,
489 url, false, delayedMimeTypes))
497 d->m_bMimeTypeKnown = !mimeType.isEmpty();
498 if (d->m_bMimeTypeKnown)
517 d->m_hidden = KFileItemPrivate::Auto;
531 d->m_bMimeTypeKnown =
false;
532 d->m_iconName.clear();
554 if ( !linkStr.isEmpty() )
558 if ( d->m_bIsLocalUrl )
565 return QFile::decodeName( buf );
571 QString KFileItemPrivate::localPath()
const
574 return m_url.toLocalFile();
583 return d->localPath();
602 if ( !fieldVal.isEmpty() )
603 return KACL( fieldVal );
606 return KACL( d->m_permissions );
613 if ( !fieldVal.isEmpty() )
614 return KACL(fieldVal);
621 return d->time(which);
624 #ifndef KDE_NO_DEPRECATED
644 QString KFileItemPrivate::user()
const
647 if (userName.isEmpty() && m_bIsLocalUrl) {
650 userName = a.owner();
653 KDE_struct_stat buff;
656 struct passwd *pwuser = getpwuid( buff.st_uid );
658 userName = QString::fromLocal8Bit(pwuser->pw_name);
672 QString KFileItemPrivate::group()
const
675 if (groupName.isEmpty() && m_bIsLocalUrl )
679 groupName = a.group();
682 KDE_struct_stat buff;
685 struct group *ge = getgrgid( buff.st_gid );
687 groupName = QString::fromLocal8Bit(ge->gr_name);
688 if (groupName.isEmpty())
689 groupName.sprintf(
"%d",ge->gr_gid);
692 groupName.sprintf(
"%d",buff.st_gid);
700 bool KFileItemPrivate::isSlow()
const
702 if (m_slow == SlowUnknown) {
703 const QString path = localPath();
704 if (!path.isEmpty()) {
711 return m_slow == Slow;
727 if ( !d->m_pMimeType || !d->m_bMimeTypeKnown )
733 Q_ASSERT(d->m_pMimeType);
735 d->m_bMimeTypeKnown =
true;
738 return d->m_pMimeType;
746 return d->m_bMimeTypeKnown && d->m_guessedMimeType.isEmpty();
752 if (!displayType.isEmpty())
763 if (isLocalUrl && !d->isSlow() && mime->
is(
"application/x-desktop")) {
766 if (!comment.isEmpty())
772 if (!comment.isEmpty())
775 return mType->
name();
786 if ( !emptyIcon.isEmpty() ) {
804 if (d->m_useIconNameCache && !d->m_iconName.isEmpty()) {
805 return d->m_iconName;
809 if (!d->m_iconName.isEmpty()) {
810 d->m_useIconNameCache = d->m_bMimeTypeKnown;
811 return d->m_iconName;
819 if (!d->m_guessedMimeType.isEmpty()) {
825 if (isLocalUrl && !
isSlow() && mime->
is(
"application/x-desktop")) {
827 if (!d->m_iconName.isEmpty()) {
828 d->m_useIconNameCache = d->m_bMimeTypeKnown;
829 return d->m_iconName;
839 d->m_iconName = mime->
iconName(url);
840 d->m_useIconNameCache = d->m_bMimeTypeKnown;
842 return d->m_iconName;
867 return mime->
is(
"application/x-desktop");
874 names.append(
"emblem-symbolic-link");
877 if ( !S_ISDIR( d->m_fileMode )
879 names.append(
"object-locked");
889 names.append(
"emblem-important" );
894 if (!dev.isEmpty()) {
897 names.append(
"emblem-mounted");
903 names.append(
"hidden");
907 if( S_ISDIR( d->m_fileMode ) && d->m_bIsLocalUrl)
913 names.append(
"network-workgroup");
918 if ( d->m_pMimeType && d->m_url.fileName().endsWith( QLatin1String(
".gz" ) ) &&
919 d->m_pMimeType->is(
"application/x-gzip") ) {
920 names.append(
"application-zip");
935 if ( !iconName.isEmpty() )
938 if (!d->m_pMimeType) {
940 if (S_ISDIR(d->m_fileMode)) {
941 static const QString * defaultFolderIcon = 0;
942 if ( !defaultFolderIcon ) {
947 kWarning(7000) <<
"No mimetype for inode/directory could be found. Check your installation.";
949 if ( defaultFolderIcon )
950 return DesktopIcon( *defaultFolderIcon, _size, _state );
958 if (!d->m_guessedMimeType.isEmpty())
961 mime = d->m_pMimeType;
965 if ( mime->
name() ==
"application/x-gzip" && d->m_url.fileName().endsWith( QLatin1String(
".gz" ) ) )
968 sf.
setPath( d->m_url.path().left( d->m_url.path().length() - 3 ) );
979 kWarning() <<
"Pixmap not found for mimetype " << d->m_pMimeType->name();
996 if ( !(S_IRUSR & d->m_permissions) && !(S_IRGRP & d->m_permissions) && !(S_IROTH & d->m_permissions) )
1000 if ( (S_IRUSR|S_IRGRP|S_IROTH) & d->m_permissions )
1005 if ( d->m_bIsLocalUrl &&
KDE::access( d->m_url.toLocalFile(), R_OK ) == -1 )
1023 if ( !(S_IWUSR & d->m_permissions) && !(S_IWGRP & d->m_permissions) && !(S_IWOTH & d->m_permissions) )
1028 if ( d->m_bIsLocalUrl &&
KDE::access( d->m_url.toLocalFile(), W_OK ) == -1 )
1037 if ( d->m_hidden != KFileItemPrivate::Auto )
1038 return d->m_hidden == KFileItemPrivate::Hidden;
1041 QString fileName = d->m_url.fileName();
1042 if (fileName.isEmpty())
1043 fileName = d->m_strName;
1044 return fileName.length() > 1 && fileName[0] ==
'.';
1054 return (S_ISDIR(d->m_fileMode));
1062 #ifndef KDE_NO_DEPRECATED
1066 if ( S_ISDIR(
mode() ) ) {
1071 if ( !d->m_bIsLocalUrl )
1074 if (
mimetype() ==
"application/x-desktop")
1078 if ( QFileInfo(d->m_url.toLocalFile()).
isExecutable() )
1093 if ( comment.isEmpty() )
1102 else if ( S_ISREG( d->m_fileMode ) )
1108 text +=
QString(
" (%1)").arg( comment );
1113 #ifndef KDE_NO_DEPRECATED
1122 const QString colorName = QApplication::palette().color(QPalette::ToolTipText).name();
1123 const QString start =
"<tr><td align=\"right\"><nobr><font color=\"" + colorName +
"\"><b>";
1124 const QString mid =
" </b></font></nobr></td><td><nobr><font color=\"" + colorName +
"\">";
1125 const char*
end =
"</font></nobr></td></tr>";
1127 tip =
"<table cellspacing=0 cellpadding=0>";
1129 tip += start +
i18n(
"Name:") + mid +
text() + end;
1130 tip += start +
i18n(
"Type:") + mid;
1134 tip +=
i18n(
"Link to %1 (%2)",
linkDest(), type) + end;
1138 if ( !S_ISDIR ( d->m_fileMode ) )
1139 tip += start +
i18n(
"Size:") + mid +
1143 tip += start +
i18n(
"Modified:") + mid +
1145 #ifndef Q_WS_WIN //TODO: show win32-specific permissions
1146 +start +
i18n(
"Owner:") + mid +
user() +
" - " +
group() + end +
1147 start +
i18n(
"Permissions:") + mid +
1157 QStringList::ConstIterator it = keys.begin();
1158 for (
int count = 0; count<maxcount && it!=keys.end() ; ++it)
1162 tip +=
"<tr><td colspan=2><center><s> </s></center></td></tr>";
1173 Qt::escape( item.
name() ) +
':' +
1193 (void)
new KRun(
targetUrl(), parentWidget, d->m_fileMode, d->m_bIsLocalUrl );
1198 return d->cmp(*item.d);
1204 return d == other.d;
1209 return d != other.d;
1212 #ifndef KDE_NO_DEPRECATED
1214 bool _delayedMimeTypes,
bool _urlIsDirectory )
1216 d->m_entry = _entry;
1218 d->m_strName.clear();
1219 d->m_strText.clear();
1220 d->m_iconName.clear();
1221 d->m_strLowerCaseName.clear();
1225 d->m_bMarked =
false;
1228 d->m_bMimeTypeKnown =
false;
1229 d->m_hidden = KFileItemPrivate::Auto;
1230 d->m_guessedMimeType.clear();
1232 d->m_delayedMimeTypes = _delayedMimeTypes;
1233 d->m_useIconNameCache =
false;
1235 d->readUDSEntry( _urlIsDirectory );
1242 return qVariantFromValue(*
this);
1245 #ifndef KDE_NO_DEPRECATED
1251 d->m_extra.insert( key, value );
1255 #ifndef KDE_NO_DEPRECATED
1258 return d->m_extra.value( key, 0 );
1262 #ifndef KDE_NO_DEPRECATED
1265 d->m_extra.remove( key );
1272 d->m_access = d->parsePermissions( d->m_permissions );
1283 #ifndef KDE_NO_DEPRECATED
1300 d->m_metaInfo = info;
1311 return d->m_metaInfo;
1314 #ifndef KDE_NO_DEPRECATED
1325 if ( !local_path.isEmpty() )
1334 local = d->m_bIsLocalUrl;
1350 s << a.d->m_strName;
1351 s << a.d->m_strText;
1358 s >> a.d->m_strName;
1359 s >> a.d->m_strText;
1360 a.d->m_bIsLocalUrl = a.d->m_url.isLocalFile();
1361 a.d->m_bMimeTypeKnown =
false;
1373 return d->m_permissions;
1378 return d->m_fileMode;
1388 return d->m_bIsLocalUrl;
1393 return d->m_strText;
1399 return d->m_strName;
1401 if ( d->m_strLowerCaseName.isNull() )
1402 d->m_strLowerCaseName = d->m_strName.toLower();
1403 return d->m_strLowerCaseName;
1409 if (!targetUrlStr.isEmpty())
1410 return KUrl(targetUrlStr);
1417 #ifndef KIO_NO_NEPOMUK
1419 if(!nepomukUriStr.isEmpty()) {
1420 return KUrl(nepomukUriStr);
1447 if (!d->m_pMimeType) {
1449 Q_ASSERT(!d->m_url.isEmpty());
1455 d->m_delayedMimeTypes, &accuracy );
1458 const bool canDoBetter = d->m_delayedMimeTypes && accuracy < 100;
1460 d->m_bMimeTypeKnown = !canDoBetter;
1462 return d->m_pMimeType;
1472 return d->m_bMarked;
1477 d->m_bMarked =
true;
1482 d->m_bMarked =
false;
1507 const_iterator it =
begin();
1508 const const_iterator itend =
end();
1509 for ( ; it != itend ; ++it ) {
1510 if ( (*it).name() == fileName ) {
1518 const_iterator it =
begin();
1519 const const_iterator itend =
end();
1520 for ( ; it != itend ; ++it ) {
1521 if ( (*it).url() == url ) {
1530 const_iterator it =
begin();
1531 const const_iterator itend =
end();
1532 for ( ; it != itend ; ++it ) {
1533 lst.append( (*it).url() );
1540 const_iterator it =
begin();
1541 const const_iterator itend =
end();
1542 for ( ; it != itend ; ++it ) {
1543 lst.append( (*it).targetUrl() );
1556 return S_ISREG(d->m_fileMode);
1562 stream <<
"[null KFileItem]";
1564 stream <<
"[KFileItem for" << item.
url() <<
"]";