summaryrefslogtreecommitdiffstats
path: root/tdeio/tdeio/tdefileitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdeio/tdeio/tdefileitem.cpp')
-rw-r--r--tdeio/tdeio/tdefileitem.cpp1202
1 files changed, 1202 insertions, 0 deletions
diff --git a/tdeio/tdeio/tdefileitem.cpp b/tdeio/tdeio/tdefileitem.cpp
new file mode 100644
index 000000000..378cd5f0a
--- /dev/null
+++ b/tdeio/tdeio/tdefileitem.cpp
@@ -0,0 +1,1202 @@
+/* This file is part of the KDE project
+ Copyright (C) 1999 David Faure <faure@kde.org>
+ 2001 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+// $Id$
+
+#include <config.h>
+
+#include <sys/time.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/types.h>
+
+#include <assert.h>
+#include <unistd.h>
+
+#include "tdefileitem.h"
+
+#include <tqdir.h>
+#include <tqfile.h>
+#include <tqmap.h>
+#include <tqstylesheet.h>
+#include <tqimage.h>
+
+#include <kdebug.h>
+#include <tdefilemetainfo.h>
+#include <ksambashare.h>
+#include <knfsshare.h>
+#include <tdeglobal.h>
+#include <tdeglobalsettings.h>
+#include <kiconloader.h>
+#include <klargefile.h>
+#include <tdelocale.h>
+#include <kmimetype.h>
+#include <krun.h>
+
+#ifdef HAVE_ELFICON
+#include "tdelficon.h"
+#endif // HAVE_ELFICON
+
+class KFileItem::KFileItemPrivate {
+ public:
+ TQString iconName;
+};
+
+KFileItem::KFileItem( const TDEIO::UDSEntry& _entry, const KURL& _url,
+ bool _determineMimeTypeOnDemand, bool _urlIsDirectory ) :
+ m_entry( _entry ),
+ m_url( _url ),
+ m_pMimeType( 0 ),
+ m_fileMode( KFileItem::Unknown ),
+ m_permissions( KFileItem::Unknown ),
+ m_bMarked( false ),
+ m_bLink( false ),
+ m_bIsLocalURL( _url.isLocalFile() ),
+ m_bMimeTypeKnown( false ),
+ m_hidden( Auto ),
+ d(0)
+{
+ readUDSEntry( _urlIsDirectory );
+ init( _determineMimeTypeOnDemand );
+}
+
+KFileItem::KFileItem( mode_t _mode, mode_t _permissions, const KURL& _url, bool _determineMimeTypeOnDemand ) :
+ m_entry(), // warning !
+ m_url( _url ),
+ m_strName( _url.fileName() ),
+ m_strText( TDEIO::decodeFileName( m_strName ) ),
+ m_pMimeType( 0 ),
+ m_fileMode ( _mode ),
+ m_permissions( _permissions ),
+ m_bMarked( false ),
+ m_bLink( false ),
+ m_bIsLocalURL( _url.isLocalFile() ),
+ m_bMimeTypeKnown( false ),
+ m_hidden( Auto ),
+ d(0)
+{
+ init( _determineMimeTypeOnDemand );
+}
+
+KFileItem::KFileItem( const KURL &url, const TQString &mimeType, mode_t mode )
+: m_url( url ),
+ m_strName( url.fileName() ),
+ m_strText( TDEIO::decodeFileName( m_strName ) ),
+ m_pMimeType( 0 ),
+ m_fileMode( mode ),
+ m_permissions( KFileItem::Unknown ),
+ m_bMarked( false ),
+ m_bLink( false ),
+ m_bIsLocalURL( url.isLocalFile() ),
+ m_bMimeTypeKnown( !mimeType.isEmpty() ),
+ m_hidden( Auto ),
+ d(0)
+{
+ if (m_bMimeTypeKnown)
+ m_pMimeType = KMimeType::mimeType( mimeType );
+
+ init( false );
+}
+
+KFileItem::KFileItem( const KFileItem & item ) :
+ d(0)
+{
+ assign( item );
+}
+
+KFileItem& KFileItem::operator=( const KFileItem & item )
+{
+ assign( item );
+ return *this;
+}
+
+KFileItem::~KFileItem()
+{
+ delete d;
+}
+
+void KFileItem::init( bool _determineMimeTypeOnDemand )
+{
+ m_access = TQString::null;
+ m_size = (TDEIO::filesize_t) -1;
+ // metaInfo = KFileMetaInfo();
+ for ( int i = 0; i < NumFlags; i++ )
+ m_time[i] = (time_t) -1;
+
+ // determine mode and/or permissions if unknown
+ if ( m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown )
+ {
+ mode_t mode = 0;
+ if ( m_url.isLocalFile() )
+ {
+ /* directories may not have a slash at the end if
+ * we want to stat() them; it requires that we
+ * change into it .. which may not be allowed
+ * stat("/is/unaccessible") -> rwx------
+ * stat("/is/unaccessible/") -> EPERM H.Z.
+ * This is the reason for the -1
+ */
+ KDE_struct_stat buf;
+ TQCString path = TQFile::encodeName(m_url.path( -1 ));
+ if ( KDE_lstat( path.data(), &buf ) == 0 )
+ {
+ mode = buf.st_mode;
+ if ( S_ISLNK( mode ) )
+ {
+ m_bLink = true;
+ if ( KDE_stat( path.data(), &buf ) == 0 )
+ mode = buf.st_mode;
+ else // link pointing to nowhere (see tdeio/file/file.cc)
+ mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO;
+ }
+ // While we're at it, store the times
+ m_time[ Modification ] = buf.st_mtime;
+ m_time[ Access ] = buf.st_atime;
+ if ( m_fileMode == KFileItem::Unknown )
+ m_fileMode = mode & S_IFMT; // extract file type
+ if ( m_permissions == KFileItem::Unknown )
+ m_permissions = mode & 07777; // extract permissions
+ }
+ }
+ }
+
+ // determine the mimetype
+ if (!m_pMimeType && !m_url.isEmpty())
+ {
+ bool accurate = false;
+ bool isLocalURL;
+ KURL url = mostLocalURL(isLocalURL);
+
+ m_pMimeType = KMimeType::findByURL( url, m_fileMode, isLocalURL,
+ // use fast mode if not mimetype on demand
+ _determineMimeTypeOnDemand, &accurate );
+ //kdDebug() << "finding mimetype for " << url.url() << " : " << m_pMimeType->name() << endl;
+ // if we didn't use fast mode, or if we got a result, then this is the mimetype
+ // otherwise, determineMimeType will be able to do better.
+ m_bMimeTypeKnown = (!_determineMimeTypeOnDemand) || accurate;
+ }
+}
+
+void KFileItem::readUDSEntry( bool _urlIsDirectory )
+{
+ // extract the mode and the filename from the TDEIO::UDS Entry
+ bool UDS_URL_seen = false;
+
+ if (&m_entry == NULL) return;
+
+ TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
+ for( ; it != m_entry.end(); ++it ) {
+ switch ((*it).m_uds) {
+
+ case TDEIO::UDS_FILE_TYPE:
+ m_fileMode = (mode_t)((*it).m_long);
+ break;
+
+ case TDEIO::UDS_ACCESS:
+ m_permissions = (mode_t)((*it).m_long);
+ break;
+
+ case TDEIO::UDS_USER:
+ m_user = ((*it).m_str);
+ break;
+
+ case TDEIO::UDS_GROUP:
+ m_group = ((*it).m_str);
+ break;
+
+ case TDEIO::UDS_NAME:
+ m_strName = (*it).m_str;
+ m_strText = TDEIO::decodeFileName( m_strName );
+ break;
+
+ case TDEIO::UDS_URL:
+ UDS_URL_seen = true;
+ m_url = KURL((*it).m_str);
+ if ( m_url.isLocalFile() )
+ m_bIsLocalURL = true;
+ break;
+
+ case TDEIO::UDS_MIME_TYPE:
+ m_pMimeType = KMimeType::mimeType((*it).m_str);
+ m_bMimeTypeKnown = true;
+ break;
+
+ case TDEIO::UDS_GUESSED_MIME_TYPE:
+ m_guessedMimeType = (*it).m_str;
+ break;
+
+ case TDEIO::UDS_LINK_DEST:
+ m_bLink = !(*it).m_str.isEmpty(); // we don't store the link dest
+ break;
+
+ case TDEIO::UDS_ICON_NAME:
+ if ( !d )
+ d = new KFileItemPrivate();
+ d->iconName = (*it).m_str;
+ break;
+
+ case TDEIO::UDS_HIDDEN:
+ if ( (*it).m_long )
+ m_hidden = Hidden;
+ else
+ m_hidden = Shown;
+ break;
+ }
+ }
+
+ // avoid creating these QStrings again and again
+ static const TQString& dot = TDEGlobal::staticQString(".");
+ if ( _urlIsDirectory && !UDS_URL_seen && !m_strName.isEmpty() && m_strName != dot )
+ m_url.addPath( m_strName );
+}
+
+void KFileItem::refresh()
+{
+ m_fileMode = KFileItem::Unknown;
+ m_permissions = KFileItem::Unknown;
+ m_pMimeType = 0L;
+ m_user = TQString::null;
+ m_group = TQString::null;
+ m_metaInfo = KFileMetaInfo();
+ m_hidden = Auto;
+
+ // Basically, we can't trust any information we got while listing.
+ // Everything could have changed...
+ // Clearing m_entry makes it possible to detect changes in the size of the file,
+ // the time information, etc.
+ m_entry = TDEIO::UDSEntry();
+ init( false );
+}
+
+void KFileItem::refreshMimeType()
+{
+ m_pMimeType = 0L;
+ init( false ); // Will determine the mimetype
+}
+
+void KFileItem::setURL( const KURL &url )
+{
+ m_url = url;
+ setName( url.fileName() );
+}
+
+void KFileItem::setName( const TQString& name )
+{
+ m_strName = name;
+ m_strText = TDEIO::decodeFileName( m_strName );
+}
+
+TQString KFileItem::linkDest() const
+{
+ if (&m_entry == NULL) return TQString::null;
+
+ // Extract it from the TDEIO::UDSEntry
+ TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
+ for( ; it != m_entry.end(); ++it )
+ if ( (*it).m_uds == TDEIO::UDS_LINK_DEST )
+ return (*it).m_str;
+ // If not in the TDEIO::UDSEntry, or if UDSEntry empty, use readlink() [if local URL]
+ if ( m_bIsLocalURL )
+ {
+ char buf[1000];
+ int n = readlink( TQFile::encodeName(m_url.path( -1 )), buf, sizeof(buf)-1 );
+ if ( n != -1 )
+ {
+ buf[ n ] = 0;
+ return TQFile::decodeName( buf );
+ }
+ }
+ return TQString::null;
+}
+
+TQString KFileItem::localPath() const
+{
+ if ( m_bIsLocalURL )
+ {
+ return m_url.path();
+ }
+ else
+ {
+ if (&m_entry == NULL) return TQString::null;
+
+ // Extract the local path from the TDEIO::UDSEntry
+ TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
+ const TDEIO::UDSEntry::ConstIterator end = m_entry.end();
+ for( ; it != end; ++it )
+ if ( (*it).m_uds == TDEIO::UDS_LOCAL_PATH )
+ return (*it).m_str;
+ }
+
+ return TQString::null;
+}
+
+TDEIO::filesize_t KFileItem::size(bool &exists) const
+{
+ exists = true;
+ if ( m_size != (TDEIO::filesize_t) -1 )
+ return m_size;
+
+ if (&m_entry == NULL) return 0L;
+
+ // Extract it from the TDEIO::UDSEntry
+ TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
+ for( ; it != m_entry.end(); ++it )
+ if ( (*it).m_uds == TDEIO::UDS_SIZE ) {
+ m_size = (*it).m_long;
+ return m_size;
+ }
+ // If not in the TDEIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL]
+ if ( m_bIsLocalURL )
+ {
+ KDE_struct_stat buf;
+ if ( KDE_stat( TQFile::encodeName(m_url.path( -1 )), &buf ) == 0 )
+ return buf.st_size;
+ }
+ exists = false;
+ return 0L;
+}
+
+bool KFileItem::hasExtendedACL() const
+{
+ if (&m_entry == NULL) return false;
+ TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
+ for( ; it != m_entry.end(); it++ )
+ if ( (*it).m_uds == TDEIO::UDS_EXTENDED_ACL ) {
+ return true;
+ }
+ return false;
+}
+
+KACL KFileItem::ACL() const
+{
+ if ( hasExtendedACL() ) {
+ if (&m_entry == NULL) return KACL( m_permissions );
+
+ // Extract it from the TDEIO::UDSEntry
+ TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
+ for( ; it != m_entry.end(); ++it )
+ if ( (*it).m_uds == TDEIO::UDS_ACL_STRING )
+ return KACL((*it).m_str);
+ }
+ // create one from the basic permissions
+ return KACL( m_permissions );
+}
+
+KACL KFileItem::defaultACL() const
+{
+ if (&m_entry == NULL) return KACL();
+
+ // Extract it from the TDEIO::UDSEntry
+ TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
+ for( ; it != m_entry.end(); ++it )
+ if ( (*it).m_uds == TDEIO::UDS_DEFAULT_ACL_STRING )
+ return KACL((*it).m_str);
+ return KACL();
+}
+
+TDEIO::filesize_t KFileItem::size() const
+{
+ bool exists;
+ return size(exists);
+}
+
+time_t KFileItem::time( unsigned int which ) const
+{
+ bool hasTime;
+ return time(which, hasTime);
+}
+time_t KFileItem::time( unsigned int which, bool &hasTime ) const
+{
+ hasTime = true;
+ unsigned int mappedWhich = 0;
+
+ switch( which ) {
+ case TDEIO::UDS_MODIFICATION_TIME:
+ mappedWhich = Modification;
+ break;
+ case TDEIO::UDS_ACCESS_TIME:
+ mappedWhich = Access;
+ break;
+ case TDEIO::UDS_CREATION_TIME:
+ mappedWhich = Creation;
+ break;
+ }
+
+ if ( m_time[mappedWhich] != (time_t) -1 )
+ return m_time[mappedWhich];
+
+ if (&m_entry == NULL) return static_cast<time_t>(0);
+
+ // Extract it from the TDEIO::UDSEntry
+ TDEIO::UDSEntry::ConstIterator it = m_entry.begin();
+ for( ; it != m_entry.end(); ++it )
+ if ( (*it).m_uds == which ) {
+ m_time[mappedWhich] = static_cast<time_t>((*it).m_long);
+ return m_time[mappedWhich];
+ }
+
+ // If not in the TDEIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL]
+ if ( m_bIsLocalURL )
+ {
+ KDE_struct_stat buf;
+ if ( KDE_stat( TQFile::encodeName(m_url.path(-1)), &buf ) == 0 )
+ {
+ if(which == TDEIO::UDS_CREATION_TIME) {
+ // We can't determine creation time for local files
+ hasTime = false;
+ m_time[mappedWhich] = static_cast<time_t>(0);
+ return m_time[mappedWhich];
+ }
+ m_time[mappedWhich] = (which == TDEIO::UDS_MODIFICATION_TIME) ?
+ buf.st_mtime :
+ /* which == TDEIO::UDS_ACCESS_TIME)*/
+ buf.st_atime;
+ return m_time[mappedWhich];
+ }
+ }
+ hasTime = false;
+ return static_cast<time_t>(0);
+}
+
+
+TQString KFileItem::user() const
+{
+ if ( m_user.isEmpty() && m_bIsLocalURL )
+ {
+ KDE_struct_stat buff;
+ if ( KDE_lstat( TQFile::encodeName(m_url.path( -1 )), &buff ) == 0) // get uid/gid of the link, if it's a link
+ {
+ struct passwd *user = getpwuid( buff.st_uid );
+ if ( user != 0L )
+ m_user = TQString::fromLocal8Bit(user->pw_name);
+ }
+ }
+ return m_user;
+}
+
+TQString KFileItem::group() const
+{
+#ifdef Q_OS_UNIX
+ if (m_group.isEmpty() && m_bIsLocalURL )
+ {
+ KDE_struct_stat buff;
+ if ( KDE_lstat( TQFile::encodeName(m_url.path( -1 )), &buff ) == 0) // get uid/gid of the link, if it's a link
+ {
+ struct group *ge = getgrgid( buff.st_gid );
+ if ( ge != 0L ) {
+ m_group = TQString::fromLocal8Bit(ge->gr_name);
+ if (m_group.isEmpty())
+ m_group.sprintf("%d",ge->gr_gid);
+ } else
+ m_group.sprintf("%d",buff.st_gid);
+ }
+ }
+#endif
+ return m_group;
+}
+
+TQString KFileItem::mimetype() const
+{
+ KFileItem * that = const_cast<KFileItem *>(this);
+ return that->determineMimeType()->name();
+}
+
+KMimeType::Ptr KFileItem::determineMimeType()
+{
+ if ( !m_pMimeType || !m_bMimeTypeKnown )
+ {
+ bool isLocalURL;
+ KURL url = mostLocalURL(isLocalURL);
+
+ m_pMimeType = KMimeType::findByURL( url, m_fileMode, isLocalURL );
+ //kdDebug() << "finding mimetype for " << url.url() << " : " << m_pMimeType->name() << endl;
+ m_bMimeTypeKnown = true;
+ }
+
+ return m_pMimeType;
+}
+
+bool KFileItem::isMimeTypeKnown() const
+{
+ // The mimetype isn't known if determineMimeType was never called (on-demand determination)
+ // or if this fileitem has a guessed mimetype (e.g. ftp symlink) - in which case
+ // it always remains "not fully determined"
+ return m_bMimeTypeKnown && m_guessedMimeType.isEmpty();
+}
+
+TQString KFileItem::mimeComment()
+{
+ KMimeType::Ptr mType = determineMimeType();
+
+ bool isLocalURL;
+ KURL url = mostLocalURL(isLocalURL);
+
+ TQString comment = mType->comment( url, isLocalURL );
+ //kdDebug() << "finding comment for " << url.url() << " : " << m_pMimeType->name() << endl;
+ if (!comment.isEmpty())
+ return comment;
+ else
+ return mType->name();
+}
+
+TQString KFileItem::iconName()
+{
+ if (d && (!d->iconName.isEmpty())) return d->iconName;
+
+ bool isLocalURL;
+ KURL url = mostLocalURL(isLocalURL);
+
+ //kdDebug() << "finding icon for " << url.url() << " : " << m_pMimeType->name() << endl;
+ return determineMimeType()->icon(url, isLocalURL);
+}
+
+int KFileItem::overlays() const
+{
+ int _state = 0;
+ if ( m_bLink )
+ _state |= TDEIcon::LinkOverlay;
+
+ if ( !S_ISDIR( m_fileMode ) // Locked dirs have a special icon, use the overlay for files only
+ && !isReadable())
+ _state |= TDEIcon::LockOverlay;
+
+ if ( isHidden() )
+ _state |= TDEIcon::HiddenOverlay;
+
+ if( S_ISDIR( m_fileMode ) && m_bIsLocalURL)
+ {
+ if (KSambaShare::instance()->isDirectoryShared( m_url.path() ) ||
+ KNFSShare::instance()->isDirectoryShared( m_url.path() ))
+ {
+ //kdDebug()<<"KFileShare::isDirectoryShared : "<<m_url.path()<<endl;
+ _state |= TDEIcon::ShareOverlay;
+ }
+ }
+
+ if ( m_pMimeType->name() == "application/x-gzip" && m_url.fileName().right(3) == ".gz" )
+ _state |= TDEIcon::ZipOverlay;
+ return _state;
+}
+
+TQPixmap KFileItem::pixmap( int _size, int _state ) const
+{
+ if (d && (!d->iconName.isEmpty()))
+ return DesktopIcon(d->iconName,_size,_state);
+
+ if ( !m_pMimeType )
+ {
+ static const TQString & defaultFolderIcon =
+ TDEGlobal::staticQString(KMimeType::mimeType( "inode/directory" )->KServiceType::icon());
+
+ if ( S_ISDIR( m_fileMode ) )
+ return DesktopIcon( defaultFolderIcon, _size, _state );
+
+ return DesktopIcon( "unknown", _size, _state );
+ }
+
+ _state |= overlays();
+
+ KMimeType::Ptr mime;
+ // Use guessed mimetype if the main one hasn't been determined for sure
+ if ( !m_bMimeTypeKnown && !m_guessedMimeType.isEmpty() )
+ mime = KMimeType::mimeType( m_guessedMimeType );
+ else
+ mime = m_pMimeType;
+
+ // Support for gzipped files: extract mimetype of contained file
+ // See also the relevant code in overlays, which adds the zip overlay.
+ if ( mime->name() == "application/x-gzip" && m_url.fileName().right(3) == ".gz" )
+ {
+ KURL sf;
+ sf.setPath( m_url.path().left( m_url.path().length() - 3 ) );
+ //kdDebug() << "KFileItem::pixmap subFileName=" << subFileName << endl;
+ mime = KMimeType::findByURL( sf, 0, m_bIsLocalURL );
+ }
+
+ bool isLocalURL;
+ KURL url = mostLocalURL(isLocalURL);
+
+ TQPixmap p = mime->pixmap( url, TDEIcon::Desktop, _size, _state );
+ //kdDebug() << "finding pixmap for " << url.url() << " : " << mime->name() << endl;
+ if (p.isNull())
+ kdWarning() << "Pixmap not found for mimetype " << m_pMimeType->name() << endl;
+
+ if ( mime->name() == "application/x-executable" ) {
+ // At first glance it might seem to be a good idea to
+ // look for .desktop files for this executable before resorting to the embedded icon
+ // in the same fashion as the minicli, but on close examination this is NOT A GOOD IDEA.
+ // Specifically it allows one executable to mimic another purely based on filename,
+ // which could at certain times fool any user regardless of experience level.
+#ifdef HAVE_ELFICON
+ // Check for an embedded icon
+ unsigned int icon_size;
+ libr_icon *icon = NULL;
+ libr_file *handle = NULL;
+ libr_access_t access = LIBR_READ;
+
+ if((handle = libr_open(const_cast<char*>(url.path().ascii()), access)) == NULL)
+ {
+ kdWarning() << "failed to open file" << url.path() << endl;
+ return p;
+ }
+
+ icon_size = _size;
+ icon = libr_icon_geticon_bysize(handle, icon_size);
+
+ // See if the embedded icon name matches any icon file names already on the system
+ // If it does, use the system icon instead of the embedded one
+ int iconresnamefound = 0;
+ iconentry *entry = NULL;
+ iconlist icons;
+ if(!get_iconlist(handle, &icons))
+ {
+ // Failed to obtain a list of ELF icons
+ kdWarning() << "failed to obtain ELF icon: " << libr_errmsg() << endl;
+
+ // See if there is a system icon we can use
+ TQString sysIconName = elf_get_resource(handle, ".metadata_sysicon");
+ if (!sysIconName.isEmpty()) {
+ if (TDEGlobal::iconLoader()->iconPath(sysIconName.ascii(), 0, true) != "") {
+ p = DesktopIcon( sysIconName.ascii(), _size, _state );
+ }
+ }
+
+ libr_close(handle);
+ return p;
+ }
+ else {
+ while((entry = get_nexticon(&icons, entry)) != NULL)
+ {
+ if(icon == NULL)
+ {
+ // Try loading this icon as fallback
+ icon = libr_icon_geticon_byname(handle, entry->name);
+ }
+ if (TDEGlobal::iconLoader()->iconPath(entry->name, 0, true) != "") {
+ iconresnamefound = 1;
+ p = DesktopIcon( entry->name, _size, _state );
+ break;
+ }
+ }
+ }
+
+ if ((iconresnamefound == 0) && (icon)) {
+ // Extract the embedded icon
+ size_t icon_data_length;
+ char* icondata = libr_icon_malloc(icon, &icon_data_length);
+ p.loadFromData(static_cast<uchar*>(static_cast<void*>(icondata)), icon_data_length); // EVIL CAST
+ if (icon_size != 0) {
+ TQImage ip = p.convertToImage();
+ ip = ip.smoothScale(icon_size, icon_size);
+ p.convertFromImage(ip);
+ }
+ free(icondata);
+ libr_icon_close(icon);
+ }
+
+ libr_close(handle);
+#endif // HAVE_ELFICON
+ }
+
+ return p;
+}
+
+bool KFileItem::isReadable() const
+{
+ /*
+ struct passwd * user = getpwuid( geteuid() );
+ bool isMyFile = (TQString::fromLocal8Bit(user->pw_name) == m_user);
+ // This gets ugly for the group....
+ // Maybe we want a static TQString for the user and a static QStringList
+ // for the groups... then we need to handle the deletion properly...
+ */
+
+ if ( m_permissions != KFileItem::Unknown ) {
+ // No read permission at all
+ if ( !(S_IRUSR & m_permissions) && !(S_IRGRP & m_permissions) && !(S_IROTH & m_permissions) )
+ return false;
+
+ // Read permissions for all: save a stat call
+ if ( (S_IRUSR|S_IRGRP|S_IROTH) & m_permissions )
+ return true;
+ }
+
+ // Or if we can't read it [using ::access()] - not network transparent
+ if ( m_bIsLocalURL && ::access( TQFile::encodeName(m_url.path()), R_OK ) == -1 )
+ return false;
+
+ return true;
+}
+
+bool KFileItem::isWritable() const
+{
+ /*
+ struct passwd * user = getpwuid( geteuid() );
+ bool isMyFile = (TQString::fromLocal8Bit(user->pw_name) == m_user);
+ // This gets ugly for the group....
+ // Maybe we want a static TQString for the user and a static QStringList
+ // for the groups... then we need to handle the deletion properly...
+ */
+
+ if ( m_permissions != KFileItem::Unknown ) {
+ // No write permission at all
+ if ( !(S_IWUSR & m_permissions) && !(S_IWGRP & m_permissions) && !(S_IWOTH & m_permissions) )
+ return false;
+ }
+
+ // Or if we can't read it [using ::access()] - not network transparent
+ if ( m_bIsLocalURL && ::access( TQFile::encodeName(m_url.path()), W_OK ) == -1 )
+ return false;
+
+ return true;
+}
+
+bool KFileItem::isHidden() const
+{
+ if ( m_hidden != Auto )
+ return m_hidden == Hidden;
+
+ if ( !m_url.isEmpty() )
+ return m_url.fileName()[0] == '.';
+ else // should never happen
+ return m_strName[0] == '.';
+}
+
+bool KFileItem::isDir() const
+{
+ if ( m_fileMode == KFileItem::Unknown )
+ {
+ kdDebug() << " KFileItem::isDir can't say -> false " << endl;
+ return false; // can't say for sure, so no
+ }
+ return (S_ISDIR(m_fileMode));
+/*
+ if (!S_ISDIR(m_fileMode)) {
+ if (m_url.isLocalFile()) {
+ KMimeType::Ptr ptr=KMimeType::findByURL(m_url,0,true,true);
+ if ((ptr!=0) && (ptr->is("directory/inode"))) return true;
+ }
+ return false
+ } else return true;*/
+}
+
+bool KFileItem::acceptsDrops()
+{
+ // A directory ?
+ if ( S_ISDIR( mode() ) ) {
+ return isWritable();
+ }
+
+ // But only local .desktop files and executables
+ if ( !m_bIsLocalURL )
+ return false;
+
+ if (( mimetype() == "application/x-desktop") ||
+ ( mimetype() == "media/builtin-mydocuments") ||
+ ( mimetype() == "media/builtin-mycomputer") ||
+ ( mimetype() == "media/builtin-mynetworkplaces") ||
+ ( mimetype() == "media/builtin-printers") ||
+ ( mimetype() == "media/builtin-trash") ||
+ ( mimetype() == "media/builtin-webbrowser"))
+ return true;
+
+ // Executable, shell script ... ?
+ if ( ::access( TQFile::encodeName(m_url.path()), X_OK ) == 0 )
+ return true;
+
+ return false;
+}
+
+TQString KFileItem::getStatusBarInfo()
+{
+ TQString text = m_strText;
+
+ if ( m_bLink )
+ {
+ TQString comment = determineMimeType()->comment( m_url, m_bIsLocalURL );
+ TQString tmp;
+ if ( comment.isEmpty() )
+ tmp = i18n ( "Symbolic Link" );
+ else
+ tmp = i18n("%1 (Link)").arg(comment);
+ text += "->";
+ text += linkDest();
+ text += " ";
+ text += tmp;
+ }
+ else if ( S_ISREG( m_fileMode ) )
+ {
+ bool hasSize;
+ TDEIO::filesize_t sizeValue = size(hasSize);
+ if(hasSize)
+ text += TQString(" (%1) ").arg( TDEIO::convertSize( sizeValue ) );
+ text += mimeComment();
+ }
+ else if ( S_ISDIR ( m_fileMode ) )
+ {
+ text += "/ ";
+ text += mimeComment();
+ }
+ else
+ {
+ text += " ";
+ text += mimeComment();
+ }
+ text.replace('\n', " "); // replace any newlines with a space, so the statusbar doesn't get a two-line string which messes the display up, Alex
+ return text;
+}
+
+TQString KFileItem::getToolTipText(int maxcount)
+{
+ // we can return TQString::null if no tool tip should be shown
+ TQString tip;
+ KFileMetaInfo info = metaInfo();
+
+ // the font tags are a workaround for the fact that the tool tip gets
+ // screwed if the color scheme uses white as default text color
+ const char* start = "<tr><td><nobr><font color=\"black\">";
+ const char* mid = "</font></nobr></td><td><nobr><font color=\"black\">";
+ const char* end = "</font></nobr></td></tr>";
+
+ tip = "<table cellspacing=0 cellpadding=0>";
+
+ tip += start + i18n("Name:") + mid + text() + end;
+ tip += start + i18n("Type:") + mid;
+
+ TQString type = TQStyleSheet::escape(mimeComment());
+ if ( m_bLink ) {
+ tip += i18n("Link to %1 (%2)").arg(linkDest(), type) + end;
+ } else
+ tip += type + end;
+
+ if ( !S_ISDIR ( m_fileMode ) ) {
+ bool hasSize;
+ TDEIO::filesize_t sizeValue = size(hasSize);
+ if(hasSize)
+ tip += start + i18n("Size:") + mid +
+ TDEIO::convertSizeWithBytes(sizeValue) + end;
+ }
+ TQString timeStr = timeString( TDEIO::UDS_MODIFICATION_TIME);
+ if(!timeStr.isEmpty())
+ tip += start + i18n("Modified:") + mid +
+ timeStr + end;
+#ifndef Q_WS_WIN //TODO: show win32-specific permissions
+ TQString userStr = user();
+ TQString groupStr = group();
+ if(!userStr.isEmpty() || !groupStr.isEmpty())
+ tip += start + i18n("Owner:") + mid + userStr + " - " + groupStr + end +
+ start + i18n("Permissions:") + mid +
+ parsePermissions(m_permissions) + end;
+#endif
+
+ if (info.isValid() && !info.isEmpty() )
+ {
+ 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>";
+ TQStringList keys = info.preferredKeys();
+
+ // now the rest
+ TQStringList::Iterator it = keys.begin();
+ for (int count = 0; count<maxcount && it!=keys.end() ; ++it)
+ {
+ KFileMetaInfoItem item = info.item( *it );
+ if ( item.isValid() )
+ {
+ TQString s = item.string();
+ if ( ( item.attributes() & KFileMimeTypeInfo::SqueezeText )
+ && s.length() > 50) {
+ s.truncate(47);
+ s.append("...");
+ }
+ if ( !s.isEmpty() )
+ {
+ count++;
+ tip += start +
+ TQStyleSheet::escape( item.translatedKey() ) + ":" +
+ mid +
+ TQStyleSheet::escape( s ) +
+ end;
+ }
+
+ }
+ }
+ }
+ tip += "</table>";
+
+ //kdDebug() << "making this the tool tip rich text:\n";
+ //kdDebug() << tip << endl;
+
+ return tip;
+}
+
+void KFileItem::run()
+{
+ // It might be faster to pass skip that when we know the mimetype,
+ // and just call KRun::runURL. But then we need to use mostLocalURL()
+ // for application/x-desktop files, to be able to execute them.
+ (void) new KRun( m_url, m_fileMode, m_bIsLocalURL );
+}
+
+bool KFileItem::cmp( const KFileItem & item )
+{
+ bool hasSize1,hasSize2,hasTime1,hasTime2;
+ hasSize1 = hasSize2 = hasTime1 = hasTime2 = false;
+ return ( m_strName == item.m_strName
+ && m_bIsLocalURL == item.m_bIsLocalURL
+ && m_fileMode == item.m_fileMode
+ && m_permissions == item.m_permissions
+ && m_user == item.m_user
+ && m_group == item.m_group
+ && m_bLink == item.m_bLink
+ && m_hidden == item.m_hidden
+ && size(hasSize1) == item.size(hasSize2)
+ && hasSize1 == hasSize2
+ && time(TDEIO::UDS_MODIFICATION_TIME, hasTime1) == item.time(TDEIO::UDS_MODIFICATION_TIME, hasTime2)
+ && hasTime1 == hasTime2
+ && (!d || !item.d || d->iconName == item.d->iconName) );
+
+ // Don't compare the mimetypes here. They might not be known, and we don't want to
+ // do the slow operation of determining them here.
+}
+
+void KFileItem::assign( const KFileItem & item )
+{
+ if ( this == &item )
+ return;
+ m_entry = item.m_entry;
+ m_url = item.m_url;
+ m_bIsLocalURL = item.m_bIsLocalURL;
+ m_strName = item.m_strName;
+ m_strText = item.m_strText;
+ m_fileMode = item.m_fileMode;
+ m_permissions = item.m_permissions;
+ m_user = item.m_user;
+ m_group = item.m_group;
+ m_bLink = item.m_bLink;
+ m_pMimeType = item.m_pMimeType;
+ m_strLowerCaseName = item.m_strLowerCaseName;
+ m_bMimeTypeKnown = item.m_bMimeTypeKnown;
+ m_hidden = item.m_hidden;
+ m_guessedMimeType = item.m_guessedMimeType;
+ m_access = item.m_access;
+ m_metaInfo = item.m_metaInfo;
+ for ( int i = 0; i < NumFlags; i++ )
+ m_time[i] = item.m_time[i];
+ m_size = item.m_size;
+ // note: m_extra is NOT copied, as we'd have no control over who is
+ // deleting the data or not.
+
+ // We had a mimetype previously (probably), so we need to re-determine it
+ determineMimeType();
+
+ if ( item.d ) {
+ if ( !d )
+ d = new KFileItemPrivate;
+ d->iconName = item.d->iconName;
+ } else {
+ delete d;
+ d = 0;
+ }
+}
+
+void KFileItem::setUDSEntry( const TDEIO::UDSEntry& _entry, const KURL& _url,
+ bool _determineMimeTypeOnDemand, bool _urlIsDirectory )
+{
+ m_entry = _entry;
+ m_url = _url;
+ m_strName = TQString::null;
+ m_strText = TQString::null;
+ m_user = TQString::null;
+ m_group = TQString::null;
+ m_strLowerCaseName = TQString::null;
+ m_pMimeType = 0;
+ m_fileMode = KFileItem::Unknown;
+ m_permissions = KFileItem::Unknown;
+ m_bMarked = false;
+ m_bLink = false;
+ m_bIsLocalURL = _url.isLocalFile();
+ m_bMimeTypeKnown = false;
+ m_hidden = Auto;
+ m_guessedMimeType = TQString::null;
+ m_metaInfo = KFileMetaInfo();
+
+ if ( d )
+ d->iconName = TQString::null;
+
+ readUDSEntry( _urlIsDirectory );
+ init( _determineMimeTypeOnDemand );
+}
+
+void KFileItem::setFileMode( mode_t m )
+{
+ m_fileMode = m;
+}
+
+void KFileItem::setMimeType( const TQString& mimetype )
+{
+ m_pMimeType = KMimeType::mimeType( mimetype );
+}
+
+void KFileItem::setExtraData( const void *key, void *value )
+{
+ if ( !key )
+ return;
+
+ m_extra.replace( key, value );
+}
+
+const void * KFileItem::extraData( const void *key ) const
+{
+ TQMapConstIterator<const void*,void*> it = m_extra.find( key );
+ if ( it != m_extra.end() )
+ return it.data();
+ return 0L;
+}
+
+void * KFileItem::extraData( const void *key )
+{
+ TQMapIterator<const void*,void*> it = m_extra.find( key );
+ if ( it != m_extra.end() )
+ return it.data();
+ return 0L;
+}
+
+void KFileItem::removeExtraData( const void *key )
+{
+ m_extra.remove( key );
+}
+
+TQString KFileItem::permissionsString() const
+{
+ if (m_access.isNull())
+ m_access = parsePermissions( m_permissions );
+
+ return m_access;
+}
+
+TQString KFileItem::parsePermissions(mode_t perm) const
+{
+ char p[] = "---------- ";
+
+ if (isDir())
+ p[0]='d';
+ else if (isLink())
+ p[0]='l';
+
+ if (perm & TQFileInfo::ReadUser)
+ p[1]='r';
+ if (perm & TQFileInfo::WriteUser)
+ p[2]='w';
+ if ((perm & TQFileInfo::ExeUser) && !(perm & S_ISUID)) p[3]='x';
+ else if ((perm & TQFileInfo::ExeUser) && (perm & S_ISUID)) p[3]='s';
+ else if (!(perm & TQFileInfo::ExeUser) && (perm & S_ISUID)) p[3]='S';
+
+ if (perm & TQFileInfo::ReadGroup)
+ p[4]='r';
+ if (perm & TQFileInfo::WriteGroup)
+ p[5]='w';
+ if ((perm & TQFileInfo::ExeGroup) && !(perm & S_ISGID)) p[6]='x';
+ else if ((perm & TQFileInfo::ExeGroup) && (perm & S_ISGID)) p[6]='s';
+ else if (!(perm & TQFileInfo::ExeGroup) && (perm & S_ISGID)) p[6]='S';
+
+ if (perm & TQFileInfo::ReadOther)
+ p[7]='r';
+ if (perm & TQFileInfo::WriteOther)
+ p[8]='w';
+ if ((perm & TQFileInfo::ExeOther) && !(perm & S_ISVTX)) p[9]='x';
+ else if ((perm & TQFileInfo::ExeOther) && (perm & S_ISVTX)) p[9]='t';
+ else if (!(perm & TQFileInfo::ExeOther) && (perm & S_ISVTX)) p[9]='T';
+
+ if (hasExtendedACL())
+ p[10]='+';
+
+ return TQString::fromLatin1(p);
+}
+
+// check if we need to cache this
+TQString KFileItem::timeString( unsigned int which ) const
+{
+ bool hasTime;
+ time_t time_ = time(which, hasTime);
+ if(!hasTime) return TQString::null;
+
+ TQDateTime t;
+ t.setTime_t( time_);
+ return TDEGlobal::locale()->formatDateTime( t );
+}
+
+void KFileItem::setMetaInfo( const KFileMetaInfo & info )
+{
+ m_metaInfo = info;
+}
+
+const KFileMetaInfo & KFileItem::metaInfo(bool autoget, int) const
+{
+ bool isLocalURL;
+ KURL url = mostLocalURL(isLocalURL);
+
+ if ( autoget && !m_metaInfo.isValid() &&
+ TDEGlobalSettings::showFilePreview(url) )
+ {
+ m_metaInfo = KFileMetaInfo( url, mimetype() );
+ }
+
+ return m_metaInfo;
+}
+
+KURL KFileItem::mostLocalURL(bool &local) const
+{
+ TQString local_path = localPath();
+
+ if ( !local_path.isEmpty() )
+ {
+ local = true;
+ KURL url;
+ url.setPath(local_path);
+ return url;
+ }
+ else
+ {
+ local = m_bIsLocalURL;
+ return m_url;
+ }
+}
+
+void KFileItem::virtual_hook( int, void* )
+{ /*BASE::virtual_hook( id, data );*/ }
+
+TQDataStream & operator<< ( TQDataStream & s, const KFileItem & a )
+{
+ // We don't need to save/restore anything that refresh() invalidates,
+ // since that means we can re-determine those by ourselves.
+ s << a.m_url;
+ s << a.m_strName;
+ s << a.m_strText;
+ return s;
+}
+
+TQDataStream & operator>> ( TQDataStream & s, KFileItem & a )
+{
+ s >> a.m_url;
+ s >> a.m_strName;
+ s >> a.m_strText;
+ a.m_bIsLocalURL = a.m_url.isLocalFile();
+ a.m_bMimeTypeKnown = false;
+ a.refresh();
+ return s;
+}