• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.8.5 API Reference
  • KDE Home
  • Contact Us
 

KIO

  • kio
  • kio
kfileitem.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE project
2  Copyright (C) 1999-2006 David Faure <faure@kde.org>
3  2001 Carsten Pfeiffer <pfeiffer@kde.org>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 #include "kfileitem.h"
22 
23 #include <config.h>
24 #include <config-kio.h>
25 
26 #include <sys/time.h>
27 #include <pwd.h>
28 #include <grp.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 
32 #include <assert.h>
33 #include <unistd.h>
34 
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>
42 
43 #include <kdebug.h>
44 #include <kfilemetainfo.h>
45 #include <kglobal.h>
46 #include <kiconloader.h>
47 #include <klocale.h>
48 #include <kmimetype.h>
49 #include <krun.h>
50 #include <kde_file.h>
51 #include <kdesktopfile.h>
52 #include <kmountpoint.h>
53 #include <kconfiggroup.h>
54 #ifndef Q_OS_WIN
55 #include <knfsshare.h>
56 #include <ksambashare.h>
57 #endif
58 #include <kfilesystemtype_p.h>
59 
60 class KFileItemPrivate : public QSharedData
61 {
62 public:
63  KFileItemPrivate(const KIO::UDSEntry& entry,
64  mode_t mode, mode_t permissions,
65  const KUrl& itemOrDirUrl,
66  bool urlIsDirectory,
67  bool delayedMimeTypes)
68  : m_entry( entry ),
69  m_url(itemOrDirUrl),
70  m_strName(),
71  m_strText(),
72  m_iconName(),
73  m_strLowerCaseName(),
74  m_pMimeType( 0 ),
75  m_fileMode( mode ),
76  m_permissions( permissions ),
77  m_bMarked( false ),
78  m_bLink( false ),
79  m_bIsLocalUrl(itemOrDirUrl.isLocalFile()),
80  m_bMimeTypeKnown( false ),
81  m_delayedMimeTypes( delayedMimeTypes ),
82  m_useIconNameCache(false),
83  m_hidden(Auto),
84  m_slow(SlowUnknown)
85  {
86  if (entry.count() != 0) {
87  readUDSEntry( urlIsDirectory );
88  } else {
89  Q_ASSERT(!urlIsDirectory);
90  m_strName = itemOrDirUrl.fileName();
91  m_strText = KIO::decodeFileName( m_strName );
92  }
93  init();
94  }
95 
96  ~KFileItemPrivate()
97  {
98  }
99 
106  void init();
107 
108  QString localPath() const;
109  KIO::filesize_t size() const;
110  KDateTime time( KFileItem::FileTimes which ) const;
111  void setTime(KFileItem::FileTimes which, long long time_t_val) const;
112  bool cmp( const KFileItemPrivate & item ) const;
113  QString user() const;
114  QString group() const;
115  bool isSlow() const;
116 
121  void readUDSEntry( bool _urlIsDirectory );
122 
126  QString parsePermissions( mode_t perm ) const;
127 
131  mutable KIO::UDSEntry m_entry;
135  KUrl m_url;
136 
140  QString m_strName;
141 
146  QString m_strText;
147 
151  mutable QString m_iconName;
152 
156  mutable QString m_strLowerCaseName;
157 
161  mutable KMimeType::Ptr m_pMimeType;
162 
166  mode_t m_fileMode;
170  mode_t m_permissions;
171 
175  bool m_bMarked:1;
179  bool m_bLink:1;
183  bool m_bIsLocalUrl:1;
184 
185  mutable bool m_bMimeTypeKnown:1;
186  bool m_delayedMimeTypes:1;
187 
189  mutable bool m_useIconNameCache:1;
190 
191  // Auto: check leading dot.
192  enum { Auto, Hidden, Shown } m_hidden:3;
193 
194  // Slow? (nfs/smb/ssh)
195  mutable enum { SlowUnknown, Fast, Slow } m_slow:3;
196 
197  // For special case like link to dirs over FTP
198  QString m_guessedMimeType;
199  mutable QString m_access;
200 #ifndef KDE_NO_DEPRECATED
201  QMap<const void*, void*> m_extra; // DEPRECATED
202 #endif
203  mutable KFileMetaInfo m_metaInfo;
204 
205  enum { NumFlags = KFileItem::CreationTime + 1 };
206  mutable KDateTime m_time[3];
207 };
208 
209 void KFileItemPrivate::init()
210 {
211  m_access.clear();
212  // metaInfo = KFileMetaInfo();
213 
214  // determine mode and/or permissions if unknown
215  // TODO: delay this until requested
216  if ( m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown )
217  {
218  mode_t mode = 0;
219  if ( m_url.isLocalFile() )
220  {
221  /* directories may not have a slash at the end if
222  * we want to stat() them; it requires that we
223  * change into it .. which may not be allowed
224  * stat("/is/unaccessible") -> rwx------
225  * stat("/is/unaccessible/") -> EPERM H.Z.
226  * This is the reason for the -1
227  */
228  KDE_struct_stat buf;
229  const QString path = m_url.toLocalFile( KUrl::RemoveTrailingSlash );
230  if ( KDE::lstat( path, &buf ) == 0 )
231  {
232  mode = buf.st_mode;
233  if ( S_ISLNK( mode ) )
234  {
235  m_bLink = true;
236  if ( KDE::stat( path, &buf ) == 0 )
237  mode = buf.st_mode;
238  else // link pointing to nowhere (see kio/file/file.cc)
239  mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO;
240  }
241  // While we're at it, store the times
242  setTime(KFileItem::ModificationTime, buf.st_mtime);
243  setTime(KFileItem::AccessTime, buf.st_atime);
244  if ( m_fileMode == KFileItem::Unknown )
245  m_fileMode = mode & S_IFMT; // extract file type
246  if ( m_permissions == KFileItem::Unknown )
247  m_permissions = mode & 07777; // extract permissions
248  } else {
249  kDebug() << path << "does not exist anymore";
250  }
251  }
252  }
253 }
254 
255 void KFileItemPrivate::readUDSEntry( bool _urlIsDirectory )
256 {
257  // extract fields from the KIO::UDS Entry
258 
259  m_fileMode = m_entry.numberValue( KIO::UDSEntry::UDS_FILE_TYPE );
260  m_permissions = m_entry.numberValue( KIO::UDSEntry::UDS_ACCESS );
261  m_strName = m_entry.stringValue( KIO::UDSEntry::UDS_NAME );
262 
263  const QString displayName = m_entry.stringValue( KIO::UDSEntry::UDS_DISPLAY_NAME );
264  if (!displayName.isEmpty())
265  m_strText = displayName;
266  else
267  m_strText = KIO::decodeFileName( m_strName );
268 
269  const QString urlStr = m_entry.stringValue( KIO::UDSEntry::UDS_URL );
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;
275  }
276  const QString mimeTypeStr = m_entry.stringValue( KIO::UDSEntry::UDS_MIME_TYPE );
277  m_bMimeTypeKnown = !mimeTypeStr.isEmpty();
278  if ( m_bMimeTypeKnown )
279  m_pMimeType = KMimeType::mimeType( mimeTypeStr );
280 
281  m_guessedMimeType = m_entry.stringValue( KIO::UDSEntry::UDS_GUESSED_MIME_TYPE );
282  m_bLink = !m_entry.stringValue( KIO::UDSEntry::UDS_LINK_DEST ).isEmpty(); // we don't store the link dest
283 
284  const int hiddenVal = m_entry.numberValue( KIO::UDSEntry::UDS_HIDDEN, -1 );
285  m_hidden = hiddenVal == 1 ? Hidden : ( hiddenVal == 0 ? Shown : Auto );
286 
287  // avoid creating these QStrings again and again
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 );
291 
292  m_iconName.clear();
293 }
294 
295 inline //because it is used only in one place
296 KIO::filesize_t KFileItemPrivate::size() const
297 {
298  // Extract it from the KIO::UDSEntry
299  long long fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_SIZE, -1 );
300  if ( fieldVal != -1 ) {
301  return fieldVal;
302  }
303 
304  // If not in the KIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL]
305  if ( m_bIsLocalUrl ) {
306  KDE_struct_stat buf;
307  if ( KDE::stat( m_url.toLocalFile(KUrl::RemoveTrailingSlash), &buf ) == 0 )
308  return buf.st_size;
309  }
310  return 0;
311 }
312 
313 void KFileItemPrivate::setTime(KFileItem::FileTimes mappedWhich, long long time_t_val) const
314 {
315  m_time[mappedWhich].setTime_t(time_t_val);
316  m_time[mappedWhich] = m_time[mappedWhich].toLocalZone(); // #160979
317 }
318 
319 KDateTime KFileItemPrivate::time( KFileItem::FileTimes mappedWhich ) const
320 {
321  if ( !m_time[mappedWhich].isNull() )
322  return m_time[mappedWhich];
323 
324  // Extract it from the KIO::UDSEntry
325  long long fieldVal = -1;
326  switch ( mappedWhich ) {
327  case KFileItem::ModificationTime:
328  fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_MODIFICATION_TIME, -1 );
329  break;
330  case KFileItem::AccessTime:
331  fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_ACCESS_TIME, -1 );
332  break;
333  case KFileItem::CreationTime:
334  fieldVal = m_entry.numberValue( KIO::UDSEntry::UDS_CREATION_TIME, -1 );
335  break;
336  }
337  if ( fieldVal != -1 ) {
338  setTime(mappedWhich, fieldVal);
339  return m_time[mappedWhich];
340  }
341 
342  // If not in the KIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL]
343  if ( m_bIsLocalUrl )
344  {
345  KDE_struct_stat buf;
346  if ( KDE::stat( m_url.toLocalFile(KUrl::RemoveTrailingSlash), &buf ) == 0 )
347  {
348  setTime(KFileItem::ModificationTime, buf.st_mtime);
349  setTime(KFileItem::AccessTime, buf.st_atime);
350  m_time[KFileItem::CreationTime] = KDateTime();
351  return m_time[mappedWhich];
352  }
353  }
354  return KDateTime();
355 }
356 
357 inline //because it is used only in one place
358 bool KFileItemPrivate::cmp( const KFileItemPrivate & item ) const
359 {
360 #if 0
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());
368  kDebug() << " UDS_EXTENDED_ACL" << (m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL ));
369  kDebug() << " UDS_ACL_STRING" << (m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ));
370  kDebug() << " UDS_DEFAULT_ACL_STRING" << (m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING ));
371  kDebug() << " m_bLink" << (m_bLink == item.m_bLink);
372  kDebug() << " m_hidden" << (m_hidden == item.m_hidden);
373  kDebug() << " size" << (size() == item.size());
374  kDebug() << " ModificationTime" << (time(KFileItem::ModificationTime) == item.time(KFileItem::ModificationTime));
375  kDebug() << " UDS_ICON_NAME" << (m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ));
376 #endif
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()
383  && m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_EXTENDED_ACL )
384  && m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING )
385  && m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING )
386  && m_bLink == item.m_bLink
387  && m_hidden == item.m_hidden
388  && size() == item.size()
389  && time(KFileItem::ModificationTime) == item.time(KFileItem::ModificationTime) // TODO only if already known!
390  && m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME ) == item.m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME )
391  );
392 
393  // Don't compare the mimetypes here. They might not be known, and we don't want to
394  // do the slow operation of determining them here.
395 }
396 
397 inline //because it is used only in one place
398 QString KFileItemPrivate::parsePermissions(mode_t perm) const
399 {
400  static char buffer[ 12 ];
401 
402  char uxbit,gxbit,oxbit;
403 
404  if ( (perm & (S_IXUSR|S_ISUID)) == (S_IXUSR|S_ISUID) )
405  uxbit = 's';
406  else if ( (perm & (S_IXUSR|S_ISUID)) == S_ISUID )
407  uxbit = 'S';
408  else if ( (perm & (S_IXUSR|S_ISUID)) == S_IXUSR )
409  uxbit = 'x';
410  else
411  uxbit = '-';
412 
413  if ( (perm & (S_IXGRP|S_ISGID)) == (S_IXGRP|S_ISGID) )
414  gxbit = 's';
415  else if ( (perm & (S_IXGRP|S_ISGID)) == S_ISGID )
416  gxbit = 'S';
417  else if ( (perm & (S_IXGRP|S_ISGID)) == S_IXGRP )
418  gxbit = 'x';
419  else
420  gxbit = '-';
421 
422  if ( (perm & (S_IXOTH|S_ISVTX)) == (S_IXOTH|S_ISVTX) )
423  oxbit = 't';
424  else if ( (perm & (S_IXOTH|S_ISVTX)) == S_ISVTX )
425  oxbit = 'T';
426  else if ( (perm & (S_IXOTH|S_ISVTX)) == S_IXOTH )
427  oxbit = 'x';
428  else
429  oxbit = '-';
430 
431  // Include the type in the first char like kde3 did; people are more used to seeing it,
432  // even though it's not really part of the permissions per se.
433  if (m_bLink)
434  buffer[0] = 'l';
435  else if (m_fileMode != KFileItem::Unknown) {
436  if (S_ISDIR(m_fileMode))
437  buffer[0] = 'd';
438  else if (S_ISSOCK(m_fileMode))
439  buffer[0] = 's';
440  else if (S_ISCHR(m_fileMode))
441  buffer[0] = 'c';
442  else if (S_ISBLK(m_fileMode))
443  buffer[0] = 'b';
444  else if (S_ISFIFO(m_fileMode))
445  buffer[0] = 'p';
446  else
447  buffer[0] = '-';
448  } else {
449  buffer[0] = '-';
450  }
451 
452  buffer[1] = ((( perm & S_IRUSR ) == S_IRUSR ) ? 'r' : '-' );
453  buffer[2] = ((( perm & S_IWUSR ) == S_IWUSR ) ? 'w' : '-' );
454  buffer[3] = uxbit;
455  buffer[4] = ((( perm & S_IRGRP ) == S_IRGRP ) ? 'r' : '-' );
456  buffer[5] = ((( perm & S_IWGRP ) == S_IWGRP ) ? 'w' : '-' );
457  buffer[6] = gxbit;
458  buffer[7] = ((( perm & S_IROTH ) == S_IROTH ) ? 'r' : '-' );
459  buffer[8] = ((( perm & S_IWOTH ) == S_IWOTH ) ? 'w' : '-' );
460  buffer[9] = oxbit;
461  // if (hasExtendedACL())
462  if (m_entry.contains(KIO::UDSEntry::UDS_EXTENDED_ACL)) {
463  buffer[10] = '+';
464  buffer[11] = 0;
465  } else {
466  buffer[10] = 0;
467  }
468 
469  return QString::fromLatin1(buffer);
470 }
471 
472 
474 
475 KFileItem::KFileItem()
476  : d(0)
477 {
478 }
479 
480 KFileItem::KFileItem( const KIO::UDSEntry& entry, const KUrl& itemOrDirUrl,
481  bool delayedMimeTypes, bool urlIsDirectory )
482  : d(new KFileItemPrivate(entry, KFileItem::Unknown, KFileItem::Unknown,
483  itemOrDirUrl, urlIsDirectory, delayedMimeTypes))
484 {
485 }
486 
487 KFileItem::KFileItem( mode_t mode, mode_t permissions, const KUrl& url, bool delayedMimeTypes )
488  : d(new KFileItemPrivate(KIO::UDSEntry(), mode, permissions,
489  url, false, delayedMimeTypes))
490 {
491 }
492 
493 KFileItem::KFileItem( const KUrl &url, const QString &mimeType, mode_t mode )
494  : d(new KFileItemPrivate(KIO::UDSEntry(), mode, KFileItem::Unknown,
495  url, false, false))
496 {
497  d->m_bMimeTypeKnown = !mimeType.isEmpty();
498  if (d->m_bMimeTypeKnown)
499  d->m_pMimeType = KMimeType::mimeType( mimeType );
500 }
501 
502 
503 KFileItem::KFileItem(const KFileItem& other)
504  : d(other.d)
505 {
506 }
507 
508 KFileItem::~KFileItem()
509 {
510 }
511 
512 void KFileItem::refresh()
513 {
514  d->m_fileMode = KFileItem::Unknown;
515  d->m_permissions = KFileItem::Unknown;
516  d->m_metaInfo = KFileMetaInfo();
517  d->m_hidden = KFileItemPrivate::Auto;
518  refreshMimeType();
519 
520  // Basically, we can't trust any information we got while listing.
521  // Everything could have changed...
522  // Clearing m_entry makes it possible to detect changes in the size of the file,
523  // the time information, etc.
524  d->m_entry.clear();
525  d->init();
526 }
527 
528 void KFileItem::refreshMimeType()
529 {
530  d->m_pMimeType = 0;
531  d->m_bMimeTypeKnown = false;
532  d->m_iconName.clear();
533 }
534 
535 void KFileItem::setUrl( const KUrl &url )
536 {
537  d->m_url = url;
538  setName( url.fileName() );
539 }
540 
541 void KFileItem::setName( const QString& name )
542 {
543  d->m_strName = name;
544  d->m_strText = KIO::decodeFileName( d->m_strName );
545  if (d->m_entry.contains(KIO::UDSEntry::UDS_NAME))
546  d->m_entry.insert(KIO::UDSEntry::UDS_NAME, d->m_strName); // #195385
547 
548 }
549 
550 QString KFileItem::linkDest() const
551 {
552  // Extract it from the KIO::UDSEntry
553  const QString linkStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_LINK_DEST );
554  if ( !linkStr.isEmpty() )
555  return linkStr;
556 
557  // If not in the KIO::UDSEntry, or if UDSEntry empty, use readlink() [if local URL]
558  if ( d->m_bIsLocalUrl )
559  {
560  char buf[1000];
561  int n = readlink( QFile::encodeName(d->m_url.toLocalFile( KUrl::RemoveTrailingSlash )), buf, sizeof(buf)-1 );
562  if ( n != -1 )
563  {
564  buf[ n ] = 0;
565  return QFile::decodeName( buf );
566  }
567  }
568  return QString();
569 }
570 
571 QString KFileItemPrivate::localPath() const
572 {
573  if (m_bIsLocalUrl) {
574  return m_url.toLocalFile();
575  }
576 
577  // Extract the local path from the KIO::UDSEntry
578  return m_entry.stringValue( KIO::UDSEntry::UDS_LOCAL_PATH );
579 }
580 
581 QString KFileItem::localPath() const
582 {
583  return d->localPath();
584 }
585 
586 KIO::filesize_t KFileItem::size() const
587 {
588  return d->size();
589 }
590 
591 bool KFileItem::hasExtendedACL() const
592 {
593  // Check if the field exists; its value doesn't matter
594  return d->m_entry.contains(KIO::UDSEntry::UDS_EXTENDED_ACL);
595 }
596 
597 KACL KFileItem::ACL() const
598 {
599  if ( hasExtendedACL() ) {
600  // Extract it from the KIO::UDSEntry
601  const QString fieldVal = d->m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING );
602  if ( !fieldVal.isEmpty() )
603  return KACL( fieldVal );
604  }
605  // create one from the basic permissions
606  return KACL( d->m_permissions );
607 }
608 
609 KACL KFileItem::defaultACL() const
610 {
611  // Extract it from the KIO::UDSEntry
612  const QString fieldVal = d->m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING );
613  if ( !fieldVal.isEmpty() )
614  return KACL(fieldVal);
615  else
616  return KACL();
617 }
618 
619 KDateTime KFileItem::time( FileTimes which ) const
620 {
621  return d->time(which);
622 }
623 
624 #ifndef KDE_NO_DEPRECATED
625 time_t KFileItem::time( unsigned int which ) const
626 {
627  switch (which) {
628  case KIO::UDSEntry::UDS_ACCESS_TIME:
629  return d->time(AccessTime).toTime_t();
630  case KIO::UDSEntry::UDS_CREATION_TIME:
631  return d->time(CreationTime).toTime_t();
632  case KIO::UDSEntry::UDS_MODIFICATION_TIME:
633  default:
634  return d->time(ModificationTime).toTime_t();
635  }
636 }
637 #endif
638 
639 QString KFileItem::user() const
640 {
641  return d->user();
642 }
643 
644 QString KFileItemPrivate::user() const
645 {
646  QString userName = m_entry.stringValue(KIO::UDSEntry::UDS_USER);
647  if (userName.isEmpty() && m_bIsLocalUrl) {
648 #ifdef Q_WS_WIN
649  QFileInfo a(m_url.toLocalFile( KUrl::RemoveTrailingSlash ));
650  userName = a.owner();
651  m_entry.insert( KIO::UDSEntry::UDS_USER, userName );
652 #else
653  KDE_struct_stat buff;
654  if ( KDE::lstat( m_url.toLocalFile( KUrl::RemoveTrailingSlash ), &buff ) == 0) // get uid/gid of the link, if it's a link
655  {
656  struct passwd *pwuser = getpwuid( buff.st_uid );
657  if ( pwuser != 0 ) {
658  userName = QString::fromLocal8Bit(pwuser->pw_name);
659  m_entry.insert( KIO::UDSEntry::UDS_USER, userName );
660  }
661  }
662 #endif
663  }
664  return userName;
665 }
666 
667 QString KFileItem::group() const
668 {
669  return d->group();
670 }
671 
672 QString KFileItemPrivate::group() const
673 {
674  QString groupName = m_entry.stringValue( KIO::UDSEntry::UDS_GROUP );
675  if (groupName.isEmpty() && m_bIsLocalUrl )
676  {
677 #ifdef Q_WS_WIN
678  QFileInfo a(m_url.toLocalFile( KUrl::RemoveTrailingSlash ));
679  groupName = a.group();
680  m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName );
681 #else
682  KDE_struct_stat buff;
683  if ( KDE::lstat( m_url.toLocalFile( KUrl::RemoveTrailingSlash ), &buff ) == 0) // get uid/gid of the link, if it's a link
684  {
685  struct group *ge = getgrgid( buff.st_gid );
686  if ( ge != 0 ) {
687  groupName = QString::fromLocal8Bit(ge->gr_name);
688  if (groupName.isEmpty())
689  groupName.sprintf("%d",ge->gr_gid);
690  }
691  else
692  groupName.sprintf("%d",buff.st_gid);
693  m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName );
694  }
695 #endif
696  }
697  return groupName;
698 }
699 
700 bool KFileItemPrivate::isSlow() const
701 {
702  if (m_slow == SlowUnknown) {
703  const QString path = localPath();
704  if (!path.isEmpty()) {
705  const KFileSystemType::Type fsType = KFileSystemType::fileSystemType(path);
706  m_slow = (fsType == KFileSystemType::Nfs || fsType == KFileSystemType::Smb) ? Slow : Fast;
707  } else {
708  m_slow = Slow;
709  }
710  }
711  return m_slow == Slow;
712 }
713 
714 bool KFileItem::isSlow() const
715 {
716  return d->isSlow();
717 }
718 
719 QString KFileItem::mimetype() const
720 {
721  KFileItem * that = const_cast<KFileItem *>(this);
722  return that->determineMimeType()->name();
723 }
724 
725 KMimeType::Ptr KFileItem::determineMimeType() const
726 {
727  if ( !d->m_pMimeType || !d->m_bMimeTypeKnown )
728  {
729  bool isLocalUrl;
730  KUrl url = mostLocalUrl(isLocalUrl);
731 
732  d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl );
733  Q_ASSERT(d->m_pMimeType);
734  //kDebug() << d << "finding final mimetype for" << url << ":" << d->m_pMimeType->name();
735  d->m_bMimeTypeKnown = true;
736  }
737 
738  return d->m_pMimeType;
739 }
740 
741 bool KFileItem::isMimeTypeKnown() const
742 {
743  // The mimetype isn't known if determineMimeType was never called (on-demand determination)
744  // or if this fileitem has a guessed mimetype (e.g. ftp symlink) - in which case
745  // it always remains "not fully determined"
746  return d->m_bMimeTypeKnown && d->m_guessedMimeType.isEmpty();
747 }
748 
749 QString KFileItem::mimeComment() const
750 {
751  const QString displayType = d->m_entry.stringValue( KIO::UDSEntry::UDS_DISPLAY_TYPE );
752  if (!displayType.isEmpty())
753  return displayType;
754 
755  KMimeType::Ptr mType = determineMimeType();
756 
757  bool isLocalUrl;
758  KUrl url = mostLocalUrl(isLocalUrl);
759 
760  KMimeType::Ptr mime = mimeTypePtr();
761  // This cannot move to kio_file (with UDS_DISPLAY_TYPE) because it needs
762  // the mimetype to be determined, which is done here, and possibly delayed...
763  if (isLocalUrl && !d->isSlow() && mime->is("application/x-desktop")) {
764  KDesktopFile cfg( url.toLocalFile() );
765  QString comment = cfg.desktopGroup().readEntry( "Comment" );
766  if (!comment.isEmpty())
767  return comment;
768  }
769 
770  QString comment = d->isSlow() ? mType->comment() : mType->comment(url);
771  //kDebug() << "finding comment for " << url.url() << " : " << d->m_pMimeType->name();
772  if (!comment.isEmpty())
773  return comment;
774  else
775  return mType->name();
776 }
777 
778 static QString iconFromDesktopFile(const QString& path)
779 {
780  KDesktopFile cfg( path );
781  const QString icon = cfg.readIcon();
782  if ( cfg.hasLinkType() ) {
783  const KConfigGroup group = cfg.desktopGroup();
784  const QString type = cfg.readPath();
785  const QString emptyIcon = group.readEntry( "EmptyIcon" );
786  if ( !emptyIcon.isEmpty() ) {
787  const QString u = cfg.readUrl();
788  const KUrl url( u );
789  if ( url.protocol() == "trash" ) {
790  // We need to find if the trash is empty, preferably without using a KIO job.
791  // So instead kio_trash leaves an entry in its config file for us.
792  KConfig trashConfig( "trashrc", KConfig::SimpleConfig );
793  if ( trashConfig.group("Status").readEntry( "Empty", true ) ) {
794  return emptyIcon;
795  }
796  }
797  }
798  }
799  return icon;
800 }
801 
802 QString KFileItem::iconName() const
803 {
804  if (d->m_useIconNameCache && !d->m_iconName.isEmpty()) {
805  return d->m_iconName;
806  }
807 
808  d->m_iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME );
809  if (!d->m_iconName.isEmpty()) {
810  d->m_useIconNameCache = d->m_bMimeTypeKnown;
811  return d->m_iconName;
812  }
813 
814  bool isLocalUrl;
815  KUrl url = mostLocalUrl(isLocalUrl);
816 
817  KMimeType::Ptr mime;
818  // Use guessed mimetype for the icon
819  if (!d->m_guessedMimeType.isEmpty()) {
820  mime = KMimeType::mimeType( d->m_guessedMimeType );
821  } else {
822  mime = mimeTypePtr();
823  }
824 
825  if (isLocalUrl && !isSlow() && mime->is("application/x-desktop")) {
826  d->m_iconName = iconFromDesktopFile(url.toLocalFile());
827  if (!d->m_iconName.isEmpty()) {
828  d->m_useIconNameCache = d->m_bMimeTypeKnown;
829  return d->m_iconName;
830  }
831  }
832 
833  // KDE5: handle .directory files here too, and get rid of
834  // KFolderMimeType and the url argument in KMimeType::iconName().
835 
836  if (isSlow())
837  d->m_iconName = mime->iconName();
838  else
839  d->m_iconName = mime->iconName(url);
840  d->m_useIconNameCache = d->m_bMimeTypeKnown;
841  //kDebug() << "finding icon for" << url << ":" << d->m_iconName;
842  return d->m_iconName;
843 }
844 
849 static bool checkDesktopFile(const KFileItem& item, bool _determineMimeType)
850 {
851  // only local files
852  bool isLocal;
853  const KUrl url = item.mostLocalUrl(isLocal);
854  if (!isLocal)
855  return false;
856 
857  // only regular files
858  if (!item.isRegularFile())
859  return false;
860 
861  // only if readable
862  if (!item.isReadable())
863  return false;
864 
865  // return true if desktop file
866  KMimeType::Ptr mime = _determineMimeType ? item.determineMimeType() : item.mimeTypePtr();
867  return mime->is("application/x-desktop");
868 }
869 
870 QStringList KFileItem::overlays() const
871 {
872  QStringList names = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_OVERLAY_NAMES ).split(',');
873  if ( d->m_bLink ) {
874  names.append("emblem-symbolic-link");
875  }
876 
877  if ( !S_ISDIR( d->m_fileMode ) // Locked dirs have a special icon, use the overlay for files only
878  && !isReadable()) {
879  names.append("object-locked");
880  }
881 
882  if ( checkDesktopFile(*this, false) ) {
883  KDesktopFile cfg( localPath() );
884  const KConfigGroup group = cfg.desktopGroup();
885 
886  // Add a warning emblem if this is an executable desktop file
887  // which is untrusted.
888  if ( group.hasKey( "Exec" ) && !KDesktopFile::isAuthorizedDesktopFile( localPath() ) ) {
889  names.append( "emblem-important" );
890  }
891 
892  if (cfg.hasDeviceType()) {
893  const QString dev = cfg.readDevice();
894  if (!dev.isEmpty()) {
895  KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByDevice(dev);
896  if (mountPoint) // mounted?
897  names.append("emblem-mounted");
898  }
899  }
900  }
901 
902  if ( isHidden() ) {
903  names.append("hidden");
904  }
905 
906 #ifndef Q_OS_WIN
907  if( S_ISDIR( d->m_fileMode ) && d->m_bIsLocalUrl)
908  {
909  if (KSambaShare::instance()->isDirectoryShared( d->m_url.toLocalFile() ) ||
910  KNFSShare::instance()->isDirectoryShared( d->m_url.toLocalFile() ))
911  {
912  //kDebug() << d->m_url.path();
913  names.append("network-workgroup");
914  }
915  }
916 #endif // Q_OS_WIN
917 
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");
921  }
922 
923  return names;
924 }
925 
926 QString KFileItem::comment() const
927 {
928  return d->m_entry.stringValue( KIO::UDSEntry::UDS_COMMENT );
929 }
930 
931 // ## where is this used?
932 QPixmap KFileItem::pixmap( int _size, int _state ) const
933 {
934  const QString iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME );
935  if ( !iconName.isEmpty() )
936  return DesktopIcon(iconName, _size, _state);
937 
938  if (!d->m_pMimeType) {
939  // No mimetype determined yet, go for a fast default icon
940  if (S_ISDIR(d->m_fileMode)) {
941  static const QString * defaultFolderIcon = 0;
942  if ( !defaultFolderIcon ) {
943  const KMimeType::Ptr mimeType = KMimeType::mimeType( "inode/directory" );
944  if ( mimeType )
945  defaultFolderIcon = &KGlobal::staticQString( mimeType->iconName() );
946  else
947  kWarning(7000) << "No mimetype for inode/directory could be found. Check your installation.";
948  }
949  if ( defaultFolderIcon )
950  return DesktopIcon( *defaultFolderIcon, _size, _state );
951 
952  }
953  return DesktopIcon( "unknown", _size, _state );
954  }
955 
956  KMimeType::Ptr mime;
957  // Use guessed mimetype for the icon
958  if (!d->m_guessedMimeType.isEmpty())
959  mime = KMimeType::mimeType( d->m_guessedMimeType );
960  else
961  mime = d->m_pMimeType;
962 
963  // Support for gzipped files: extract mimetype of contained file
964  // See also the relevant code in overlays, which adds the zip overlay.
965  if ( mime->name() == "application/x-gzip" && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) )
966  {
967  KUrl sf;
968  sf.setPath( d->m_url.path().left( d->m_url.path().length() - 3 ) );
969  //kDebug() << "subFileName=" << subFileName;
970  mime = KMimeType::findByUrl( sf, 0, d->m_bIsLocalUrl );
971  }
972 
973  bool isLocalUrl;
974  KUrl url = mostLocalUrl(isLocalUrl);
975 
976  QPixmap p = KIconLoader::global()->loadMimeTypeIcon( mime->iconName( url ), KIconLoader::Desktop, _size, _state );
977  //kDebug() << "finding pixmap for " << url.url() << " : " << mime->name();
978  if (p.isNull())
979  kWarning() << "Pixmap not found for mimetype " << d->m_pMimeType->name();
980 
981  return p;
982 }
983 
984 bool KFileItem::isReadable() const
985 {
986  /*
987  struct passwd * user = getpwuid( geteuid() );
988  bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user);
989  // This gets ugly for the group....
990  // Maybe we want a static QString for the user and a static QStringList
991  // for the groups... then we need to handle the deletion properly...
992  */
993 
994  if (d->m_permissions != KFileItem::Unknown) {
995  // No read permission at all
996  if ( !(S_IRUSR & d->m_permissions) && !(S_IRGRP & d->m_permissions) && !(S_IROTH & d->m_permissions) )
997  return false;
998 
999  // Read permissions for all: save a stat call
1000  if ( (S_IRUSR|S_IRGRP|S_IROTH) & d->m_permissions )
1001  return true;
1002  }
1003 
1004  // Or if we can't read it [using ::access()] - not network transparent
1005  if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), R_OK ) == -1 )
1006  return false;
1007 
1008  return true;
1009 }
1010 
1011 bool KFileItem::isWritable() const
1012 {
1013  /*
1014  struct passwd * user = getpwuid( geteuid() );
1015  bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user);
1016  // This gets ugly for the group....
1017  // Maybe we want a static QString for the user and a static QStringList
1018  // for the groups... then we need to handle the deletion properly...
1019  */
1020 
1021  if (d->m_permissions != KFileItem::Unknown) {
1022  // No write permission at all
1023  if ( !(S_IWUSR & d->m_permissions) && !(S_IWGRP & d->m_permissions) && !(S_IWOTH & d->m_permissions) )
1024  return false;
1025  }
1026 
1027  // Or if we can't read it [using ::access()] - not network transparent
1028  if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), W_OK ) == -1 )
1029  return false;
1030 
1031  return true;
1032 }
1033 
1034 bool KFileItem::isHidden() const
1035 {
1036  // The kioslave can specify explicitly that a file is hidden or shown
1037  if ( d->m_hidden != KFileItemPrivate::Auto )
1038  return d->m_hidden == KFileItemPrivate::Hidden;
1039 
1040  // Prefer the filename that is part of the URL, in case the display name is different.
1041  QString fileName = d->m_url.fileName();
1042  if (fileName.isEmpty()) // e.g. "trash:/"
1043  fileName = d->m_strName;
1044  return fileName.length() > 1 && fileName[0] == '.'; // Just "." is current directory, not hidden.
1045 }
1046 
1047 bool KFileItem::isDir() const
1048 {
1049  if (d->m_fileMode == KFileItem::Unknown) {
1050  // Probably the file was deleted already, and KDirLister hasn't told the world yet.
1051  //kDebug() << d << url() << "can't say -> false";
1052  return false; // can't say for sure, so no
1053  }
1054  return (S_ISDIR(d->m_fileMode));
1055 }
1056 
1057 bool KFileItem::isFile() const
1058 {
1059  return !isDir();
1060 }
1061 
1062 #ifndef KDE_NO_DEPRECATED
1063 bool KFileItem::acceptsDrops() const
1064 {
1065  // A directory ?
1066  if ( S_ISDIR( mode() ) ) {
1067  return isWritable();
1068  }
1069 
1070  // But only local .desktop files and executables
1071  if ( !d->m_bIsLocalUrl )
1072  return false;
1073 
1074  if ( mimetype() == "application/x-desktop")
1075  return true;
1076 
1077  // Executable, shell script ... ?
1078  if ( QFileInfo(d->m_url.toLocalFile()).isExecutable() )
1079  return true;
1080 
1081  return false;
1082 }
1083 #endif
1084 
1085 QString KFileItem::getStatusBarInfo() const
1086 {
1087  QString text = d->m_strText;
1088  const QString comment = mimeComment();
1089 
1090  if ( d->m_bLink )
1091  {
1092  text += ' ';
1093  if ( comment.isEmpty() )
1094  text += i18n ( "(Symbolic Link to %1)", linkDest() );
1095  else
1096  text += i18n("(%1, Link to %2)", comment, linkDest());
1097  }
1098  else if ( targetUrl() != url() )
1099  {
1100  text += i18n ( " (Points to %1)", targetUrl().pathOrUrl());
1101  }
1102  else if ( S_ISREG( d->m_fileMode ) )
1103  {
1104  text += QString(" (%1, %2)").arg( comment, KIO::convertSize( size() ) );
1105  }
1106  else
1107  {
1108  text += QString(" (%1)").arg( comment );
1109  }
1110  return text;
1111 }
1112 
1113 #ifndef KDE_NO_DEPRECATED
1114 QString KFileItem::getToolTipText(int maxcount) const
1115 {
1116  // we can return QString() if no tool tip should be shown
1117  QString tip;
1118  KFileMetaInfo info = metaInfo();
1119 
1120  // the font tags are a workaround for the fact that the tool tip gets
1121  // screwed if the color scheme uses white as default text color
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 = "&nbsp;</b></font></nobr></td><td><nobr><font color=\"" + colorName + "\">";
1125  const char* end = "</font></nobr></td></tr>";
1126 
1127  tip = "<table cellspacing=0 cellpadding=0>";
1128 
1129  tip += start + i18n("Name:") + mid + text() + end;
1130  tip += start + i18n("Type:") + mid;
1131 
1132  QString type = Qt::escape(mimeComment());
1133  if ( d->m_bLink ) {
1134  tip += i18n("Link to %1 (%2)", linkDest(), type) + end;
1135  } else
1136  tip += type + end;
1137 
1138  if ( !S_ISDIR ( d->m_fileMode ) )
1139  tip += start + i18n("Size:") + mid +
1140  QString("%1").arg(KIO::convertSize(size())) +
1141  end;
1142 
1143  tip += start + i18n("Modified:") + mid +
1144  timeString( KFileItem::ModificationTime ) + end
1145 #ifndef Q_WS_WIN //TODO: show win32-specific permissions
1146  +start + i18n("Owner:") + mid + user() + " - " + group() + end +
1147  start + i18n("Permissions:") + mid +
1148  permissionsString() + end
1149 #endif
1150  ;
1151 
1152  if (info.isValid())
1153  {
1154  const QStringList keys = info.preferredKeys();
1155 
1156  // now the rest
1157  QStringList::ConstIterator it = keys.begin();
1158  for (int count = 0; count<maxcount && it!=keys.end() ; ++it)
1159  {
1160  if ( count == 0 )
1161  {
1162  tip += "<tr><td colspan=2><center><s>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</s></center></td></tr>";
1163  }
1164 
1165  KFileMetaInfoItem item = info.item( *it );
1166  if ( item.isValid() )
1167  {
1168  QString s = item.value().toString();
1169  if ( !s.isEmpty() )
1170  {
1171  count++;
1172  tip += start +
1173  Qt::escape( item.name() ) + ':' +
1174  mid +
1175  Qt::escape( s ) +
1176  end;
1177  }
1178 
1179  }
1180  }
1181  }
1182  tip += "</table>";
1183 
1184  //kDebug() << "making this the tool tip rich text:\n";
1185  //kDebug() << tip;
1186 
1187  return tip;
1188 }
1189 #endif
1190 
1191 void KFileItem::run( QWidget* parentWidget ) const
1192 {
1193  (void) new KRun( targetUrl(), parentWidget, d->m_fileMode, d->m_bIsLocalUrl );
1194 }
1195 
1196 bool KFileItem::cmp( const KFileItem & item ) const
1197 {
1198  return d->cmp(*item.d);
1199 }
1200 
1201 bool KFileItem::operator==(const KFileItem& other) const
1202 {
1203  // is this enough?
1204  return d == other.d;
1205 }
1206 
1207 bool KFileItem::operator!=(const KFileItem& other) const
1208 {
1209  return d != other.d;
1210 }
1211 
1212 #ifndef KDE_NO_DEPRECATED
1213 void KFileItem::setUDSEntry( const KIO::UDSEntry& _entry, const KUrl& _url,
1214  bool _delayedMimeTypes, bool _urlIsDirectory )
1215 {
1216  d->m_entry = _entry;
1217  d->m_url = _url;
1218  d->m_strName.clear();
1219  d->m_strText.clear();
1220  d->m_iconName.clear();
1221  d->m_strLowerCaseName.clear();
1222  d->m_pMimeType = 0;
1223  d->m_fileMode = KFileItem::Unknown;
1224  d->m_permissions = KFileItem::Unknown;
1225  d->m_bMarked = false;
1226  d->m_bLink = false;
1227  d->m_bIsLocalUrl = _url.isLocalFile();
1228  d->m_bMimeTypeKnown = false;
1229  d->m_hidden = KFileItemPrivate::Auto;
1230  d->m_guessedMimeType.clear();
1231  d->m_metaInfo = KFileMetaInfo();
1232  d->m_delayedMimeTypes = _delayedMimeTypes;
1233  d->m_useIconNameCache = false;
1234 
1235  d->readUDSEntry( _urlIsDirectory );
1236  d->init();
1237 }
1238 #endif
1239 
1240 KFileItem::operator QVariant() const
1241 {
1242  return qVariantFromValue(*this);
1243 }
1244 
1245 #ifndef KDE_NO_DEPRECATED
1246 void KFileItem::setExtraData( const void *key, void *value )
1247 {
1248  if ( !key )
1249  return;
1250 
1251  d->m_extra.insert( key, value ); // replaces the value of key if already there
1252 }
1253 #endif
1254 
1255 #ifndef KDE_NO_DEPRECATED
1256 const void * KFileItem::extraData( const void *key ) const
1257 {
1258  return d->m_extra.value( key, 0 );
1259 }
1260 #endif
1261 
1262 #ifndef KDE_NO_DEPRECATED
1263 void KFileItem::removeExtraData( const void *key )
1264 {
1265  d->m_extra.remove( key );
1266 }
1267 #endif
1268 
1269 QString KFileItem::permissionsString() const
1270 {
1271  if (d->m_access.isNull() && d->m_permissions != KFileItem::Unknown)
1272  d->m_access = d->parsePermissions( d->m_permissions );
1273 
1274  return d->m_access;
1275 }
1276 
1277 // check if we need to cache this
1278 QString KFileItem::timeString( FileTimes which ) const
1279 {
1280  return KGlobal::locale()->formatDateTime( d->time(which) );
1281 }
1282 
1283 #ifndef KDE_NO_DEPRECATED
1284 QString KFileItem::timeString( unsigned int which ) const
1285 {
1286  switch (which) {
1287  case KIO::UDSEntry::UDS_ACCESS_TIME:
1288  return timeString(AccessTime);
1289  case KIO::UDSEntry::UDS_CREATION_TIME:
1290  return timeString(CreationTime);
1291  case KIO::UDSEntry::UDS_MODIFICATION_TIME:
1292  default:
1293  return timeString(ModificationTime);
1294  }
1295 }
1296 #endif
1297 
1298 void KFileItem::setMetaInfo( const KFileMetaInfo & info ) const
1299 {
1300  d->m_metaInfo = info;
1301 }
1302 
1303 KFileMetaInfo KFileItem::metaInfo(bool autoget, int what) const
1304 {
1305  if ((isRegularFile() || isDir()) && autoget && !d->m_metaInfo.isValid())
1306  {
1307  bool isLocalUrl;
1308  KUrl url(mostLocalUrl(isLocalUrl));
1309  d->m_metaInfo = KFileMetaInfo(url.toLocalFile(), mimetype(), (KFileMetaInfo::What)what);
1310  }
1311  return d->m_metaInfo;
1312 }
1313 
1314 #ifndef KDE_NO_DEPRECATED
1315 void KFileItem::assign( const KFileItem & item )
1316 {
1317  *this = item;
1318 }
1319 #endif
1320 
1321 KUrl KFileItem::mostLocalUrl(bool &local) const
1322 {
1323  QString local_path = localPath();
1324 
1325  if ( !local_path.isEmpty() )
1326  {
1327  local = true;
1328  KUrl url;
1329  url.setPath(local_path);
1330  return url;
1331  }
1332  else
1333  {
1334  local = d->m_bIsLocalUrl;
1335  return d->m_url;
1336  }
1337 }
1338 
1339 KUrl KFileItem::mostLocalUrl() const
1340 {
1341  bool local = false;
1342  return mostLocalUrl(local);
1343 }
1344 
1345 QDataStream & operator<< ( QDataStream & s, const KFileItem & a )
1346 {
1347  // We don't need to save/restore anything that refresh() invalidates,
1348  // since that means we can re-determine those by ourselves.
1349  s << a.d->m_url;
1350  s << a.d->m_strName;
1351  s << a.d->m_strText;
1352  return s;
1353 }
1354 
1355 QDataStream & operator>> ( QDataStream & s, KFileItem & a )
1356 {
1357  s >> a.d->m_url;
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;
1362  a.refresh();
1363  return s;
1364 }
1365 
1366 KUrl KFileItem::url() const
1367 {
1368  return d->m_url;
1369 }
1370 
1371 mode_t KFileItem::permissions() const
1372 {
1373  return d->m_permissions;
1374 }
1375 
1376 mode_t KFileItem::mode() const
1377 {
1378  return d->m_fileMode;
1379 }
1380 
1381 bool KFileItem::isLink() const
1382 {
1383  return d->m_bLink;
1384 }
1385 
1386 bool KFileItem::isLocalFile() const
1387 {
1388  return d->m_bIsLocalUrl;
1389 }
1390 
1391 QString KFileItem::text() const
1392 {
1393  return d->m_strText;
1394 }
1395 
1396 QString KFileItem::name( bool lowerCase ) const
1397 {
1398  if ( !lowerCase )
1399  return d->m_strName;
1400  else
1401  if ( d->m_strLowerCaseName.isNull() )
1402  d->m_strLowerCaseName = d->m_strName.toLower();
1403  return d->m_strLowerCaseName;
1404 }
1405 
1406 KUrl KFileItem::targetUrl() const
1407 {
1408  const QString targetUrlStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_TARGET_URL );
1409  if (!targetUrlStr.isEmpty())
1410  return KUrl(targetUrlStr);
1411  else
1412  return url();
1413 }
1414 
1415 KUrl KFileItem::nepomukUri() const
1416 {
1417 #ifndef KIO_NO_NEPOMUK
1418  const QString nepomukUriStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_NEPOMUK_URI );
1419  if(!nepomukUriStr.isEmpty()) {
1420  return KUrl(nepomukUriStr);
1421  }
1422  else if(targetUrl().isLocalFile()) {
1423  return targetUrl();
1424  }
1425  else {
1426  return KUrl();
1427  }
1428 #else
1429  return KUrl();
1430 #endif
1431 }
1432 
1433 /*
1434  * Mimetype handling.
1435  *
1436  * Initial state: m_pMimeType = 0.
1437  * When mimeTypePtr() is called first: fast mimetype determination,
1438  * might either find an accurate mimetype (-> Final state), otherwise we
1439  * set m_pMimeType but not m_bMimeTypeKnown (-> Intermediate state)
1440  * Intermediate state: determineMimeType() does the real determination -> Final state.
1441  *
1442  * If delayedMimeTypes isn't set, then we always go to the Final state directly.
1443  */
1444 
1445 KMimeType::Ptr KFileItem::mimeTypePtr() const
1446 {
1447  if (!d->m_pMimeType) {
1448  // On-demand fast (but not always accurate) mimetype determination
1449  Q_ASSERT(!d->m_url.isEmpty());
1450  bool isLocalUrl;
1451  KUrl url = mostLocalUrl(isLocalUrl);
1452  int accuracy;
1453  d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl,
1454  // use fast mode if delayed mimetype determination can refine it later
1455  d->m_delayedMimeTypes, &accuracy );
1456  // If we used the "fast mode" (no sniffing), and we didn't get a perfect (extension-based) match,
1457  // then determineMimeType will be able to do better.
1458  const bool canDoBetter = d->m_delayedMimeTypes && accuracy < 100;
1459  //kDebug() << "finding mimetype for" << url << ":" << d->m_pMimeType->name() << "canDoBetter=" << canDoBetter;
1460  d->m_bMimeTypeKnown = !canDoBetter;
1461  }
1462  return d->m_pMimeType;
1463 }
1464 
1465 KIO::UDSEntry KFileItem::entry() const
1466 {
1467  return d->m_entry;
1468 }
1469 
1470 bool KFileItem::isMarked() const
1471 {
1472  return d->m_bMarked;
1473 }
1474 
1475 void KFileItem::mark()
1476 {
1477  d->m_bMarked = true;
1478 }
1479 
1480 void KFileItem::unmark()
1481 {
1482  d->m_bMarked = false;
1483 }
1484 
1485 KFileItem& KFileItem::operator=(const KFileItem& other)
1486 {
1487  d = other.d;
1488  return *this;
1489 }
1490 
1491 bool KFileItem::isNull() const
1492 {
1493  return d == 0;
1494 }
1495 
1496 KFileItemList::KFileItemList()
1497 {
1498 }
1499 
1500 KFileItemList::KFileItemList( const QList<KFileItem> &items )
1501  : QList<KFileItem>( items )
1502 {
1503 }
1504 
1505 KFileItem KFileItemList::findByName( const QString& fileName ) const
1506 {
1507  const_iterator it = begin();
1508  const const_iterator itend = end();
1509  for ( ; it != itend ; ++it ) {
1510  if ( (*it).name() == fileName ) {
1511  return *it;
1512  }
1513  }
1514  return KFileItem();
1515 }
1516 
1517 KFileItem KFileItemList::findByUrl( const KUrl& url ) const {
1518  const_iterator it = begin();
1519  const const_iterator itend = end();
1520  for ( ; it != itend ; ++it ) {
1521  if ( (*it).url() == url ) {
1522  return *it;
1523  }
1524  }
1525  return KFileItem();
1526 }
1527 
1528 KUrl::List KFileItemList::urlList() const {
1529  KUrl::List lst;
1530  const_iterator it = begin();
1531  const const_iterator itend = end();
1532  for ( ; it != itend ; ++it ) {
1533  lst.append( (*it).url() );
1534  }
1535  return lst;
1536 }
1537 
1538 KUrl::List KFileItemList::targetUrlList() const {
1539  KUrl::List lst;
1540  const_iterator it = begin();
1541  const const_iterator itend = end();
1542  for ( ; it != itend ; ++it ) {
1543  lst.append( (*it).targetUrl() );
1544  }
1545  return lst;
1546 }
1547 
1548 
1549 bool KFileItem::isDesktopFile() const
1550 {
1551  return checkDesktopFile(*this, true);
1552 }
1553 
1554 bool KFileItem::isRegularFile() const
1555 {
1556  return S_ISREG(d->m_fileMode);
1557 }
1558 
1559 QDebug operator<<(QDebug stream, const KFileItem& item)
1560 {
1561  if (item.isNull()) {
1562  stream << "[null KFileItem]";
1563  } else {
1564  stream << "[KFileItem for" << item.url() << "]";
1565  }
1566  return stream;
1567 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Fri Nov 16 2012 15:10:02 by doxygen 1.8.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.8.5 API Reference

Skip menu "kdelibs-4.8.5 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal