1 /*
2 This file is part of KCachegrind.
3
4 SPDX-FileCopyrightText: 2002-2016 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
5
6 SPDX-License-Identifier: GPL-2.0-only
7 */
8
9 /*
10 * Items for caller/callee view.
11 */
12
13 #include "callitem.h"
14
15 #include <QFontMetrics>
16
17 #include "globalguiconfig.h"
18 #include "listutils.h"
19 #include "callview.h"
20
21
22 // CallItem
23
24
CallItem(CallView * view,QTreeWidget * parent,TraceCall * c)25 CallItem::CallItem(CallView* view, QTreeWidget* parent, TraceCall* c)
26 : QTreeWidgetItem(parent)
27 {
28 for (int i = 0 ; i < 5; ++i)
29 setTextAlignment(i, Qt::AlignRight);
30
31 _call = c;
32 _view = view;
33
34 _active = _view->activeFunction();
35 bool baseIsCycle = (_active && (_active == _active->cycle()));
36
37 QString fName;
38 if (_view->showCallers()) {
39 _shown = _call->caller(true);
40 fName = c->callerName(!baseIsCycle);
41 }
42 else {
43 _shown = _call->called(true);
44 fName = c->calledName(!baseIsCycle);
45 }
46
47 _shown->addPrettyLocation(fName);
48
49 setText(5, fName);
50 updateGroup();
51 updateCost();
52 }
53
updateGroup()54 void CallItem::updateGroup()
55 {
56 QColor c = GlobalGUIConfig::functionColor(_view->groupType(), _shown);
57 setIcon(5, colorPixmap(10, 10, c));
58 }
59
updateCost()60 void CallItem::updateCost()
61 {
62 bool sameCycle = _shown->cycle() && (_active->cycle() == _shown->cycle());
63 bool shownIsCycle = (_shown == _shown->cycle());
64 bool selectedIsCycle = (_active == _active->cycle());
65 if (_call->isRecursion()) sameCycle=true;
66
67 QString cStr;
68 if ((selectedIsCycle || shownIsCycle) && sameCycle)
69 cStr = QStringLiteral("-");
70 else {
71 _cc = _call->callCount();
72 if (_cc == 0)
73 cStr = QObject::tr("(active)");
74 else
75 cStr = _call->prettyCallCount();
76 }
77 setText(4, cStr);
78
79 ProfileCostArray* totalCost;
80 if (GlobalConfig::showExpanded()) {
81 if (_active->cycle())
82 totalCost = _active->cycle()->inclusive();
83 else
84 totalCost = _active->inclusive();
85 }
86 else
87 totalCost = _active->data();
88
89 EventType* ct = _view->eventType();
90 _sum = _call->subCost(ct);
91 double total = totalCost->subCost(ct);
92
93 if (total == 0.0) {
94 QString str = QStringLiteral("-");
95
96 setText(0, str);
97 setIcon(0, QIcon());
98 }
99 else {
100 double sum = 100.0 * _sum / total;
101
102 if (GlobalConfig::showPercentage())
103 setText(0, QStringLiteral("%1")
104 .arg(sum, 0, 'f', GlobalConfig::percentPrecision()));
105 else {
106 setText(0, _call->prettySubCost(ct));
107 }
108 setIcon(0, costPixmap(ct, _call, total, false));
109 setText(1, _call->prettySubCostPerCall(ct, _cc));
110 }
111
112 // Cost Type 2
113 EventType* ct2 = _view->eventType2();
114 if (ct2) {
115 _sum2 = _call->subCost(ct2);
116 double total = totalCost->subCost(ct2);
117
118 if (total == 0.0) {
119 QString str = QStringLiteral("-");
120
121 setText(2, str);
122 setIcon(2, QIcon());
123 }
124 else {
125 double sum = 100.0 * _sum2 / total;
126
127 if (GlobalConfig::showPercentage())
128 setText(2, QStringLiteral("%1")
129 .arg(sum, 0, 'f', GlobalConfig::percentPrecision()));
130 else {
131 setText(2, _call->prettySubCost(ct2));
132 }
133 setIcon(2, costPixmap(ct2, _call, total, false));
134 setText(3, _call->prettySubCostPerCall(ct2, _cc));
135 }
136 }
137
138 QIcon p;
139 if (sameCycle && !selectedIsCycle && !shownIsCycle) {
140 QFontMetrics fm(font(4));
141 p = QIcon::fromTheme(QStringLiteral("edit-undo")).pixmap(fm.height());
142 }
143 setIcon(4, p);
144 }
145
146
operator <(const QTreeWidgetItem & other) const147 bool CallItem::operator<(const QTreeWidgetItem& other) const
148 {
149 int col = treeWidget()->sortColumn();
150 const CallItem* ci1 = this;
151 const CallItem* ci2 = (CallItem*) &other;
152
153 if (col==0)
154 return ci1->_sum < ci2->_sum;
155
156 if (col==1) {
157 uint64 cc1 = ci1->_cc;
158 uint64 cc2 = ci2->_cc;
159 if (cc1 == 0) cc1 = 1;
160 if (cc2 == 0) cc2 = 1;
161 return (ci1->_sum / cc1) < (ci2->_sum / cc2);
162 }
163
164 if (col==2)
165 return ci1->_sum2 < ci2->_sum2;
166
167 if (col==3) {
168 uint64 cc1 = ci1->_cc;
169 uint64 cc2 = ci2->_cc;
170 if (cc1 == 0) cc1 = 1;
171 if (cc2 == 0) cc2 = 1;
172 return (ci1->_sum2 / cc1) < (ci2->_sum2 / cc2);
173 }
174
175 if (col==4)
176 return ci1->_cc < ci2->_cc;
177
178 return QTreeWidgetItem::operator <(other);
179 }
180
181