Filelight – graphical disk usage analyzer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
filelight/src/part/remoteLister.cpp

160 lines
4.4 KiB

//Author: Max Howell <max.howell@methylblue.com>, (C) 2003-4
//Copyright: See COPYING file that comes with this distribution
#include <debug.h>
#include "fileTree.h"
#include <tqapplication.h>
#include <tqtimer.h>
#include <tqvaluelist.h>
#include "remoteLister.h"
#include "scan.h"
namespace Filelight
{
//you need to use a single DirLister
//one per directory breaks KIO (seemingly) and also uses un-godly amounts of memory!
//TODO delete all this stuff!
struct Store {
typedef TQValueList<Store*> List;
/// location of the directory
const KURL url;
/// the directory on which we are operating
Directory *directory;
/// so we can reference the parent store
Store *parent;
/// directories in this directory that need to be scanned before we can propagate()
List stores;
Store()
: directory( 0 ), parent( 0 ) {}
Store( const KURL &u, const TQString &name, Store *s )
: url( u ), directory( new Directory( name.local8Bit() + '/' ) ), parent( s ) {}
Store*
propagate()
{
/// returns the next store available for scanning
debug() << "propagate: " << url << endl;
if( parent ) {
parent->directory->append( directory );
if( parent->stores.isEmpty() ) {
return parent->propagate();
}
else
return parent;
}
//we reached the root, let's get our next directory scanned
return this;
}
private:
Store( Store& );
Store &operator=( const Store& );
};
RemoteLister::RemoteLister( const KURL &url, TQWidget *parent )
: KDirLister( true /*don't fetch mimetypes*/ )
, m_root( new Store( url, url.url(), 0 ) )
, m_store( m_root )
{
setAutoUpdate( false ); //don't use KDirWatchers
setShowingDotFiles( true ); //stupid KDirLister API function names
setMainWindow( parent );
//use TQT_SIGNAL(result(KIO::Job*)) instead and then use Job::error()
connect( this, TQT_SIGNAL(completed()), TQT_SLOT(completed()) );
connect( this, TQT_SIGNAL(canceled()), TQT_SLOT(canceled()) );
//we do this non-recursively - it is the only way!
openURL( url );
}
RemoteLister::~RemoteLister()
{
Directory *tree = isFinished() ? m_store->directory : 0;
TQCustomEvent *e = new TQCustomEvent( 1000 );
e->setData( tree );
TQApplication::postEvent( parent(), e );
delete m_root;
}
void
RemoteLister::completed()
{
debug() << "completed: " << url().prettyURL() << endl;
//as usual KDE documentation didn't suggest I needed to do this at all
//I had to figure it out myself
// -- avoid crash
TQTimer::singleShot( 0, this, TQT_SLOT(_completed()) );
}
void
RemoteLister::canceled()
{
debug() << "canceled: " << url().prettyURL() << endl;
TQTimer::singleShot( 0, this, TQT_SLOT(_completed()) );
}
void
RemoteLister::_completed()
{
//m_directory is set to the directory we should operate on
KFileItemList items = KDirLister::items();
for( KFileItemList::ConstIterator it = items.begin(), end = items.end(); it != end; ++it )
{
if( (*it)->isDir() )
m_store->stores += new Store( (*it)->url(), (*it)->name(), m_store );
else
m_store->directory->append( (*it)->name().local8Bit(), (*it)->size() / 1024 );
ScanManager::s_files++;
}
if( m_store->stores.isEmpty() )
//no directories to scan, so we need to append ourselves to the parent directory
//propagate() will return the next ancestor that has stores left to be scanned, or root if we are done
m_store = m_store->propagate();
if( !m_store->stores.isEmpty() )
{
Store::List::Iterator first = m_store->stores.begin();
const KURL url( (*first)->url );
Store *currentStore = m_store;
//we should operate with this store next time this function is called
m_store = *first;
//we don't want to handle this store again
currentStore->stores.remove( first );
//this returns _immediately_
debug() << "scanning: " << url << endl;
openURL( url );
}
else {
debug() << "I think we're done\n";
Q_ASSERT( m_root == m_store );
delete this;
}
}
}
#include "remoteLister.moc"