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