File indexing completed on 2024-04-28 05:41:36
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 * Part View 0011 */ 0012 0013 0014 #include "partview.h" 0015 0016 #include <QAction> 0017 #include <QMenu> 0018 #include <QTreeWidget> 0019 #include <QHeaderView> 0020 #include <QKeyEvent> 0021 0022 #include "partlistitem.h" 0023 #include "toplevelbase.h" 0024 0025 0026 // 0027 // PartView 0028 // 0029 0030 0031 PartView::PartView(TraceItemView* parentView, QWidget* parent) 0032 : QTreeWidget(parent), TraceItemView(parentView) 0033 { 0034 _inSelectionUpdate = false; 0035 0036 QStringList headerLabels; 0037 headerLabels << tr( "Profile Part" ) 0038 << tr( "Incl." ) 0039 << tr( "Self" ) 0040 << tr( "Called" ) 0041 << tr( "Comment" ); 0042 setHeaderLabels(headerLabels); 0043 0044 setAllColumnsShowFocus(true); 0045 setRootIsDecorated(false); 0046 setUniformRowHeights(true); 0047 // sorting will be enabled after refresh() 0048 sortByColumn(0, Qt::DescendingOrder); 0049 setMinimumHeight(50); 0050 setSelectionMode(QAbstractItemView::ExtendedSelection); 0051 0052 connect( this, &QTreeWidget::itemSelectionChanged, 0053 this, &PartView::selectionChangedSlot ); 0054 0055 setContextMenuPolicy(Qt::CustomContextMenu); 0056 connect( this, 0057 &QWidget::customContextMenuRequested, 0058 this, &PartView::context); 0059 0060 connect(header(), &QHeaderView::sectionClicked, 0061 this, &PartView::headerClicked); 0062 0063 setWhatsThis( whatsThis() ); 0064 } 0065 0066 QString PartView::whatsThis() const 0067 { 0068 return tr( "<b>Trace Part List</b>" 0069 "<p>This list shows all trace parts of the loaded " 0070 "trace. For each part, the " 0071 "self/inclusive cost of the current selected " 0072 "function, spent in the part, is shown; " 0073 "percentage costs are always relative to the " 0074 "total cost <em>of the part</em> (not to the whole " 0075 "trace as in the Trace Part Overview). " 0076 "Also shown are the calls happening to/from the " 0077 "current function inside of the trace part.</p>" 0078 "<p>By choosing one or more trace parts from the " 0079 "list, the costs shown all over KCachegrind will " 0080 "only be the ones spent in the selected part(s). " 0081 "If no list selection is shown, in fact all trace " 0082 "parts are selected implicitly.</p>" 0083 "<p>This is a multi-selection list. You can select " 0084 "ranges by dragging the mouse or use SHIFT/CTRL " 0085 "modifiers. " 0086 "Selection/Deselection of trace parts can also be " 0087 "done by using the Trace Part Overview Dockable. " 0088 "This one also supports multiple selection.</p>" 0089 "<p>Note that the list is hidden if only one trace " 0090 "part is loaded.</p>"); 0091 } 0092 0093 0094 void PartView::context(const QPoint & p) 0095 { 0096 QMenu popup; 0097 addGoMenu(&popup); 0098 0099 // p is in local coordinates 0100 popup.exec(mapToGlobal(p + QPoint(0,header()->height()))); 0101 } 0102 0103 0104 void PartView::selectionChangedSlot() 0105 { 0106 if (_inSelectionUpdate) return; 0107 0108 TracePartList l; 0109 QList<QTreeWidgetItem*> sItems = selectedItems(); 0110 foreach(QTreeWidgetItem* item, sItems) 0111 l.append( ((PartListItem*)item)->part() ); 0112 0113 // nothing selected means all 0114 if (l.isEmpty()) l = _data->parts(); 0115 0116 partsSelected(l); 0117 } 0118 0119 void PartView::headerClicked(int col) 0120 { 0121 // name columns should be sortable in both ways 0122 if ((col == 0) || (col == 4)) return; 0123 0124 // all others only descending 0125 sortByColumn(col, Qt::DescendingOrder); 0126 } 0127 0128 CostItem* PartView::canShow(CostItem* i) 0129 { 0130 if (!TraceItemView::data()) return nullptr; 0131 if (TraceItemView::data()->parts().count()>1) return i; 0132 return nullptr; 0133 } 0134 0135 void PartView::doUpdate(int changeType, bool) 0136 { 0137 // Special case ? 0138 if (changeType == eventType2Changed) return; 0139 if (changeType == selectedItemChanged) return; 0140 0141 if (changeType == groupTypeChanged) { 0142 QTreeWidgetItem *item; 0143 for (int i=0; i<topLevelItemCount(); i++){ 0144 item = topLevelItem(i); 0145 ((PartListItem*)item)->setGroupType(_groupType); 0146 } 0147 return; 0148 } 0149 0150 if (changeType == eventTypeChanged) { 0151 #if QT_VERSION >= 0x050000 0152 header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); 0153 header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); 0154 #else 0155 header()->setResizeMode(1, QHeaderView::ResizeToContents); 0156 header()->setResizeMode(2, QHeaderView::ResizeToContents); 0157 #endif 0158 // need to disable sorting! Otherwise each change of shown cost 0159 // can reorders list and change order returned by topLevelItem() 0160 setSortingEnabled(false); 0161 for (int i=0; i< topLevelItemCount(); i++) { 0162 PartListItem* item = (PartListItem*) topLevelItem(i); 0163 item->setEventType(_eventType); 0164 } 0165 #if QT_VERSION >= 0x050000 0166 header()->setSectionResizeMode(1, QHeaderView::Interactive); 0167 header()->setSectionResizeMode(2, QHeaderView::Interactive); 0168 #else 0169 header()->setResizeMode(1, QHeaderView::Interactive); 0170 header()->setResizeMode(2, QHeaderView::Interactive); 0171 #endif 0172 setSortingEnabled(true); 0173 header()->setSortIndicatorShown(false); 0174 0175 return; 0176 } 0177 0178 if (changeType == partsChanged) { 0179 0180 TracePart* part; 0181 0182 _inSelectionUpdate = true; 0183 for (int i=0; i< topLevelItemCount(); i++) { 0184 PartListItem* item = (PartListItem*) topLevelItem(i); 0185 part = ((PartListItem*)item)->part(); 0186 0187 if (_partList.contains(part)) { 0188 item->setSelected(true); 0189 scrollToItem(item); 0190 } 0191 else 0192 item->setSelected(false); 0193 } 0194 _inSelectionUpdate = false; 0195 0196 return; 0197 } 0198 0199 refresh(); 0200 } 0201 0202 void PartView::refresh() 0203 { 0204 setColumnWidth(1, 50); 0205 setColumnWidth(2, 50); 0206 0207 if (!_data || !_activeItem) { 0208 clear(); 0209 return; 0210 } 0211 0212 ProfileContext::Type t = _activeItem->type(); 0213 TraceFunction* f = nullptr; 0214 if (t == ProfileContext::Function) f = (TraceFunction*) _activeItem; 0215 if (!f) return; 0216 0217 TracePartList hidden; 0218 if (_topLevel) 0219 hidden = _topLevel->hiddenParts(); 0220 0221 _inSelectionUpdate = true; 0222 clear(); 0223 0224 QList<QTreeWidgetItem*> items; 0225 QTreeWidgetItem* item; 0226 foreach(TracePart* part, _data->parts()) { 0227 if (hidden.contains(part)) continue; 0228 item = new PartListItem(nullptr, f, _eventType, _groupType, part); 0229 items.append(item); 0230 } 0231 setSortingEnabled(false); 0232 addTopLevelItems(items); 0233 setSortingEnabled(true); 0234 header()->setSortIndicatorShown(false); 0235 header()->resizeSections(QHeaderView::ResizeToContents); 0236 0237 foreach(item, items) { 0238 TracePart* part = ((PartListItem*)item)->part(); 0239 if (hidden.contains(part)) continue; 0240 if (part->isActive()) { 0241 item->setSelected(true); 0242 scrollToItem(item); 0243 } 0244 } 0245 0246 _inSelectionUpdate = false; 0247 } 0248 0249 #include "moc_partview.cpp"