|
|
|
/* 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>
|
|
|
|
|
|
|
|
#include "netaccess.h"
|
|
|
|
|
|
|
|
#ifdef HAVE_ELFICON
|
|
|
|
#include "tdelficon.h"
|
|
|
|
#endif // HAVE_ELFICON
|
|
|
|
|
|
|
|
class KFileItem::KFileItemPrivate {
|
|
|
|
public:
|
|
|
|
KFileItemPrivate() : commentCached(false) {}
|
|
|
|
|
|
|
|
public:
|
|
|
|
TQString iconName;
|
|
|
|
TQString comment;
|
|
|
|
bool commentCached;
|
|
|
|
};
|
|
|
|
|
|
|
|
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.cpp)
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
if ( d ) {
|
|
|
|
d->iconName = TQString::null;
|
|
|
|
d->comment = TQString::null;
|
|
|
|
d->commentCached = false;
|
|
|
|
}
|
|
|
|
m_pMimeType = 0L;
|
|
|
|
init( false ); // Will determine the mimetype
|
|
|
|
}
|
|
|
|
|
|
|
|
void KFileItem::setURL( const KURL &url )
|
|
|
|
{
|
|
|
|
m_url = url;
|
|
|
|
setName( url.fileName() );
|
|
|
|
m_bIsLocalURL = m_url.isLocalFile();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KFileItem::setListerURL( const KURL &url )
|
|
|
|
{
|
|
|
|
m_listerURL = url;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we still do not have a local URL, use the lister URL
|
|
|
|
// Without this, Trash functionality will not work with the media:/ tdeioslave!
|
|
|
|
if ((!m_url.isLocalFile())/* && (m_url.protocol() == "media")*/) {
|
|
|
|
if (m_listerURL.isLocalFile()) {
|
|
|
|
return m_listerURL.path();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KFileItem::mimetypeFast() const
|
|
|
|
{
|
|
|
|
if (isMimeTypeKnown()) {
|
|
|
|
return mimetype();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return m_pMimeType->name();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KMimeType::Ptr KFileItem::mimeTypePtrFast()
|
|
|
|
{
|
|
|
|
return m_pMimeType;
|
|
|
|
}
|
|
|
|
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
if (d && (d->commentCached)) return d->comment;
|
|
|
|
|
|
|
|
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 ( !d ) {
|
|
|
|
d = new KFileItemPrivate();
|
|
|
|
}
|
|
|
|
if (!comment.isEmpty()) {
|
|
|
|
d->comment = comment;
|
|
|
|
d->commentCached = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
d->comment = mType->name();
|
|
|
|
d->commentCached = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return d->comment;
|
|
|
|
}
|
|
|
|
|
|
|
|
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" || mime->name() == "application/x-pie-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
|
|
|
|
kdDebug() << "failed to obtain ELF icon from " << url.path() << ": " << 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 )
|
|
|
|
{
|
|
|
|
if ( !d ) {
|
|
|
|
d = new KFileItemPrivate();
|
|
|
|
}
|
|
|
|
if (!d->commentCached) {
|
|
|
|
d->comment = determineMimeType()->comment( m_url, m_bIsLocalURL );
|
|
|
|
d->commentCached = true;
|
|
|
|
}
|
|
|
|
TQString tmp;
|
|
|
|
if ( d->comment.isEmpty() )
|
|
|
|
tmp = i18n ( "Symbolic Link" );
|
|
|
|
else
|
|
|
|
tmp = i18n("%1 (Link)").arg(d->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> </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)
|
|
|
|
&& (!isMimeTypeKnown() || !item.isMimeTypeKnown() || mimetype() == item.mimetype()) );
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
d->comment = item.d->comment;
|
|
|
|
d->commentCached = item.d->commentCached;
|
|
|
|
} 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;
|
|
|
|
d->comment = TQString::null;
|
|
|
|
d->commentCached = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|