File indexing completed on 2024-04-28 05:41:38

0001 /*
0002     This file is part of KCachegrind.
0003 
0004     SPDX-FileCopyrightText: 2003-2016 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
0005 
0006     SPDX-License-Identifier: GPL-2.0-only
0007 */
0008 
0009 /*
0010  * Trace Item View
0011  */
0012 
0013 #ifndef TRACEITEMVIEW_H
0014 #define TRACEITEMVIEW_H
0015 
0016 #include <QTimer>
0017 
0018 #include "tracedata.h"
0019 
0020 class QWidget;
0021 class QMenu;
0022 
0023 class TopLevelBase;
0024 class TraceItemView;
0025 
0026 /* Helper class for TraceItemView for merging update requests.
0027  *
0028  * This can not be directly done in TraceItemView which can not have slots,
0029  * as this would need TraceItemView to be inherited from QObject. However,
0030  * we want subclasses of TraceItemView to also inherit from QWidget, and
0031  * multiple inheritance of a QObject is impossible
0032  */
0033 class TraceItemViewUpdateTimer: public QTimer
0034 {
0035     Q_OBJECT
0036 
0037 public:
0038     explicit TraceItemViewUpdateTimer(TraceItemView* view);
0039 
0040 private Q_SLOTS:
0041     void timeoutTriggered();
0042 
0043 private:
0044     TraceItemView* _view;
0045 };
0046 
0047 
0048 /**
0049  * Abstract Base Class for KCachegrind Views
0050  *
0051  * This class delivers the shared functionality of all KCachegrind
0052  * Views for one ProfileCost (like Function, Object...), the "active"
0053  * item. Additional view attributes are current primary cost type,
0054  * an optional secondary cost type, group type,
0055  * and possibly a selected costitem in this view.
0056  * Note that there is a difference in changing the selected item of
0057  * a view (this usually changes selection in other views, too), and
0058  * activating that item.
0059  */
0060 class TraceItemView
0061 {
0062     friend class TraceItemViewUpdateTimer;
0063 
0064 public:
0065 
0066     /**
0067      * Change type for update functions
0068      * - @c dataChanged is used if e.g. cycles are recalculated
0069      */
0070     enum { nothingChanged      = 0,
0071            eventTypeChanged    = 1,
0072            eventType2Changed   = 2,
0073            groupTypeChanged    = 4,
0074            partsChanged        = 8,
0075            activeItemChanged   = 16,
0076            selectedItemChanged = 32,
0077            dataChanged         = 64,
0078            configChanged       = 128 };
0079 
0080     enum Direction { None, Back, Forward, Up };
0081 
0082     // a TraceItemView can have a position in a parent container
0083     enum Position { Hidden, Top, Right, Left, Bottom };
0084 
0085     explicit TraceItemView(TraceItemView* parentView, TopLevelBase* top = nullptr);
0086     virtual ~TraceItemView();
0087 
0088     virtual QString whatsThis() const;
0089 
0090     // visualization layout and options (uses ConfigStorage)
0091     virtual void saveLayout(const QString& prefix, const QString& postfix);
0092     virtual void restoreLayout(const QString& prefix, const QString& postfix);
0093     virtual void saveOptions(const QString& prefix, const QString& postfix);
0094     virtual void restoreOptions(const QString& prefix, const QString& postfix);
0095 
0096     // Immediate remove all references to old data, and set the new.
0097     // This resets the visualization state.
0098     // A GUI update has to be triggered with updateView().
0099     // Overwrite in container views to also set new data for all members.
0100     virtual void setData(TraceData* d);
0101 
0102     // modify visualization state, updates automatically
0103     void setEventType(EventType* t) { _newEventType = t; updateView(); }
0104     void setEventType2(EventType* t) { _newEventType2 = t; updateView(); }
0105     void set(ProfileContext::Type g) { _newGroupType = g; updateView(); }
0106     void set(const TracePartList& l) { _newPartList = l; updateView(); }
0107     // returns false if nothing can be shown for this trace item
0108     bool activate(CostItem* i);
0109     void select(CostItem* i);
0110     void notifyChange(int changeType) { _status |= changeType; updateView(); }
0111     // all in one
0112     bool set(int, TraceData*, EventType*, EventType*,
0113              ProfileContext::Type, const TracePartList&,
0114              CostItem*, CostItem*);
0115 
0116     // if mergeUpdates is true (default), calls to updateView do not
0117     // directly trigger an update of the view
0118     void setMergeUpdates(bool b) { _mergeUpdates = b; }
0119 
0120     // general update request, call if view is/gets visible
0121     // force: update immediately even if invisible and no change was detected
0122     void updateView(bool force = false);
0123 
0124     /**
0125      * Notification from child views.
0126      * Default implementation notifies parent
0127      */
0128     virtual void selected(TraceItemView* sender, CostItem*);
0129     virtual void partsSelected(TraceItemView* sender, const TracePartList&);
0130     virtual void directionActivated(TraceItemView* sender, Direction);
0131     virtual void selectedEventType(TraceItemView* sender, EventType*);
0132     virtual void selectedEventType2(TraceItemView* sender, EventType*);
0133     virtual void activated(TraceItemView* sender, CostItem*);
0134     virtual void selectedGroupType(TraceItemView* sender, ProfileContext::Type);
0135 
0136     // getters...
0137     // always get the newest values
0138     TraceData* data() const { return _newData; }
0139     CostItem* activeItem() const { return _newActiveItem; }
0140     CostItem* selectedItem() const { return _newSelectedItem; }
0141     EventType* eventType() const { return _newEventType; }
0142     EventType* eventType2() const { return _newEventType2; }
0143     ProfileContext::Type groupType() const { return _newGroupType; }
0144     const TracePartList& partList() const { return _newPartList; }
0145 
0146     TraceFunction* activeFunction();
0147     int status() const { return _status; }
0148 
0149     // pointer to top level window to e.g. show status messages
0150     void setTopLevel(TopLevelBase* t) { _topLevel = t; }
0151     TopLevelBase* topLevel() const { return _topLevel; }
0152 
0153     void setPosition(Position p) { _pos = p; }
0154     Position position() const { return _pos; }
0155 
0156     void setTitle(QString t) { _title = t; }
0157     QString title() const { return _title; }
0158 
0159     // We depend on derived class to be a widget.
0160     // Force overriding by making this abstract.
0161     virtual QWidget* widget() = 0;
0162 
0163     /**
0164      * Called when a new item is about to become active.
0165      * Itemviews should reimplement this to notify that a
0166      * given item cannot be shown (return 0) or should be
0167      * redirected to another item to be shown as active.
0168      *
0169      * Use the methods like data() instead of _data here, as
0170      * _data possibly will give old/wrong information.
0171      */
0172     virtual CostItem* canShow(CostItem* i) { return i; }
0173 
0174     /* convenience functions for often used context menu items */
0175     void addEventTypeMenu(QMenu*,bool withCost2 = true);
0176     void addGoMenu(QMenu*);
0177 
0178 protected:
0179     // helpers to call selected()/activated() of parentView
0180     void selected(CostItem*);
0181     void partsSelected(const TracePartList&);
0182     void activated(CostItem*);
0183     void selectedEventType(EventType*);
0184     void selectedEventType2(EventType*);
0185     void selectedGroupType(ProfileContext::Type);
0186     void directionActivated(TraceItemView::Direction);
0187 
0188     /* Is this view visible?
0189      * if not, doUpdate() will not be called by updateView()
0190      */
0191     virtual bool isViewVisible();
0192 
0193     // update handler (to be reimplemented)
0194     virtual void doUpdate(int changeType, bool force);
0195 
0196     TraceItemView* _parentView;
0197     TopLevelBase* _topLevel;
0198 
0199     TraceData* _data;
0200     TracePartList _partList;
0201     CostItem *_activeItem, *_selectedItem;
0202     EventType *_eventType, *_eventType2;
0203     ProfileContext::Type _groupType;
0204 
0205 private:
0206     /* Multiple update requests via updateView() are merged, and result in one
0207      * call to triggerUpdate() after a timeout (using TraceItemViewUpdateTimer)
0208      */
0209     void triggerUpdate(bool force);
0210 
0211     TraceData* _newData;
0212     TracePartList _newPartList;
0213     CostItem *_newActiveItem, *_newSelectedItem;
0214     EventType *_newEventType, *_newEventType2;
0215     ProfileContext::Type _newGroupType;
0216     TraceItemViewUpdateTimer* _updateTimer;
0217 
0218     QString _title;
0219     int _status;
0220     bool _mergeUpdates, _needsUpdate;
0221     Position _pos;
0222 };
0223 
0224 
0225 
0226 #endif