diff options
Diffstat (limited to 'src/app/VFS/virt_vfs.cpp')
-rw-r--r-- | src/app/VFS/virt_vfs.cpp | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/src/app/VFS/virt_vfs.cpp b/src/app/VFS/virt_vfs.cpp new file mode 100644 index 0000000..3c70231 --- /dev/null +++ b/src/app/VFS/virt_vfs.cpp @@ -0,0 +1,341 @@ +/*************************************************************************** + virt_vfs.cpp - description + ------------------- + begin : Fri Dec 5 2003 + copyright : (C) 2003 by Shie Erlich & Rafi Yanai + email : +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <unistd.h> +#include <time.h> + +#include <tdefileitem.h> +#include <tdeglobalsettings.h> +#include <kurl.h> +#include <tdemessagebox.h> +#include <tdelocale.h> +#include <kdirsize.h> +#include <kstandarddirs.h> + +#include "krpermhandler.h" +#include "../krusader.h" +#include "../defaults.h" +#include "virt_vfs.h" + +#define VIRT_VFS_DB "virt_vfs.db" + +TQDict<KURL::List> virt_vfs::virtVfsDict; +TDEConfig* virt_vfs::virt_vfs_db=0; + +virt_vfs::virt_vfs( TQObject* panel, bool quiet ) : vfs( panel, quiet ) { + // set the writable attribute + isWritable = true; + + virtVfsDict.setAutoDelete( true ); + if ( virtVfsDict.isEmpty() ) { + restore(); + } + + vfs_type = VIRT; +} + +virt_vfs::~virt_vfs() {} + +bool virt_vfs::populateVfsList( const KURL& origin, bool /*showHidden*/ ) { + vfs_origin = origin; + vfs_origin.adjustPath(-1); + path = origin.path( -1 ).mid( 1 ); + if ( path.isEmpty() ) path = "/"; + + KURL::List* urlList = virtVfsDict[ path ]; + if ( !urlList ) { + urlList = new KURL::List(); + virtVfsDict.insert( path, urlList ); + virtVfsDict[ "/" ] ->append( KURL::fromPathOrURL( "virt:/" + path ) ); + } + + if ( urlList->isEmpty() ) return true; + KURL::List::iterator it; + for ( it = urlList->begin() ; it != urlList->end() ; /*++it*/ ) { + KURL url = *it; + // translate url->vfile and remove urls that no longer exist from the list + vfile* vf = stat(url); + if ( !vf ) { + it = urlList->remove( it ); + // the iterator is advanced automaticly + continue; + } + foundVfile( vf ); + ++it; + } + save(); + return true; +} + +void virt_vfs::vfs_addFiles( KURL::List *fileUrls, TDEIO::CopyJob::CopyMode /*mode*/, TQObject* /*toNotify*/, TQString /*dir*/, PreserveMode /*pmode*/ ) { + if ( path == "/" ) { + if ( !quietMode ) + KMessageBox::error( krApp, i18n( "You can't copy files directly to the 'virt:/' directory.\nYou can create a sub directory and copy your files into it." ), i18n( "Error" ) ); + return ; + } + + KURL::List* urlList = virtVfsDict[ path ]; + for( unsigned i=0; i != fileUrls->count(); i++ ) { + if( !urlList->contains( (*fileUrls)[ i ] ) ) + urlList->push_back( (*fileUrls)[ i ] ); + } + + vfs_refresh(); +} + +void virt_vfs::vfs_delFiles( TQStringList *fileNames ) { + if ( path == "/" ) { + for ( uint i = 0 ; i < fileNames->count(); ++i ) { + TQString filename = ( *fileNames ) [ i ]; + virtVfsDict[ "/" ] ->remove( TQString("virt:/")+filename ); + virtVfsDict.remove( filename ); + } + vfs_refresh(); + return ; + } + + KURL::List filesUrls; + KURL url; + + // names -> urls + for ( uint i = 0 ; i < fileNames->count(); ++i ) { + TQString filename = ( *fileNames ) [ i ]; + filesUrls.append( vfs_getFile( filename ) ); + } + TDEIO::Job *job; + + // delete of move to trash ? + krConfig->setGroup( "General" ); + if ( krConfig->readBoolEntry( "Move To Trash", _MoveToTrash ) ) { +#if KDE_IS_VERSION(3,4,0) + job = TDEIO::trash( filesUrls, true ); +#else + job = new TDEIO::CopyJob( filesUrls, TDEGlobalSettings::trashPath(), TDEIO::CopyJob::Move, false, true ); +#endif + connect( job, TQ_SIGNAL( result( TDEIO::Job* ) ), krApp, TQ_SLOT( changeTrashIcon() ) ); + } else + job = new TDEIO::DeleteJob( filesUrls, false, true ); + + // refresh will remove the deleted files... + connect( job, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( vfs_refresh( TDEIO::Job* ) ) ); +} + +void virt_vfs::vfs_removeFiles( TQStringList *fileNames ) { + if ( path == "/" ) + return; + + // removing the URLs from the collection + for ( uint i = 0 ; i < fileNames->count(); ++i ) { + KURL::List* urlList = virtVfsDict[ path ]; + if( urlList ) + urlList->remove( vfs_getFile( ( *fileNames ) [ i ] ) ); + } + + vfs_refresh(); +} + +KURL::List* virt_vfs::vfs_getFiles( TQStringList* names ) { + KURL url; + KURL::List* urls = new KURL::List(); + for ( TQStringList::Iterator name = names->begin(); name != names->end(); ++name ) { + url = vfs_getFile( *name ); + urls->append( url ); + } + return urls; +} + +KURL virt_vfs::vfs_getFile( const TQString& name ) { + vfile * vf = vfs_search( name ); + if ( !vf ) return KURL(); // empty + + KURL url = vf->vfile_getUrl(); + if ( vf->vfile_isDir() ) url.adjustPath( + 1 ); + return url; +} + +void virt_vfs::vfs_mkdir( const TQString& name ) { + if ( path != "/" ) { + if ( !quietMode ) + KMessageBox::error( krApp, i18n( "Creating new directories is allowed only in the 'virt:/' directory." ), i18n( "Error" ) ); + return ; + } + KURL::List* temp = new KURL::List(); + virtVfsDict.insert( name, temp ); + virtVfsDict[ "/" ] ->append( TQString( "virt:/" )+name ); + + vfs_refresh(); +} + +void virt_vfs::vfs_rename( const TQString& fileName, const TQString& newName ) { + KURL::List fileUrls; + KURL url , dest; + + vfile* vf = vfs_search( fileName ); + if ( !vf ) return ; // not found + + if ( path == "/" ) { + virtVfsDict[ "/" ] ->append( TQString( "virt:/" ) + newName ); + virtVfsDict[ "/" ] ->remove( TQString( "virt:/" ) + fileName ); + virtVfsDict.insert( newName, virtVfsDict.take( fileName ) ); + vfs_refresh(); + return ; + } + + url = vf->vfile_getUrl(); + fileUrls.append( url ); + + dest = fromPathOrURL( newName ); + // add the new url to the list + // the the list is refreshed only existing files remain - + // so we don't have to worry if the job was successful + virtVfsDict[ path ] ->append( dest ); + + TDEIO::Job *job = new TDEIO::CopyJob( fileUrls, dest, TDEIO::CopyJob::Move, true, false ); + connect( job, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( vfs_refresh( TDEIO::Job* ) ) ); +} + +void virt_vfs::slotStatResult( TDEIO::Job* job ) { + if( !job || job->error() ) entry = TDEIO::UDSEntry(); + else entry = static_cast<TDEIO::StatJob*>(job)->statResult(); + busy = false; +} + +vfile* virt_vfs::stat( const KURL& url ) { + if( url.protocol() == "virt" ){ + TQString path = url.path().mid(1); + if( path.isEmpty() ) path = "/"; + vfile * temp = new vfile( path, 0, "drwxr-xr-x", time( 0 ), false, getuid(), getgid(), "inode/directory", "", 0 ); + temp->vfile_setUrl( url ); + return temp; + } + KFileItem* kfi; + if ( url.isLocalFile() ) { + kfi = new KFileItem( KFileItem::Unknown, KFileItem::Unknown, url, true ); + } + else { + busy = true; + TDEIO::StatJob* statJob = TDEIO::stat( url, false ); + connect( statJob, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( slotStatResult( TDEIO::Job* ) ) ); + while ( busy && vfs_processEvents() ); + if( entry.isEmpty() ) return 0; // statJob failed + + kfi = new KFileItem(entry, url, true ); + } + + if ( !kfi->time( TDEIO::UDS_MODIFICATION_TIME ) ){ + delete kfi; + return 0; // file not found + } + + vfile *temp; + + // get file statistics + TQString name; + if( url.isLocalFile() ) + name = url.path(); + else + name = url.prettyURL(); + + TDEIO::filesize_t size = kfi->size(); + time_t mtime = kfi->time( TDEIO::UDS_MODIFICATION_TIME ); + bool symLink = kfi->isLink(); + mode_t mode = kfi->mode() | kfi->permissions(); + TQString perm = KRpermHandler::mode2TQString( mode ); +// set the mimetype + TQString mime = TQString(); + TQString symDest = ""; + if ( symLink ) { + symDest = kfi->linkDest(); + if ( kfi->isDir() ) perm[ 0 ] = 'd'; + } + + // create a new virtual file object + if ( kfi->user().isEmpty() ) + temp = new vfile( name, size, perm, mtime, symLink, getuid(), getgid(), mime, symDest, mode ); + else { + TQString currentUser = url.user(); + if ( currentUser.contains( "@" ) ) /* remove the FTP proxy tags from the username */ + currentUser.truncate( currentUser.find( '@' ) ); + if ( currentUser.isEmpty() ) + currentUser = KRpermHandler::uid2user( getuid() ); + temp = new vfile( name, size, perm, mtime, symLink, kfi->user(), kfi->group(), currentUser, mime, symDest, mode ); + } + + temp->vfile_setUrl( kfi->url() ); + delete kfi; + return temp; +} + +TDEConfig* virt_vfs::getVirtDB(){ + if( !virt_vfs_db ){ + virt_vfs_db = new TDEConfig(VIRT_VFS_DB,false,"data"); + } + return virt_vfs_db; +} + +bool virt_vfs::save(){ + TDEConfig* db = getVirtDB(); + + db->setGroup("virt_db"); + TQDictIterator<KURL::List> it( virtVfsDict ); // See TQDictIterator + for( ; it.current(); ++it ){ + KURL::List::iterator url; + TQStringList entry; + for ( url = it.current()->begin() ; url != it.current()->end() ; ++url ) { + entry.append( (*url).prettyURL() ); + } + db->writeEntry(it.currentKey(),entry); + } + + db->sync(); + + return true; +} + +bool virt_vfs::restore(){ + TDEConfig* db = getVirtDB(); + db->setGroup("virt_db"); + + TQMap<TQString, TQString> map = db->entryMap("virt_db"); + TQMap<TQString, TQString>::Iterator it; + KURL::List* urlList; + for ( it = map.begin(); it != map.end(); ++it ) { + urlList = new KURL::List( db->readListEntry(it.key()) ); + virtVfsDict.insert( it.key(),urlList ); + } + + if( !virtVfsDict["/" ]){ + urlList = new KURL::List(); + virtVfsDict.insert( "/", urlList ); + } + + return true; +} + +void virt_vfs::vfs_calcSpace( TQString name , TDEIO::filesize_t* totalSize, unsigned long* totalFiles, unsigned long* totalDirs, bool* stop ) { + if ( stop && *stop ) return ; + if( path == "/" ) { + KURL::List* urlList = virtVfsDict[ name ]; + if ( urlList ) + for( unsigned i=0; (i != urlList->size()) && !(*stop); i++ ) + calculateURLSize( (*urlList)[ i ], totalSize, totalFiles, totalDirs, stop ); + return; + } + return vfs::vfs_calcSpace( name, totalSize, totalFiles, totalDirs, stop ); +} + +#include "virt_vfs.moc" |