• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.10.1 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  if (!d) {
515  kWarning() << "null item";
516  return;
517  }
518 
519  d->m_fileMode = KFileItem::Unknown;
520  d->m_permissions = KFileItem::Unknown;
521  d->m_metaInfo = KFileMetaInfo();
522  d->m_hidden = KFileItemPrivate::Auto;
523  refreshMimeType();
524 
525  // Basically, we can't trust any information we got while listing.
526  // Everything could have changed...
527  // Clearing m_entry makes it possible to detect changes in the size of the file,
528  // the time information, etc.
529  d->m_entry.clear();
530  d->init();
531 }
532 
533 void KFileItem::refreshMimeType()
534 {
535  if (!d)
536  return;
537 
538  d->m_pMimeType = 0;
539  d->m_bMimeTypeKnown = false;
540  d->m_iconName.clear();
541 }
542 
543 void KFileItem::setUrl( const KUrl &url )
544 {
545  if (!d) {
546  kWarning() << "null item";
547  return;
548  }
549 
550  d->m_url = url;
551  setName( url.fileName() );
552 }
553 
554 void KFileItem::setName( const QString& name )
555 {
556  if (!d) {
557  kWarning() << "null item";
558  return;
559  }
560 
561  d->m_strName = name;
562  d->m_strText = KIO::decodeFileName( d->m_strName );
563  if (d->m_entry.contains(KIO::UDSEntry::UDS_NAME))
564  d->m_entry.insert(KIO::UDSEntry::UDS_NAME, d->m_strName); // #195385
565 
566 }
567 
568 QString KFileItem::linkDest() const
569 {
570  if (!d)
571  return QString();
572 
573  // Extract it from the KIO::UDSEntry
574  const QString linkStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_LINK_DEST );
575  if ( !linkStr.isEmpty() )
576  return linkStr;
577 
578  // If not in the KIO::UDSEntry, or if UDSEntry empty, use readlink() [if local URL]
579  if ( d->m_bIsLocalUrl )
580  {
581  char buf[1000];
582  int n = readlink( QFile::encodeName(d->m_url.toLocalFile( KUrl::RemoveTrailingSlash )), buf, sizeof(buf)-1 );
583  if ( n != -1 )
584  {
585  buf[ n ] = 0;
586  return QFile::decodeName( buf );
587  }
588  }
589  return QString();
590 }
591 
592 QString KFileItemPrivate::localPath() const
593 {
594  if (m_bIsLocalUrl) {
595  return m_url.toLocalFile();
596  }
597 
598  // Extract the local path from the KIO::UDSEntry
599  return m_entry.stringValue( KIO::UDSEntry::UDS_LOCAL_PATH );
600 }
601 
602 QString KFileItem::localPath() const
603 {
604  if (!d)
605  return QString();
606 
607  return d->localPath();
608 }
609 
610 KIO::filesize_t KFileItem::size() const
611 {
612  if (!d)
613  return 0;
614 
615  return d->size();
616 }
617 
618 bool KFileItem::hasExtendedACL() const
619 {
620  if (!d)
621  return false;
622 
623  // Check if the field exists; its value doesn't matter
624  return d->m_entry.contains(KIO::UDSEntry::UDS_EXTENDED_ACL);
625 }
626 
627 KACL KFileItem::ACL() const
628 {
629  if (!d)
630  return KACL();
631 
632  if ( hasExtendedACL() ) {
633  // Extract it from the KIO::UDSEntry
634  const QString fieldVal = d->m_entry.stringValue( KIO::UDSEntry::UDS_ACL_STRING );
635  if ( !fieldVal.isEmpty() )
636  return KACL( fieldVal );
637  }
638  // create one from the basic permissions
639  return KACL( d->m_permissions );
640 }
641 
642 KACL KFileItem::defaultACL() const
643 {
644  if (!d)
645  return KACL();
646 
647  // Extract it from the KIO::UDSEntry
648  const QString fieldVal = d->m_entry.stringValue( KIO::UDSEntry::UDS_DEFAULT_ACL_STRING );
649  if ( !fieldVal.isEmpty() )
650  return KACL(fieldVal);
651  else
652  return KACL();
653 }
654 
655 KDateTime KFileItem::time( FileTimes which ) const
656 {
657  if (!d)
658  return KDateTime();
659 
660  return d->time(which);
661 }
662 
663 #ifndef KDE_NO_DEPRECATED
664 time_t KFileItem::time( unsigned int which ) const
665 {
666  if (!d)
667  return 0;
668 
669  switch (which) {
670  case KIO::UDSEntry::UDS_ACCESS_TIME:
671  return d->time(AccessTime).toTime_t();
672  case KIO::UDSEntry::UDS_CREATION_TIME:
673  return d->time(CreationTime).toTime_t();
674  case KIO::UDSEntry::UDS_MODIFICATION_TIME:
675  default:
676  return d->time(ModificationTime).toTime_t();
677  }
678 }
679 #endif
680 
681 QString KFileItem::user() const
682 {
683  if (!d)
684  return QString();
685 
686  return d->user();
687 }
688 
689 QString KFileItemPrivate::user() const
690 {
691  QString userName = m_entry.stringValue(KIO::UDSEntry::UDS_USER);
692  if (userName.isEmpty() && m_bIsLocalUrl) {
693 #ifdef Q_WS_WIN
694  QFileInfo a(m_url.toLocalFile( KUrl::RemoveTrailingSlash ));
695  userName = a.owner();
696  m_entry.insert( KIO::UDSEntry::UDS_USER, userName );
697 #else
698  KDE_struct_stat buff;
699  if ( KDE::lstat( m_url.toLocalFile( KUrl::RemoveTrailingSlash ), &buff ) == 0) // get uid/gid of the link, if it's a link
700  {
701  struct passwd *pwuser = getpwuid( buff.st_uid );
702  if ( pwuser != 0 ) {
703  userName = QString::fromLocal8Bit(pwuser->pw_name);
704  m_entry.insert( KIO::UDSEntry::UDS_USER, userName );
705  }
706  }
707 #endif
708  }
709  return userName;
710 }
711 
712 QString KFileItem::group() const
713 {
714  if (!d)
715  return QString();
716 
717  return d->group();
718 }
719 
720 QString KFileItemPrivate::group() const
721 {
722  QString groupName = m_entry.stringValue( KIO::UDSEntry::UDS_GROUP );
723  if (groupName.isEmpty() && m_bIsLocalUrl )
724  {
725 #ifdef Q_WS_WIN
726  QFileInfo a(m_url.toLocalFile( KUrl::RemoveTrailingSlash ));
727  groupName = a.group();
728  m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName );
729 #else
730  KDE_struct_stat buff;
731  if ( KDE::lstat( m_url.toLocalFile( KUrl::RemoveTrailingSlash ), &buff ) == 0) // get uid/gid of the link, if it's a link
732  {
733  struct group *ge = getgrgid( buff.st_gid );
734  if ( ge != 0 ) {
735  groupName = QString::fromLocal8Bit(ge->gr_name);
736  if (groupName.isEmpty())
737  groupName.sprintf("%d",ge->gr_gid);
738  }
739  else
740  groupName.sprintf("%d",buff.st_gid);
741  m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName );
742  }
743 #endif
744  }
745  return groupName;
746 }
747 
748 bool KFileItemPrivate::isSlow() const
749 {
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;
755  } else {
756  m_slow = Slow;
757  }
758  }
759  return m_slow == Slow;
760 }
761 
762 bool KFileItem::isSlow() const
763 {
764  if (!d)
765  return false;
766 
767  return d->isSlow();
768 }
769 
770 QString KFileItem::mimetype() const
771 {
772  if (!d)
773  return QString();
774 
775  KFileItem * that = const_cast<KFileItem *>(this);
776  return that->determineMimeType()->name();
777 }
778 
779 KMimeType::Ptr KFileItem::determineMimeType() const
780 {
781  if (!d)
782  return KMimeType::Ptr();
783 
784  if ( !d->m_pMimeType || !d->m_bMimeTypeKnown )
785  {
786  bool isLocalUrl;
787  KUrl url = mostLocalUrl(isLocalUrl);
788 
789  d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl );
790  Q_ASSERT(d->m_pMimeType);
791  //kDebug() << d << "finding final mimetype for" << url << ":" << d->m_pMimeType->name();
792  d->m_bMimeTypeKnown = true;
793  }
794 
795  return d->m_pMimeType;
796 }
797 
798 bool KFileItem::isMimeTypeKnown() const
799 {
800  if (!d)
801  return false;
802 
803  // The mimetype isn't known if determineMimeType was never called (on-demand determination)
804  // or if this fileitem has a guessed mimetype (e.g. ftp symlink) - in which case
805  // it always remains "not fully determined"
806  return d->m_bMimeTypeKnown && d->m_guessedMimeType.isEmpty();
807 }
808 
809 QString KFileItem::mimeComment() const
810 {
811  if (!d)
812  return QString();
813 
814  const QString displayType = d->m_entry.stringValue( KIO::UDSEntry::UDS_DISPLAY_TYPE );
815  if (!displayType.isEmpty())
816  return displayType;
817 
818  KMimeType::Ptr mType = determineMimeType();
819 
820  bool isLocalUrl;
821  KUrl url = mostLocalUrl(isLocalUrl);
822 
823  KMimeType::Ptr mime = mimeTypePtr();
824  // This cannot move to kio_file (with UDS_DISPLAY_TYPE) because it needs
825  // the mimetype to be determined, which is done here, and possibly delayed...
826  if (isLocalUrl && !d->isSlow() && mime->is("application/x-desktop")) {
827  KDesktopFile cfg( url.toLocalFile() );
828  QString comment = cfg.desktopGroup().readEntry( "Comment" );
829  if (!comment.isEmpty())
830  return comment;
831  }
832 
833  QString comment = d->isSlow() ? mType->comment() : mType->comment(url);
834  //kDebug() << "finding comment for " << url.url() << " : " << d->m_pMimeType->name();
835  if (!comment.isEmpty())
836  return comment;
837  else
838  return mType->name();
839 }
840 
841 static QString iconFromDesktopFile(const QString& path)
842 {
843  KDesktopFile cfg( path );
844  const QString icon = cfg.readIcon();
845  if ( cfg.hasLinkType() ) {
846  const KConfigGroup group = cfg.desktopGroup();
847  const QString type = cfg.readPath();
848  const QString emptyIcon = group.readEntry( "EmptyIcon" );
849  if ( !emptyIcon.isEmpty() ) {
850  const QString u = cfg.readUrl();
851  const KUrl url( u );
852  if ( url.protocol() == "trash" ) {
853  // We need to find if the trash is empty, preferably without using a KIO job.
854  // So instead kio_trash leaves an entry in its config file for us.
855  KConfig trashConfig( "trashrc", KConfig::SimpleConfig );
856  if ( trashConfig.group("Status").readEntry( "Empty", true ) ) {
857  return emptyIcon;
858  }
859  }
860  }
861  }
862  return icon;
863 }
864 
865 QString KFileItem::iconName() const
866 {
867  if (!d)
868  return QString();
869 
870  if (d->m_useIconNameCache && !d->m_iconName.isEmpty()) {
871  return d->m_iconName;
872  }
873 
874  d->m_iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME );
875  if (!d->m_iconName.isEmpty()) {
876  d->m_useIconNameCache = d->m_bMimeTypeKnown;
877  return d->m_iconName;
878  }
879 
880  bool isLocalUrl;
881  KUrl url = mostLocalUrl(isLocalUrl);
882 
883  KMimeType::Ptr mime;
884  // Use guessed mimetype for the icon
885  if (!d->m_guessedMimeType.isEmpty()) {
886  mime = KMimeType::mimeType( d->m_guessedMimeType );
887  } else {
888  mime = mimeTypePtr();
889  }
890 
891  if (isLocalUrl && !isSlow() && mime->is("application/x-desktop")) {
892  d->m_iconName = iconFromDesktopFile(url.toLocalFile());
893  if (!d->m_iconName.isEmpty()) {
894  d->m_useIconNameCache = d->m_bMimeTypeKnown;
895  return d->m_iconName;
896  }
897  }
898 
899  // KDE5: handle .directory files here too, and get rid of
900  // KFolderMimeType and the url argument in KMimeType::iconName().
901 
902  if (isSlow())
903  d->m_iconName = mime->iconName();
904  else
905  d->m_iconName = mime->iconName(url);
906  d->m_useIconNameCache = d->m_bMimeTypeKnown;
907  //kDebug() << "finding icon for" << url << ":" << d->m_iconName;
908  return d->m_iconName;
909 }
910 
915 static bool checkDesktopFile(const KFileItem& item, bool _determineMimeType)
916 {
917  // only local files
918  bool isLocal;
919  const KUrl url = item.mostLocalUrl(isLocal);
920  if (!isLocal)
921  return false;
922 
923  // only regular files
924  if (!item.isRegularFile())
925  return false;
926 
927  // only if readable
928  if (!item.isReadable())
929  return false;
930 
931  // return true if desktop file
932  KMimeType::Ptr mime = _determineMimeType ? item.determineMimeType() : item.mimeTypePtr();
933  return mime->is("application/x-desktop");
934 }
935 
936 QStringList KFileItem::overlays() const
937 {
938  if (!d)
939  return QStringList();
940 
941  QStringList names = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_OVERLAY_NAMES ).split(',');
942  if ( d->m_bLink ) {
943  names.append("emblem-symbolic-link");
944  }
945 
946  if ( !S_ISDIR( d->m_fileMode ) // Locked dirs have a special icon, use the overlay for files only
947  && !isReadable()) {
948  names.append("object-locked");
949  }
950 
951  if ( checkDesktopFile(*this, false) ) {
952  KDesktopFile cfg( localPath() );
953  const KConfigGroup group = cfg.desktopGroup();
954 
955  // Add a warning emblem if this is an executable desktop file
956  // which is untrusted.
957  if ( group.hasKey( "Exec" ) && !KDesktopFile::isAuthorizedDesktopFile( localPath() ) ) {
958  names.append( "emblem-important" );
959  }
960 
961  if (cfg.hasDeviceType()) {
962  const QString dev = cfg.readDevice();
963  if (!dev.isEmpty()) {
964  KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByDevice(dev);
965  if (mountPoint) // mounted?
966  names.append("emblem-mounted");
967  }
968  }
969  }
970 
971  if ( isHidden() ) {
972  names.append("hidden");
973  }
974 
975 #ifndef Q_OS_WIN
976  if( S_ISDIR( d->m_fileMode ) && d->m_bIsLocalUrl)
977  {
978  if (KSambaShare::instance()->isDirectoryShared( d->m_url.toLocalFile() ) ||
979  KNFSShare::instance()->isDirectoryShared( d->m_url.toLocalFile() ))
980  {
981  //kDebug() << d->m_url.path();
982  names.append("network-workgroup");
983  }
984  }
985 #endif // Q_OS_WIN
986 
987  if ( d->m_pMimeType && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) &&
988  d->m_pMimeType->is("application/x-gzip") ) {
989  names.append("application-zip");
990  }
991 
992  return names;
993 }
994 
995 QString KFileItem::comment() const
996 {
997  if (!d)
998  return QString();
999 
1000  return d->m_entry.stringValue( KIO::UDSEntry::UDS_COMMENT );
1001 }
1002 
1003 // ## where is this used?
1004 QPixmap KFileItem::pixmap( int _size, int _state ) const
1005 {
1006  if (!d)
1007  return QPixmap();
1008 
1009  const QString iconName = d->m_entry.stringValue( KIO::UDSEntry::UDS_ICON_NAME );
1010  if ( !iconName.isEmpty() )
1011  return DesktopIcon(iconName, _size, _state);
1012 
1013  if (!d->m_pMimeType) {
1014  // No mimetype determined yet, go for a fast default icon
1015  if (S_ISDIR(d->m_fileMode)) {
1016  static const QString * defaultFolderIcon = 0;
1017  if ( !defaultFolderIcon ) {
1018  const KMimeType::Ptr mimeType = KMimeType::mimeType( "inode/directory" );
1019  if ( mimeType )
1020  defaultFolderIcon = &KGlobal::staticQString( mimeType->iconName() );
1021  else
1022  kWarning(7000) << "No mimetype for inode/directory could be found. Check your installation.";
1023  }
1024  if ( defaultFolderIcon )
1025  return DesktopIcon( *defaultFolderIcon, _size, _state );
1026 
1027  }
1028  return DesktopIcon( "unknown", _size, _state );
1029  }
1030 
1031  KMimeType::Ptr mime;
1032  // Use guessed mimetype for the icon
1033  if (!d->m_guessedMimeType.isEmpty())
1034  mime = KMimeType::mimeType( d->m_guessedMimeType );
1035  else
1036  mime = d->m_pMimeType;
1037 
1038  // Support for gzipped files: extract mimetype of contained file
1039  // See also the relevant code in overlays, which adds the zip overlay.
1040  if ( mime->name() == "application/x-gzip" && d->m_url.fileName().endsWith( QLatin1String( ".gz" ) ) )
1041  {
1042  KUrl sf;
1043  sf.setPath( d->m_url.path().left( d->m_url.path().length() - 3 ) );
1044  //kDebug() << "subFileName=" << subFileName;
1045  mime = KMimeType::findByUrl( sf, 0, d->m_bIsLocalUrl );
1046  }
1047 
1048  bool isLocalUrl;
1049  KUrl url = mostLocalUrl(isLocalUrl);
1050 
1051  QPixmap p = KIconLoader::global()->loadMimeTypeIcon( mime->iconName( url ), KIconLoader::Desktop, _size, _state );
1052  //kDebug() << "finding pixmap for " << url.url() << " : " << mime->name();
1053  if (p.isNull())
1054  kWarning() << "Pixmap not found for mimetype " << d->m_pMimeType->name();
1055 
1056  return p;
1057 }
1058 
1059 bool KFileItem::isReadable() const
1060 {
1061  if (!d)
1062  return false;
1063 
1064  /*
1065  struct passwd * user = getpwuid( geteuid() );
1066  bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user);
1067  // This gets ugly for the group....
1068  // Maybe we want a static QString for the user and a static QStringList
1069  // for the groups... then we need to handle the deletion properly...
1070  */
1071 
1072  if (d->m_permissions != KFileItem::Unknown) {
1073  // No read permission at all
1074  if ( !(S_IRUSR & d->m_permissions) && !(S_IRGRP & d->m_permissions) && !(S_IROTH & d->m_permissions) )
1075  return false;
1076 
1077  // Read permissions for all: save a stat call
1078  if ( (S_IRUSR|S_IRGRP|S_IROTH) & d->m_permissions )
1079  return true;
1080  }
1081 
1082  // Or if we can't read it [using ::access()] - not network transparent
1083  if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), R_OK ) == -1 )
1084  return false;
1085 
1086  return true;
1087 }
1088 
1089 bool KFileItem::isWritable() const
1090 {
1091  if (!d)
1092  return false;
1093 
1094  /*
1095  struct passwd * user = getpwuid( geteuid() );
1096  bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user);
1097  // This gets ugly for the group....
1098  // Maybe we want a static QString for the user and a static QStringList
1099  // for the groups... then we need to handle the deletion properly...
1100  */
1101 
1102  if (d->m_permissions != KFileItem::Unknown) {
1103  // No write permission at all
1104  if ( !(S_IWUSR & d->m_permissions) && !(S_IWGRP & d->m_permissions) && !(S_IWOTH & d->m_permissions) )
1105  return false;
1106  }
1107 
1108  // Or if we can't read it [using ::access()] - not network transparent
1109  if ( d->m_bIsLocalUrl && KDE::access( d->m_url.toLocalFile(), W_OK ) == -1 )
1110  return false;
1111 
1112  return true;
1113 }
1114 
1115 bool KFileItem::isHidden() const
1116 {
1117  if (!d)
1118  return false;
1119 
1120  // The kioslave can specify explicitly that a file is hidden or shown
1121  if ( d->m_hidden != KFileItemPrivate::Auto )
1122  return d->m_hidden == KFileItemPrivate::Hidden;
1123 
1124  // Prefer the filename that is part of the URL, in case the display name is different.
1125  QString fileName = d->m_url.fileName();
1126  if (fileName.isEmpty()) // e.g. "trash:/"
1127  fileName = d->m_strName;
1128  return fileName.length() > 1 && fileName[0] == '.'; // Just "." is current directory, not hidden.
1129 }
1130 
1131 bool KFileItem::isDir() const
1132 {
1133  if (!d)
1134  return false;
1135 
1136  if (d->m_fileMode == KFileItem::Unknown) {
1137  // Probably the file was deleted already, and KDirLister hasn't told the world yet.
1138  //kDebug() << d << url() << "can't say -> false";
1139  return false; // can't say for sure, so no
1140  }
1141  return (S_ISDIR(d->m_fileMode));
1142 }
1143 
1144 bool KFileItem::isFile() const
1145 {
1146  if (!d)
1147  return false;
1148 
1149  return !isDir();
1150 }
1151 
1152 #ifndef KDE_NO_DEPRECATED
1153 bool KFileItem::acceptsDrops() const
1154 {
1155  // A directory ?
1156  if ( S_ISDIR( mode() ) ) {
1157  return isWritable();
1158  }
1159 
1160  // But only local .desktop files and executables
1161  if ( !d->m_bIsLocalUrl )
1162  return false;
1163 
1164  if ( mimetype() == "application/x-desktop")
1165  return true;
1166 
1167  // Executable, shell script ... ?
1168  if ( QFileInfo(d->m_url.toLocalFile()).isExecutable() )
1169  return true;
1170 
1171  return false;
1172 }
1173 #endif
1174 
1175 QString KFileItem::getStatusBarInfo() const
1176 {
1177  if (!d)
1178  return QString();
1179 
1180  QString text = d->m_strText;
1181  const QString comment = mimeComment();
1182 
1183  if ( d->m_bLink )
1184  {
1185  text += ' ';
1186  if ( comment.isEmpty() )
1187  text += i18n ( "(Symbolic Link to %1)", linkDest() );
1188  else
1189  text += i18n("(%1, Link to %2)", comment, linkDest());
1190  }
1191  else if ( targetUrl() != url() )
1192  {
1193  text += i18n ( " (Points to %1)", targetUrl().pathOrUrl());
1194  }
1195  else if ( S_ISREG( d->m_fileMode ) )
1196  {
1197  text += QString(" (%1, %2)").arg( comment, KIO::convertSize( size() ) );
1198  }
1199  else
1200  {
1201  text += QString(" (%1)").arg( comment );
1202  }
1203  return text;
1204 }
1205 
1206 #ifndef KDE_NO_DEPRECATED
1207 QString KFileItem::getToolTipText(int maxcount) const
1208 {
1209  if (!d)
1210  return QString();
1211 
1212  // we can return QString() if no tool tip should be shown
1213  QString tip;
1214  KFileMetaInfo info = metaInfo();
1215 
1216  // the font tags are a workaround for the fact that the tool tip gets
1217  // screwed if the color scheme uses white as default text color
1218  const QString colorName = QApplication::palette().color(QPalette::ToolTipText).name();
1219  const QString start = "<tr><td align=\"right\"><nobr><font color=\"" + colorName + "\"><b>";
1220  const QString mid = "&nbsp;</b></font></nobr></td><td><nobr><font color=\"" + colorName + "\">";
1221  const char* end = "</font></nobr></td></tr>";
1222 
1223  tip = "<table cellspacing=0 cellpadding=0>";
1224 
1225  tip += start + i18n("Name:") + mid + text() + end;
1226  tip += start + i18n("Type:") + mid;
1227 
1228  QString type = Qt::escape(mimeComment());
1229  if ( d->m_bLink ) {
1230  tip += i18n("Link to %1 (%2)", linkDest(), type) + end;
1231  } else
1232  tip += type + end;
1233 
1234  if ( !S_ISDIR ( d->m_fileMode ) )
1235  tip += start + i18n("Size:") + mid +
1236  QString("%1").arg(KIO::convertSize(size())) +
1237  end;
1238 
1239  tip += start + i18n("Modified:") + mid +
1240  timeString( KFileItem::ModificationTime ) + end
1241 #ifndef Q_WS_WIN //TODO: show win32-specific permissions
1242  +start + i18n("Owner:") + mid + user() + " - " + group() + end +
1243  start + i18n("Permissions:") + mid +
1244  permissionsString() + end
1245 #endif
1246  ;
1247 
1248  if (info.isValid())
1249  {
1250  const QStringList keys = info.preferredKeys();
1251 
1252  // now the rest
1253  QStringList::ConstIterator it = keys.begin();
1254  for (int count = 0; count<maxcount && it!=keys.end() ; ++it)
1255  {
1256  if ( count == 0 )
1257  {
1258  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>";
1259  }
1260 
1261  KFileMetaInfoItem item = info.item( *it );
1262  if ( item.isValid() )
1263  {
1264  QString s = item.value().toString();
1265  if ( !s.isEmpty() )
1266  {
1267  count++;
1268  tip += start +
1269  Qt::escape( item.name() ) + ':' +
1270  mid +
1271  Qt::escape( s ) +
1272  end;
1273  }
1274 
1275  }
1276  }
1277  }
1278  tip += "</table>";
1279 
1280  //kDebug() << "making this the tool tip rich text:\n";
1281  //kDebug() << tip;
1282 
1283  return tip;
1284 }
1285 #endif
1286 
1287 void KFileItem::run( QWidget* parentWidget ) const
1288 {
1289  if (!d) {
1290  kWarning() << "null item";
1291  return;
1292  }
1293 
1294  (void) new KRun( targetUrl(), parentWidget, d->m_fileMode, d->m_bIsLocalUrl );
1295 }
1296 
1297 bool KFileItem::cmp( const KFileItem & item ) const
1298 {
1299  if (!d && !item.d)
1300  return true;
1301 
1302  if (!d || !item.d)
1303  return false;
1304 
1305  return d->cmp(*item.d);
1306 }
1307 
1308 bool KFileItem::operator==(const KFileItem& other) const
1309 {
1310  if (!d && !other.d)
1311  return true;
1312 
1313  if (!d || !other.d)
1314  return false;
1315 
1316  return d->m_url == other.d->m_url;
1317 }
1318 
1319 bool KFileItem::operator!=(const KFileItem& other) const
1320 {
1321  return !operator==(other);
1322 }
1323 
1324 #ifndef KDE_NO_DEPRECATED
1325 void KFileItem::setUDSEntry( const KIO::UDSEntry& _entry, const KUrl& _url,
1326  bool _delayedMimeTypes, bool _urlIsDirectory )
1327 {
1328  if (!d)
1329  return;
1330 
1331  d->m_entry = _entry;
1332  d->m_url = _url;
1333  d->m_strName.clear();
1334  d->m_strText.clear();
1335  d->m_iconName.clear();
1336  d->m_strLowerCaseName.clear();
1337  d->m_pMimeType = 0;
1338  d->m_fileMode = KFileItem::Unknown;
1339  d->m_permissions = KFileItem::Unknown;
1340  d->m_bMarked = false;
1341  d->m_bLink = false;
1342  d->m_bIsLocalUrl = _url.isLocalFile();
1343  d->m_bMimeTypeKnown = false;
1344  d->m_hidden = KFileItemPrivate::Auto;
1345  d->m_guessedMimeType.clear();
1346  d->m_metaInfo = KFileMetaInfo();
1347  d->m_delayedMimeTypes = _delayedMimeTypes;
1348  d->m_useIconNameCache = false;
1349 
1350  d->readUDSEntry( _urlIsDirectory );
1351  d->init();
1352 }
1353 #endif
1354 
1355 KFileItem::operator QVariant() const
1356 {
1357  return qVariantFromValue(*this);
1358 }
1359 
1360 #ifndef KDE_NO_DEPRECATED
1361 void KFileItem::setExtraData( const void *key, void *value )
1362 {
1363  if (!d)
1364  return;
1365 
1366  if ( !key )
1367  return;
1368 
1369  d->m_extra.insert( key, value ); // replaces the value of key if already there
1370 }
1371 #endif
1372 
1373 #ifndef KDE_NO_DEPRECATED
1374 const void * KFileItem::extraData( const void *key ) const
1375 {
1376  if (!d)
1377  return 0;
1378 
1379  return d->m_extra.value( key, 0 );
1380 }
1381 #endif
1382 
1383 #ifndef KDE_NO_DEPRECATED
1384 void KFileItem::removeExtraData( const void *key )
1385 {
1386  if (!d)
1387  return;
1388 
1389  d->m_extra.remove( key );
1390 }
1391 #endif
1392 
1393 QString KFileItem::permissionsString() const
1394 {
1395  if (!d)
1396  return QString();
1397 
1398  if (d->m_access.isNull() && d->m_permissions != KFileItem::Unknown)
1399  d->m_access = d->parsePermissions( d->m_permissions );
1400 
1401  return d->m_access;
1402 }
1403 
1404 // check if we need to cache this
1405 QString KFileItem::timeString( FileTimes which ) const
1406 {
1407  if (!d)
1408  return QString();
1409 
1410  return KGlobal::locale()->formatDateTime( d->time(which) );
1411 }
1412 
1413 #ifndef KDE_NO_DEPRECATED
1414 QString KFileItem::timeString( unsigned int which ) const
1415 {
1416  if (!d)
1417  return QString();
1418 
1419  switch (which) {
1420  case KIO::UDSEntry::UDS_ACCESS_TIME:
1421  return timeString(AccessTime);
1422  case KIO::UDSEntry::UDS_CREATION_TIME:
1423  return timeString(CreationTime);
1424  case KIO::UDSEntry::UDS_MODIFICATION_TIME:
1425  default:
1426  return timeString(ModificationTime);
1427  }
1428 }
1429 #endif
1430 
1431 void KFileItem::setMetaInfo( const KFileMetaInfo & info ) const
1432 {
1433  if (!d)
1434  return;
1435 
1436  d->m_metaInfo = info;
1437 }
1438 
1439 KFileMetaInfo KFileItem::metaInfo(bool autoget, int what) const
1440 {
1441  if (!d)
1442  return KFileMetaInfo();
1443 
1444  if ((isRegularFile() || isDir()) && autoget && !d->m_metaInfo.isValid())
1445  {
1446  bool isLocalUrl;
1447  KUrl url(mostLocalUrl(isLocalUrl));
1448  d->m_metaInfo = KFileMetaInfo(url.toLocalFile(), mimetype(), (KFileMetaInfo::What)what);
1449  }
1450  return d->m_metaInfo;
1451 }
1452 
1453 #ifndef KDE_NO_DEPRECATED
1454 void KFileItem::assign( const KFileItem & item )
1455 {
1456  *this = item;
1457 }
1458 #endif
1459 
1460 KUrl KFileItem::mostLocalUrl(bool &local) const
1461 {
1462  if (!d)
1463  return KUrl();
1464 
1465  QString local_path = localPath();
1466 
1467  if ( !local_path.isEmpty() )
1468  {
1469  local = true;
1470  KUrl url;
1471  url.setPath(local_path);
1472  return url;
1473  }
1474  else
1475  {
1476  local = d->m_bIsLocalUrl;
1477  return d->m_url;
1478  }
1479 }
1480 
1481 KUrl KFileItem::mostLocalUrl() const
1482 {
1483  bool local = false;
1484  return mostLocalUrl(local);
1485 }
1486 
1487 QDataStream & operator<< ( QDataStream & s, const KFileItem & a )
1488 {
1489  if (a.d) {
1490  // We don't need to save/restore anything that refresh() invalidates,
1491  // since that means we can re-determine those by ourselves.
1492  s << a.d->m_url;
1493  s << a.d->m_strName;
1494  s << a.d->m_strText;
1495  } else {
1496  s << KUrl();
1497  s << QString();
1498  s << QString();
1499  }
1500 
1501  return s;
1502 }
1503 
1504 QDataStream & operator>> ( QDataStream & s, KFileItem & a )
1505 {
1506  KUrl url;
1507  QString strName, strText;
1508 
1509  s >> url;
1510  s >> strName;
1511  s >> strText;
1512 
1513  if (!a.d) {
1514  kWarning() << "null item";
1515  return s;
1516  }
1517 
1518  if (url.isEmpty()) {
1519  a.d = 0;
1520  return s;
1521  }
1522 
1523  a.d->m_url = url;
1524  a.d->m_strName = strName;
1525  a.d->m_strText = strText;
1526  a.d->m_bIsLocalUrl = a.d->m_url.isLocalFile();
1527  a.d->m_bMimeTypeKnown = false;
1528  a.refresh();
1529 
1530  return s;
1531 }
1532 
1533 KUrl KFileItem::url() const
1534 {
1535  if (!d)
1536  return KUrl();
1537 
1538  return d->m_url;
1539 }
1540 
1541 mode_t KFileItem::permissions() const
1542 {
1543  if (!d)
1544  return 0;
1545 
1546  return d->m_permissions;
1547 }
1548 
1549 mode_t KFileItem::mode() const
1550 {
1551  if (!d)
1552  return 0;
1553 
1554  return d->m_fileMode;
1555 }
1556 
1557 bool KFileItem::isLink() const
1558 {
1559  if (!d)
1560  return false;
1561 
1562  return d->m_bLink;
1563 }
1564 
1565 bool KFileItem::isLocalFile() const
1566 {
1567  if (!d)
1568  return false;
1569 
1570  return d->m_bIsLocalUrl;
1571 }
1572 
1573 QString KFileItem::text() const
1574 {
1575  if (!d)
1576  return QString();
1577 
1578  return d->m_strText;
1579 }
1580 
1581 QString KFileItem::name( bool lowerCase ) const
1582 {
1583  if (!d)
1584  return QString();
1585 
1586  if ( !lowerCase )
1587  return d->m_strName;
1588  else
1589  if ( d->m_strLowerCaseName.isNull() )
1590  d->m_strLowerCaseName = d->m_strName.toLower();
1591  return d->m_strLowerCaseName;
1592 }
1593 
1594 KUrl KFileItem::targetUrl() const
1595 {
1596  if (!d)
1597  return KUrl();
1598 
1599  const QString targetUrlStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_TARGET_URL );
1600  if (!targetUrlStr.isEmpty())
1601  return KUrl(targetUrlStr);
1602  else
1603  return url();
1604 }
1605 
1606 KUrl KFileItem::nepomukUri() const
1607 {
1608 #ifndef KIO_NO_NEPOMUK
1609  if (!d)
1610  return KUrl();
1611 
1612  const QString nepomukUriStr = d->m_entry.stringValue( KIO::UDSEntry::UDS_NEPOMUK_URI );
1613  if(!nepomukUriStr.isEmpty()) {
1614  return KUrl(nepomukUriStr);
1615  }
1616  else if(targetUrl().isLocalFile()) {
1617  return targetUrl();
1618  }
1619  else {
1620  return KUrl();
1621  }
1622 #else
1623  return KUrl();
1624 #endif
1625 }
1626 
1627 /*
1628  * Mimetype handling.
1629  *
1630  * Initial state: m_pMimeType = 0.
1631  * When mimeTypePtr() is called first: fast mimetype determination,
1632  * might either find an accurate mimetype (-> Final state), otherwise we
1633  * set m_pMimeType but not m_bMimeTypeKnown (-> Intermediate state)
1634  * Intermediate state: determineMimeType() does the real determination -> Final state.
1635  *
1636  * If delayedMimeTypes isn't set, then we always go to the Final state directly.
1637  */
1638 
1639 KMimeType::Ptr KFileItem::mimeTypePtr() const
1640 {
1641  if (!d)
1642  return KMimeType::Ptr();
1643 
1644  if (!d->m_pMimeType) {
1645  // On-demand fast (but not always accurate) mimetype determination
1646  Q_ASSERT(!d->m_url.isEmpty());
1647  bool isLocalUrl;
1648  KUrl url = mostLocalUrl(isLocalUrl);
1649  int accuracy;
1650  d->m_pMimeType = KMimeType::findByUrl( url, d->m_fileMode, isLocalUrl,
1651  // use fast mode if delayed mimetype determination can refine it later
1652  d->m_delayedMimeTypes, &accuracy );
1653  // If we used the "fast mode" (no sniffing), and we didn't get a perfect (extension-based) match,
1654  // then determineMimeType will be able to do better.
1655  const bool canDoBetter = d->m_delayedMimeTypes && accuracy < 100;
1656  //kDebug() << "finding mimetype for" << url << ":" << d->m_pMimeType->name() << "canDoBetter=" << canDoBetter;
1657  d->m_bMimeTypeKnown = !canDoBetter;
1658  }
1659  return d->m_pMimeType;
1660 }
1661 
1662 KIO::UDSEntry KFileItem::entry() const
1663 {
1664  if (!d)
1665  return KIO::UDSEntry();
1666 
1667  return d->m_entry;
1668 }
1669 
1670 bool KFileItem::isMarked() const
1671 {
1672  if (!d)
1673  return false;
1674 
1675  return d->m_bMarked;
1676 }
1677 
1678 void KFileItem::mark()
1679 {
1680  if (!d) {
1681  kWarning() << "null item";
1682  return;
1683  }
1684 
1685  d->m_bMarked = true;
1686 }
1687 
1688 void KFileItem::unmark()
1689 {
1690  if (!d) {
1691  kWarning() << "null item";
1692  return;
1693  }
1694 
1695  d->m_bMarked = false;
1696 }
1697 
1698 KFileItem& KFileItem::operator=(const KFileItem& other)
1699 {
1700  d = other.d;
1701  return *this;
1702 }
1703 
1704 bool KFileItem::isNull() const
1705 {
1706  return d == 0;
1707 }
1708 
1709 KFileItemList::KFileItemList()
1710 {
1711 }
1712 
1713 KFileItemList::KFileItemList( const QList<KFileItem> &items )
1714  : QList<KFileItem>( items )
1715 {
1716 }
1717 
1718 KFileItem KFileItemList::findByName( const QString& fileName ) const
1719 {
1720  const_iterator it = begin();
1721  const const_iterator itend = end();
1722  for ( ; it != itend ; ++it ) {
1723  if ( (*it).name() == fileName ) {
1724  return *it;
1725  }
1726  }
1727  return KFileItem();
1728 }
1729 
1730 KFileItem KFileItemList::findByUrl( const KUrl& url ) const {
1731  const_iterator it = begin();
1732  const const_iterator itend = end();
1733  for ( ; it != itend ; ++it ) {
1734  if ( (*it).url() == url ) {
1735  return *it;
1736  }
1737  }
1738  return KFileItem();
1739 }
1740 
1741 KUrl::List KFileItemList::urlList() const {
1742  KUrl::List lst;
1743  const_iterator it = begin();
1744  const const_iterator itend = end();
1745  for ( ; it != itend ; ++it ) {
1746  lst.append( (*it).url() );
1747  }
1748  return lst;
1749 }
1750 
1751 KUrl::List KFileItemList::targetUrlList() const {
1752  KUrl::List lst;
1753  const_iterator it = begin();
1754  const const_iterator itend = end();
1755  for ( ; it != itend ; ++it ) {
1756  lst.append( (*it).targetUrl() );
1757  }
1758  return lst;
1759 }
1760 
1761 
1762 bool KFileItem::isDesktopFile() const
1763 {
1764  return checkDesktopFile(*this, true);
1765 }
1766 
1767 bool KFileItem::isRegularFile() const
1768 {
1769  if (!d)
1770  return false;
1771 
1772  return S_ISREG(d->m_fileMode);
1773 }
1774 
1775 QDebug operator<<(QDebug stream, const KFileItem& item)
1776 {
1777  if (item.isNull()) {
1778  stream << "[null KFileItem]";
1779  } else {
1780  stream << "[KFileItem for" << item.url() << "]";
1781  }
1782  return stream;
1783 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Wed Mar 20 2013 07:19:33 by doxygen 1.8.3.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.10.1 API Reference

Skip menu "kdelibs-4.10.1 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