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 mutable 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() )
230 if ( KDE::lstat( path, &buf ) == 0 )
233 if ( S_ISLNK( mode ) )
236 if ( KDE::stat( path, &buf ) == 0 )
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 )
279 m_pMimeType = KMimeType::mimeType( mimeTypeStr );
285 m_hidden = hiddenVal == 1 ? Hidden : ( hiddenVal == 0 ? Shown : Auto );
288 static const QString& dot = KGlobal::staticQString(
".");
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)
499 d->m_pMimeType = KMimeType::mimeType( mimeType );
522 d->m_hidden = KFileItemPrivate::Auto;
539 d->m_bMimeTypeKnown =
false;
540 d->m_iconName.clear();
575 if ( !linkStr.isEmpty() )
579 if ( d->m_bIsLocalUrl )
586 return QFile::decodeName( buf );
592 QString KFileItemPrivate::localPath()
const
595 return m_url.toLocalFile();
607 return d->localPath();
635 if ( !fieldVal.isEmpty() )
636 return KACL( fieldVal );
639 return KACL( d->m_permissions );
649 if ( !fieldVal.isEmpty() )
650 return KACL(fieldVal);
660 return d->time(which);
663 #ifndef KDE_NO_DEPRECATED
689 QString KFileItemPrivate::user()
const
692 if (userName.isEmpty() && m_bIsLocalUrl) {
695 userName = a.owner();
698 KDE_struct_stat buff;
701 struct passwd *pwuser = getpwuid( buff.st_uid );
703 userName = QString::fromLocal8Bit(pwuser->pw_name);
720 QString KFileItemPrivate::group()
const
723 if (groupName.isEmpty() && m_bIsLocalUrl )
727 groupName = a.group();
730 KDE_struct_stat buff;
733 struct group *ge = getgrgid( buff.st_gid );
735 groupName = QString::fromLocal8Bit(ge->gr_name);
736 if (groupName.isEmpty())
737 groupName.sprintf(
"%d",ge->gr_gid);
740 groupName.sprintf(
"%d",buff.st_gid);
748 bool KFileItemPrivate::isSlow()
const
750 if (m_slow == SlowUnknown) {
751 const QString path = localPath();
752 if (!path.isEmpty()) {
753 const KFileSystemType::Type fsType = KFileSystemType::fileSystemType(path);
754 m_slow = (fsType == KFileSystemType::Nfs || fsType == KFileSystemType::Smb) ? Slow : Fast;
759 return m_slow == Slow;
784 if ( !d->m_pMimeType || !d->m_bMimeTypeKnown )
789 d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl );
790 Q_ASSERT(d->m_pMimeType);
792 d->m_bMimeTypeKnown =
true;
795 if (d->m_delayedMimeTypes) {
796 d->m_delayedMimeTypes =
false;
797 d->m_useIconNameCache =
false;
801 return d->m_pMimeType;
812 return d->m_bMimeTypeKnown && d->m_guessedMimeType.isEmpty();
820 return d->m_bMimeTypeKnown && (!d->m_delayedMimeTypes);
829 if (!displayType.isEmpty())
840 if (isLocalUrl && !d->isSlow() && mime->is(
"application/x-desktop")) {
843 if (!comment.isEmpty())
847 QString comment = d->isSlow() ? mType->comment() : mType->comment(url);
849 if (!comment.isEmpty())
852 return mType->name();
863 if ( !emptyIcon.isEmpty() ) {
884 if (d->m_useIconNameCache && !d->m_iconName.isEmpty()) {
885 return d->m_iconName;
889 if (!d->m_iconName.isEmpty()) {
890 d->m_useIconNameCache = d->m_bMimeTypeKnown;
891 return d->m_iconName;
899 if (!d->m_guessedMimeType.isEmpty()) {
900 mime = KMimeType::mimeType( d->m_guessedMimeType );
905 const bool delaySlowOperations = d->m_delayedMimeTypes;
907 if (isLocalUrl && !delaySlowOperations && mime->is(
"application/x-desktop")) {
909 if (!d->m_iconName.isEmpty()) {
910 d->m_useIconNameCache = d->m_bMimeTypeKnown;
911 return d->m_iconName;
918 if (delaySlowOperations)
919 d->m_iconName = mime->iconName();
921 d->m_iconName = mime->iconName(url);
922 d->m_useIconNameCache = d->m_bMimeTypeKnown;
924 return d->m_iconName;
949 return mime->is(
"application/x-desktop");
959 names.append(
"emblem-symbolic-link");
962 if ( !S_ISDIR( d->m_fileMode )
964 names.append(
"object-locked");
974 names.append(
"emblem-important" );
979 if (!dev.isEmpty()) {
982 names.append(
"emblem-mounted");
988 names.append(
"hidden");
992 if( S_ISDIR( d->m_fileMode ) && d->m_bIsLocalUrl)
998 names.append(
"network-workgroup");
1003 if ( d->m_pMimeType && d->m_url.fileName().endsWith( QLatin1String(
".gz" ) ) &&
1004 d->m_pMimeType->is(
"application/x-gzip") ) {
1005 names.append(
"application-zip");
1026 if ( !iconName.isEmpty() )
1029 if (!d->m_pMimeType) {
1031 if (S_ISDIR(d->m_fileMode)) {
1032 static const QString * defaultFolderIcon = 0;
1033 if ( !defaultFolderIcon ) {
1034 const KMimeType::Ptr mimeType = KMimeType::mimeType(
"inode/directory" );
1036 defaultFolderIcon = &KGlobal::staticQString( mimeType->iconName() );
1038 kWarning(7000) <<
"No mimetype for inode/directory could be found. Check your installation.";
1040 if ( defaultFolderIcon )
1041 return DesktopIcon( *defaultFolderIcon, _size, _state );
1049 if (!d->m_guessedMimeType.isEmpty())
1050 mime = KMimeType::mimeType( d->m_guessedMimeType );
1052 mime = d->m_pMimeType;
1056 if ( mime->name() ==
"application/x-gzip" && d->m_url.fileName().endsWith( QLatin1String(
".gz" ) ) )
1059 sf.
setPath( d->m_url.path().left( d->m_url.path().length() - 3 ) );
1061 mime = KMimeType::findByUrl( sf, 0, d->m_bIsLocalUrl );
1070 kWarning() <<
"Pixmap not found for mimetype " << d->m_pMimeType->name();
1090 if ( !(S_IRUSR & d->m_permissions) && !(S_IRGRP & d->m_permissions) && !(S_IROTH & d->m_permissions) )
1094 if ( (S_IRUSR|S_IRGRP|S_IROTH) & d->m_permissions )
1099 if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), R_OK ) == -1 )
1120 if ( !(S_IWUSR & d->m_permissions) && !(S_IWGRP & d->m_permissions) && !(S_IWOTH & d->m_permissions) )
1125 if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), W_OK ) == -1 )
1137 if ( d->m_hidden != KFileItemPrivate::Auto )
1138 return d->m_hidden == KFileItemPrivate::Hidden;
1141 QString fileName = d->m_url.fileName();
1142 if (fileName.isEmpty())
1143 fileName = d->m_strName;
1144 return fileName.length() > 1 && fileName[0] ==
'.';
1157 return (S_ISDIR(d->m_fileMode));
1168 #ifndef KDE_NO_DEPRECATED
1172 if ( S_ISDIR(
mode() ) ) {
1177 if ( !d->m_bIsLocalUrl )
1180 if (
mimetype() ==
"application/x-desktop")
1184 if ( QFileInfo(d->m_url.toLocalFile()).
isExecutable() )
1202 if ( comment.isEmpty() )
1211 else if ( S_ISREG( d->m_fileMode ) )
1217 text +=
QString(
" (%1)").arg( comment );
1222 #ifndef KDE_NO_DEPRECATED
1234 const QString colorName = QApplication::palette().color(QPalette::ToolTipText).name();
1235 const QString start =
"<tr><td align=\"right\"><nobr><font color=\"" + colorName +
"\"><b>";
1236 const QString mid =
" </b></font></nobr></td><td><nobr><font color=\"" + colorName +
"\">";
1237 const char*
end =
"</font></nobr></td></tr>";
1239 tip =
"<table cellspacing=0 cellpadding=0>";
1241 tip += start +
i18n(
"Name:") + mid +
text() + end;
1242 tip += start +
i18n(
"Type:") + mid;
1246 tip +=
i18n(
"Link to %1 (%2)",
linkDest(), type) + end;
1250 if ( !S_ISDIR ( d->m_fileMode ) )
1251 tip += start +
i18n(
"Size:") + mid +
1255 tip += start +
i18n(
"Modified:") + mid +
1257 #ifndef Q_WS_WIN //TODO: show win32-specific permissions
1258 +start +
i18n(
"Owner:") + mid +
user() +
" - " +
group() + end +
1259 start +
i18n(
"Permissions:") + mid +
1269 QStringList::ConstIterator it = keys.begin();
1270 for (
int count = 0; count<maxcount && it!=keys.end() ; ++it)
1274 tip +=
"<tr><td colspan=2><center><s> </s></center></td></tr>";
1285 Qt::escape( item.
name() ) +
':' +
1310 (void)
new KRun(
targetUrl(), parentWidget, d->m_fileMode, d->m_bIsLocalUrl );
1321 return d->cmp(*item.d);
1332 return d->m_url == other.d->m_url;
1340 #ifndef KDE_NO_DEPRECATED
1342 bool _delayedMimeTypes,
bool _urlIsDirectory )
1347 d->m_entry = _entry;
1349 d->m_strName.clear();
1350 d->m_strText.clear();
1351 d->m_iconName.clear();
1352 d->m_strLowerCaseName.clear();
1356 d->m_bMarked =
false;
1359 d->m_bMimeTypeKnown =
false;
1360 d->m_hidden = KFileItemPrivate::Auto;
1361 d->m_guessedMimeType.clear();
1363 d->m_delayedMimeTypes = _delayedMimeTypes;
1364 d->m_useIconNameCache =
false;
1366 d->readUDSEntry( _urlIsDirectory );
1373 return qVariantFromValue(*
this);
1376 #ifndef KDE_NO_DEPRECATED
1385 d->m_extra.insert( key, value );
1389 #ifndef KDE_NO_DEPRECATED
1395 return d->m_extra.value( key, 0 );
1399 #ifndef KDE_NO_DEPRECATED
1405 d->m_extra.remove( key );
1415 d->m_access = d->parsePermissions( d->m_permissions );
1426 return KGlobal::locale()->formatDateTime( d->time(which) );
1429 #ifndef KDE_NO_DEPRECATED
1452 d->m_metaInfo = info;
1466 return d->m_metaInfo;
1469 #ifndef KDE_NO_DEPRECATED
1483 if ( !local_path.isEmpty() )
1492 local = d->m_bIsLocalUrl;
1509 s << a.d->m_strName;
1510 s << a.d->m_strText;
1534 if (url.isEmpty()) {
1540 a.d->m_strName = strName;
1541 a.d->m_strText = strText;
1542 a.d->m_bIsLocalUrl = a.d->m_url.isLocalFile();
1543 a.d->m_bMimeTypeKnown =
false;
1562 return d->m_permissions;
1570 return d->m_fileMode;
1586 return d->m_bIsLocalUrl;
1594 return d->m_strText;
1603 return d->m_strName;
1605 if ( d->m_strLowerCaseName.isNull() )
1606 d->m_strLowerCaseName = d->m_strName.toLower();
1607 return d->m_strLowerCaseName;
1616 if (!targetUrlStr.isEmpty())
1617 return KUrl(targetUrlStr);
1624 #ifndef KIO_NO_NEPOMUK
1629 if(!nepomukUriStr.isEmpty()) {
1630 return KUrl(nepomukUriStr);
1660 if (!d->m_pMimeType) {
1662 Q_ASSERT(!d->m_url.isEmpty());
1666 d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl,
1668 d->m_delayedMimeTypes, &accuracy );
1671 const bool canDoBetter = d->m_delayedMimeTypes && accuracy < 100;
1673 d->m_bMimeTypeKnown = !canDoBetter;
1675 return d->m_pMimeType;
1691 return d->m_bMarked;
1701 d->m_bMarked =
true;
1711 d->m_bMarked =
false;
1736 const_iterator it =
begin();
1737 const const_iterator itend =
end();
1738 for ( ; it != itend ; ++it ) {
1739 if ( (*it).name() == fileName ) {
1747 const_iterator it =
begin();
1748 const const_iterator itend =
end();
1749 for ( ; it != itend ; ++it ) {
1750 if ( (*it).url() == url ) {
1759 const_iterator it =
begin();
1760 const const_iterator itend =
end();
1761 for ( ; it != itend ; ++it ) {
1762 lst.append( (*it).url() );
1769 const_iterator it =
begin();
1770 const const_iterator itend =
end();
1771 for ( ; it != itend ; ++it ) {
1772 lst.append( (*it).targetUrl() );
1788 return S_ISREG(d->m_fileMode);
1794 stream <<
"[null KFileItem]";
1796 stream <<
"[KFileItem for" << item.
url() <<
"]";