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.
418 lines
7.0 KiB
418 lines
7.0 KiB
/*
|
|
* File name: kdirtreeiterators.h
|
|
* Summary: Support classes for KDirStat - KDirTree iterator classes
|
|
* License: LGPL - See file COPYING.LIB for details.
|
|
* Author: Stefan Hundhammer <sh@suse.de>
|
|
*
|
|
* 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 );
|
|
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<KFileInfo>()
|
|
{
|
|
_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( TQCollection::Item it1, TQCollection::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<KFileSize>( file1->totalSize(), file2->totalSize() );
|
|
break;
|
|
|
|
case KSortByLatestMtime:
|
|
result = compare<time_t>( file1->latestMtime(), file2->latestMtime() );
|
|
break;
|
|
}
|
|
|
|
return _ascending ? result : -result;
|
|
}
|
|
|
|
|
|
|
|
|
|
// EOF
|