File indexing completed on 2024-04-28 05:41:37
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 * StackSelection for KCachegrind 0011 * For function selection of a most expected stack, 0012 * to be put into a QDockWindow 0013 */ 0014 0015 #include "stackselection.h" 0016 0017 #include <QPushButton> 0018 #include <QVBoxLayout> 0019 #include <QTreeWidget> 0020 #include <QHeaderView> 0021 0022 #include "stackbrowser.h" 0023 #include "stackitem.h" 0024 0025 0026 StackSelection::StackSelection(QWidget* parent) 0027 : QWidget(parent) 0028 { 0029 _data = nullptr; 0030 _browser = new StackBrowser(); 0031 _function = nullptr; 0032 _eventType = nullptr; 0033 _eventType2 = nullptr; 0034 _groupType = ProfileContext::Function; 0035 0036 setWindowTitle(tr("Stack Selection")); 0037 0038 QVBoxLayout* vboxLayout = new QVBoxLayout(this); 0039 vboxLayout->setSpacing(6); 0040 vboxLayout->setContentsMargins(3, 3, 3, 3); 0041 0042 _stackList = new QTreeWidget(this); 0043 QStringList headerLabels; 0044 headerLabels << tr("Cost") 0045 << tr("Cost2") 0046 << tr("Calls") 0047 << tr("Function"); 0048 _stackList->setHeaderLabels(headerLabels); 0049 _stackList->setRootIsDecorated(false); 0050 _stackList->setAllColumnsShowFocus(true); 0051 _stackList->setUniformRowHeights(true); 0052 _stackList->setSortingEnabled(false); 0053 _stackList->setColumnWidth(0, 50); 0054 // 2nd cost column hidden at first (_eventType2 == 0) 0055 _stackList->setColumnWidth(1, 0); 0056 _stackList->setColumnWidth(2, 50); 0057 vboxLayout->addWidget(_stackList); 0058 0059 connect(_stackList, 0060 &QTreeWidget::currentItemChanged, 0061 this, &StackSelection::stackSelected ); 0062 } 0063 0064 StackSelection::~StackSelection() 0065 { 0066 delete _browser; 0067 } 0068 0069 void StackSelection::setData(TraceData* data) 0070 { 0071 if (_data == data) return; 0072 0073 _data = data; 0074 0075 _stackList->clear(); 0076 delete _browser; 0077 _browser = new StackBrowser(); 0078 _function = nullptr; 0079 } 0080 0081 0082 void StackSelection::setFunction(TraceFunction* f) 0083 { 0084 if (_function == f) return; 0085 _function = f; 0086 0087 if (!_data || !_function) return; 0088 0089 //qDebug() << "StackSelection::setFunction " << f->name(); 0090 0091 HistoryItem* item = _browser->current(); 0092 if (!item || item->function() != f) { 0093 _browser->select(f); 0094 rebuildStackList(); 0095 } 0096 } 0097 0098 0099 void StackSelection::rebuildStackList() 0100 { 0101 HistoryItem* item = _browser->current(); 0102 _stackList->clear(); 0103 _stackList->setColumnWidth(0, 50); 0104 _stackList->setColumnWidth(1, _eventType2 ? 50:0); 0105 _stackList->setColumnWidth(2, 50); 0106 if (!item || !item->stack()) return; 0107 0108 TraceFunction* top = item->stack()->top(); 0109 if (!top) return; 0110 0111 0112 QList<QTreeWidgetItem*> items; 0113 QTreeWidgetItem* activeItem = nullptr; 0114 TraceCallList l = item->stack()->calls(); 0115 for(int i=l.count()-1; i>=0; i--) { 0116 StackItem* si = new StackItem(this, nullptr, l.at(i)); 0117 if (si->function() == item->function()) 0118 activeItem = si; 0119 items.prepend(si); 0120 } 0121 StackItem* si = new StackItem(this, nullptr, top); 0122 if (si->function() == item->function()) 0123 activeItem = si; 0124 items.prepend(si); 0125 0126 #if QT_VERSION >= 0x050000 0127 _stackList->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); 0128 _stackList->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); 0129 _stackList->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); 0130 #else 0131 _stackList->header()->setResizeMode(0, QHeaderView::ResizeToContents); 0132 _stackList->header()->setResizeMode(1, QHeaderView::ResizeToContents); 0133 _stackList->header()->setResizeMode(2, QHeaderView::ResizeToContents); 0134 #endif 0135 0136 _stackList->addTopLevelItems(items); 0137 if (activeItem) { 0138 // this calls stackFunctionSelected() 0139 _stackList->setCurrentItem(activeItem); 0140 _stackList->scrollToItem(activeItem); 0141 } 0142 0143 #if QT_VERSION >= 0x050000 0144 _stackList->header()->setSectionResizeMode(0, QHeaderView::Interactive); 0145 _stackList->header()->setSectionResizeMode(1, QHeaderView::Interactive); 0146 _stackList->header()->setSectionResizeMode(2, QHeaderView::Interactive); 0147 #else 0148 _stackList->header()->setResizeMode(0, QHeaderView::Interactive); 0149 _stackList->header()->setResizeMode(1, QHeaderView::Interactive); 0150 _stackList->header()->setResizeMode(2, QHeaderView::Interactive); 0151 #endif 0152 0153 if (!_eventType2) { 0154 _stackList->setColumnWidth(1, 0); 0155 } 0156 } 0157 0158 void StackSelection::stackSelected(QTreeWidgetItem* i, QTreeWidgetItem*) 0159 { 0160 if (!i) return; 0161 0162 TraceFunction* f = ((StackItem*)i)->function(); 0163 emit functionSelected(f); 0164 } 0165 0166 0167 void StackSelection::browserBack() 0168 { 0169 if (_browser && _browser->canGoBack()) { 0170 _browser->goBack(); 0171 rebuildStackList(); 0172 } 0173 } 0174 0175 void StackSelection::browserForward() 0176 { 0177 if (_browser && _browser->canGoForward()) { 0178 _browser->goForward(); 0179 rebuildStackList(); 0180 } 0181 } 0182 0183 void StackSelection::browserUp() 0184 { 0185 if (_browser) { 0186 _browser->goUp(); 0187 rebuildStackList(); 0188 } 0189 } 0190 0191 void StackSelection::browserDown() 0192 { 0193 if (_browser) { 0194 _browser->goDown(); 0195 rebuildStackList(); 0196 } 0197 } 0198 0199 void StackSelection::refresh() 0200 { 0201 #if QT_VERSION >= 0x050000 0202 _stackList->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); 0203 _stackList->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); 0204 #else 0205 _stackList->header()->setResizeMode(0, QHeaderView::ResizeToContents); 0206 _stackList->header()->setResizeMode(1, QHeaderView::ResizeToContents); 0207 #endif 0208 0209 // there is no resorting allowed, so this is save 0210 for(int i = 0; i < _stackList->topLevelItemCount(); i++) { 0211 QTreeWidgetItem* item = _stackList->topLevelItem(i); 0212 ((StackItem*)item)->updateCost(); 0213 } 0214 0215 if (!_eventType2) { 0216 #if QT_VERSION >= 0x050000 0217 _stackList->header()->setSectionResizeMode(1, QHeaderView::Interactive); 0218 #else 0219 _stackList->header()->setResizeMode(1, QHeaderView::Interactive); 0220 #endif 0221 _stackList->setColumnWidth(1, 0); 0222 } 0223 } 0224 0225 void StackSelection::setEventType(EventType* ct) 0226 { 0227 if (ct == _eventType) return; 0228 _eventType = ct; 0229 0230 if (_eventType) 0231 _stackList->headerItem()->setText(0, _eventType->name()); 0232 0233 refresh(); 0234 } 0235 0236 void StackSelection::setEventType2(EventType* ct) 0237 { 0238 if (ct == _eventType2) return; 0239 _eventType2 = ct; 0240 0241 if (_eventType2) 0242 _stackList->headerItem()->setText(1, _eventType2->name()); 0243 0244 refresh(); 0245 } 0246 0247 void StackSelection::setGroupType(ProfileContext::Type gt) 0248 { 0249 if (_groupType == gt) return; 0250 _groupType = gt; 0251 0252 for(int i = 0; i < _stackList->topLevelItemCount(); i++) { 0253 QTreeWidgetItem* item = _stackList->topLevelItem(i); 0254 ((StackItem*)item)->updateGroup(); 0255 } 0256 } 0257 0258 #include "moc_stackselection.cpp"