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 #include "traceitemview.h" 0014 0015 #include <QtGlobal> 0016 #include <QWidget> 0017 0018 #include "toplevelbase.h" 0019 0020 #define TRACE_UPDATES 0 0021 0022 0023 // TraceItemViewUpdateTimer 0024 0025 TraceItemViewUpdateTimer::TraceItemViewUpdateTimer(TraceItemView* view) 0026 { 0027 _view = view; 0028 setSingleShot(true); 0029 connect(this, &QTimer::timeout, this, &TraceItemViewUpdateTimer::timeoutTriggered); 0030 } 0031 0032 void TraceItemViewUpdateTimer::timeoutTriggered() 0033 { 0034 _view->triggerUpdate(false); 0035 } 0036 0037 // TraceItemView 0038 0039 TraceItemView::TraceItemView(TraceItemView* parentView, TopLevelBase* top) 0040 { 0041 _parentView = parentView; 0042 _topLevel = top ? top : parentView->topLevel(); 0043 0044 _data = _newData = nullptr; 0045 // _partList and _newPartList is empty 0046 _activeItem = _newActiveItem = nullptr; 0047 _selectedItem = _newSelectedItem = nullptr; 0048 _eventType = _newEventType = nullptr; 0049 _eventType2 = _newEventType2 = nullptr; 0050 _groupType = _newGroupType = ProfileContext::InvalidType; 0051 0052 _status = nothingChanged; 0053 _needsUpdate = false; 0054 _pos = Hidden; 0055 0056 _mergeUpdates = true; 0057 _updateTimer = new TraceItemViewUpdateTimer(this); 0058 } 0059 0060 TraceItemView::~TraceItemView() 0061 { 0062 delete _updateTimer; 0063 } 0064 0065 QString TraceItemView::whatsThis() const 0066 { 0067 return QObject::tr("No description available"); 0068 } 0069 0070 void TraceItemView::select(CostItem* i) 0071 { 0072 if (_selectedItem == i) return; 0073 0074 _newSelectedItem = i; 0075 updateView(); 0076 } 0077 0078 void TraceItemView::saveLayout(const QString&, const QString&) 0079 { 0080 #if 0 0081 qDebug("In '%s', saveLayout not implemented", 0082 widget()->name()); 0083 #endif 0084 } 0085 0086 void TraceItemView::saveOptions(const QString&, const QString&) 0087 { 0088 #if 0 0089 qDebug("In '%s', saveOptions not implemented", 0090 widget()->name()); 0091 #endif 0092 } 0093 0094 void TraceItemView::restoreLayout(const QString&, const QString&) 0095 {} 0096 0097 void TraceItemView::restoreOptions(const QString&, const QString&) 0098 {} 0099 0100 0101 bool TraceItemView::activate(CostItem* i) 0102 { 0103 _newActiveItem = canShow(i); 0104 if (_activeItem != _newActiveItem) { 0105 // new item activated, start with empty selection 0106 _newSelectedItem = nullptr; 0107 updateView(); 0108 } 0109 0110 return (_newActiveItem != nullptr); 0111 } 0112 0113 TraceFunction* TraceItemView::activeFunction() 0114 { 0115 if (!_activeItem) return nullptr; 0116 0117 ProfileContext::Type t = _activeItem->type(); 0118 switch(t) { 0119 case ProfileContext::Function: 0120 case ProfileContext::FunctionCycle: 0121 return (TraceFunction*) _activeItem; 0122 default: 0123 break; 0124 } 0125 return nullptr; 0126 } 0127 0128 bool TraceItemView::set(int changeType, TraceData* d, 0129 EventType* t1, EventType* t2, 0130 ProfileContext::Type g, const TracePartList& l, 0131 CostItem* a, CostItem* s) 0132 { 0133 _status |= changeType; 0134 _newData = d; 0135 _newGroupType = g; 0136 _newEventType = t1; 0137 _newEventType2 = t2; 0138 _newPartList = l; 0139 _newSelectedItem = s; 0140 _newActiveItem = canShow(a); 0141 if (_activeItem != _newActiveItem) { 0142 // new item activated, start with empty selection 0143 _newSelectedItem = nullptr; 0144 } 0145 updateView(); 0146 0147 return (_newActiveItem != nullptr); 0148 } 0149 0150 0151 bool TraceItemView::isViewVisible() 0152 { 0153 QWidget* w = widget(); 0154 if (w) 0155 return w->isVisible(); 0156 return false; 0157 } 0158 0159 void TraceItemView::setData(TraceData* d) 0160 { 0161 if (_data == d) return; 0162 _newData = d; 0163 0164 // invalidate all pointers to old data 0165 _activeItem = _newActiveItem = nullptr; 0166 _selectedItem = _newSelectedItem = nullptr; 0167 _eventType = _newEventType = nullptr; 0168 _eventType2 = _newEventType2 = nullptr; 0169 _groupType = _newGroupType = ProfileContext::InvalidType; 0170 _partList.clear(); 0171 _newPartList.clear(); 0172 0173 // updateView will change this to dataChanged 0174 _status = nothingChanged; 0175 updateView(); 0176 } 0177 0178 // force: update immediately even if invisible and no change was detected 0179 void TraceItemView::updateView(bool force) 0180 { 0181 if (!_mergeUpdates || force) { 0182 _needsUpdate = true; 0183 _updateTimer->stop(); 0184 triggerUpdate(force); 0185 return; 0186 } 0187 0188 // if _needsUpdate is true, an update is already scheduled 0189 if (_needsUpdate) return; 0190 0191 _needsUpdate = true; 0192 _updateTimer->start(1); 0193 } 0194 0195 0196 void TraceItemView::triggerUpdate(bool force) 0197 { 0198 // If already updated no need to update again. 0199 // This can happen if a update by timer is scheduled, but a "force"d 0200 // update is done before the timer triggers 0201 if (!_needsUpdate) return; 0202 _needsUpdate = false; 0203 0204 if (!force) { 0205 if (!isViewVisible()) return; 0206 } 0207 0208 if (_newData != _data) { 0209 _status |= dataChanged; 0210 _data = _newData; 0211 } 0212 else { 0213 _status &= ~dataChanged; 0214 0215 // if there is no data change and data is 0, no update needed 0216 if (!_data) return; 0217 } 0218 0219 if (!(_newPartList == _partList)) { 0220 _status |= partsChanged; 0221 _partList = _newPartList; 0222 } 0223 else 0224 _status &= ~partsChanged; 0225 0226 if (_newActiveItem != _activeItem) { 0227 0228 // when setting a new active item, there is no selection 0229 _selectedItem = nullptr; 0230 0231 _status |= activeItemChanged; 0232 _activeItem = _newActiveItem; 0233 } 0234 else 0235 _status &= ~activeItemChanged; 0236 0237 if (_newEventType != _eventType) { 0238 _status |= eventTypeChanged; 0239 _eventType = _newEventType; 0240 } 0241 else 0242 _status &= ~eventTypeChanged; 0243 0244 if (_newEventType2 != _eventType2) { 0245 _status |= eventType2Changed; 0246 _eventType2 = _newEventType2; 0247 } 0248 else 0249 _status &= ~eventType2Changed; 0250 0251 if (_newGroupType != _groupType) { 0252 _status |= groupTypeChanged; 0253 _groupType = _newGroupType; 0254 } 0255 else 0256 _status &= ~groupTypeChanged; 0257 0258 0259 if (_newSelectedItem != _selectedItem) { 0260 _status |= selectedItemChanged; 0261 _selectedItem = _newSelectedItem; 0262 } 0263 else 0264 _status &= ~selectedItemChanged; 0265 0266 0267 if (!force && (_status == nothingChanged)) return; 0268 0269 #if TRACE_UPDATES 0270 qDebug("%s::doUpate", 0271 widget() ? qPrintable(widget()->objectName()) : "TraceItemView"); 0272 0273 if (_status & dataChanged) 0274 qDebug(" data changed"); 0275 0276 if (_status & configChanged) 0277 qDebug(" config changed"); 0278 0279 if (_status & partsChanged) 0280 qDebug(" parts changed: %s", qPrintable(_partList[0]->name()) ); 0281 0282 if (_status & eventTypeChanged) 0283 qDebug(" event type 1 changed: %s", 0284 _eventType ? qPrintable( _eventType->name() ) : "(None)"); 0285 0286 if (_status & eventType2Changed) 0287 qDebug(" event type 2 changed: %s", 0288 _eventType2 ? qPrintable( _eventType2->name() ) : "(None)"); 0289 0290 if (_status & groupTypeChanged) 0291 qDebug(" group type changed: %s", 0292 qPrintable(ProfileContext::typeName(_groupType))); 0293 0294 if (_status & activeItemChanged) 0295 qDebug(" active item changed: %s", 0296 _activeItem ? qPrintable( _activeItem->fullName() ) : "(none)"); 0297 0298 if (_status & selectedItemChanged) 0299 qDebug(" selected item changed: %s", 0300 _selectedItem ? qPrintable( _selectedItem->fullName() ) : "(none)"); 0301 #endif 0302 0303 int st = _status; 0304 _status = nothingChanged; 0305 doUpdate(st, force); 0306 } 0307 0308 0309 void TraceItemView::selected(TraceItemView* /*sender*/, CostItem* i) 0310 { 0311 #if 0 // TRACE_UPDATES 0312 qDebug("%s::selected( item %s, sender %s )", 0313 widget() ? qPrintable(widget()->objectName()) : "TraceItemView", 0314 i ? qPrintable( i->name() ): "(none)", 0315 qPrintable(sender->widget()->objectName()) ); 0316 #endif 0317 0318 if (_parentView) _parentView->selected(this, i); 0319 } 0320 0321 void TraceItemView::partsSelected(TraceItemView* /*sender*/, const TracePartList& l) 0322 { 0323 #if 0 // TRACE_UPDATES 0324 qDebug() << (widget() ? widget()->name() : "TraceItemView") 0325 << "::selected " 0326 << l.names() 0327 << ", sender " 0328 << sender->widget()->name(); 0329 #endif 0330 0331 if (_parentView) 0332 _parentView->partsSelected(this, l); 0333 else 0334 if (_topLevel) _topLevel->activePartsChangedSlot(l); 0335 } 0336 0337 void TraceItemView::activated(TraceItemView* /*sender*/, CostItem* i) 0338 { 0339 #if 0 // TRACE_UPDATES 0340 qDebug("%s::activated( item %s, sender %s )", 0341 widget() ? qPrintable(widget()->objectName()) : "TraceItemView", 0342 i ? qPrintable( i->name() ): "(none)", 0343 qPrintable(sender->widget()->objectName()) ); 0344 #endif 0345 0346 if (_parentView) 0347 _parentView->activated(this, i); 0348 else 0349 if (_topLevel) _topLevel->setTraceItemDelayed(i); 0350 } 0351 0352 void TraceItemView::selectedEventType(TraceItemView*, EventType* t) 0353 { 0354 if (_parentView) 0355 _parentView->selectedEventType(this, t); 0356 else 0357 if (_topLevel) _topLevel->setEventTypeDelayed(t); 0358 } 0359 0360 void TraceItemView::selectedEventType2(TraceItemView*, EventType* t) 0361 { 0362 if (_parentView) 0363 _parentView->selectedEventType2(this, t); 0364 else 0365 if (_topLevel) _topLevel->setEventType2Delayed(t); 0366 } 0367 0368 void TraceItemView::selectedGroupType(TraceItemView*, ProfileContext::Type t) 0369 { 0370 if (_parentView) 0371 _parentView->selectedGroupType(this, t); 0372 else 0373 if (_topLevel) _topLevel->setGroupTypeDelayed(t); 0374 } 0375 0376 0377 void TraceItemView::directionActivated(TraceItemView*, TraceItemView::Direction d) 0378 { 0379 if (_parentView) 0380 _parentView->directionActivated(this, d); 0381 else 0382 if (_topLevel) _topLevel->setDirectionDelayed(d); 0383 } 0384 0385 void TraceItemView::doUpdate(int, bool) 0386 { 0387 } 0388 0389 void TraceItemView::selected(CostItem* i) 0390 { 0391 #if TRACE_UPDATES 0392 qDebug("%s::selected( item %s )", 0393 widget() ? qPrintable(widget()->objectName()) : "TraceItemView", 0394 i ? qPrintable( i->name() ): "(none)" ); 0395 #endif 0396 0397 if (_parentView) 0398 _parentView->selected(this, i); 0399 0400 } 0401 0402 void TraceItemView::partsSelected(const TracePartList& l) 0403 { 0404 if (_parentView) 0405 _parentView->partsSelected(this, l); 0406 else 0407 if (_topLevel) _topLevel->activePartsChangedSlot(l); 0408 } 0409 0410 void TraceItemView::activated(CostItem* i) 0411 { 0412 #if TRACE_UPDATES 0413 qDebug("%s::activated( item %s )", 0414 widget() ? qPrintable(widget()->objectName()) : "TraceItemView", 0415 i ? qPrintable( i->name() ): "(none)" ); 0416 #endif 0417 0418 if (_parentView) 0419 _parentView->activated(this, i); 0420 else 0421 if (_topLevel) _topLevel->setTraceItemDelayed(i); 0422 } 0423 0424 void TraceItemView::selectedEventType(EventType* t) 0425 { 0426 if (_parentView) 0427 _parentView->selectedEventType(this, t); 0428 else 0429 if (_topLevel) _topLevel->setEventTypeDelayed(t); 0430 } 0431 0432 void TraceItemView::selectedEventType2(EventType* t) 0433 { 0434 if (_parentView) 0435 _parentView->selectedEventType2(this, t); 0436 else 0437 if (_topLevel) _topLevel->setEventType2Delayed(t); 0438 } 0439 0440 void TraceItemView::selectedGroupType(ProfileContext::Type t) 0441 { 0442 if (_parentView) 0443 _parentView->selectedGroupType(this, t); 0444 else 0445 if (_topLevel) _topLevel->setGroupTypeDelayed(t); 0446 } 0447 0448 void TraceItemView::directionActivated(TraceItemView::Direction d) 0449 { 0450 if (_parentView) 0451 _parentView->directionActivated(this, d); 0452 else 0453 if (_topLevel) _topLevel->setDirectionDelayed(d); 0454 } 0455 0456 void TraceItemView::addEventTypeMenu(QMenu* p, bool withCost2) 0457 { 0458 if (_topLevel) _topLevel->addEventTypeMenu(p, withCost2); 0459 } 0460 0461 void TraceItemView::addGoMenu(QMenu* p) 0462 { 0463 if (_topLevel) _topLevel->addGoMenu(p); 0464 } 0465 0466 #include "moc_traceitemview.cpp"