1 /* 2 This file is part of KCachegrind. 3 4 SPDX-FileCopyrightText: 2003-2016 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> 5 6 SPDX-License-Identifier: GPL-2.0-only 7 */ 8 9 /* 10 * Trace Item View 11 */ 12 13 #ifndef TRACEITEMVIEW_H 14 #define TRACEITEMVIEW_H 15 16 #include <QTimer> 17 18 #include "tracedata.h" 19 20 class QWidget; 21 class QMenu; 22 23 class TopLevelBase; 24 class TraceItemView; 25 26 /* Helper class for TraceItemView for merging update requests. 27 * 28 * This can not be directly done in TraceItemView which can not have slots, 29 * as this would need TraceItemView to be inherited from QObject. However, 30 * we want subclasses of TraceItemView to also inherit from QWidget, and 31 * multiple inheritance of a QObject is impossible 32 */ 33 class TraceItemViewUpdateTimer: public QTimer 34 { 35 Q_OBJECT 36 37 public: 38 explicit TraceItemViewUpdateTimer(TraceItemView* view); 39 40 private Q_SLOTS: 41 void timeoutTriggered(); 42 43 private: 44 TraceItemView* _view; 45 }; 46 47 48 /** 49 * Abstract Base Class for KCachegrind Views 50 * 51 * This class delivers the shared functionality of all KCachegrind 52 * Views for one ProfileCost (like Function, Object...), the "active" 53 * item. Additional view attributes are current primary cost type, 54 * an optional secondary cost type, group type, 55 * and possibly a selected costitem in this view. 56 * Note that there is a difference in changing the selected item of 57 * a view (this usually changes selection in other views, too), and 58 * activating that item. 59 */ 60 class TraceItemView 61 { 62 friend class TraceItemViewUpdateTimer; 63 64 public: 65 66 /** 67 * Change type for update functions 68 * - @c dataChanged is used if e.g. cycles are recalculated 69 */ 70 enum { nothingChanged = 0, 71 eventTypeChanged = 1, 72 eventType2Changed = 2, 73 groupTypeChanged = 4, 74 partsChanged = 8, 75 activeItemChanged = 16, 76 selectedItemChanged = 32, 77 dataChanged = 64, 78 configChanged = 128 }; 79 80 enum Direction { None, Back, Forward, Up }; 81 82 // a TraceItemView can have a position in a parent container 83 enum Position { Hidden, Top, Right, Left, Bottom }; 84 85 explicit TraceItemView(TraceItemView* parentView, TopLevelBase* top = nullptr); 86 virtual ~TraceItemView(); 87 88 virtual QString whatsThis() const; 89 90 // visualization layout and options (uses ConfigStorage) 91 virtual void saveLayout(const QString& prefix, const QString& postfix); 92 virtual void restoreLayout(const QString& prefix, const QString& postfix); 93 virtual void saveOptions(const QString& prefix, const QString& postfix); 94 virtual void restoreOptions(const QString& prefix, const QString& postfix); 95 96 // Immediate remove all references to old data, and set the new. 97 // This resets the visualization state. 98 // A GUI update has to be triggered with updateView(). 99 // Overwrite in container views to also set new data for all members. 100 virtual void setData(TraceData* d); 101 102 // modify visualization state, updates automatically setEventType(EventType * t)103 void setEventType(EventType* t) { _newEventType = t; updateView(); } setEventType2(EventType * t)104 void setEventType2(EventType* t) { _newEventType2 = t; updateView(); } set(ProfileContext::Type g)105 void set(ProfileContext::Type g) { _newGroupType = g; updateView(); } set(const TracePartList & l)106 void set(const TracePartList& l) { _newPartList = l; updateView(); } 107 // returns false if nothing can be shown for this trace item 108 bool activate(CostItem* i); 109 void select(CostItem* i); notifyChange(int changeType)110 void notifyChange(int changeType) { _status |= changeType; updateView(); } 111 // all in one 112 bool set(int, TraceData*, EventType*, EventType*, 113 ProfileContext::Type, const TracePartList&, 114 CostItem*, CostItem*); 115 116 // if mergeUpdates is true (default), calls to updateView do not 117 // directly trigger an update of the view setMergeUpdates(bool b)118 void setMergeUpdates(bool b) { _mergeUpdates = b; } 119 120 // general update request, call if view is/gets visible 121 // force: update immediately even if invisible and no change was detected 122 void updateView(bool force = false); 123 124 /** 125 * Notification from child views. 126 * Default implementation notifies parent 127 */ 128 virtual void selected(TraceItemView* sender, CostItem*); 129 virtual void partsSelected(TraceItemView* sender, const TracePartList&); 130 virtual void directionActivated(TraceItemView* sender, Direction); 131 virtual void selectedEventType(TraceItemView* sender, EventType*); 132 virtual void selectedEventType2(TraceItemView* sender, EventType*); 133 virtual void activated(TraceItemView* sender, CostItem*); 134 virtual void selectedGroupType(TraceItemView* sender, ProfileContext::Type); 135 136 // getters... 137 // always get the newest values data()138 TraceData* data() const { return _newData; } activeItem()139 CostItem* activeItem() const { return _newActiveItem; } selectedItem()140 CostItem* selectedItem() const { return _newSelectedItem; } eventType()141 EventType* eventType() const { return _newEventType; } eventType2()142 EventType* eventType2() const { return _newEventType2; } groupType()143 ProfileContext::Type groupType() const { return _newGroupType; } partList()144 const TracePartList& partList() const { return _newPartList; } 145 146 TraceFunction* activeFunction(); status()147 int status() const { return _status; } 148 149 // pointer to top level window to e.g. show status messages setTopLevel(TopLevelBase * t)150 void setTopLevel(TopLevelBase* t) { _topLevel = t; } topLevel()151 TopLevelBase* topLevel() const { return _topLevel; } 152 setPosition(Position p)153 void setPosition(Position p) { _pos = p; } position()154 Position position() const { return _pos; } 155 setTitle(QString t)156 void setTitle(QString t) { _title = t; } title()157 QString title() const { return _title; } 158 159 // We depend on derived class to be a widget. 160 // Force overriding by making this abstract. 161 virtual QWidget* widget() = 0; 162 163 /** 164 * Called when a new item is about to become active. 165 * Itemviews should reimplement this to notify that a 166 * given item cannot be shown (return 0) or should be 167 * redirected to another item to be shown as active. 168 * 169 * Use the methods like data() instead of _data here, as 170 * _data possibly will give old/wrong information. 171 */ canShow(CostItem * i)172 virtual CostItem* canShow(CostItem* i) { return i; } 173 174 /* convenience functions for often used context menu items */ 175 void addEventTypeMenu(QMenu*,bool withCost2 = true); 176 void addGoMenu(QMenu*); 177 178 protected: 179 // helpers to call selected()/activated() of parentView 180 void selected(CostItem*); 181 void partsSelected(const TracePartList&); 182 void activated(CostItem*); 183 void selectedEventType(EventType*); 184 void selectedEventType2(EventType*); 185 void selectedGroupType(ProfileContext::Type); 186 void directionActivated(TraceItemView::Direction); 187 188 /* Is this view visible? 189 * if not, doUpdate() will not be called by updateView() 190 */ 191 virtual bool isViewVisible(); 192 193 // update handler (to be reimplemented) 194 virtual void doUpdate(int changeType, bool force); 195 196 TraceItemView* _parentView; 197 TopLevelBase* _topLevel; 198 199 TraceData* _data; 200 TracePartList _partList; 201 CostItem *_activeItem, *_selectedItem; 202 EventType *_eventType, *_eventType2; 203 ProfileContext::Type _groupType; 204 205 private: 206 /* Multiple update requests via updateView() are merged, and result in one 207 * call to triggerUpdate() after a timeout (using TraceItemViewUpdateTimer) 208 */ 209 void triggerUpdate(bool force); 210 211 TraceData* _newData; 212 TracePartList _newPartList; 213 CostItem *_newActiveItem, *_newSelectedItem; 214 EventType *_newEventType, *_newEventType2; 215 ProfileContext::Type _newGroupType; 216 TraceItemViewUpdateTimer* _updateTimer; 217 218 QString _title; 219 int _status; 220 bool _mergeUpdates, _needsUpdate; 221 Position _pos; 222 }; 223 224 225 226 #endif 227