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 #include "partlistitem.h"
10
11 #include <math.h>
12
13 #include <QPixmap>
14
15 #include "listutils.h"
16 #include "coverage.h"
17 #include "globalconfig.h"
18
19
20 // PartListItem
21
PartListItem(QTreeWidget * parent,TraceCostItem * costItem,EventType * et,ProfileContext::Type gt,TracePart * part)22 PartListItem::PartListItem(QTreeWidget* parent, TraceCostItem* costItem,
23 EventType* et, ProfileContext::Type gt,
24 TracePart* part)
25 :QTreeWidgetItem(parent)
26 {
27 _partCostItem = costItem->findDepFromPart(part);
28 _part = part;
29 _groupType = gt;
30 _eventType = et;
31
32 setTextAlignment(0, Qt::AlignRight);
33 setTextAlignment(1, Qt::AlignRight);
34 setTextAlignment(2, Qt::AlignRight);
35
36 setText(0, _part->prettyName());
37
38 if (_part->trigger().isEmpty())
39 setText(4, QObject::tr("(none)"));
40 else
41 setText(4, _part->trigger());
42
43 update();
44 }
45
setEventType(EventType * et)46 void PartListItem::setEventType(EventType* et)
47 {
48 if (_eventType == et) return;
49
50 _eventType = et;
51 update();
52 }
53
setGroupType(ProfileContext::Type gt)54 void PartListItem::setGroupType(ProfileContext::Type gt)
55 {
56 if (_groupType == gt) return;
57
58 _groupType = gt;
59 update();
60 }
61
update()62 void PartListItem::update()
63 {
64 TracePartFunction* pf;
65 pf = !_partCostItem ? nullptr :
66 (_partCostItem->type()==ProfileContext::PartFunction) ?
67 ((TracePartFunction*)_partCostItem) : nullptr;
68
69 double total = _part->subCost(_eventType);
70
71 ProfileCostArray* selfTotalCost = _part;
72 if (pf && GlobalConfig::showExpanded()) {
73 switch(_groupType) {
74 case ProfileContext::Object: selfTotalCost = pf->partObject(); break;
75 case ProfileContext::Class: selfTotalCost = pf->partClass(); break;
76 case ProfileContext::File: selfTotalCost = pf->partFile(); break;
77 default: break;
78 }
79 }
80 double selfTotal = selfTotalCost->subCost(_eventType);
81
82 _pure = _partCostItem ? _partCostItem->subCost(_eventType) : SubCost(0);
83 _sum = pf ? pf->inclusive()->subCost(_eventType) : SubCost(0);
84
85 if (selfTotal == 0 || !_partCostItem) {
86 setText(2, QStringLiteral("-"));
87 setIcon(2, QPixmap());
88 }
89 else {
90 double pure = 100.0 * _pure / selfTotal;
91 if (GlobalConfig::showPercentage()) {
92 setText(2, QStringLiteral("%1")
93 .arg(pure, 0, 'f', GlobalConfig::percentPrecision()));
94 }
95 else
96 setText(2, _partCostItem->prettySubCost(_eventType));
97
98 setIcon(2, costPixmap(_eventType, _partCostItem, selfTotal, false));
99 }
100
101 if (total == 0 || !pf) {
102 setText(1, QStringLiteral("-"));
103 setIcon(1, QPixmap());
104 }
105 else {
106 double sum = 100.0 * _sum / total;
107 if (GlobalConfig::showPercentage()) {
108 setText(1, QStringLiteral("%1")
109 .arg(sum, 0, 'f', GlobalConfig::percentPrecision()));
110 }
111 else
112 setText(1, _sum.pretty());
113
114 setIcon(1, costPixmap(_eventType, pf->inclusive(), total, false));
115 }
116
117 if (!pf) {
118 setText(3, QStringLiteral("-"));
119 _callCount = 0;
120 return;
121 }
122
123 SubCost callCount;
124 QString str;
125
126 callCount = 0;
127 foreach(TracePartCall* pc, pf->partCallers())
128 callCount += pc->callCount();
129
130 if ((callCount == 0) && (pf->calledContexts()>0))
131 str = QObject::tr("(active)");
132 else
133 str = callCount.pretty();
134
135 _callCount = callCount;
136 setText(3, str);
137 }
138
operator <(const QTreeWidgetItem & other) const139 bool PartListItem::operator<(const QTreeWidgetItem& other) const
140 {
141 const PartListItem* pi1 = this;
142 const PartListItem* pi2 = (PartListItem*) &other;
143 int col = treeWidget()->sortColumn();
144
145 if (col==0)
146 return (*(pi1->_part) < *(pi2->_part));
147
148 if (col==1)
149 return (pi1->_sum < pi2->_sum);
150
151 if (col==2)
152 return (pi1->_pure < pi2->_pure);
153
154 if (col==3)
155 return (pi1->_callCount < pi2->_callCount);
156
157 return QTreeWidgetItem::operator <(other);
158 }
159