summaryrefslogtreecommitdiffstats
path: root/konq-plugins/fsview/treemap.h
diff options
context:
space:
mode:
Diffstat (limited to 'konq-plugins/fsview/treemap.h')
-rw-r--r--konq-plugins/fsview/treemap.h742
1 files changed, 742 insertions, 0 deletions
diff --git a/konq-plugins/fsview/treemap.h b/konq-plugins/fsview/treemap.h
new file mode 100644
index 0000000..a834d23
--- /dev/null
+++ b/konq-plugins/fsview/treemap.h
@@ -0,0 +1,742 @@
+/* This file is part of KCachegrind.
+ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
+
+ KCachegrind is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation, version 2.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * A Widget for visualizing hierarchical metrics as areas.
+ * The API is similar to QListView.
+ *
+ * This file defines the following classes:
+ * DrawParams, RectDrawing, TreeMapItem, TreeMapWidget
+ *
+ * DrawParams/RectDrawing allows reusing of TreeMap drawing
+ * functions in other widgets.
+ */
+
+#ifndef TREEMAP_H
+#define TREEMAP_H
+
+#include <qstring.h>
+#include <qwidget.h>
+#include <qpixmap.h>
+#include <qptrlist.h>
+#include <qvaluevector.h>
+#include <qcolor.h>
+#include <qapplication.h>
+#include <qstringlist.h>
+
+class QPopupMenu;
+class TreeMapTip;
+class TreeMapWidget;
+class TreeMapItem;
+class TreeMapItemList;
+class QString;
+
+class KConfigGroup;
+
+
+/**
+ * Drawing parameters for an object.
+ * A Helper Interface for RectDrawing.
+ */
+class DrawParams
+{
+public:
+ /**
+ * Positions for drawing into a rectangle.
+ *
+ * The specified position assumes no rotation.
+ * If there is more than one text for one position, it is put
+ * nearer to the center of the item.
+ *
+ * Drawing at top positions cuts free space from top,
+ * drawing at bottom positions cuts from bottom.
+ * Default usually gives positions clockwise according to field number.
+ */
+ enum Position { TopLeft, TopCenter, TopRight,
+ BottomLeft, BottomCenter, BottomRight,
+ Default, Unknown};
+
+ // no constructor as this is an abstract class
+ virtual ~DrawParams() {}
+
+ virtual QString text(int) const = 0;
+ virtual QPixmap pixmap(int) const = 0;
+ virtual Position position(int) const = 0;
+ // 0: no limit, negative: leave at least -maxLines() free
+ virtual int maxLines(int) const { return 0; }
+ virtual int fieldCount() const { return 0; }
+
+ virtual QColor backColor() const { return Qt::white; }
+ virtual const QFont& font() const = 0;
+
+ virtual bool selected() const { return false; }
+ virtual bool current() const { return false; }
+ virtual bool shaded() const { return true; }
+ virtual bool rotated() const { return false; }
+};
+
+
+/*
+ * DrawParam with attributes stored
+ */
+class StoredDrawParams: public DrawParams
+{
+public:
+ StoredDrawParams();
+ StoredDrawParams(QColor c,
+ bool selected = false, bool current = false);
+
+ // getters
+ QString text(int) const;
+ QPixmap pixmap(int) const;
+ Position position(int) const;
+ int maxLines(int) const;
+ int fieldCount() const { return _field.size(); }
+
+ QColor backColor() const { return _backColor; }
+ bool selected() const { return _selected; }
+ bool current() const { return _current; }
+ bool shaded() const { return _shaded; }
+ bool rotated() const { return _rotated; }
+
+ const QFont& font() const;
+
+ // attribute setters
+ void setField(int f, const QString& t, QPixmap pm = QPixmap(),
+ Position p = Default, int maxLines = 0);
+ void setText(int f, const QString&);
+ void setPixmap(int f, const QPixmap&);
+ void setPosition(int f, Position);
+ void setMaxLines(int f, int);
+ void setBackColor(const QColor& c) { _backColor = c; }
+ void setSelected(bool b) { _selected = b; }
+ void setCurrent(bool b) { _current = b; }
+ void setShaded(bool b) { _shaded = b; }
+ void setRotated(bool b) { _rotated = b; }
+
+protected:
+ QColor _backColor;
+ bool _selected, _current, _shaded, _rotated;
+
+private:
+ // resize field array if needed to allow to access field <f>
+ void ensureField(int f);
+
+ struct Field {
+ QString text;
+ QPixmap pix;
+ Position pos;
+ int maxLines;
+ };
+
+ QValueVector<Field> _field;
+};
+
+
+/* State for drawing on a rectangle.
+ *
+ * Following drawing functions are provided:
+ * - background drawing with shading and 3D frame
+ * - successive pixmap/text drawing at various positions with wrap-around
+ * optimized for minimal space usage (e.g. if a text is drawn at top right
+ * after text on top left, the same line is used if space allows)
+ *
+ */
+class RectDrawing
+{
+public:
+ RectDrawing(QRect);
+ ~RectDrawing();
+
+ // The default DrawParams object used.
+ DrawParams* drawParams();
+ // we take control over the given object (i.e. delete at destruction)
+ void setDrawParams(DrawParams*);
+
+ // draw on a given QPainter, use this class as info provider per default
+ void drawBack(QPainter*, DrawParams* dp = 0);
+ /* Draw field at position() from pixmap()/text() with maxLines().
+ * Returns true if something was drawn
+ */
+ bool drawField(QPainter*, int f, DrawParams* dp = 0);
+
+ // resets rectangle for free space
+ void setRect(QRect);
+
+ // Returns the rectangle area still free of text/pixmaps after
+ // a number of drawText() calls.
+ QRect remainingRect(DrawParams* dp = 0);
+
+private:
+ int _usedTopLeft, _usedTopCenter, _usedTopRight;
+ int _usedBottomLeft, _usedBottomCenter, _usedBottomRight;
+ QRect _rect;
+
+ // temporary
+ int _fontHeight;
+ QFontMetrics* _fm;
+ DrawParams* _dp;
+};
+
+
+class TreeMapItemList: public QPtrList<TreeMapItem>
+{
+public:
+ TreeMapItem* commonParent();
+protected:
+ int compareItems ( Item item1, Item item2 );
+};
+
+typedef QPtrListIterator<TreeMapItem> TreeMapItemListIterator;
+
+
+/**
+ * Base class of items in TreeMap.
+ *
+ * This class supports an arbitrary number of text() strings
+ * positioned counterclock-wise starting at TopLeft. Each item
+ * has its own static value(), sum() and sorting(). The
+ * splitMode() and borderWidth() is taken from a TreeMapWidget.
+ *
+ * If you want more flexibility, reimplement TreeMapItem and
+ * override the corresponding methods. For dynamic creation of child
+ * items on demand, reimplement children().
+ */
+class TreeMapItem: public StoredDrawParams
+{
+public:
+
+ /**
+ * Split direction for nested areas:
+ * AlwaysBest: Choose split direction for every subitem according to
+ * longest side of rectangle left for drawing
+ * Best: Choose split direction for all subitems of an area
+ * depending on longest side
+ * HAlternate: Horizontal at top; alternate direction on depth step
+ * VAlternate: Vertical at top; alternate direction on depth step
+ * Horizontal: Always horizontal split direction
+ * Vertical: Always vertical split direction
+ */
+ enum SplitMode { Bisection, Columns, Rows,
+ AlwaysBest, Best,
+ HAlternate, VAlternate,
+ Horizontal, Vertical };
+
+ TreeMapItem(TreeMapItem* parent = 0, double value = 1.0 );
+ TreeMapItem(TreeMapItem* parent, double value,
+ QString text1, QString text2 = QString::null,
+ QString text3 = QString::null, QString text4 = QString::null);
+ virtual ~TreeMapItem();
+
+ bool isChildOf(TreeMapItem*);
+
+ TreeMapItem* commonParent(TreeMapItem* item);
+
+ // force a redraw of this item
+ void redraw();
+
+ // delete all children
+ void clear();
+
+ // force new child generation & refresh
+ void refresh();
+
+ // call in a reimplemented items() method to check if already called
+ // after a clear(), this will return false
+ bool initialized();
+
+ /**
+ * Adds an item to a parent.
+ * When no sorting is used, the item is appended (drawn at bottom).
+ * This is only needed if the parent was not already specified in the
+ * construction of the item.
+ */
+ void addItem(TreeMapItem*);
+
+ /**
+ * Returns a list of text strings of specified text number,
+ * from root up to this item.
+ */
+ QStringList path(int) const;
+
+ /**
+ * Depth of this item. This is the distance to root.
+ */
+ int depth() const;
+
+ /**
+ * Parent Item
+ */
+ TreeMapItem* parent() const { return _parent; }
+
+ /**
+ * Temporary rectangle used for drawing this item the last time.
+ * This is internally used to map from a point to an item.
+ */
+ void setItemRect(const QRect& r) { _rect = r; }
+ void clearItemRect();
+ const QRect& itemRect() const { return _rect; }
+ int width() const { return _rect.width(); }
+ int height() const { return _rect.height(); }
+
+ /**
+ * Temporary rectangle list of free space of this item.
+ * Used internally to enable tooltip.
+ */
+ void clearFreeRects();
+ QPtrList<QRect>* freeRects() const { return _freeRects; }
+ void addFreeRect(const QRect& r);
+
+ /**
+ * Temporary child item index of the child that was current() recently.
+ */
+ int index() const { return _index; }
+ void setIndex(int i) { _index = i; }
+
+
+ /**
+ * TreeMap widget this item is put in.
+ */
+ TreeMapWidget* widget() const { return _widget; }
+
+ void setParent(TreeMapItem* p);
+ void setWidget(TreeMapWidget* w) { _widget = w; }
+ void setSum(double s) { _sum = s; }
+ void setValue(double s) { _value = s; }
+
+ virtual double sum() const;
+ virtual double value() const;
+ // replace "Default" position with setting from TreeMapWidget
+ virtual Position position(int) const;
+ virtual const QFont& font() const;
+ virtual bool isMarked(int) const;
+
+ virtual int borderWidth() const;
+
+ /**
+ * Returns the text number after that sorting is done or
+ * -1 for no sorting, -2 for value() sorting (default).
+ * If ascending != 0, a bool value is written at that location
+ * to indicate if sorting should be ascending.
+ */
+ virtual int sorting(bool* ascending) const;
+
+ /**
+ * Set the sorting for child drawing.
+ *
+ * Default is no sorting: <textNo> = -1
+ * For value() sorting, use <textNo> = -2
+ *
+ * For fast sorting, set this to -1 before child insertions and call
+ * again after inserting all children.
+ */
+ void setSorting(int textNo, bool ascending = true);
+
+ /**
+ * Resort according to the already set sorting.
+ *
+ * This has to be done if the sorting base changes (e.g. text or values
+ * change). If this is only true for the children of this item, you can
+ * set the recursive parameter to false.
+ */
+ void resort(bool recursive = true);
+
+ virtual SplitMode splitMode() const;
+ virtual int rtti() const;
+ // not const as this can create children on demand
+ virtual TreeMapItemList* children();
+
+protected:
+ TreeMapItemList* _children;
+ double _sum, _value;
+
+private:
+ TreeMapWidget* _widget;
+ TreeMapItem* _parent;
+
+ int _sortTextNo;
+ bool _sortAscending;
+
+ // temporary layout
+ QRect _rect;
+ QPtrList<QRect>* _freeRects;
+ int _depth;
+
+ // temporary self value (when using level skipping)
+ double _unused_self;
+
+ // index of last active subitem
+ int _index;
+};
+
+
+/**
+ * Class for visualisation of a metric of hierarchically
+ * nested items as 2D areas.
+ */
+class TreeMapWidget: public QWidget
+{
+ Q_OBJECT
+
+public:
+
+ /**
+ * Same as in QListBox/QListView
+ */
+ enum SelectionMode { Single, Multi, Extended, NoSelection };
+
+ TreeMapWidget(TreeMapItem* base, QWidget* parent=0, const char* name=0);
+ ~TreeMapWidget();
+
+ /**
+ * Returns the TreeMapItem filling out the widget space
+ */
+ TreeMapItem* base() const { return _base; }
+
+ /**
+ * Returns a reference to the current widget font.
+ */
+ const QFont& currentFont() const;
+
+ /**
+ * Returns the area item at position x/y, independent from any
+ * maxSelectDepth setting.
+ */
+ TreeMapItem* item(int x, int y) const;
+
+ /**
+ * Returns the nearest item with a visible area; this
+ * can be the given item itself.
+ */
+ TreeMapItem* visibleItem(TreeMapItem*) const;
+
+ /**
+ * Returns the item possible for selection. this returns the
+ * given item itself or a parent thereof,
+ * depending on setting of maxSelectDepth().
+ */
+ TreeMapItem* possibleSelection(TreeMapItem*) const;
+
+ /**
+ * Selects or unselects an item.
+ * In multiselection mode, the constrain that a selected item
+ * has no selected children or parents stays true.
+ */
+ void setSelected(TreeMapItem*, bool selected = true);
+
+ /**
+ * Switches on the marking <markNo>. Marking 0 switches off marking.
+ * This is mutually exclusive to selection, and is automatically
+ * switched off when selection is changed (also by the user).
+ * Marking is visually the same as selection, and is based on
+ * TreeMapItem::isMarked(<markNo>).
+ * This enables to programmatically show multiple selected items
+ * at once even in single selection mode.
+ */
+ void setMarked(int markNo = 1, bool redraw = true);
+
+ /**
+ * Clear selection of all selected items which are children of
+ * parent. When parent == 0, clears whole selection
+ * Returns true if selection changed.
+ */
+ bool clearSelection(TreeMapItem* parent = 0);
+
+ /**
+ * Selects or unselects items in a range.
+ * This is needed internally for Shift-Click in Extented mode.
+ * Range means for a hierarchical widget:
+ * - select/unselect i1 and i2 according selected
+ * - search common parent of i1 and i2, and select/unselect the
+ * range of direct children between but excluding the child
+ * leading to i1 and the child leading to i2.
+ */
+ void setRangeSelection(TreeMapItem* i1,
+ TreeMapItem* i2, bool selected);
+
+ /**
+ * Sets the current item.
+ * The current item is mainly used for keyboard navigation.
+ */
+ void setCurrent(TreeMapItem*, bool kbd=false);
+
+ /**
+ * Set the maximal depth a selected item can have.
+ * If you try to select a item with higher depth, the ancestor holding
+ * this condition is used.
+ *
+ * See also possibleSelection().
+ */
+ void setMaxSelectDepth(int d) { _maxSelectDepth = d; }
+
+
+ void setSelectionMode(SelectionMode m) { _selectionMode = m; }
+
+ /**
+ * for setting/getting global split direction
+ */
+ void setSplitMode(TreeMapItem::SplitMode m);
+ TreeMapItem::SplitMode splitMode() const;
+ // returns true if string was recognized
+ bool setSplitMode(QString);
+ QString splitModeString() const;
+
+
+ /*
+ * Shading of rectangles enabled ?
+ */
+ void setShadingEnabled(bool s);
+ bool isShadingEnabled() const { return _shading; }
+
+
+ /**
+ * Items usually have a size proportional to their value().
+ * With <width>, you can give the minimum width
+ * of the resulting rectangle to still be drawn.
+ * For space not used because of to small items, you can specify
+ * with <reuseSpace> if the background should shine through or
+ * the space will be used to enlarge the next item to be drawn
+ * at this level.
+ */
+ void setVisibleWidth(int width, bool reuseSpace = false);
+
+ /**
+ * If a children value() is almost the parents sum(),
+ * it can happen that the border to be drawn for visibilty of
+ * nesting relations takes to much space, and the
+ * parent/child size relation can not be mapped to a correct
+ * area size relation.
+ *
+ * Either
+ * (1) Ignore the incorrect drawing, or
+ * (2) Skip drawing of the parent level alltogether.
+ */
+ void setSkipIncorrectBorder(bool enable = true);
+ bool skipIncorrectBorder() const { return _skipIncorrectBorder; }
+
+ /**
+ * Maximal nesting depth
+ */
+ void setMaxDrawingDepth(int d);
+ int maxDrawingDepth() const { return _maxDrawingDepth; }
+
+ /**
+ * Minimal area for rectangles to draw
+ */
+ void setMinimalArea(int area);
+ int minimalArea() const { return _minimalArea; }
+
+ /* defaults for text attributes */
+ QString defaultFieldType(int) const;
+ QString defaultFieldStop(int) const;
+ bool defaultFieldVisible(int) const;
+ bool defaultFieldForced(int) const;
+ DrawParams::Position defaultFieldPosition(int) const;
+
+ /**
+ * Set the type name of a field.
+ * This is important for the visualization menu generated
+ * with visualizationMenu()
+ */
+ void setFieldType(int, QString);
+ QString fieldType(int) const;
+
+ /**
+ * Stop drawing at item with name
+ */
+ void setFieldStop(int, QString);
+ QString fieldStop(int) const;
+
+ /**
+ * Should the text with number textNo be visible?
+ * This is only done if remaining space is enough to allow for
+ * proportional size constrains.
+ */
+ void setFieldVisible(int, bool);
+ bool fieldVisible(int) const;
+
+ /**
+ * Should the drawing of the name into the rectangle be forced?
+ * This enables drawing of the name before drawing subitems, and
+ * thus destroys proportional constrains.
+ */
+ void setFieldForced(int, bool);
+ bool fieldForced(int) const;
+
+ /**
+ * Set the field position in the area. See TreeMapItem::Position
+ */
+ void setFieldPosition(int, DrawParams::Position);
+ DrawParams::Position fieldPosition(int) const;
+ void setFieldPosition(int, QString);
+ QString fieldPositionString(int) const;
+
+ /**
+ * Do we allow the texts to be rotated by 90 degrees for better fitting?
+ */
+ void setAllowRotation(bool);
+ bool allowRotation() const { return _allowRotation; }
+
+ void setBorderWidth(int w);
+ int borderWidth() const { return _borderWidth; }
+
+ /**
+ * Save/restore options.
+ */
+ void saveOptions(KConfigGroup*, QString prefix = QString::null);
+ void restoreOptions(KConfigGroup*, QString prefix = QString::null);
+
+ /**
+ * These functions populate given popup menus.
+ * The added items are already connected to handlers.
+ *
+ * The int is the menu id where to start for the items (100 IDs reserved).
+ */
+ void addSplitDirectionItems(QPopupMenu*, int);
+ void addSelectionItems(QPopupMenu*, int, TreeMapItem*);
+ void addFieldStopItems(QPopupMenu*, int, TreeMapItem*);
+ void addAreaStopItems(QPopupMenu*, int, TreeMapItem*);
+ void addDepthStopItems(QPopupMenu*, int, TreeMapItem*);
+ void addVisualizationItems(QPopupMenu*, int);
+
+ TreeMapWidget* widget() { return this; }
+ TreeMapItem* current() const { return _current; }
+ TreeMapItemList selection() const { return _selection; }
+ bool isSelected(TreeMapItem* i) const;
+ int maxSelectDepth() const { return _maxSelectDepth; }
+ SelectionMode selectionMode() const { return _selectionMode; }
+
+ /**
+ * Return tooltip string to show for a item (can be rich text)
+ * Default implementation gives lines with "text0 (text1)" going to root.
+ */
+ virtual QString tipString(TreeMapItem* i) const;
+
+ /**
+ * Redraws an item with all children.
+ * This takes changed values(), sums(), colors() and text() into account.
+ */
+ void redraw(TreeMapItem*);
+ void redraw() { redraw(_base); }
+
+ /**
+ * Resort all TreeMapItems. See TreeMapItem::resort().
+ */
+ void resort() { _base->resort(true); }
+
+ // internal
+ void drawTreeMap();
+
+ // used internally when items are destroyed
+ void deletingItem(TreeMapItem*);
+
+protected slots:
+ void splitActivated(int);
+ void selectionActivated(int);
+ void fieldStopActivated(int);
+ void areaStopActivated(int);
+ void depthStopActivated(int);
+ void visualizationActivated(int);
+
+signals:
+ void selectionChanged();
+ void selectionChanged(TreeMapItem*);
+
+ /**
+ * This signal is emitted if the current item changes.
+ * If the change is done because of keyboard navigation,
+ * the <kbd> is set to true
+ */
+ void currentChanged(TreeMapItem*, bool keyboard);
+ void clicked(TreeMapItem*);
+ void returnPressed(TreeMapItem*);
+ void doubleClicked(TreeMapItem*);
+ void rightButtonPressed(TreeMapItem*, const QPoint &);
+ void contextMenuRequested(TreeMapItem*, const QPoint &);
+
+protected:
+ void mousePressEvent( QMouseEvent * );
+ void contextMenuEvent( QContextMenuEvent * );
+ void mouseReleaseEvent( QMouseEvent * );
+ void mouseMoveEvent( QMouseEvent * );
+ void mouseDoubleClickEvent( QMouseEvent * );
+ void keyPressEvent( QKeyEvent* );
+ void paintEvent( QPaintEvent * );
+ void resizeEvent( QResizeEvent * );
+ void showEvent( QShowEvent * );
+ void fontChange( const QFont& );
+
+private:
+ TreeMapItemList diff(TreeMapItemList&, TreeMapItemList&);
+ // returns true if selection changed
+ TreeMapItem* setTmpSelected(TreeMapItem*, bool selected = true);
+ TreeMapItem* setTmpRangeSelection(TreeMapItem* i1,
+ TreeMapItem* i2, bool selected);
+ bool isTmpSelected(TreeMapItem* i);
+
+ void drawItem(QPainter* p, TreeMapItem*);
+ void drawItems(QPainter* p, TreeMapItem*);
+ bool horizontal(TreeMapItem* i, const QRect& r);
+ void drawFill(TreeMapItem*,QPainter* p, QRect& r);
+ void drawFill(TreeMapItem*,QPainter* p, QRect& r,
+ TreeMapItemListIterator it, int len, bool goBack);
+ bool drawItemArray(QPainter* p, TreeMapItem*, QRect& r, double,
+ TreeMapItemListIterator it, int len, bool);
+ bool resizeAttr(int);
+
+ TreeMapItem* _base;
+ TreeMapItem *_current, *_pressed, *_lastOver, *_oldCurrent;
+ TreeMapTip* _tip;
+ int _maxSelectDepth, _maxDrawingDepth;
+
+ // attributes for field, per textNo
+ struct FieldAttr {
+ QString type, stop;
+ bool visible, forced;
+ DrawParams::Position pos;
+ };
+ QValueVector<FieldAttr> _attr;
+
+ SelectionMode _selectionMode;
+ TreeMapItem::SplitMode _splitMode;
+ int _visibleWidth, _stopArea, _minimalArea, _borderWidth;
+ bool _reuseSpace, _skipIncorrectBorder, _drawSeparators, _shading;
+ bool _allowRotation;
+ TreeMapItem * _needsRefresh;
+ TreeMapItemList _selection;
+ int _markNo;
+
+ // for the context menus: start IDs
+ int _splitID, _selectionID, _visID;
+ int _fieldStopID, _areaStopID, _depthStopID;
+ TreeMapItem* _menuItem;
+
+ // temporary selection while dragging, used for drawing
+ // most of the time, _selection == _tmpSelection
+ TreeMapItemList _tmpSelection;
+ bool _inShiftDrag, _inControlDrag;
+
+ // temporary widget font metrics while drawing
+ QFont _font;
+ int _fontHeight;
+
+ // back buffer pixmap
+ QPixmap _pixmap;
+};
+
+#endif