/* * File name: kdirtreeiterators.h * Summary: Support classes for KDirStat - KDirTree iterator classes * License: LGPL - See file COPYING.LIB for details. * Author: Stefan Hundhammer * * Updated: 2003-01-07 */ #include "kdirtreeiterators.h" #include "kdirtree.h" using namespace KDirStat; KFileInfoIterator::KFileInfoIterator( KFileInfo * parent, KDotEntryPolicy dotEntryPolicy ) { init( parent, dotEntryPolicy, true ); // callNext } KFileInfoIterator::KFileInfoIterator( KFileInfo * parent, KDotEntryPolicy dotEntryPolicy, bool callNext ) { init( parent, dotEntryPolicy, callNext ); } void KFileInfoIterator::init( KFileInfo * parent, KDotEntryPolicy dotEntryPolicy, bool callNext ) { _parent = parent; _policy = dotEntryPolicy; _current = 0; _directChildrenProcessed = false; _dotEntryProcessed = false; _dotEntryChildrenProcessed = false; if ( callNext ) next(); } KFileInfoIterator::~KFileInfoIterator() { // NOP } void KFileInfoIterator::next() { if ( ! _directChildrenProcessed ) { // Process direct children _current = _current ? _current->next() : _parent->firstChild(); if ( ! _current ) { _directChildrenProcessed = true; next(); } else { // kdDebug() << k_funcinfo << " direct child " << _current << endl; } } else // _directChildrenProcessed { if ( ! _dotEntryProcessed ) { // Process dot entry _current = _policy == KDotEntryAsSubDir ? _parent->dotEntry() : 0; _dotEntryProcessed = true; if ( ! _current ) { next(); } else { // kdDebug() << k_funcinfo << " dot entry " << _current << endl; } } else // Dot entry already processed or processing it not desired { if ( ! _dotEntryChildrenProcessed ) { if ( _policy == KDotEntryTransparent ) { // Process dot entry children _current = _current ? _current->next() : ( _parent->dotEntry() ? _parent->dotEntry()->firstChild() : 0 ); if ( ! _current ) { _dotEntryChildrenProcessed = true; } else { // kdDebug() << k_funcinfo << " dot entry child " << _current << endl; } } else // _policy != KDotEntryTransparent { _current = 0; _dotEntryChildrenProcessed = true; } } } } } int KFileInfoIterator::count() { int cnt = 0; // Count direct children KFileInfo *child = _parent->firstChild(); while ( child ) { cnt++; child = child->next(); } // Handle the dot entry switch ( _policy ) { case KDotEntryTransparent: // Count the dot entry's children as well. if ( _parent->dotEntry() ) { child = _parent->dotEntry()->firstChild(); while ( child ) { cnt++; child = child->next(); } } break; case KDotEntryAsSubDir: // The dot entry counts as one item. if ( _parent->dotEntry() ) cnt++; break; case KDotEntryIgnore: // We're done. break; } return cnt; } KFileInfoSortedIterator::KFileInfoSortedIterator( KFileInfo * parent, KDotEntryPolicy dotEntryPolicy, KFileInfoSortOrder sortOrder, bool ascending ) : KFileInfoIterator( parent, dotEntryPolicy, false ) { _sortOrder = sortOrder; _ascending = ascending; _initComplete = false; _childrenList = 0; _current = 0; } void KFileInfoSortedIterator::delayedInit() { _childrenList = new KFileInfoList( _sortOrder, _ascending ); TQ_CHECK_PTR( _childrenList ); if ( _sortOrder == KSortByName ) { makeDefaultOrderChildrenList(); } else { makeChildrenList(); } _current = _childrenList->first(); _initComplete = true; } KFileInfoSortedIterator::~KFileInfoSortedIterator() { if ( _childrenList ) delete _childrenList; } void KFileInfoSortedIterator::makeDefaultOrderChildrenList() { // Fill children list with direct children KFileInfo *child = _parent->firstChild(); while ( child ) { _childrenList->append( child ); child = child->next(); } _childrenList->sort(); if ( _policy == KDotEntryAsSubDir && _parent->dotEntry() ) { // Append dot entry to the children list _childrenList->append( _parent->dotEntry() ); } // Append the dot entry's children to the children list if ( _policy == KDotEntryTransparent && _parent->dotEntry() ) { // Create a temporary list for the dot entry children KFileInfoList dotEntryChildrenList( _sortOrder, _ascending ); child = _parent->dotEntry()->firstChild(); while ( child ) { dotEntryChildrenList.append( child ); child = child->next(); } dotEntryChildrenList.sort(); // Now append all of this dot entry children list to the children list child = dotEntryChildrenList.first(); while ( child ) { _childrenList->append( child ); child = dotEntryChildrenList.next(); } } } void KFileInfoSortedIterator::makeChildrenList() { KFileInfoIterator it( _parent, _policy ); while ( *it ) { _childrenList->append( *it ); ++it; } _childrenList->sort(); } KFileInfo * KFileInfoSortedIterator::current() { if ( ! _initComplete ) delayedInit(); return _current; } void KFileInfoSortedIterator::next() { if ( ! _initComplete ) delayedInit(); _current = _childrenList->next(); } bool KFileInfoSortedIterator::finished() { if ( ! _initComplete ) delayedInit(); return _current == 0; } KFileInfoSortedBySizeIterator::KFileInfoSortedBySizeIterator( KFileInfo * parent, KFileSize minSize, KDotEntryPolicy dotEntryPolicy, bool ascending ) : KFileInfoSortedIterator( parent, dotEntryPolicy, KSortByTotalSize, ascending ) , _minSize( minSize ) { } void KFileInfoSortedBySizeIterator::makeChildrenList() { KFileInfoIterator it( _parent, _policy ); while ( *it ) { if ( (*it)->totalSize() >= _minSize ) _childrenList->append( *it ); ++it; } _childrenList->sort(); } KFileInfoList::KFileInfoList( KFileInfoSortOrder sortOrder, bool ascending ) : TQPtrList() { _sortOrder = sortOrder; _ascending = ascending; } KFileInfoList::~KFileInfoList() { // NOP } KFileSize KFileInfoList::sumTotalSizes() { KFileSize sum = 0; KFileInfoListIterator it( *this ); while ( *it ) { sum += (*it)->totalSize(); ++it; } return sum; } int KFileInfoList::compareItems( TQPtrCollection::Item it1, TQPtrCollection::Item it2 ) { if ( it1 == it2 ) return 0; KFileInfo *file1 = (KFileInfo *) it1; KFileInfo *file2 = (KFileInfo *) it2; int result = 0; switch ( _sortOrder ) { case KUnsorted: return 1; case KSortByName: result = TQString::compare( file1->name(), file2->name() ); break; case KSortByTotalSize: result = compare( file1->totalSize(), file2->totalSize() ); break; case KSortByLatestMtime: result = compare( file1->latestMtime(), file2->latestMtime() ); break; } return _ascending ? result : -result; } // EOF