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.
1440 lines
41 KiB
1440 lines
41 KiB
/*
|
|
* File name: kdirtree.h
|
|
* Summary: Support classes for KDirStat
|
|
* License: LGPL - See file COPYING.LIB for details.
|
|
* Author: Stefan Hundhammer <sh@suse.de>
|
|
*
|
|
* Updated: 2005-01-07
|
|
*/
|
|
|
|
|
|
#ifndef KDirTree_h
|
|
#define KDirTree_h
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
#include <limits.h>
|
|
#include <dirent.h>
|
|
#include <tqptrqueue.h>
|
|
#include <kdebug.h>
|
|
#include <tdefileitem.h>
|
|
#include <tdeio/jobclasses.h>
|
|
|
|
#ifndef NOT_USED
|
|
# define NOT_USED(PARAM) ( (void) (PARAM) )
|
|
#endif
|
|
|
|
// Open a new name space since KDE's name space is pretty much cluttered
|
|
// already - all names that would even remotely match are already used up,
|
|
// yet the resprective classes don't quite fit the purposes required here.
|
|
|
|
namespace KDirStat
|
|
{
|
|
// With today's hard disks, the 2 GB we could sum up with 'long' (or 4 GB
|
|
// with 'unsigned long') are definitely not enough. So we have to go for
|
|
// something larger:
|
|
typedef long long KFileSize;
|
|
|
|
// Taken from Linux <limits.h> (the Alpha definition - 64 Bit long!).
|
|
// This is how much bytes this program can handle.
|
|
#define KFileSizeMax 9223372036854775807LL
|
|
|
|
// Forward declarations
|
|
class KDirInfo;
|
|
class KDirTree;
|
|
class KDirReadJob;
|
|
class KDirTreeView;
|
|
|
|
|
|
/**
|
|
* Status of a directory read job.
|
|
**/
|
|
typedef enum
|
|
{
|
|
KDirQueued, // Waiting in the directory read queue
|
|
KDirReading, // Reading in progress
|
|
KDirFinished, // Reading finished and OK
|
|
KDirOnRequestOnly, // Will be read upon explicit request only (mount points)
|
|
KDirAborted, // Reading aborted upon user request
|
|
KDirError // Error while reading
|
|
} KDirReadState;
|
|
|
|
|
|
/**
|
|
* Directory read methods.
|
|
**/
|
|
typedef enum
|
|
{
|
|
KDirReadUnknown, // Unknown (yet)
|
|
KDirReadLocal, // Use opendir() and lstat()
|
|
KDirReadKIO // Use KDE 2.x's TDEIO network transparent methods
|
|
} KDirReadMethod;
|
|
|
|
|
|
|
|
/**
|
|
* The most basic building block of a @ref KDirTree:
|
|
*
|
|
* Information about one single directory entry. This is the type of info
|
|
* typically obtained by stat() / lstat() or similar calls. Most of this
|
|
* can also be obtained by @ref TDEIO::KDirListJob, but not all: The device
|
|
* this file resides on is something none of TDEIO's many classes will tell
|
|
* (since of course this only makes sense for local files) - yet this had
|
|
* been _the_ single most requested feature of KDirStat <1.0: Stay on one
|
|
* filesystem. To facilitate this, information about the device is
|
|
* required, thus we'll do lstat() sys calls ourselves for local
|
|
* files. This is what the classes in this file are all about.
|
|
*
|
|
* This class is tuned for size rather than speed: A typical Linux system
|
|
* easily has 150,000+ file system objects, and at least one entry of this
|
|
* sort is required for each of them.
|
|
*
|
|
* This class provides stubs for children management, yet those stubs all
|
|
* are default implementations that don't really deal with children.
|
|
* Derived classes need to take care of that.
|
|
*
|
|
* @short Basic file information (like obtained by the lstat() sys call)
|
|
**/
|
|
class KFileInfo
|
|
{
|
|
public:
|
|
/**
|
|
* Default constructor.
|
|
**/
|
|
KFileInfo( KDirTree * tree,
|
|
KDirInfo * parent = 0,
|
|
const char * name = 0 );
|
|
|
|
/**
|
|
* Constructor from a stat buffer (i.e. based on an lstat() call).
|
|
**/
|
|
KFileInfo( const TQString & filenameWithoutPath,
|
|
struct stat * statInfo,
|
|
KDirTree * tree,
|
|
KDirInfo * parent = 0 );
|
|
|
|
/**
|
|
* Constructor from a KFileItem, i.e. from a @ref TDEIO::StatJob
|
|
**/
|
|
KFileInfo( const KFileItem * fileItem,
|
|
KDirTree * tree,
|
|
KDirInfo * parent = 0 );
|
|
|
|
/**
|
|
* Destructor.
|
|
*
|
|
* Don't forget to call @ref KFileInfo::unlinkChild() when deleting
|
|
* objects of this class!
|
|
**/
|
|
virtual ~KFileInfo();
|
|
|
|
/**
|
|
* Returns whether or not this is a local file (protocol "file:").
|
|
* It might as well be a remote file ("ftp:", "smb:" etc.).
|
|
**/
|
|
bool isLocalFile() const { return _isLocalFile; }
|
|
|
|
/**
|
|
* Returns the file or directory name without path, i.e. only the last
|
|
* path name component (i.e. "printcap" rather than "/etc/printcap").
|
|
*
|
|
* If a directory scan doesn't begin at the root directory and this is
|
|
* the top entry of this directory scan it will also contain the base
|
|
* path and maybe the protocol (for remote files),
|
|
* i.e. "/usr/share/man" rather than just "man" if a scan was requested
|
|
* for "/usr/share/man". Notice, however, that the entry for
|
|
* "/usr/share/man/man1" will only return "man1" in this example.
|
|
**/
|
|
TQString name() const { return _name; }
|
|
|
|
/**
|
|
* Returns the full URL of this object with full path and protocol
|
|
* (unless the protocol is "file:").
|
|
*
|
|
* This is a (somewhat) expensive operation since it will recurse up
|
|
* to the top of the tree.
|
|
**/
|
|
TQString url() const;
|
|
|
|
/**
|
|
* Very much like @ref KFileInfo::url(), but with "/<Files>" appended
|
|
* if this is a dot entry. Useful for debugging.
|
|
* Notice: You can simply use the @ref kdbgstream operator<< to
|
|
* output exactly this:
|
|
*
|
|
* kdDebug() << "Found fileInfo " << info << endl;
|
|
**/
|
|
TQString debugUrl() const;
|
|
|
|
/**
|
|
* Returns part no. "level" of this object's URL, i.e. traverses up the
|
|
* tree until this tree level is reached and returns this predecessor's
|
|
* @ref name() . This is useful for tree searches in symmetrical trees
|
|
* to find an item's counterpart in the other tree.
|
|
**/
|
|
TQString urlPart( int level ) const;
|
|
|
|
/**
|
|
* Returns the major and minor device numbers of the device this file
|
|
* resides on or 0 if this is a remote file.
|
|
**/
|
|
dev_t device() const { return _device; }
|
|
|
|
/**
|
|
* The file permissions and object type as returned by lstat().
|
|
* You might want to use the repective convenience methods instead:
|
|
* @ref isDir(), @ref isFile(), ...
|
|
**/
|
|
mode_t mode() const { return _mode; }
|
|
|
|
/**
|
|
* The number of hard links to this file. Relevant for size summaries
|
|
* to avoid counting one file several times.
|
|
**/
|
|
nlink_t links() const { return _links; }
|
|
|
|
/**
|
|
* The file size in bytes. This does not take unused space in the last
|
|
* disk block (cluster) into account, yet it is the only size all kinds
|
|
* of info functions can obtain. This is also what most file system
|
|
* utilities (like "ls -l") display.
|
|
**/
|
|
KFileSize byteSize() const { return _size; }
|
|
|
|
/**
|
|
* The number of bytes actually allocated on the file system. Usually
|
|
* this will be more than @ref byteSize() since the last few bytes of a
|
|
* file usually consume an additional cluster on the file system.
|
|
*
|
|
* In the case of sparse files, however, this might as well be
|
|
* considerably less than @ref byteSize() - this means that this file
|
|
* has "holes", i.e. large portions filled with zeros. This is typical
|
|
* for large core dumps for example. The only way to create such a file
|
|
* is to lseek() far ahead of the previous file size and then writing
|
|
* data. Most file system utilities will however disregard the fact
|
|
* that files are sparse files and simply allocate the holes as well,
|
|
* thus greatly increasing the disk space consumption of such a
|
|
* file. Only some few file system utilities like "cp", "rsync", "tar"
|
|
* have options to handle this more graciously - but usually only when
|
|
* specifically requested. See the respective man pages.
|
|
**/
|
|
KFileSize allocatedSize() const;
|
|
|
|
/**
|
|
* The file size, taking into account multiple links for plain files or
|
|
* the true allocated size for sparse files. For plain files with
|
|
* multiple links this will be size/no_links, for sparse files it is
|
|
* the number of bytes actually allocated.
|
|
**/
|
|
KFileSize size() const;
|
|
|
|
/**
|
|
* The file size in 512 byte blocks.
|
|
**/
|
|
KFileSize blocks() const { return _blocks; }
|
|
|
|
/**
|
|
* The size of one single block that @ref blocks() returns.
|
|
* Notice: This is _not_ the blocksize that lstat() returns!
|
|
**/
|
|
KFileSize blockSize() const { return 512L; }
|
|
|
|
/**
|
|
* The modification time of the file (not the inode).
|
|
**/
|
|
time_t mtime() const { return _mtime; }
|
|
|
|
/**
|
|
* Returns the total size in bytes of this subtree.
|
|
* Derived classes that have children should overwrite this.
|
|
**/
|
|
virtual KFileSize totalSize() { return size(); }
|
|
|
|
/**
|
|
* Returns the total size in blocks of this subtree.
|
|
* Derived classes that have children should overwrite this.
|
|
**/
|
|
virtual KFileSize totalBlocks() { return _blocks; }
|
|
|
|
/**
|
|
* Returns the total number of children in this subtree, excluding this item.
|
|
* Derived classes that have children should overwrite this.
|
|
**/
|
|
virtual int totalItems() { return 0; }
|
|
|
|
/**
|
|
* Returns the total number of subdirectories in this subtree,
|
|
* excluding this item. Dot entries and "." or ".." are not counted.
|
|
* Derived classes that have children should overwrite this.
|
|
**/
|
|
virtual int totalSubDirs() { return 0; }
|
|
|
|
/**
|
|
* Returns the total number of plain file children in this subtree,
|
|
* excluding this item.
|
|
* Derived classes that have children should overwrite this.
|
|
**/
|
|
virtual int totalFiles() { return 0; }
|
|
|
|
/**
|
|
* Returns the latest modification time of this subtree.
|
|
* Derived classes that have children should overwrite this.
|
|
**/
|
|
virtual time_t latestMtime() { return _mtime; }
|
|
|
|
/**
|
|
* Returns whether or not this is a mount point.
|
|
* Derived classes may want to overwrite this.
|
|
**/
|
|
virtual bool isMountPoint() { return false; }
|
|
|
|
/**
|
|
* Sets the mount point state, i.e. whether or not this is a mount
|
|
* point.
|
|
*
|
|
* This default implementation silently ignores the value passed and
|
|
* does nothing. Derived classes may want to overwrite this.
|
|
**/
|
|
virtual void setMountPoint( bool isMountPoint = true )
|
|
{ ((void) isMountPoint); return; }
|
|
|
|
/**
|
|
* Returns true if this subtree is finished reading.
|
|
*
|
|
* This default implementation always returns 'true';
|
|
* derived classes should overwrite this.
|
|
**/
|
|
virtual bool isFinished() { return true; }
|
|
|
|
/**
|
|
* Returns true if this subtree is busy, i.e. it is not finished
|
|
* reading yet.
|
|
*
|
|
* This default implementation always returns 'false';
|
|
* derived classes should overwrite this.
|
|
**/
|
|
virtual bool isBusy() { return false; }
|
|
|
|
/**
|
|
* Returns the number of pending read jobs in this subtree. When this
|
|
* number reaches zero, the entire subtree is done.
|
|
* Derived classes that have children should overwrite this.
|
|
**/
|
|
virtual int pendingReadJobs() { return 0; }
|
|
|
|
|
|
//
|
|
// Tree management
|
|
//
|
|
|
|
/**
|
|
* Returns a pointer to the @ref KDirTree this entry belongs to.
|
|
**/
|
|
KDirTree * tree() const { return _tree; }
|
|
|
|
/**
|
|
* Returns a pointer to this entry's parent entry or 0 if there is
|
|
* none.
|
|
**/
|
|
KDirInfo * parent() const { return _parent; }
|
|
|
|
/**
|
|
* Set the "parent" pointer.
|
|
**/
|
|
void setParent( KDirInfo *newParent ) { _parent = newParent; }
|
|
|
|
/**
|
|
* Returns a pointer to the next entry on the same level
|
|
* or 0 if there is none.
|
|
**/
|
|
KFileInfo * next() const { return _next; }
|
|
|
|
/**
|
|
* Set the "next" pointer.
|
|
**/
|
|
void setNext( KFileInfo *newNext ) { _next = newNext; }
|
|
|
|
/**
|
|
* Returns the first child of this item or 0 if there is none.
|
|
* Use the child's next() method to get the next child.
|
|
*
|
|
* This default implementation always returns 0.
|
|
**/
|
|
virtual KFileInfo * firstChild() const { return 0; }
|
|
|
|
/**
|
|
* Set this entry's first child.
|
|
* Use this method only if you know exactly what you are doing.
|
|
*
|
|
* This default implementation does nothing.
|
|
* Derived classes might want to overwrite this.
|
|
**/
|
|
virtual void setFirstChild( KFileInfo *newFirstChild )
|
|
{ NOT_USED( newFirstChild ); }
|
|
|
|
/**
|
|
* Returns true if this entry has any children.
|
|
**/
|
|
virtual bool hasChildren() const;
|
|
|
|
/**
|
|
* Returns true if this entry is in subtree 'subtree', i.e. if this is
|
|
* a child or grandchild etc. of 'subtree'.
|
|
**/
|
|
bool isInSubtree( const KFileInfo *subtree ) const;
|
|
|
|
/**
|
|
* Locate a child somewhere in this subtree whose URL (i.e. complete
|
|
* path) matches the URL passed. Returns 0 if there is no such child.
|
|
*
|
|
* Notice: This is a very expensive operation since the entire subtree
|
|
* is searched recursively.
|
|
*
|
|
* Derived classes might or might not wish to overwrite this method;
|
|
* it's only advisable to do so if a derived class comes up with a
|
|
* different method than brute-force search all children.
|
|
*
|
|
* 'findDotEntries' specifies if locating "dot entries" (".../<Files>")
|
|
* is desired.
|
|
**/
|
|
virtual KFileInfo * locate( TQString url, bool findDotEntries = false );
|
|
|
|
/**
|
|
* Insert a child into the children list.
|
|
*
|
|
* The order of children in this list is absolutely undefined;
|
|
* don't rely on any implementation-specific order.
|
|
*
|
|
* This default implementation does nothing.
|
|
**/
|
|
virtual void insertChild( KFileInfo *newChild ) { NOT_USED( newChild ); }
|
|
|
|
/**
|
|
* Return the "Dot Entry" for this node if there is one (or 0
|
|
* otherwise): This is a pseudo entry that directory nodes use to store
|
|
* non-directory children separately from directories. This way the end
|
|
* user can easily tell which summary fields belong to the directory
|
|
* itself and which are the accumulated values of the entire subtree.
|
|
*
|
|
* This default implementation always returns 0.
|
|
**/
|
|
virtual KFileInfo *dotEntry() const { return 0; }
|
|
|
|
/**
|
|
* Set a "Dot Entry". This makes sense for directories only.
|
|
*
|
|
* This default implementation does nothing.
|
|
**/
|
|
virtual void setDotEntry( KFileInfo *newDotEntry ) { NOT_USED( newDotEntry ); }
|
|
|
|
/**
|
|
* Returns true if this is a "Dot Entry".
|
|
* See @ref dotEntry() for details.
|
|
*
|
|
* This default implementation always returns false.
|
|
**/
|
|
virtual bool isDotEntry() const { return false; }
|
|
|
|
/**
|
|
* Returns the tree level (depth) of this item.
|
|
* The topmost level is 0.
|
|
*
|
|
* This is a (somewhat) expensive operation since it will recurse up
|
|
* to the top of the tree.
|
|
**/
|
|
int treeLevel() const;
|
|
|
|
/**
|
|
* Notification that a child has been added somewhere in the subtree.
|
|
*
|
|
* This default implementation does nothing.
|
|
**/
|
|
virtual void childAdded( KFileInfo *newChild ) { NOT_USED( newChild ); }
|
|
|
|
/**
|
|
* Remove a child from the children list.
|
|
*
|
|
* IMPORTANT: This MUST be called just prior to deleting an object of
|
|
* this class. Regrettably, this cannot simply be moved to the
|
|
* destructor: Important parts of the object might already be destroyed
|
|
* (e.g., the virtual table - no more virtual methods).
|
|
*
|
|
* This default implementation does nothing.
|
|
* Derived classes that can handle children should overwrite this.
|
|
**/
|
|
virtual void unlinkChild( KFileInfo *deletedChild ) { NOT_USED( deletedChild ); }
|
|
|
|
/**
|
|
* Notification that a child is about to be deleted somewhere in the
|
|
* subtree.
|
|
**/
|
|
virtual void deletingChild( KFileInfo *deletedChild ) { NOT_USED( deletedChild ); }
|
|
|
|
/**
|
|
* Get the current state of the directory reading process:
|
|
*
|
|
* This default implementation always returns KDirFinished.
|
|
* Derived classes should overwrite this.
|
|
**/
|
|
virtual KDirReadState readState() const { return KDirFinished; }
|
|
|
|
/**
|
|
* Returns true if this is a @ref KDirInfo object.
|
|
*
|
|
* Don't confuse this with @ref isDir() which tells whether or not this
|
|
* is a disk directory! Both should return the same, but you'll never
|
|
* know - better be safe than sorry!
|
|
*
|
|
* This default implementation always returns 'false'. Derived classes
|
|
* (in particular, those derived from @ref KDirInfo) should overwrite this.
|
|
**/
|
|
virtual bool isDirInfo() const { return false; }
|
|
|
|
/**
|
|
* Returns true if this is a sparse file, i.e. if this file has
|
|
* actually fewer disk blocks allocated than its byte size would call
|
|
* for.
|
|
*
|
|
* This is a cheap operation since it relies on a cached flag that is
|
|
* calculated in the constructor rather than doing repeated
|
|
* calculations and comparisons.
|
|
*
|
|
* Please not that @ref size() already takes this into account.
|
|
**/
|
|
bool isSparseFile() const { return _isSparseFile; }
|
|
|
|
|
|
//
|
|
// File type / mode convenience methods.
|
|
// These are simply shortcuts to the respective macros from
|
|
// <sys/stat.h>.
|
|
//
|
|
|
|
/**
|
|
* Returns true if this is a directory.
|
|
**/
|
|
bool isDir() const { return S_ISDIR( _mode ) ? true : false; }
|
|
|
|
/**
|
|
* Returns true if this is a regular file.
|
|
**/
|
|
bool isFile() const { return S_ISREG( _mode ) ? true : false; }
|
|
|
|
/**
|
|
* Returns true if this is a symbolic link.
|
|
**/
|
|
bool isSymLink() const { return S_ISLNK( _mode ) ? true : false; }
|
|
|
|
|
|
/**
|
|
* Returns true if this is a (block or character) device.
|
|
**/
|
|
bool isDevice() const { return ( S_ISBLK ( _mode ) ||
|
|
S_ISCHR ( _mode ) ) ? true : false; }
|
|
|
|
/**
|
|
* Returns true if this is a block device.
|
|
**/
|
|
bool isBlockDevice() const { return S_ISBLK ( _mode ) ? true : false; }
|
|
|
|
/**
|
|
* Returns true if this is a block device.
|
|
**/
|
|
bool isCharDevice() const { return S_ISCHR ( _mode ) ? true : false; }
|
|
|
|
/**
|
|
* Returns true if this is a "special" file, i.e. a (block or character)
|
|
* device, a FIFO (named pipe) or a socket.
|
|
**/
|
|
bool isSpecial() const { return ( S_ISBLK ( _mode ) ||
|
|
S_ISCHR ( _mode ) ||
|
|
S_ISFIFO( _mode ) ||
|
|
S_ISSOCK( _mode ) ) ? true : false; }
|
|
|
|
protected:
|
|
|
|
// Data members.
|
|
//
|
|
// Keep this short in order to use as little memory as possible -
|
|
// there will be a _lot_ of entries of this kind!
|
|
|
|
TQString _name; // the file name (without path!)
|
|
bool _isLocalFile :1; // flag: local or remote file?
|
|
bool _isSparseFile :1; // (cache) flag: sparse file (file with "holes")?
|
|
dev_t _device; // device this object resides on
|
|
mode_t _mode; // file permissions + object type
|
|
nlink_t _links; // number of links
|
|
KFileSize _size; // size in bytes
|
|
KFileSize _blocks; // 512 bytes blocks
|
|
time_t _mtime; // modification time
|
|
|
|
KDirInfo * _parent; // pointer to the parent entry
|
|
KFileInfo * _next; // pointer to the next entry
|
|
KDirTree * _tree; // pointer to the parent tree
|
|
}; // class KFileInfo
|
|
|
|
|
|
/**
|
|
* A more specialized version of @ref KFileInfo: This class can actually
|
|
* manage children. The base class (@ref KFileInfo) has only stubs for the
|
|
* respective methods to integrate seamlessly with the abstraction of a
|
|
* file / directory tree; this class fills those stubs with life.
|
|
*
|
|
* @short directory item within a @ref KDirTree.
|
|
**/
|
|
class KDirInfo: public KFileInfo
|
|
{
|
|
public:
|
|
/**
|
|
* Default constructor.
|
|
*
|
|
* If "asDotEntry" is set, this will be used as the parent's
|
|
* "dot entry", i.e. the pseudo directory that holds all the parent's
|
|
* non-directory children. This is the only way to create a "dot
|
|
* entry"!
|
|
**/
|
|
KDirInfo( KDirTree * tree,
|
|
KDirInfo * parent = 0,
|
|
bool asDotEntry = false );
|
|
|
|
/**
|
|
* Constructor from a stat buffer (i.e. based on an lstat() call).
|
|
**/
|
|
KDirInfo( const TQString & filenameWithoutPath,
|
|
struct stat * statInfo,
|
|
KDirTree * tree,
|
|
KDirInfo * parent = 0 );
|
|
|
|
/**
|
|
* Constructor from a KFileItem, i.e. from a @ref TDEIO::StatJob
|
|
**/
|
|
KDirInfo( const KFileItem * fileItem,
|
|
KDirTree * tree,
|
|
KDirInfo * parent = 0 );
|
|
|
|
/**
|
|
* Destructor.
|
|
**/
|
|
virtual ~KDirInfo();
|
|
|
|
|
|
/**
|
|
* Returns the total size in bytes of this subtree.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual KFileSize totalSize();
|
|
|
|
/**
|
|
* Returns the total size in blocks of this subtree.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual KFileSize totalBlocks();
|
|
|
|
/**
|
|
* Returns the total number of children in this subtree, excluding this item.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual int totalItems();
|
|
|
|
/**
|
|
* Returns the total number of subdirectories in this subtree,
|
|
* excluding this item. Dot entries and "." or ".." are not counted.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual int totalSubDirs();
|
|
|
|
/**
|
|
* Returns the total number of plain file children in this subtree,
|
|
* excluding this item.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual int totalFiles();
|
|
|
|
/**
|
|
* Returns the latest modification time of this subtree.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual time_t latestMtime();
|
|
|
|
/**
|
|
* Returns whether or not this is a mount point.
|
|
*
|
|
* This will return 'false' only if this information can be obtained at
|
|
* all, i.e. if local directory reading methods are used.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual bool isMountPoint() { return _isMountPoint; }
|
|
|
|
/**
|
|
* Sets the mount point state, i.e. whether or not this is a mount
|
|
* point.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual void setMountPoint( bool isMountPoint = true );
|
|
|
|
/**
|
|
* Returns true if this subtree is finished reading.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual bool isFinished();
|
|
|
|
/**
|
|
* Returns true if this subtree is busy, i.e. it is not finished
|
|
* reading yet.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual bool isBusy();
|
|
|
|
/**
|
|
* Returns the number of pending read jobs in this subtree. When this
|
|
* number reaches zero, the entire subtree is done.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual int pendingReadJobs() { return _pendingReadJobs; }
|
|
|
|
/**
|
|
* Returns the first child of this item or 0 if there is none.
|
|
* Use the child's next() method to get the next child.
|
|
**/
|
|
virtual KFileInfo * firstChild() const { return _firstChild; }
|
|
|
|
/**
|
|
* Set this entry's first child.
|
|
* Use this method only if you know exactly what you are doing.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual void setFirstChild( KFileInfo *newfirstChild )
|
|
{ _firstChild = newfirstChild; }
|
|
|
|
/**
|
|
* Insert a child into the children list.
|
|
*
|
|
* The order of children in this list is absolutely undefined;
|
|
* don't rely on any implementation-specific order.
|
|
**/
|
|
virtual void insertChild( KFileInfo *newChild );
|
|
|
|
/**
|
|
* Get the "Dot Entry" for this node if there is one (or 0 otherwise):
|
|
* This is a pseudo entry that directory nodes use to store
|
|
* non-directory children separately from directories. This way the end
|
|
* user can easily tell which summary fields belong to the directory
|
|
* itself and which are the accumulated values of the entire subtree.
|
|
**/
|
|
virtual KFileInfo * dotEntry() const { return _dotEntry; }
|
|
|
|
/**
|
|
* Set a "Dot Entry". This makes sense for directories only.
|
|
**/
|
|
virtual void setDotEntry( KFileInfo *newDotEntry ) { _dotEntry = newDotEntry; }
|
|
|
|
/**
|
|
* Returns true if this is a "Dot Entry". See @ref dotEntry() for
|
|
* details.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual bool isDotEntry() const { return _isDotEntry; }
|
|
|
|
/**
|
|
* Notification that a child has been added somewhere in the subtree.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual void childAdded( KFileInfo *newChild );
|
|
|
|
/**
|
|
* Remove a child from the children list.
|
|
*
|
|
* IMPORTANT: This MUST be called just prior to deleting an object of
|
|
* this class. Regrettably, this cannot simply be moved to the
|
|
* destructor: Important parts of the object might already be destroyed
|
|
* (e.g., the virtual table - no more virtual methods).
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual void unlinkChild( KFileInfo *deletedChild );
|
|
|
|
/**
|
|
* Notification that a child is about to be deleted somewhere in the
|
|
* subtree.
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual void deletingChild( KFileInfo *deletedChild );
|
|
|
|
/**
|
|
* Notification of a new directory read job somewhere in the subtree.
|
|
**/
|
|
void readJobAdded();
|
|
|
|
/**
|
|
* Notification of a finished directory read job somewhere in the
|
|
* subtree.
|
|
**/
|
|
void readJobFinished();
|
|
|
|
/**
|
|
* Notification of an aborted directory read job somewhere in the
|
|
* subtree.
|
|
**/
|
|
void readJobAborted();
|
|
|
|
/**
|
|
* Finalize this directory level after reading it is completed.
|
|
* This does _not_ mean reading reading all subdirectories is completed
|
|
* as well!
|
|
*
|
|
* Clean up unneeded dot entries.
|
|
**/
|
|
virtual void finalizeLocal();
|
|
|
|
/**
|
|
* Get the current state of the directory reading process:
|
|
*
|
|
* KDirQueued waiting in the directory read queue
|
|
* KDirReading reading in progress
|
|
* KDirFinished reading finished and OK
|
|
* KDirAborted reading aborted upon user request
|
|
* KDirError error while reading
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual KDirReadState readState() const;
|
|
|
|
/**
|
|
* Set the state of the directory reading process.
|
|
* See @ref readState() for details.
|
|
**/
|
|
void setReadState( KDirReadState newReadState );
|
|
|
|
/**
|
|
* Returns true if this is a @ref KDirInfo object.
|
|
*
|
|
* Don't confuse this with @ref isDir() which tells whether or not this
|
|
* is a disk directory! Both should return the same, but you'll never
|
|
* know - better be safe than sorry!
|
|
*
|
|
* Reimplemented - inherited from @ref KFileInfo.
|
|
**/
|
|
virtual bool isDirInfo() const { return true; }
|
|
|
|
|
|
protected:
|
|
|
|
/**
|
|
* Recursively recalculate the summary fields when they are dirty.
|
|
*
|
|
* This is a _very_ expensive operation since the entire subtree may
|
|
* recursively be traversed.
|
|
**/
|
|
void recalc();
|
|
|
|
/**
|
|
* Clean up unneeded / undesired dot entries:
|
|
* Delete dot entries that don't have any children,
|
|
* reparent dot entry children to the "real" (parent) directory if
|
|
* there are not subdirectory siblings at the level of the dot entry.
|
|
**/
|
|
void cleanupDotEntries();
|
|
|
|
|
|
bool _isDotEntry; // Flag: is this entry a "dot entry"?
|
|
bool _isMountPoint; // Flag: is this a mount point?
|
|
int _pendingReadJobs; // number of open directories in this subtree
|
|
|
|
// Children management
|
|
|
|
KFileInfo * _firstChild; // pointer to the first child
|
|
KFileInfo * _dotEntry; // pseudo entry to hold non-dir children
|
|
|
|
// Some cached values
|
|
|
|
KFileSize _totalSize;
|
|
KFileSize _totalBlocks;
|
|
int _totalItems;
|
|
int _totalSubDirs;
|
|
int _totalFiles;
|
|
time_t _latestMtime;
|
|
|
|
bool _summaryDirty; // dirty flag for the cached values
|
|
bool _beingDestroyed;
|
|
KDirReadState _readState;
|
|
|
|
|
|
private:
|
|
|
|
void init();
|
|
|
|
}; // class KDirInfo
|
|
|
|
|
|
/**
|
|
* A directory read job that can be queued. This is mainly to prevent
|
|
* buffer thrashing because of too many directories opened at the same time
|
|
* because of simultaneous reads or even system resource consumption
|
|
* (directory handles in this case).
|
|
*
|
|
* Objects of this kind are transient by nature: They live only as long as
|
|
* the job is queued or executed. When it's done, the data is contained in
|
|
* the corresponding @ref KDirInfo subtree of the corresponding @ref
|
|
* KDirTree.
|
|
*
|
|
* For each entry automatically a @ref KFileInfo or @ref KDirInfo will be
|
|
* created and added to the parent @ref KDirInfo. For each directory a new
|
|
* @ref KDirReadJob will be created and added to the @ref KDirTree 's job
|
|
* queue.
|
|
*
|
|
* Notice: This class contains pure virtuals - you cannot use it
|
|
* directly. Derive your own class from it or use one of
|
|
* @ref KLocalDirReadJob or @ref KAnyDirReadJob.
|
|
*
|
|
* @short Abstract base class for directory reading.
|
|
**/
|
|
class KDirReadJob
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
**/
|
|
KDirReadJob( KDirTree *tree, KDirInfo *dir );
|
|
|
|
/**
|
|
* Destructor.
|
|
**/
|
|
virtual ~KDirReadJob();
|
|
|
|
/**
|
|
* Start reading the directory. Prior to this nothing happens.
|
|
*
|
|
* Please notice there is no corresponding abortReading() call:
|
|
* Simply delete the reader if the user requests to abort reading.
|
|
*
|
|
* Derived classes need to implement this method.
|
|
**/
|
|
virtual void startReading() = 0;
|
|
|
|
/**
|
|
* Returns the corresponding @ref KDirInfo item.
|
|
**/
|
|
virtual KDirInfo * dir() { return _dir; }
|
|
|
|
|
|
protected:
|
|
|
|
/**
|
|
* Notification that a new child has been added.
|
|
*
|
|
* Derived classes are required to call this whenever a new child is
|
|
* added so this notification can be passed up to the @ref KDirTree
|
|
* which in turn emits a corresponding signal.
|
|
**/
|
|
void childAdded( KFileInfo *newChild );
|
|
|
|
/**
|
|
* Notification that a child is about to be deleted.
|
|
*
|
|
* Derived classes are required to call this just before a child is
|
|
* deleted so this notification can be passed up to the @ref KDirTree
|
|
* which in turn emits a corresponding signal.
|
|
*
|
|
* Derived classes are not required to handle child deletion at all,
|
|
* but if they do, calling this method is required.
|
|
**/
|
|
void deletingChild( KFileInfo *deletedChild );
|
|
|
|
|
|
KDirTree * _tree;
|
|
KDirInfo * _dir;
|
|
};
|
|
|
|
|
|
/**
|
|
* Impementation of the abstract @ref KDirReadJob class that reads a local
|
|
* directory.
|
|
*
|
|
* This will use lstat() system calls rather than KDE's network transparent
|
|
* directory services since lstat() unlike the KDE services can obtain
|
|
* information about the device (i.e. file system) a file or directory
|
|
* resides on. This is important if you wish to limit directory scans to
|
|
* one file system - which is most desirable when that one file system runs
|
|
* out of space.
|
|
*
|
|
* @short Directory reader that reads one local directory.
|
|
**/
|
|
class KLocalDirReadJob: public KDirReadJob
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
**/
|
|
KLocalDirReadJob( KDirTree * tree, KDirInfo * dir );
|
|
|
|
/**
|
|
* Destructor.
|
|
**/
|
|
virtual ~KLocalDirReadJob();
|
|
|
|
/**
|
|
* Start reading the directory. Prior to this nothing happens.
|
|
*
|
|
* Inherited and reimplemented from @ref KDirReadJob.
|
|
**/
|
|
virtual void startReading();
|
|
|
|
/**
|
|
* Obtain information about the URL specified and create a new @ref
|
|
* KFileInfo or a @ref KDirInfo (whatever is appropriate) from that
|
|
* information. Use @ref KFileInfo::isDirInfo() to find out which.
|
|
* Returns 0 if such information cannot be obtained (i.e. the
|
|
* appropriate stat() call fails).
|
|
**/
|
|
static KFileInfo * stat( const KURL & url,
|
|
KDirTree * tree,
|
|
KDirInfo * parent = 0 );
|
|
|
|
protected:
|
|
DIR * _diskDir;
|
|
};
|
|
|
|
|
|
/**
|
|
* Generic impementation of the abstract @ref KDirReadJob class, using
|
|
* KDE's network transparent IO methods.
|
|
*
|
|
* This is much more generic than @ref KLocalDirReadJob since it supports
|
|
* protocols like 'ftp', 'http', 'smb', 'tar' etc., too. Its only drawback
|
|
* is that is cannot be prevented from crossing file system boundaries -
|
|
* which makes it pretty useless for figuring out the cause of a 'file
|
|
* system full' error.
|
|
*
|
|
* @short Generic directory reader that reads one directory, remote or local.
|
|
**/
|
|
class KAnyDirReadJob: public TQObject, public KDirReadJob
|
|
{
|
|
TQ_OBJECT
|
|
|
|
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
**/
|
|
KAnyDirReadJob( KDirTree * tree, KDirInfo * dir );
|
|
|
|
/**
|
|
* Destructor.
|
|
**/
|
|
virtual ~KAnyDirReadJob();
|
|
|
|
/**
|
|
* Start reading the directory. Prior to this nothing happens.
|
|
*
|
|
* Inherited and reimplemented from @ref KDirReadJob.
|
|
**/
|
|
virtual void startReading();
|
|
|
|
/**
|
|
* Obtain information about the URL specified and create a new @ref
|
|
* KFileInfo or a @ref KDirInfo (whatever is appropriate) from that
|
|
* information. Use @ref KFileInfo::isDirInfo() to find out which.
|
|
* Returns 0 if such information cannot be obtained (i.e. the
|
|
* appropriate stat() call fails).
|
|
**/
|
|
static KFileInfo * stat( const KURL & url,
|
|
KDirTree * tree,
|
|
KDirInfo * parent = 0 );
|
|
|
|
/**
|
|
* Obtain the owner of the URL specified.
|
|
*
|
|
* This is a moderately expensive operation since it involves a network
|
|
* transparent stat() call.
|
|
**/
|
|
static TQString owner( KURL url );
|
|
|
|
|
|
protected slots:
|
|
/**
|
|
* Receive directory entries from a TDEIO job.
|
|
**/
|
|
void entries( TDEIO::Job * job,
|
|
const TDEIO::UDSEntryList & entryList );
|
|
|
|
/**
|
|
* TDEIO job is finished.
|
|
**/
|
|
void finished( TDEIO::Job * job );
|
|
|
|
protected:
|
|
|
|
TDEIO::ListJob * _job;
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
* This class provides some infrastructure as well as global data for a
|
|
* directory tree. It acts as the glue that holds things together: The root
|
|
* item from which to descend into the subtree, the read queue and some
|
|
* global policies (like whether or not to cross file systems while reading
|
|
* directories).
|
|
*
|
|
* @short Directory tree global data and infrastructure
|
|
**/
|
|
class KDirTree: public TQObject
|
|
{
|
|
TQ_OBJECT
|
|
|
|
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* Remember to call @ref startReading() after the constructor and
|
|
* setting up connections.
|
|
**/
|
|
KDirTree();
|
|
|
|
/**
|
|
* Destructor.
|
|
**/
|
|
virtual ~KDirTree();
|
|
|
|
|
|
public slots:
|
|
|
|
/**
|
|
* Actually start reading.
|
|
*
|
|
* It's not very pretty this is required as an extra method, but this
|
|
* cannot simply be done in the constructor: We need to give the caller
|
|
* a chance to set up TQt signal connections, and for this the
|
|
* constructor must return before any signals are sent, i.e. before
|
|
* anything is read.
|
|
**/
|
|
void startReading( const KURL & url );
|
|
|
|
/**
|
|
* Forcefully stop a running read process.
|
|
**/
|
|
void abortReading();
|
|
|
|
/**
|
|
* Refresh a subtree, i.e. read its contents from disk again.
|
|
*
|
|
* The old subtree will be deleted and rebuilt from scratch, i.e. all
|
|
* pointers to elements within this subtree will become invalid (a
|
|
* @ref subtreeDeleted() signal will be emitted to notify about that
|
|
* fact).
|
|
*
|
|
* When 0 is passed, the entire tree will be refreshed, i.e. from the
|
|
* root element on.
|
|
**/
|
|
void refresh( KFileInfo *subtree = 0 );
|
|
|
|
/**
|
|
* Select some other item in this tree. Triggers the @ref
|
|
* selectionChanged() signal - even to the sender of this signal,
|
|
* i.e. take care not to cause endless signal ping-pong!
|
|
*
|
|
* Select nothing if '0' is passed.
|
|
**/
|
|
void selectItem( KFileInfo *newSelection );
|
|
|
|
/**
|
|
* Delete a subtree.
|
|
**/
|
|
void deleteSubtree( KFileInfo *subtree );
|
|
|
|
|
|
public:
|
|
|
|
/**
|
|
* Returns the root item of this tree.
|
|
*
|
|
* Currently, there can only be one single root item for each tree.
|
|
*/
|
|
KFileInfo * root() const { return _root; }
|
|
|
|
/**
|
|
* Locate a child somewhere in the tree whose URL (i.e. complete path)
|
|
* matches the URL passed. Returns 0 if there is no such child.
|
|
*
|
|
* Notice: This is a very expensive operation since the entire tree is
|
|
* searched recursively.
|
|
*
|
|
* 'findDotEntries' specifies if locating "dot entries" (".../<Files>")
|
|
* is desired.
|
|
*
|
|
* This is just a convenience method that maps to
|
|
* KDirTree::root()->locate( url, findDotEntries )
|
|
**/
|
|
KFileInfo * locate( TQString url, bool findDotEntries = false )
|
|
{ return _root ? _root->locate( url, findDotEntries ) : 0; }
|
|
|
|
/**
|
|
* Notification of a finished directory read job.
|
|
* All read jobs are required to call this upon (successful or
|
|
* unsuccessful) completion.
|
|
**/
|
|
void jobFinishedNotify( KDirReadJob *job );
|
|
|
|
/**
|
|
* Add a new directory read job to the queue.
|
|
**/
|
|
void addJob( KDirReadJob * job );
|
|
|
|
/**
|
|
* Obtain the directory read method for this tree:
|
|
* KDirReadLocal use opendir() and lstat()
|
|
* KDirReadKDirLister use KDE 2.x's KDirLister
|
|
**/
|
|
KDirReadMethod readMethod() const { return _readMethod; }
|
|
|
|
/**
|
|
* Should directory scans cross file systems?
|
|
*
|
|
* Notice: This can only be avoided with local directories where the
|
|
* device number a file resides on can be obtained.
|
|
* Remember, that's what this KDirStat business is all about. ;-)
|
|
**/
|
|
bool crossFileSystems() const { return _crossFileSystems; }
|
|
|
|
/**
|
|
* Set or unset the "cross file systems" flag.
|
|
**/
|
|
void setCrossFileSystems( bool doCross ) { _crossFileSystems = doCross; }
|
|
|
|
/**
|
|
* Return the tree's current selection.
|
|
*
|
|
* Even though the KDirTree by itself doesn't have a visual
|
|
* representation, it supports the concept of one single selected
|
|
* item. Views can use this to transparently keep track of this single
|
|
* selected item, notifying the KDirTree and thus other views with @ref
|
|
* KDirTree::selectItem() . Attached views should connect to the @ref
|
|
* selectionChanged() signal to be notified when the selection changes.
|
|
*
|
|
* NOTE: This method returns 0 if nothing is selected.
|
|
**/
|
|
KFileInfo * selection() const { return _selection; }
|
|
|
|
/**
|
|
* Notification that a child has been added.
|
|
*
|
|
* Directory read jobs are required to call this for each child added
|
|
* so the tree can emit the corresponding @ref childAdded() signal.
|
|
**/
|
|
virtual void childAddedNotify( KFileInfo *newChild );
|
|
|
|
/**
|
|
* Notification that a child is about to be deleted.
|
|
*
|
|
* Directory read jobs are required to call this for each deleted child
|
|
* so the tree can emit the corresponding @ref deletingChild() signal.
|
|
**/
|
|
virtual void deletingChildNotify( KFileInfo *deletedChild );
|
|
|
|
/**
|
|
* Notification that one or more children have been deleted.
|
|
*
|
|
* Directory read jobs are required to call this when one or more
|
|
* children are deleted so the tree can emit the corresponding @ref
|
|
* deletingChild() signal. For multiple deletions (e.g. entire
|
|
* subtrees) this should only happen once at the end.
|
|
**/
|
|
virtual void childDeletedNotify();
|
|
|
|
/**
|
|
* Send a @ref progressInfo() signal to keep the user entertained while
|
|
* directories are being read.
|
|
**/
|
|
void sendProgressInfo( const TQString &infoLine );
|
|
|
|
/**
|
|
* Send a @ref finalizeLocal() signal to give views a chance to
|
|
* finalize the display of this directory level - e.g. clean up dot
|
|
* entries, set the final "expandable" state etc.
|
|
**/
|
|
void sendFinalizeLocal( KDirInfo *dir );
|
|
|
|
/**
|
|
* Returns 'true' if this tree uses the 'file:/' protocol (regardless
|
|
* of local or network transparent directory reader).
|
|
**/
|
|
bool isFileProtocol() { return _isFileProtocol; }
|
|
|
|
/**
|
|
* Returns 'true' if directory reading is in progress in this tree.
|
|
**/
|
|
bool isBusy() { return _isBusy; }
|
|
|
|
|
|
signals:
|
|
|
|
/**
|
|
* Emitted when a child has been added.
|
|
**/
|
|
void childAdded( KFileInfo *newChild );
|
|
|
|
/**
|
|
* Emitted when a child is about to be deleted.
|
|
**/
|
|
void deletingChild( KFileInfo *deletedChild );
|
|
|
|
/**
|
|
* Emitted after a child is deleted. If you are interested which child
|
|
* it was, better use the @ref deletingChild() signal.
|
|
* @ref childDeleted() is only useful to rebuild a view etc. completely.
|
|
* If possible, this signal is sent only once for multiple deletions -
|
|
* e.g., when entire subtrees are deleted.
|
|
**/
|
|
void childDeleted();
|
|
|
|
/**
|
|
* Emitted when reading is started.
|
|
**/
|
|
void startingReading();
|
|
|
|
/**
|
|
* Emitted when reading this directory tree is finished.
|
|
**/
|
|
void finished();
|
|
|
|
/**
|
|
* Emitted when reading this directory tree has been aborted.
|
|
**/
|
|
void aborted();
|
|
|
|
/**
|
|
* Emitted when reading a directory is finished.
|
|
* This does _not_ mean reading all subdirectories is finished, too -
|
|
* only this directory level is complete!
|
|
*
|
|
* WARNING: 'dir' may be 0 if the the tree's root could not be read.
|
|
*
|
|
* Use this signal to do similar cleanups like
|
|
* @ref KDirInfo::finalizeLocal(), e.g. cleaning up unused / undesired
|
|
* dot entries like in @ref KDirInfo::cleanupDotEntries().
|
|
**/
|
|
void finalizeLocal( KDirInfo *dir );
|
|
|
|
/**
|
|
* Emitted when the current selection has changed, i.e. whenever some
|
|
* attached view triggers the @ref selectItem() slot or when the
|
|
* current selection is deleted.
|
|
*
|
|
* NOTE: 'newSelection' may be 0 if nothing is selected.
|
|
**/
|
|
void selectionChanged( KFileInfo *newSelection );
|
|
|
|
/**
|
|
* Single line progress information, emitted when the read status
|
|
* changes - typically when a new directory is being read. Connect to a
|
|
* status bar etc. to keep the user entertained.
|
|
**/
|
|
void progressInfo( const TQString &infoLine );
|
|
|
|
|
|
protected slots:
|
|
|
|
/**
|
|
* Time-sliced work procedure to be performed while the application is
|
|
* in the main loop: Read some directory entries, but relinquish
|
|
* control back to the application so it can maintain some
|
|
* responsiveness. This method uses single-shot timers of minimal
|
|
* duration to activate itself as soon as there are no more user events
|
|
* to process. Call this only once directly after inserting a read job
|
|
* into the job queue.
|
|
**/
|
|
void timeSlicedRead();
|
|
|
|
/**
|
|
* Read some parameters from the global @ref TDEConfig object.
|
|
**/
|
|
void readConfig();
|
|
|
|
|
|
protected:
|
|
|
|
KFileInfo * _root;
|
|
KFileInfo * _selection;
|
|
TQPtrQueue<KDirReadJob> _jobQueue;
|
|
KDirReadMethod _readMethod;
|
|
bool _crossFileSystems;
|
|
bool _enableLocalDirReader;
|
|
bool _isFileProtocol;
|
|
bool _isBusy;
|
|
};
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// Static Functions
|
|
//----------------------------------------------------------------------
|
|
|
|
/**
|
|
* Make a valid, fixed and cleaned URL from a (possibly dirty) URL or maybe
|
|
* a path.
|
|
**/
|
|
KURL fixedUrl( const TQString & dirtyUrl );
|
|
|
|
|
|
/**
|
|
* Format a file / subtree size human readable, i.e. in "GB" / "MB"
|
|
* etc. rather than huge numbers of digits.
|
|
*
|
|
* Note: For kdDebug() etc., operator<< is overwritten to do exactly that:
|
|
*
|
|
* kdDebug() << "Size: " << x->totalSize() << endl;
|
|
**/
|
|
TQString formatSize ( KFileSize lSize );
|
|
|
|
|
|
/**
|
|
* Print the debugUrl() of a @ref KFileInfo in a debug stream.
|
|
**/
|
|
inline kdbgstream & operator<< ( kdbgstream & stream, const KFileInfo * info )
|
|
{
|
|
if ( info )
|
|
stream << info->debugUrl();
|
|
else
|
|
stream << "<NULL>";
|
|
|
|
return stream;
|
|
}
|
|
|
|
|
|
/**
|
|
* Human-readable output of a file size in a debug stream.
|
|
**/
|
|
inline kdbgstream & operator<< ( kdbgstream & stream, KFileSize lSize )
|
|
{
|
|
stream << formatSize( lSize );
|
|
|
|
return stream;
|
|
}
|
|
|
|
} // namespace KDirStat
|
|
|
|
|
|
#endif // ifndef KDirTree_h
|
|
|
|
|
|
// EOF
|