File indexing completed on 2024-04-28 05:41:31

0001 /*
0002     This file is part of KCachegrind.
0003 
0004     SPDX-FileCopyrightText: 2002-2016 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
0005 
0006     SPDX-License-Identifier: GPL-2.0-only
0007 */
0008 
0009 /*
0010  * Items for caller/callee view.
0011  */
0012 
0013 #include "callitem.h"
0014 
0015 #include <QFontMetrics>
0016 
0017 #include "globalguiconfig.h"
0018 #include "listutils.h"
0019 #include "callview.h"
0020 
0021 
0022 // CallItem
0023 
0024 
0025 CallItem::CallItem(CallView* view, QTreeWidget* parent, TraceCall* c)
0026     : QTreeWidgetItem(parent)
0027 {
0028     for (int i = 0 ; i < 5; ++i)
0029         setTextAlignment(i, Qt::AlignRight);
0030 
0031     _call = c;
0032     _view = view;
0033 
0034     _active = _view->activeFunction();
0035     bool baseIsCycle = (_active && (_active == _active->cycle()));
0036 
0037     QString fName;
0038     if (_view->showCallers()) {
0039         _shown = _call->caller(true);
0040         fName  = c->callerName(!baseIsCycle);
0041     }
0042     else {
0043         _shown = _call->called(true);
0044         fName = c->calledName(!baseIsCycle);
0045     }
0046 
0047     _shown->addPrettyLocation(fName);
0048 
0049     setText(5, fName);
0050     updateGroup();
0051     updateCost();
0052 }
0053 
0054 void  CallItem::updateGroup()
0055 {
0056     QColor c = GlobalGUIConfig::functionColor(_view->groupType(), _shown);
0057     setIcon(5, colorPixmap(10, 10, c));
0058 }
0059 
0060 void CallItem::updateCost()
0061 {
0062     bool sameCycle = _shown->cycle() && (_active->cycle() == _shown->cycle());
0063     bool shownIsCycle = (_shown == _shown->cycle());
0064     bool selectedIsCycle = (_active == _active->cycle());
0065     if (_call->isRecursion()) sameCycle=true;
0066 
0067     QString cStr;
0068     if ((selectedIsCycle || shownIsCycle) && sameCycle)
0069         cStr = QStringLiteral("-");
0070     else {
0071         _cc  = _call->callCount();
0072         if (_cc == 0)
0073             cStr = QObject::tr("(active)");
0074         else
0075             cStr = _call->prettyCallCount();
0076     }
0077     setText(4, cStr);
0078 
0079     ProfileCostArray* totalCost;
0080     if (GlobalConfig::showExpanded()) {
0081         if (_active->cycle())
0082             totalCost = _active->cycle()->inclusive();
0083         else
0084             totalCost = _active->inclusive();
0085     }
0086     else
0087         totalCost = _active->data();
0088 
0089     EventType* ct = _view->eventType();
0090     _sum = _call->subCost(ct);
0091     double total = totalCost->subCost(ct);
0092 
0093     if (total == 0.0) {
0094         QString str = QStringLiteral("-");
0095 
0096         setText(0, str);
0097         setIcon(0, QIcon());
0098     }
0099     else {
0100         double sum  = 100.0 * _sum / total;
0101 
0102         if (GlobalConfig::showPercentage())
0103             setText(0, QStringLiteral("%1")
0104                     .arg(sum, 0, 'f', GlobalConfig::percentPrecision()));
0105         else {
0106             setText(0, _call->prettySubCost(ct));
0107         }
0108         setIcon(0, costPixmap(ct, _call, total, false));
0109         setText(1, _call->prettySubCostPerCall(ct, _cc));
0110     }
0111 
0112     // Cost Type 2
0113     EventType* ct2 = _view->eventType2();
0114     if (ct2) {
0115         _sum2 = _call->subCost(ct2);
0116         double total = totalCost->subCost(ct2);
0117 
0118         if (total == 0.0) {
0119             QString str = QStringLiteral("-");
0120 
0121             setText(2, str);
0122             setIcon(2, QIcon());
0123         }
0124         else {
0125             double sum  = 100.0 * _sum2 / total;
0126 
0127             if (GlobalConfig::showPercentage())
0128                 setText(2, QStringLiteral("%1")
0129                         .arg(sum, 0, 'f', GlobalConfig::percentPrecision()));
0130             else {
0131                 setText(2, _call->prettySubCost(ct2));
0132             }
0133             setIcon(2, costPixmap(ct2, _call, total, false));
0134             setText(3, _call->prettySubCostPerCall(ct2, _cc));
0135         }
0136     }
0137 
0138     QIcon p;
0139     if (sameCycle && !selectedIsCycle && !shownIsCycle) {
0140         QFontMetrics fm(font(4));
0141         p = QIcon::fromTheme(QStringLiteral("edit-undo")).pixmap(fm.height());
0142     }
0143     setIcon(4, p);
0144 }
0145 
0146 
0147 bool CallItem::operator<(const QTreeWidgetItem& other) const
0148 {
0149     int col = treeWidget()->sortColumn();
0150     const CallItem* ci1 = this;
0151     const CallItem* ci2 = (CallItem*) &other;
0152 
0153     if (col==0)
0154         return ci1->_sum < ci2->_sum;
0155 
0156     if (col==1) {
0157         uint64 cc1 = ci1->_cc;
0158         uint64 cc2 = ci2->_cc;
0159         if (cc1 == 0) cc1 = 1;
0160         if (cc2 == 0) cc2 = 1;
0161         return (ci1->_sum / cc1) < (ci2->_sum / cc2);
0162     }
0163 
0164     if (col==2)
0165         return ci1->_sum2 < ci2->_sum2;
0166 
0167     if (col==3) {
0168         uint64 cc1 = ci1->_cc;
0169         uint64 cc2 = ci2->_cc;
0170         if (cc1 == 0) cc1 = 1;
0171         if (cc2 == 0) cc2 = 1;
0172         return (ci1->_sum2 / cc1) < (ci2->_sum2 / cc2);
0173     }
0174 
0175     if (col==4)
0176         return ci1->_cc < ci2->_cc;
0177 
0178     return QTreeWidgetItem::operator <(other);
0179 }
0180