/* * File name: kdirtreeview.h * Summary: High level classes for KDirStat * License: LGPL - See file COPYING.LIB for details. * Author: Stefan Hundhammer * * Updated: 2003-08-26 */ #ifndef KDirTreeView_h #define KDirTreeView_h // Alternative parent class for KDirTreeView. // // If you change this, don't forget to change the KDirTreeView class // declaration also. Unfortunately there this 'define' can't be used - // it seems to confuse the 'moc' preprocessor. #define USE_KLISTVIEW 0 #define DEBUG_COUNTERS 10 #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "kdirtree.h" // Forward declarations class TQWidget; class TQTimer; class TQPopupMenu; class KPacManAnimation; // 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 { #define KDirTreeViewMaxFillColor 16 #if USE_KLISTVIEW # define KDirTreeViewParentClass TDEListView #else # define KDirTreeViewParentClass TQListView #endif class KDirTreeViewItem; class KDirTreeView: public TQListView // Using // class KDirTreeView: public KDirTreeViewParentClass // or some other 'ifdef' ... construct seems to confuse "moc". { TQ_OBJECT public: /** * Default constructor. **/ KDirTreeView( TQWidget * parent = 0 ); /** * Destructor. **/ virtual ~KDirTreeView(); /** * Locate the counterpart to an original tree item "wanted" somewhere * within this view tree. Returns 0 on failure. * If "lazy" is set, only the open part of the tree is searched. * "doClone" specifies whether or not to (deferred) clone nodes that * are not cloned yet. This is only used if "lazy" is false. **/ KDirTreeViewItem * locate( KFileInfo * wanted, bool lazy = true, bool doClone = true ); /** * Get the first child of this view or 0 if there is none. * Use the child's next() method to get the next child. * Reimplemented from @ref TQListView. **/ KDirTreeViewItem * firstChild() const { return (KDirTreeViewItem *) KDirTreeViewParentClass::firstChild(); } /** * Return the currently selected item or 0, if none is selected. **/ KDirTreeViewItem * selection() const { return _selection; } /** * Returns the default level until which items are opened by default * (unless they are dot entries). **/ int openLevel() const { return _openLevel; } /** * Returns true if the view tree is to be cloned lazily, i.e. only * those view tree branches that are really visible are synced with the * original tree. **/ bool doLazyClone() const { return _doLazyClone; } /** * Enable / disable PacMan animation in this tree view during directory * reading. This is disabled by default since it eats quite some * performance. **/ void enablePacManAnimation( bool enable ) { _doPacManAnimation = enable; } /** * Returns true if the PacMan animation is to be used during directory * reading. **/ bool doPacManAnimation() const { return _doPacManAnimation; } /** * Returns the number of open items in the entire tree. **/ int openCount(); /** * Return the percentage bar fill color for the specified directory * level (0..MaxInt). Wraps around every usedFillColors() colors. **/ const TQColor & fillColor( int level ) const; /** * Very much like @ref fillColor(), but doesn't wrap around at @ref * usedFillColors(), but at KDirTreeViewMaxFillColor. **/ const TQColor & rawFillColor( int level ) const; /** * Set the fill color of percentage bars of the specified directory * level (0..KDirTreeViewMaxFillColor-1). * * Calling repaint() after setting all desired colors is the * caller's responsibility. **/ void setFillColor( int level, const TQColor &color ); /** * Set all tree colors to default values. **/ void setDefaultFillColors(); /** * Set the number of used percentage bar fill colors * (1..KDirTreeViewMaxFillColor). **/ void setUsedFillColors( int usedFillColors ); /** * Returns the number of used percentage bar fill colors. **/ int usedFillColors() const { return _usedFillColors; } /** * Set the tree background color. * * Calling repaint() after setting all desired colors is the * caller's responsibility. **/ void setTreeBackground( const TQColor &color ); /** * Returns the tree background color. **/ const TQColor & treeBackground() const { return _treeBackground; } /** * Returns the background color for percentage bars. **/ const TQColor & percentageBarBackground() const { return _percentageBarBackground; } /** * (Try to) ensure good contrast between the tree background and the * percentage bars' 3D edges - prevent ugly 3D effects which will * inevitably be the case for a white background (which unfortunately * is very common): The percentage bars use white and black for 3D * borders - like any other widget. But other widgets normally can * assume their parent widget uses some more neutral color so white and * black will result in at least some minimal contrast. * * This function automagically sets a reasonable default background * color for the tree display: If the current color scheme's document * background color (as used for input fields, lists etc.) is white or * black, use the palette midlight color (the same color as "normal" * widgets like push buttons etc., but brighter). For all other colors * than white, the document background color (the palette base color) * is used. **/ void ensureContrast(); /** * Set the sort column. * * Reimplemented from TQListView so we can keep track of the sort column. **/ virtual void setSorting( int column, bool increasing = TRUE ); /** * Returns the internal @ref KDirTree this view works on. * Handle with caution: This might be short-lived information. * The view might choose to create a new tree shortly after returning * this, so don't store this pointer internally. **/ KDirTree *tree() { return _tree; } int nameCol() const { return _nameCol; } int iconCol() const { return _iconCol; } int percentBarCol() const { return _percentBarCol; } int percentNumCol() const { return _percentNumCol; } int totalSizeCol() const { return _totalSizeCol; } int workingStatusCol() const { return _workingStatusCol; } int ownSizeCol() const { return _ownSizeCol; } int totalItemsCol() const { return _totalItemsCol; } int totalFilesCol() const { return _totalFilesCol; } int totalSubDirsCol() const { return _totalSubDirsCol; } int latestMtimeCol() const { return _latestMtimeCol; } int readJobsCol() const { return _readJobsCol; } int sortCol() const { return _sortCol; } TQPixmap openDirIcon() const { return _openDirIcon; } TQPixmap closedDirIcon() const { return _closedDirIcon; } TQPixmap openDotEntryIcon() const { return _openDotEntryIcon; } TQPixmap closedDotEntryIcon() const { return _closedDotEntryIcon; } TQPixmap unreadableDirIcon() const { return _unreadableDirIcon; } TQPixmap mountPointIcon() const { return _mountPointIcon; } TQPixmap fileIcon() const { return _fileIcon; } TQPixmap symLinkIcon() const { return _symLinkIcon; } TQPixmap blockDevIcon() const { return _blockDevIcon; } TQPixmap charDevIcon() const { return _charDevIcon; } TQPixmap fifoIcon() const { return _fifoIcon; } TQPixmap stopIcon() const { return _stopIcon; } TQPixmap workingIcon() const { return _workingIcon; } TQPixmap readyIcon() const { return _readyIcon; } /** * Set function name of debug function #i **/ void setDebugFunc( int i, const TQString & functionName ); /** * Increase debug counter #i **/ void incDebugCount( int i ); public slots: /** * Open a directory URL. Assume "file:" protocol unless otherwise specified. **/ void openURL( KURL url ); /** * Refresh (i.e. re-read from disk) the entire tree. **/ void refreshAll(); /** * Refresh (i.e. re-read from disk) the selected subtree. **/ void refreshSelected(); /** * Forcefully stop a running read process. **/ void abortReading(); /** * Clear this view's contents. **/ void clear(); /** * Select a (TQListViewItem) item. Triggers selectionChanged() signals. **/ void selectItem( TQListViewItem *item ); /** * Select an item. Triggers selectionChanged() signals. * Overloaded for convenience. **/ void selectItem( KDirTreeViewItem *item ) { selectItem( (TQListViewItem *) item ); } /** * Select a KDirTree item. Used for connecting the @ref * KDirTree::selectionChanged() signal. **/ void selectItem( KFileInfo *item ); /** * Clear the current selection. Triggers selectionChanged() signals. **/ void clearSelection(); /** * Close all tree branches except the one specified. **/ void closeAllExcept( KDirTreeViewItem *except ); /** * Send a standardized mail to the owner of the selected branch. * The user will get a mailer window where he can edit that mail all he * likes before deciding to send or discard it. * * The mail includes all currently open branches from the selected * branch on. **/ void sendMailToOwner(); /** * Notification of a change in the KDE palette, i.e. the user selected * and applied different colors in the KDE control center. **/ void paletteChanged(); /** * Read configuration and initialize variables accordingly. * Will be called automatically in the constructor. **/ void readConfig(); /** * Save configuraton. **/ void saveConfig() const; /** * Emit a @ref userActivity() signal worth 'points' activity points. **/ void logActivity( int points ); /** * Returns the minimum recommended size for this widget. * Reimplemented from TQWidget. **/ virtual TQSize minimumSizeHint() const { return TQSize( 0, 0 ); } protected slots: /** * Add a child as a clone of original tree item "newChild" to this view * tree. **/ void addChild ( KFileInfo *newChild ); /** * Delete a cloned child. **/ void deleteChild ( KFileInfo *newChild ); /** * Recursively update the visual representation of the summary fields. * This update is as lazy as possible for optimum performance since it * is called very frequently as a cyclic update. **/ void updateSummary(); /** * Signal end of all read jobs, finalize display and terminate pending * cyclic visual update. **/ void slotFinished(); /** * Signal abortion of all read jobs, finalize display and terminate pending * cyclic visual update. **/ void slotAborted(); /** * Signal end of one read job at this level and finalize display of * this level. **/ void finalizeLocal( KDirInfo *dir ); /** * Display progress information in the status bar. Automatically adds * the elapsed time of a directory scan. **/ void sendProgressInfo( const TQString & currentDir = "" ); /** * Set up everything prior to reading: Cyclic update timer, display * busy state, default sorting, stopwatch. **/ void prepareReading(); /** * Change the tree display to "busy" state, i.e. add a column to * display the number of pending read jobs for each level. **/ void busyDisplay(); /** * Change the tree display back to "idle" state, i.e. remove columns * that are useful only while directories are being read, like the * pending read jobs column. **/ void idleDisplay(); /** * Pop up context menu (i.e. emit the contextMenu() signal) or open a * small info popup with exact information, depending on 'column'. **/ void popupContextMenu ( TQListViewItem * listViewItem, const TQPoint & pos, int column ); /** * Pop up info window with exact byte size. **/ void popupContextSizeInfo ( const TQPoint & pos, KFileSize size ); /** * Pop up info window with arbitrary one-line text. **/ void popupContextInfo ( const TQPoint & pos, const TQString & info ); protected slots: /** * Notification that a column has just been resized, thus may need * repaining. **/ void columnResized( int column, int oldSize, int newSize ); signals: /** * 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 busy. **/ void progressInfo( const TQString &infoLine ); /** * Emitted when reading is started. **/ void startingReading(); /** * Emitted when reading this tree is finished. **/ void finished(); /** * Emitted when reading this tree has been aborted. **/ void aborted(); /** * Emitted when the currently selected item changes. * Caution: 'item' may be 0 when the selection is cleared. **/ void selectionChanged( KDirTreeViewItem *item ); /** * Emitted when the currently selected item changes. * Caution: 'item' may be 0 when the selection is cleared. **/ void selectionChanged( KFileInfo *item ); /** * Emitted when a context menu for this item should be opened. * (usually on right click). 'pos' contains the click's mouse * coordinates. * * NOTE: * * This is _not_ the same as @ref TQListView::rightButtonClicked(): * The context menu may not open on a right click on every column, * usually only in the nameCol(). **/ void contextMenu( KDirTreeViewItem *item, const TQPoint &pos ); /** * Emitted at user activity. Some interactive actions are assigned an * amount of "activity points" that can be used to judge whether or not * the user is actually using this program or if it's just idly sitting * around on the desktop. This is intended for use together with a @ref * KActivityTracker. **/ void userActivity( int points ); protected: KDirTree * _tree; TQTimer * _updateTimer; TQTime _stopWatch; TQString _currentDir; KDirTreeViewItem * _selection; TQPopupMenu * _contextInfo; int _idContextInfo; int _openLevel; bool _doLazyClone; bool _doPacManAnimation; int _updateInterval; // millisec int _usedFillColors; TQColor _fillColor [ KDirTreeViewMaxFillColor ]; TQColor _treeBackground; TQColor _percentageBarBackground; // The various columns in which to display information int _nameCol; int _iconCol; int _percentNumCol; int _percentBarCol; int _totalSizeCol; int _workingStatusCol; int _ownSizeCol; int _totalItemsCol; int _totalFilesCol; int _totalSubDirsCol; int _latestMtimeCol; int _readJobsCol; int _sortCol; int _debugCount[ DEBUG_COUNTERS ]; TQString _debugFunc [ DEBUG_COUNTERS ]; // The various icons TQPixmap _openDirIcon; TQPixmap _closedDirIcon; TQPixmap _openDotEntryIcon; TQPixmap _closedDotEntryIcon; TQPixmap _unreadableDirIcon; TQPixmap _mountPointIcon; TQPixmap _fileIcon; TQPixmap _symLinkIcon; TQPixmap _blockDevIcon; TQPixmap _charDevIcon; TQPixmap _fifoIcon; TQPixmap _stopIcon; TQPixmap _workingIcon; TQPixmap _readyIcon; }; class KDirTreeViewItem: public TQListViewItem { public: /** * Constructor for the root item. **/ KDirTreeViewItem ( KDirTreeView * view, KFileInfo * orig ); /** * Constructor for all other items. **/ KDirTreeViewItem ( KDirTreeView * view, KDirTreeViewItem * parent, KFileInfo * orig ); /** * Destructor. **/ virtual ~KDirTreeViewItem(); /** * Locate the counterpart to an original tree item "wanted" somewhere * within this view tree. Returns 0 on failure. * * When "lazy" is set, only the open part of the tree is searched. * "doClone" specifies whether or not to (deferred) clone nodes that * are not cloned yet. This is only used if "lazy" is false. * "Level" is just a hint for the current tree level for better * performance. It will be calculated automatically if omitted. **/ KDirTreeViewItem * locate( KFileInfo * wanted, bool lazy = true, bool doClone = true, int level = -1 ); /** * Recursively update the visual representation of the summary fields. * This update is as lazy as possible for optimum performance. **/ void updateSummary(); /** * Bring (the top level of) this branch of the view tree in sync with * the original tree. Does _not_ recurse into subdirectories - only * this level of this branch is processed. Called when lazy tree * cloning is in effect and this branch is about to be opened. **/ void deferredClone(); /** * Finalize this level - clean up unneeded / undesired dot entries. **/ void finalizeLocal(); /** * Returns the corresponding view. **/ KDirTreeView * view() { return _view; } /** * Returns the parent view item or 0 if this is the root. **/ KDirTreeViewItem * parent() { return _parent; } /** * Returns the corresponding original item of the "real" (vs. view) * tree where all the important information resides. **/ KFileInfo * orig() { return _orig; } /** * Returns the first child of this item or 0 if there is none. * Use the child's next() method to get the next child. * Reimplemented from @ref TQListViewItem. **/ KDirTreeViewItem * firstChild() const { return (KDirTreeViewItem *) TQListViewItem::firstChild(); } /** * Returns the next sibling of this item or 0 if there is none. * (Kind of) reimplemented from @ref TQListViewItem. **/ KDirTreeViewItem * next() const { return (KDirTreeViewItem *) TQListViewItem::nextSibling(); } /** * Comparison function used for sorting the list. * * Using this function is much more efficient than overwriting * TQListViewItem::key() which operates on TQStrings. * * Returns: * -1 if this < other * 0 if this == other * +1 if this > other * * Reimplemented from TQListViewItem **/ virtual int compare( TQListViewItem * other, int col, bool ascending ) const; /** * Perform any necessary pending updates when a branch is opened. * Reimplemented from @ref TQListViewItem. **/ virtual void setOpen( bool open ); /** * Notification that a branch in this subtree has been opened or close * somewhere. Don't call this if the state hasn't really changed! **/ void openNotify( bool open ); /** * Recursively open this subtree and all its ancestors up to the root. **/ void openSubtree(); /** * Recursively close all tree branches from here on downwards. **/ void closeSubtree(); /** * Close all tree branches except this one from the root on. **/ void closeAllExceptThis(); /** * Returns the number of open items in this subtree. **/ int openCount() const { return _openCount; } /** * Recursively return an ASCII representation of all open items from * here on. **/ TQString asciiDump(); protected: /** * Set the appropriate icon depending on this item's type and open / * closed state. **/ void setIcon(); /** * Remove dot entry if it doesn't have any children. * Reparent all of the dot entry's children if there are no * subdirectories on this level. **/ void cleanupDotEntries(); /** * Find this entry's dot entry (clone). * * This doesn't create one if deferred cloning is in effect (which is * not a drawback since cloning directory nodes create a dot entry * clone along with the directory clone). * * Returns 0 if there is no dot entry clone. **/ KDirTreeViewItem * findDotEntry() const; /** * Paint method. Reimplemented from @ref TQListViewItem so different * colors can be used - and of course for painting percentage bars. * * Reimplemented from @ref TQListViewItem. **/ virtual void paintCell ( TQPainter * painter, const TQColorGroup & colorGroup, int column, int width, int alignment ); /** * Paint a percentage bar into a @ref TQListViewItem cell. * 'width' is the width of the entire cell. * 'indent' is the number of pixels to indent the bar. **/ void paintPercentageBar ( float percent, TQPainter * painter, int indent, int width, const TQColor & fillColor, const TQColor & barBackground ); /** * Generic comparison function. **/ template inline int compare( T a, T b ) const { if ( a < b ) return -1; if ( a > b ) return 1; return 0; } private: /** * Initializations common to all constructors. **/ void init ( KDirTreeView * view, KDirTreeViewItem * parent, KFileInfo * orig ); protected: // Data members KDirTreeView * _view; KDirTreeViewItem * _parent; KFileInfo * _orig; KPacManAnimation * _pacMan; float _percent; int _openCount; }; inline kdbgstream & operator<< ( kdbgstream & stream, KDirTreeViewItem * item ) { if ( item ) { if ( item->orig() ) { stream << item->orig()->debugUrl(); } else { stream << " " << endl; } } else stream << ""; return stream; } //---------------------------------------------------------------------- // Static Functions //---------------------------------------------------------------------- /** * Format a file size with all digits, yet human readable using the current * locale's thousand separator, i.e. 12,345,678 rather than 12345678 **/ TQString formatSizeLong( KFileSize size ); /** * Format a file size for use within a TQListView::key() function: * Right-justify and fill with leading zeroes. **/ TQString hexKey( KFileSize size ); /** * Format a millisecond granularity time human readable. * Milliseconds will only be inluded if 'showMilliSeconds' is true. **/ TQString formatTime ( long millisec, bool showMilliSeconds = false ); /** * Format counters of any kind. * * Returns an empty string if 'suppressZero' is 'true' and the value of * 'count' is 0. **/ TQString formatCount( int count, bool suppressZero = false ); /** * Format percentages. **/ TQString formatPercent( float percent ); /** * Format time and date human-readable as "yyyy-mm-dd hh:mm:ss" * - unlike that ctime() crap that is really useless. * See the source for more about why this format. **/ TQString formatTimeDate( time_t rawTime ); /** * Format time and date according to the current locale for those who * really must have that brain-dead ctime() format. **/ TQString localeTimeDate( time_t rawTime ); /** * Return a color that contrasts to 'contrastColor'. **/ TQColor contrastingColor ( const TQColor &desiredColor, const TQColor &contrastColor ); } // namespace KDirStat #endif // ifndef KDirTreeView_h // EOF