2 * KTreeView class interface
4 * Copyright (C) 1997 Johannes Sixt
6 * based on KTreeList, which is
7 * Copyright (C) 1996 Keith Brown and KtSoft
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details. You should have received a copy
18 * of the GNU General Public License along with this program; if not, write
19 * to the Free Software Foundation, Inc, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
23 #ifndef KDE_KTREE_VIEW_H
24 #define KDE_KTREE_VIEW_H
26 #include <qpixmap.h> /* used in items */
28 #include <q3gridview.h> /* base class for widget */
30 #include <QMouseEvent>
31 #include <QFocusEvent>
34 // use stack of strings to represent path information
35 typedef QStack
<QString
*> KPath
;
37 class KTreeView
; /* forward declaration */
39 /** Items for the KTreeView widget */
42 friend class KTreeView
;
45 * Item constructor. While text defaults to a null string, and the
46 * item can be constructed this way, the text has to be non-null when
47 * the item is added to the tree, or it will not be inserted.
49 * The constructor sets the delete-children flag to false. This flag
50 * tells the item whether it shall delete the child items when it is
51 * itself deleted. By default the creator of the item is responsible to
52 * also delete the child items. (However, the versions of
53 * KTreeView::appendChildItem and KTreeView::insertChildItem that do
54 * not take a KTreeViewItem set the delete-children flag to true.)
56 KTreeViewItem(const QString
& theText
= QString()); // text can not be null when added to the list!
57 KTreeViewItem(const QString
& theText
, const QPixmap
& thePixmap
);
60 * Destructor. It destroys its children if this item has been marked
61 * with setDeleteChildren(true).
63 virtual ~KTreeViewItem();
66 * Appends a new (direct) child item at the end. It does not update
67 * administrative data in newChild except for its parent (which is this
70 void appendChild(KTreeViewItem
* newChild
);
73 * Returns a pointer to the child item at the given index in this
74 * item's sub tree, or 0 if not found.
76 KTreeViewItem
* childAt(int index
) const;
79 * Returns the number of child items in this item's sub tree.
81 uint
childCount() const;
84 * Returns the index in this items sub tree of the given item or -1 if
85 * not found. The specified child must not be 0.
87 int childIndex(KTreeViewItem
* child
) const;
90 * Determines whether the specified point is inside the expand button.
92 bool expandButtonClicked(const QPoint
& coord
) const;
95 * Give the item a chance to process the mouse event.
97 virtual bool mousePressEvent( const QPoint
& coord
);
100 * Returns a pointer to the first child item in this item's sub tree, or
103 KTreeViewItem
* getChild() const;
106 * Returns a pointer to the parent of this item, or 0 if none.
108 KTreeViewItem
* getParent() const;
111 * Returns a reference to this item's pixmap. If there is no pixmap
112 * associated with this item, it will return a reference to a valid,
115 const QPixmap
& getPixmap() const;
118 * Returns a pointer to the next item in the same branch below this
121 KTreeViewItem
* getSibling() const;
124 * Returns this item's text.
126 const QString
& getText() const;
129 * Indicates whether this item has any children.
131 bool hasChild() const;
134 * Indicates whether this item has a parent.
136 bool hasParent() const;
139 * Indicates whether this item has a sibling item, that is, an item
140 * that would be displayed below it at the same level as this item.
142 bool hasSibling() const;
145 * Inserts the a new (direct) child in this item before the child at
146 * the specified index (first child is index 0). If there is no child
147 * at the specified index, the item is appended. It does not update
148 * administrative data in newChild except for its parent (which is this
151 void insertChild(int index
, KTreeViewItem
* newChild
);
154 * Indicateds whether the item is expanded, that is, whether the child
155 * items (if any) would be visible if this item were visible.
157 * Note: If this function returns true, it does not necessarily indicate that
158 * this item is visible or that this item has any children.
160 bool isExpanded() const;
163 * Returns true if the item is visible. An item is visible if all its
164 * ancestors are expanded.
166 bool isVisible() const;
169 * Removes the specified (direct) child from this item and returns
170 * true. If it is not a direct child of this item, nothing happens, and
171 * false is returned. This function does not update the owning
174 bool removeChild(KTreeViewItem
* child
);
177 * Sets the delayed-expanding flag. If this flag is true, the expanding
178 * signal is emitted when the item is about to be expanded. The expand
179 * button is always painted for this item, even if it doesn't have
182 void setDelayedExpanding(bool flag
);
185 * Tells the item whether it should delete its children when it is
186 * deleted. The default is false, which means that the child items must
187 * be deleted explicitly.
189 void setDeleteChildren(bool flag
);
191 void setDrawExpandButton(bool doit
);
193 void setDrawText(bool doit
);
195 void setDrawTree(bool doit
);
197 void setExpanded(bool is
);
200 * Sets the item pixmap to the given pixmap. It does not redraw the
201 * item or update the owning KTreeView.
203 void setPixmap(const QPixmap
& pm
);
206 * Sets the item text. This function does not redraw the item or update
207 * the owning KTreeView.
209 void setText(const QString
& t
);
213 * Returns the bounding rectangle of the item.
215 virtual QRect
boundingRect(int indent
) const;
218 * Returns the hieght of the item. The default implementation uses font
219 * metrics of the owning KTreeView widget.
221 virtual int height() const;
224 * Returns the height of the item depending on the passed-in font
227 virtual int height(const QFontMetrics
& fm
) const;
230 * Paints the item: pixmap, text, expand button, parent branches
232 virtual void paint(QPainter
* p
, int indent
,
233 const QColorGroup
& cg
, bool highlighted
) const;
236 * paints the expand button
238 virtual void paintExpandButton(QPainter
* p
, int indent
, int cellHeight
) const;
241 * paints the highlighted text
243 virtual void paintHighlight(QPainter
* p
, int indent
,
244 const QColorGroup
& cg
, bool hasFocus
,
245 Qt::GUIStyle style
) const;
248 * paints the item's text
250 virtual void paintText(QPainter
* p
, int indent
, int cellHeight
,
251 const QColorGroup
& cg
, bool highlighted
) const;
254 * paints the item's tree part.
256 virtual void paintTree(QPainter
* p
, int indent
, int cellHeight
) const;
259 * Internal function that counts the number of child items.
261 void synchNumChildren();
264 * Returns the bounding rectangle of the text.
266 virtual QRect
textBoundingRect(int indent
) const;
269 * Returns the width of the item taking into account the specified
270 * indentation. The default implementation uses font metrics of the
271 * owning KTreeView widget.
273 virtual int width(int indent
) const;
276 * Returns the width of the item depending on the passed-in font
277 * metrics and taking into account the specified indentation.
279 virtual int width(int indent
, const QFontMetrics
& fm
) const;
282 /** The KTreeView that this item belongs to */
287 bool delayedExpanding
;
290 mutable QRect expandButton
; /* is set in paint() */
291 KTreeViewItem
* child
;
292 KTreeViewItem
* parent
;
293 KTreeViewItem
* sibling
;
299 // easier declarations of function prototypes for forEvery type functions
300 typedef bool (KTreeView::*KForEveryM
)
301 (KTreeViewItem
*, void *);
302 typedef bool (*KForEvery
)
303 (KTreeViewItem
*, void *);
306 A collapsible treelist widget.
314 ================================================================================
316 KTreeView is a class inherited from QTableView in the Qt user interface
317 library. It provides a way to display hierarchical data in a single-inheritance
318 tree, similar to tree controls in Microsoft Windows and other GUI's. It is most
319 suitable for directory trees or outlines, but I'm sure other uses will come to
320 mind. Frankly, it was designed mostly with the above two functions in mind, but
321 I have tried to make it as flexible as I know how to make it easy to adapt to
324 In case of problems, I encourage you to read all of the other documentation
325 files in this package before contacting me as you may find the answer to your
326 question in one of them. Also read the source code if you have time. I have
327 tried to comment it adequately and make the source understandable.
330 ================================================================================
332 * Displays both text and optional pixmap supplied by the programmer. A support
333 class, KTreeViewItem, can be inherited and modified to draw items as needed
336 * The list items can be returned by index or logical path and the tree
337 navigated by parent, child or sibling references contained in them. Also,
338 item information such as text, pixmap, branch level can be obtained.
340 * Items can be inserted, changed and removed either by index in the visible
341 structure, or by logical paths through the tree hierarchy.
343 * The logical path through the tree for any item can be obtained with the index
346 * Tree structure display and expanding/collapsing of sub-trees is handled with
347 no intervention from the programmer.
349 * entire tree can be expanded or collapsed to a specified sub-level (handy for
352 * Configuration as follows:
354 enable/disable item text display (if you only want to display pixmaps)
356 enable/disable drawing of expand/collapse button
358 enable/disable drawing of tree structure
360 * Keyboard support as follows:
362 up/down arrows move the highlight appropriately and scroll the list an item at
365 pgup/pgdn move the highlight a 'page' up or down as applicable and scroll the
368 +/- keys expand/collapse the highlighted item if it appropriate
370 enter key selects the highlighted item
372 * Mouse support as follows:
374 left click on item highlights it
376 left click on an item "hot button" expands or collapses its sub-tree, as
379 double click on item selects it
381 normal scrolling functions in conjunction with scrollbars if present
383 2nd scrolling with the middle mouse button: pressing MMB inserts a
384 rubberband, showing which part of the whole tree is currently visible.
385 moving the mouse will scroll the visible part
389 signal void highlighted(int) - emitted when an item in the tree is
390 highlighted; sends the index of the item
392 signal void selected(int) - emitted when an item in the tree is
393 selected; sends the index of the item
395 signal void expanded(int) - emitted when an item in the tree is expanded;
396 sends the index of the item
398 signal void collpased(int) - emitted when an item in the tree is collapsed;
399 sends the index of the item
401 class KTreeView
: public Q3GridView
403 friend class KTreeViewItem
;
407 * Widget contructor. Passes all parameters on to base QTableView, and
408 * does not use them directly. Does internal initialization, sets the
409 * current item to -1, and sets default values for scroll bars (both
412 KTreeView(QWidget
* parent
= 0, const char* name
= 0, Qt::WFlags f
= 0);
415 * Desctructor. Deletes all items from the topmost level that have been
416 * marked with setDeleteChildren(true).
418 virtual ~KTreeView();
421 * Appends a new child item to the item at the specified row. If that
422 * item already has children, the new item is appended below these
423 * children. A KTreeViewItem is created for which the delete-children
424 * flag is set to true.
426 void appendChildItem(const QString
& theText
, const QPixmap
& thePixmap
,
430 * Same as above except that the parent item is specified by a path.
432 void appendChildItem(const QString
& theText
, const QPixmap
& thePixmap
,
433 const KPath
& thePath
);
436 * Appendss the specified item as a child of the item that is at the
437 * specified row. If that item already has children, the new item is
438 * appended below these children.
440 void appendChildItem(KTreeViewItem
* newItem
, int index
);
443 * Same as above except that the parent item is specified by a path.
445 void appendChildItem(KTreeViewItem
* newItem
, const KPath
& thePath
);
448 Returns a bool value indicating whether the list will display a
449 horizontal scrollbar if one of the displayed items is wider than can
450 be displayed at the current width of the view.
452 bool autoBottomScrollBar() const;
455 Returns a bool value indicating whether the list will display a
456 vertical scrollbar if the number of displayed items is more than can
457 be displayed at the current height of the view.
459 bool autoScrollBar() const;
462 Returns a bool value indicating whether the list will update
463 immediately on changing the state of the widget in some way.
465 bool autoUpdate() const;
468 Returns a bool value indicating whether the list has currently has a
469 horizontal scroll bar.
471 bool bottomScrollBar() const;
474 Changes the text and/or pixmap of the given item at the specified
475 index to the given values and updates the display if auto update
476 enabled. If changing only the text or pixmap, set the other parameter
479 void changeItem(const QString
& newText
,
480 const QPixmap
*newPixmap
,
484 Same as above function, except item to change is specified by a path
487 void changeItem(const QString
& newText
,
488 const QPixmap
*newPixmap
,
489 const KPath
& thePath
);
492 Removes all items from the tree.
498 Returns the total number of items in the tree, whether visible
499 (expanded sub-trees) or not (collapsed).
504 Returns the index of the current (highlighted) item. If no current
507 int currentItem() const;
510 Collapses the sub-tree at the specified index.
512 void collapseItem(int index
);
515 Expands the sub-tree at the specified index.
517 void expandItem(int index
);
520 Returns the depth to which all parent items are automatically
523 int expandLevel() const;
526 Same as above functions combined into one. If sub-tree is expanded,
527 collapses it, if it is collapsed, it expands it.
529 void expandOrCollapseItem(int index
);
532 * Iterates every item in the tree, visible or not, and applies the
533 * function func with a pointer to each item and user data supplied as
534 * parameters. The children of the specified root item are visited
535 * (root itself is not visited!). If root is 0 all items in the tree
536 * are visited. KForEveryFunc is defined as:
538 * typedef bool (*KForEvery)(KTreeViewItem*, void*);
540 * That is, a function that returns bool and takes a pointer to a
541 * KTreeViewItem and pointer to void as parameters. The traversal ends
542 * earlier if the supplied function returns bool. In this case the
543 * return value is also true.
545 bool forEveryItem(KForEvery func
, void* user
,
546 KTreeViewItem
* root
= 0);
549 * Same as above, but only iterates visible items, in order. If the
550 * specified root item is invisible no items are visited.
552 bool forEveryVisibleItem(KForEvery func
, void *user
,
553 KTreeViewItem
* root
= 0);
556 Returns a pointer to the current item if there is one, or 0.
558 KTreeViewItem
*getCurrentItem();
561 * Returns the number of pixels an item is indented for each level. If,
562 * in a derived class, the levels are indented differently this value
568 * Inserts an item into the tree with the given text and pixmap either
569 * before or after the item currently at the given row, depending on
570 * the value of prefix. The new item is added to the same branch as the
571 * referenced item. If row is -1, the item is simply appended to the
572 * tree at the topmost level. A KTreeViewItem is created for which the
573 * delete-children flag is set to true. Returns true if the item has
574 * been successfully inserted in the tree, otherwise false.
576 bool insertItem(const QString
& theText
, const QPixmap
& thePixmap
,
577 int row
= -1, bool prefix
= true);
580 * Same as above, but uses a path through the tree to reference the
581 * insert position. If there is no item at the specified path, the item
582 * is simply appended to the tree at the topmost level.
584 bool insertItem(const QString
& theText
, const QPixmap
& thePixmap
,
585 const KPath
& thePath
, bool prefix
= true);
588 * Same as above, but an item is specified instead of a text and a pixmap.
590 bool insertItem(KTreeViewItem
*newItem
,
591 int row
= -1, bool prefix
= true);
594 * Same as above, but uses a path through the tree to reference the
597 bool insertItem(KTreeViewItem
*newItem
,
598 const KPath
& thePath
, bool prefix
= true);
601 * Returns a pointer to the item in the specified row, or 0 if the
602 * specified row is outside the limits. This is a cheap operation.
604 KTreeViewItem
* itemAt(int row
);
607 * Returns a pointer to the item at the end of the path.
609 KTreeViewItem
* itemAt(const KPath
& path
);
612 * Returns the row at which the specified item is found in the visible
613 * tree or -1 if the item is not visible or not in the tree.
615 int itemRow(KTreeViewItem
* item
);
618 * Fills path with the logical path to the item at the specified row.
619 * The specified path variable should be empty. Any strings popped from
620 * the path must be deleted by the caller. If the row is invalid, path
621 * remains unchanged (i.e. empty).
623 void itemPath(int row
, KPath
& path
);
626 * Outdents the item at the given row one level so that it becomes a
627 * sibling of its parent.
629 void join(int index
);
632 * Same as above but uses a path to specify the item.
634 void join(const KPath
& path
);
637 * Moves the item at the specified row down one row in its current
640 void lowerItem(int index
);
643 * Same as above but uses a path to specify the item.
645 void lowerItem(const KPath
& path
);
648 * Moves the item at the specified row up one row in its current
651 void raiseItem(int row
);
654 * Same as above but uses a path to specify the item.
656 void raiseItem(const KPath
& path
);
659 * Removes the item at the specified row.
661 void removeItem(int row
);
664 * Same as above except uses path through the tree to find the item.
666 void removeItem(const KPath
& thePath
);
669 Returns bool value indicating whether the list currently displays a
672 bool scrollBar() const;
675 If enable is TRUE (default), enables auto update, else disables it.
677 void setAutoUpdate(bool enable
);
680 If enable is TRUE, displays a horizontal scroll bar, else hides it.
682 void setBottomScrollBar(bool enable
);
685 * Makes the item at row current and highlights it. The signal
686 * highlighted is emitted if the current item changes.
688 void setCurrentItem(int row
);
690 void setExpandButtonDrawing(bool enable
);
692 void setExpandLevel(int level
);
695 * Sets the indentation stepping, in pixels. If, in a derived class,
696 * the levels are indented differently this value may be ignored.
698 void setIndentSpacing(int spacing
);
701 If enable is TRUE, displays a vertical scroll bar, else hides it.
703 void setScrollBar(bool enable
);
706 If enable is TRUE (default), item text will be displayed, otherwise
707 it will not, and no highlight will be shown in the default widget.
709 void setShowItemText(bool enable
);
712 If enable is TRUE, enables smooth scrolling, else disables
715 void setSmoothScrolling(bool enable
);
718 If enable is TRUE (default), lines depicting the structure of the
719 tree will be drawn, otherwise they will not.
721 void setTreeDrawing(bool enable
);
724 Indicates whether item text is displayed.
726 bool showItemText() const;
729 Returns a bool value indicating whether smooth scrolling is enabled.
731 bool smoothScrolling() const;
734 * Indents the item at the specified index, creating a new branch.
736 void split(int index
);
739 * Same as above but uses a path to specify the item.
741 void split(const KPath
& path
);
744 * Removes the item at the given index from the tree, but does not
745 * delete it, returning a pointer to the removed item.
747 KTreeViewItem
* takeItem(int index
);
750 * Same as above but uses a path to specify the item to take.
752 KTreeViewItem
* takeItem(const KPath
& path
);
755 Indicates whether the tree structure is drawn.
757 bool treeDrawing() const;
760 * This function is deprecated. Use numRows() instead.
761 * Returns the number of items that are visible (their parents are
764 int visibleCount() const { return numRows(); }
767 void collapsed(int index
);
768 void expanded(int index
);
770 * The expanding signal is emitted when an item that has the
771 * delayedExpanding flag set is about to be expanded. The
772 * delayedExpanding flag is not reset; the slot that the signal is
773 * connected to should do so. The item being expanded is passed to the
774 * slot. The slot gets the opportunity to insert child items into that
775 * item. It should not change the item any other way. It can allow or
776 * disallow the expansion by setting the second parameter allow. If it
777 * is set to false, the item is not expanded.
779 * The signal is always emitted, regardless whether the expansion was
780 * triggered by the user or by the program.
782 void expanding(KTreeViewItem
* item
, bool& allow
);
783 void highlighted(int index
);
784 void selected(int index
);
786 void popupMenu( int index
, const QPoint
& );
789 * Appends theChild to theParent as a new direct child. All internal
790 * state is updated and the widget is repainted as necessary. theChild
791 * remains invisible if any ancestor of theParent is collapsed.
793 void appendChildItem(KTreeViewItem
* theParent
,
794 KTreeViewItem
* theChild
);
795 void changeItem(KTreeViewItem
* toChange
,
796 int itemRow
, const QString
& newText
,
797 const QPixmap
* newPixmap
);
799 * Collapses the specified subtree and updates the display. subRoot
800 * need not be visible.
802 void collapseSubTree(KTreeViewItem
* subRoot
);
803 /** Internal function used for counting items */
804 bool countItem(KTreeViewItem
* item
, void* total
);
806 void expandOrCollapse(KTreeViewItem
*parentItem
);
808 * Expands the specified subtree and updates the display. subRoot need
811 void expandSubTree(KTreeViewItem
* subRoot
);
812 void fixChildren(KTreeViewItem
*parentItem
);
813 virtual void focusInEvent(QFocusEvent
*e
);
814 void forEveryItem(KForEveryM func
,
816 void forEveryVisibleItem(KForEveryM func
,
819 /** internal function used to determine maximum item width */
820 bool getMaxItemWidth(KTreeViewItem
* item
, void *user
);
823 * Returns the indentation of the specified item in pixels.
825 virtual int indentation(KTreeViewItem
* item
) const;
828 * Inserts the specified newItem before or after the specified
829 * referenceItem. If referenceItem is 0, the newItem is appended at the
830 * topmost level. If referenceItem is not 0, it must be an item that is
831 * already in the KTreeView. Internal data is updated and the display
832 * is refreshed as necessary. The inserted item may still be invisible
833 * if any of the parents is collapsed. newItem must not be 0.
835 bool insertItem(KTreeViewItem
* referenceItem
, KTreeViewItem
* newItem
,
839 * Finds the logical path of the specified item. The specified path
840 * variable should be empty.
842 void itemPath(KTreeViewItem
* item
, KPath
& path
) const;
844 void join(KTreeViewItem
*item
);
845 virtual void keyPressEvent(QKeyEvent
*e
);
846 int level(KTreeViewItem
* item
) const;
847 void lowerItem(KTreeViewItem
*item
);
848 virtual void mouseDoubleClickEvent(QMouseEvent
*e
);
849 virtual void mouseMoveEvent(QMouseEvent
*e
);
850 virtual void mousePressEvent(QMouseEvent
*e
);
851 virtual void mouseReleaseEvent(QMouseEvent
*e
);
852 virtual void paintCell(QPainter
*p
, int row
, int col
);
854 * virtual void paintItem(QPainter *p, KTreeViewItem *item,
857 void raiseItem(KTreeViewItem
* item
);
860 * Internal function that finds the item at the given path. Returns 0
861 * if the item cannot be found. The path is destroyed by this function.
863 KTreeViewItem
* recursiveFind(KPath
& path
);
865 bool setItemExpanded(KTreeViewItem
*item
, void *);
866 bool setItemExpandButtonDrawing(KTreeViewItem
*item
, void *);
867 bool setItemShowText(KTreeViewItem
*item
, void *);
868 bool setItemTreeDrawing(KTreeViewItem
*item
, void *);
869 void split(KTreeViewItem
*item
);
871 void takeItem(KTreeViewItem
*item
);
873 virtual void updateCellWidth();
874 virtual void updateVisibleItems();
875 void updateVisibleItemRec(KTreeViewItem
* parent
, int& count
, int& width
);
877 KTreeViewItem
* treeRoot
;
880 bool drawExpandButton
;
887 // list of visible items
888 int itemCapacity
; /* for how many items we've space allocated */
889 KTreeViewItem
** visibleItems
;
891 // Rainer Bawidamann: move window in "rubberband" mode
892 bool rubberband_mode
; // true if in "rubberband_mode"
893 QPoint rubber_startMouse
; // where the user pressed the MMB
894 int rubber_height
, rubber_width
, // the size if the rubberband rect
895 rubber_startX
, rubber_startY
; // the x/yOffset() when the MMB was pressed
896 void draw_rubberband();
897 void start_rubberband(const QPoint
& where
);
898 void end_rubberband();
899 void move_rubberband(const QPoint
& where
);
902 #endif // KDE_KTREE_VIEW_H