diff options
Diffstat (limited to 'src/app/DiskUsage/filelightParts')
-rw-r--r-- | src/app/DiskUsage/filelightParts/Config.cpp | 50 | ||||
-rw-r--r-- | src/app/DiskUsage/filelightParts/Config.h | 37 | ||||
-rw-r--r-- | src/app/DiskUsage/filelightParts/Makefile.am | 9 | ||||
-rw-r--r-- | src/app/DiskUsage/filelightParts/debug.h | 14 | ||||
-rw-r--r-- | src/app/DiskUsage/filelightParts/fileTree.cpp | 78 | ||||
-rw-r--r-- | src/app/DiskUsage/filelightParts/fileTree.h | 299 |
6 files changed, 487 insertions, 0 deletions
diff --git a/src/app/DiskUsage/filelightParts/Config.cpp b/src/app/DiskUsage/filelightParts/Config.cpp new file mode 100644 index 0000000..bf25a29 --- /dev/null +++ b/src/app/DiskUsage/filelightParts/Config.cpp @@ -0,0 +1,50 @@ + +#include "Config.h" +#include <tdeconfig.h> +#include <tdeglobal.h> + + +bool Config::varyLabelFontSizes = true; +bool Config::showSmallFiles = false; +uint Config::contrast = 50; +uint Config::antiAliasFactor = 2; +uint Config::minFontPitch = 10; +uint Config::defaultRingDepth = 4; +Filelight::MapScheme Config::scheme; + + +inline TDEConfig& +Filelight::Config::tdeconfig() +{ + TDEConfig *config = TDEGlobal::config(); + config->setGroup( "DiskUsage" ); + return *config; +} + +void +Filelight::Config::read() +{ + const TDEConfig &config = tdeconfig(); + + varyLabelFontSizes = config.readBoolEntry( "varyLabelFontSizes", true ); + showSmallFiles = config.readBoolEntry( "showSmallFiles", false ); + contrast = config.readNumEntry( "contrast", 50 ); + antiAliasFactor = config.readNumEntry( "antiAliasFactor", 2 ); + minFontPitch = config.readNumEntry( "minFontPitch", TQFont().pointSize() - 3); + scheme = (MapScheme) config.readNumEntry( "scheme", 0 ); + + defaultRingDepth = 4; +} + +void +Filelight::Config::write() +{ + TDEConfig &config = tdeconfig(); + + config.writeEntry( "varyLabelFontSizes", varyLabelFontSizes ); + config.writeEntry( "showSmallFiles", showSmallFiles); + config.writeEntry( "contrast", contrast ); + config.writeEntry( "antiAliasFactor", antiAliasFactor ); + config.writeEntry( "minFontPitch", minFontPitch ); + config.writeEntry( "scheme", scheme ); +} diff --git a/src/app/DiskUsage/filelightParts/Config.h b/src/app/DiskUsage/filelightParts/Config.h new file mode 100644 index 0000000..52a98b7 --- /dev/null +++ b/src/app/DiskUsage/filelightParts/Config.h @@ -0,0 +1,37 @@ + +#ifndef Config_H +#define Config_H + +#include <tqstringlist.h> + +class TDEConfig; + + +namespace Filelight +{ + enum MapScheme { Rainbow, HighContrast, KDE, FileDensity, ModTime }; + + class Config + { + static TDEConfig& tdeconfig(); + + public: + static void read(); + static void write(); + + //keep everything positive, avoid using DON'T, NOT or NO + + static bool varyLabelFontSizes; + static bool showSmallFiles; + static uint contrast; + static uint antiAliasFactor; + static uint minFontPitch; + static uint defaultRingDepth; + + static MapScheme scheme; + }; +} + +using Filelight::Config; + +#endif diff --git a/src/app/DiskUsage/filelightParts/Makefile.am b/src/app/DiskUsage/filelightParts/Makefile.am new file mode 100644 index 0000000..002f461 --- /dev/null +++ b/src/app/DiskUsage/filelightParts/Makefile.am @@ -0,0 +1,9 @@ +noinst_LIBRARIES = libfilelightparts.a + +INCLUDES = $(all_includes) + +METASOURCES = AUTO + +libfilelightparts_a_SOURCES = \ + Config.cpp \ + fileTree.cpp diff --git a/src/app/DiskUsage/filelightParts/debug.h b/src/app/DiskUsage/filelightParts/debug.h new file mode 100644 index 0000000..252a001 --- /dev/null +++ b/src/app/DiskUsage/filelightParts/debug.h @@ -0,0 +1,14 @@ +//Author: Max Howell <max.howell@methylblue.com>, (C) 2003-4 +//Copyright: See COPYING file that comes with this distribution + +#ifndef DEBUG_H +#define DEBUG_H + +#include <kdebug.h> + +#define debug kdDebug +#define error kdError +#define fatal kdFatal +#define warning kdWarning + +#endif diff --git a/src/app/DiskUsage/filelightParts/fileTree.cpp b/src/app/DiskUsage/filelightParts/fileTree.cpp new file mode 100644 index 0000000..0afd4d4 --- /dev/null +++ b/src/app/DiskUsage/filelightParts/fileTree.cpp @@ -0,0 +1,78 @@ +//Author: Max Howell <max.howell@methylblue.com>, (C) 2004 +//Copyright: See COPYING file that comes with this distribution + +#include "fileTree.h" +#include <tdeglobal.h> +#include <tdelocale.h> +#include <tqstring.h> + +//static definitions +const FileSize File::DENOMINATOR[4] = { 1ull, 1ull<<10, 1ull<<20, 1ull<<30 }; +const char File::PREFIX[5][2] = { "", "K", "M", "G", "T" }; + +TQString +File::fullPath( const Directory *root /*= 0*/ ) const +{ + TQString path; + + if( root == this ) root = 0; //prevent returning empty string when there is something we could return + + const File *d; + + for( d = this; d != root && d && d->parent() != 0; d = d->parent() ) + { + if( !path.isEmpty() ) + path = "/" + path; + + path = d->name() + path; + } + + if( d ) + { + while( d->parent() ) + d = d->parent(); + + if( d->directory().endsWith( "/" ) ) + return d->directory() + path; + else + return d->directory() + "/" + path; + } + else + return path; +} + +TQString +File::humanReadableSize( UnitPrefix key /*= mega*/ ) const //FIXME inline +{ + return humanReadableSize( m_size, key ); +} + +TQString +File::humanReadableSize( FileSize size, UnitPrefix key /*= mega*/ ) //static +{ + TQString s; + double prettySize = (double)size / (double)DENOMINATOR[key]; + const TDELocale &locale = *TDEGlobal::locale(); + + if( prettySize >= 0.01 ) + { + if( prettySize < 1 ) s = locale.formatNumber( prettySize, 2 ); + else if( prettySize < 100 ) s = locale.formatNumber( prettySize, 1 ); + else s = locale.formatNumber( prettySize, 0 ); + + s += ' '; + s += PREFIX[key]; + s += 'B'; + } + + if( prettySize < 0.1 ) + { + s += " ("; + s += locale.formatNumber( size / DENOMINATOR[ key ? key - 1 : 0 ], 0 ); + s += ' '; + s += PREFIX[key]; + s += "B)"; + } + + return s; +} diff --git a/src/app/DiskUsage/filelightParts/fileTree.h b/src/app/DiskUsage/filelightParts/fileTree.h new file mode 100644 index 0000000..2ba79ae --- /dev/null +++ b/src/app/DiskUsage/filelightParts/fileTree.h @@ -0,0 +1,299 @@ +//Author: Max Howell <max.howell@methylblue.com>, (C) 2004 +//Copyright: See COPYING file that comes with this distribution + +#ifndef FILETREE_H +#define FILETREE_H + +#include <stdlib.h> +#include <sys/types.h> +#include <tdeio/global.h> + +//TODO these are pointlessly general purpose now, make them incredibly specific + + + +typedef TDEIO::filesize_t FileSize; + +template <class T> class Iterator; +template <class T> class ConstIterator; +template <class T> class Chain; + +template <class T> +class Link +{ +public: + Link( T* const t ) : prev( this ), next( this ), data( t ) {} + Link() : prev( this ), next( this ), data( 0 ) {} + + //TODO unlinking is slow and you don't use it very much in this context. + // ** Perhaps you can make a faster deletion system that doesn't bother tidying up first + // ** and then you MUST call some kind of detach() function when you remove elements otherwise + ~Link() { delete data; unlink(); } + + friend class Iterator<T>; + friend class ConstIterator<T>; + friend class Chain<T>; + +private: + void unlink() { prev->next = next; next->prev = prev; prev = next = this; } + + Link<T>* prev; + Link<T>* next; + + T* data; //ensure only iterators have access to this +}; + + +template <class T> +class Iterator +{ +public: + Iterator() : link( 0 ) { } //**** remove this, remove this REMOVE THIS!!! dangerous as your implementation doesn't test for null links, always assumes they can be derefenced + Iterator( Link<T> *p ) : link( p ) { } + + bool operator==( const Iterator<T>& it ) const { return link == it.link; } + bool operator!=( const Iterator<T>& it ) const { return link != it.link; } + bool operator!=( const Link<T> *p ) const { return p != link; } + + //here we have a choice, really I should make two classes one const the other not + const T* operator*() const { return link->data; } + T* operator*() { return link->data; } + + Iterator<T>& operator++() { link = link->next; return *this; } //**** does it waste time returning in places where we don't use the retval? + + bool isNull() const { return (link == 0); } //REMOVE WITH ABOVE REMOVAL you don't want null iterators to be possible + + void transferTo( Chain<T> &chain ) + { + chain.append( remove() ); + } + + T* const remove() //remove from list, delete Link, data is returned NOT deleted + { + T* const d = link->data; + Link<T>* const p = link->prev; + + link->data = 0; + delete link; + link = p; //make iterator point to previous element, YOU must check this points to an element + + return d; + } + +private: + Link<T> *link; +}; + + +template <class T> +class ConstIterator +{ +public: + ConstIterator( Link<T> *p ) : link( p ) { } + + bool operator==( const Iterator<T>& it ) const { return link == it.link; } + bool operator!=( const Iterator<T>& it ) const { return link != it.link; } + bool operator!=( const Link<T> *p ) const { return p != link; } + + const T* operator*() const { return link->data; } + + ConstIterator<T>& operator++() { link = link->next; return *this; } + +private: + const Link<T> *link; +}; + +//**** try to make a generic list class and then a brief full list template that inlines +// thus reducing code bloat +template <class T> +class Chain +{ +public: + Chain() { } + virtual ~Chain() { empty(); } + + void append( T* const data ) + { + Link<T>* const link = new Link<T>( data ); + + link->prev = head.prev; + link->next = &head; + + head.prev->next = link; + head.prev = link; + } + + void transferTo( Chain &c ) + { + if( isEmpty() ) return; + + Link<T>* const first = head.next; + Link<T>* const last = head.prev; + + head.unlink(); + + first->prev = c.head.prev; + c.head.prev->next = first; + + last->next = &c.head; + c.head.prev = last; + } + + void empty() { while( head.next != &head ) { delete head.next; } } + + Iterator<T> iterator() const { return Iterator<T>( head.next ); } + ConstIterator<T> constIterator() const { return ConstIterator<T>( head.next ); } + const Link<T> *end() const { return &head; } + bool isEmpty() const { return ( head.next == &head ); } + +private: + Link<T> head; + void operator=( const Chain& ) {} +}; + + +class Directory; +class TQString; +class KURL; + +class File +{ +protected: + Directory *m_parent; //0 if this is treeRoot + TQString m_name; //< file name + TQString m_directory;//< the directory of the file + FileSize m_size; //< size with subdirectories + FileSize m_ownSize; //< size without subdirectories + mode_t m_mode; //< file mode + TQString m_owner; //< file owner name + TQString m_group; //< file group name + TQString m_perm; //< file permissions string + time_t m_time; //< file modification in time_t format + bool m_symLink; //< true if the file is a symlink + TQString m_mimeType; //< file mimetype + bool m_excluded; //< flag if the file is excluded from du + int m_percent; //< percent flag + +public: + File( Directory *parentIn, const TQString &nameIn, const TQString &dir, FileSize sizeIn, mode_t modeIn, + const TQString &ownerIn, const TQString &groupIn, const TQString &permIn, time_t timeIn, bool symLinkIn, + const TQString &mimeTypeIn ) + : m_parent( parentIn ), m_name( nameIn ), m_directory( dir ), m_size( sizeIn ), m_ownSize( sizeIn ), m_mode( modeIn ), + m_owner( ownerIn ), m_group( groupIn ), m_perm( permIn ), m_time( timeIn ), m_symLink( symLinkIn ), + m_mimeType( mimeTypeIn ), m_excluded( false ), m_percent( -1 ) {} + + File( const TQString &nameIn, FileSize sizeIn ) + : m_parent( 0 ), m_name( nameIn ), m_directory( TQString() ), m_size( sizeIn ), m_ownSize( sizeIn ), m_mode( 0 ), + m_owner( TQString() ), m_group( TQString() ), m_perm( TQString() ), m_time( -1 ), + m_symLink( false ), m_mimeType( TQString() ), m_excluded( false ), m_percent( -1 ) + { + } + + virtual ~File() {} + + inline const TQString & name() const {return m_name;} + inline const TQString & directory() const {return m_directory;} + inline const FileSize size() const {return m_excluded ? 0 : m_size;} + inline const FileSize ownSize() const {return m_excluded ? 0 : m_ownSize;} + inline const mode_t mode() const {return m_mode;} + inline const TQString & owner() const {return m_owner;} + inline const TQString & group() const {return m_group;} + inline const TQString & perm() const {return m_perm;} + inline const time_t time() const {return m_time;} + inline const TQString & mime() const {return m_mimeType;} + inline const bool isSymLink() const {return m_symLink;} + virtual const bool isDir() const {return false;} + inline const bool isExcluded() const {return m_excluded;} + inline void exclude( bool flag ) {m_excluded = flag;} + inline const int intPercent() const {return m_percent;} + inline const TQString percent() const {if( m_percent < 0 ) + return "INV"; + TQString buf; + buf.sprintf( "%d.%02d%%", m_percent / 100, m_percent % 100 ); + return buf;} + inline void setPercent( int p ) {m_percent = p;} + inline const Directory* parent() const {return m_parent;} + + inline void setSizes( TDEIO::filesize_t totalSize, TDEIO::filesize_t ownSize ) + { + m_ownSize = ownSize; + m_size = totalSize; + } + + enum UnitPrefix { kilo, mega, giga, tera }; + + static const FileSize DENOMINATOR[4]; + static const char PREFIX[5][2]; + + TQString fullPath( const Directory* = 0 ) const; + TQString humanReadableSize( UnitPrefix key = mega ) const; + + static TQString humanReadableSize( FileSize size, UnitPrefix Key = mega ); + + friend class Directory; +}; + + +//TODO when you modify this to take into account hardlinks you should make the Chain layered not inherited +class Directory : public Chain<File>, public File +{ +public: + Directory( Directory *parentIn, const TQString &nameIn, const TQString &dir, FileSize sizeIn, mode_t modeIn, + const TQString &ownerIn, const TQString &groupIn, const TQString &permIn, time_t timeIn, bool symLinkIn, + const TQString &mimeTypeIn ) + : File( parentIn, nameIn, dir, sizeIn, modeIn, ownerIn, groupIn, permIn, timeIn, symLinkIn, mimeTypeIn ), + m_fileCount( 0 ) + {} + + Directory( const TQString &name, TQString url ) : File( name, 0 ), m_fileCount( 0 ) + { + m_directory = url; + } + + virtual ~Directory() {} + virtual const bool isDir() const {return true;} + + void append( File *p ) + { + ++m_fileCount; + + Directory *parent = m_parent; + while( parent ) + { + parent->m_fileCount++; + parent = parent->m_parent; + } + + Chain<File>::append( p ); + p->m_parent = this; + } + + void remove( File *p ) + { + for( Iterator<File> it = Chain<File>::iterator(); it != Chain<File>::end(); ++it ) + if( (*it) == p ) + { + --m_fileCount; + + Directory *parent = m_parent; + while( parent ) + { + parent->m_fileCount--; + parent = parent->m_parent; + } + + it.remove(); + break; + } + } + + uint fileCount() const { return m_fileCount; } + +private: + Directory( const Directory& ); + void operator=( const Directory& ); + + uint m_fileCount; +}; + +#endif |