• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdesdk API Reference
  • KDE Home
  • Contact Us
 

kcachegrind

  • sources
  • kde-4.12
  • kdesdk
  • kcachegrind
  • libviews
sourceitem.cpp
Go to the documentation of this file.
1 /* This file is part of KCachegrind.
2  Copyright (C) 2011 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
3 
4  KCachegrind is free software; you can redistribute it and/or
5  modify it under the terms of the GNU General Public
6  License as published by the Free Software Foundation, version 2.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; see the file COPYING. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17 */
18 
19 /*
20  * Items of source view.
21  */
22 
23 #include "sourceitem.h"
24 
25 #include <QPixmap>
26 #include <QRegExp>
27 #include <QPainter>
28 #include <QPolygon>
29 #include <QTextDocument>
30 
31 #include "globalguiconfig.h"
32 #include "listutils.h"
33 #include "sourceview.h"
34 
35 
36 //
37 // SourceItem
38 //
39 
40 // for source lines
41 SourceItem::SourceItem(SourceView* sv, QTreeWidget* parent,
42  int fileno, unsigned int lineno,
43  bool inside, const QString& src,
44  TraceLine* line)
45  : QTreeWidgetItem(parent)
46 {
47  _view = sv;
48  _lineno = lineno;
49  _fileno = fileno;
50  _inside = inside;
51  _line = line;
52  _lineCall = 0;
53  _lineJump = 0;
54 
55  setTextAlignment(0, Qt::AlignRight);
56  setTextAlignment(1, Qt::AlignRight);
57  setTextAlignment(2, Qt::AlignRight);
58 
59  if (src == "...")
60  setText(0, src);
61  else
62  setText(0, QString::number(lineno));
63 
64  QString s = src;
65  setText(4, s.replace( QRegExp("\t"), " " ));
66 
67  updateGroup();
68  updateCost();
69 }
70 
71 // for call lines
72 SourceItem::SourceItem(SourceView* sv, QTreeWidgetItem* parent,
73  int fileno, unsigned int lineno,
74  TraceLine* line, TraceLineCall* lineCall)
75  : QTreeWidgetItem(parent)
76 {
77  _view = sv;
78  _lineno = lineno;
79  _fileno = fileno;
80  _inside = true;
81  _line = line;
82  _lineCall = lineCall;
83  _lineJump = 0;
84 
85  setTextAlignment(0, Qt::AlignRight);
86  setTextAlignment(1, Qt::AlignRight);
87  setTextAlignment(2, Qt::AlignRight);
88 
89  //qDebug("SourceItem: (file %d, line %d) Linecall to %s",
90  // fileno, lineno, _lineCall->call()->called()->prettyName().toAscii());
91 
92  SubCost cc = _lineCall->callCount();
93  QString callStr = " ";
94  if (cc==0)
95  callStr += QObject::tr("Active call to '%1'")
96  .arg(_lineCall->call()->calledName());
97  else
98  callStr += QObject::tr("%n call(s) to '%2'", "", (uint64)cc)
99  .arg(_lineCall->call()->calledName());
100 
101  TraceFunction* calledF = _lineCall->call()->called();
102  calledF->addPrettyLocation(callStr);
103 
104  setText(4, callStr);
105 
106  updateGroup();
107  updateCost();
108 }
109 
110 // for jump lines
111 SourceItem::SourceItem(SourceView* sv, QTreeWidgetItem* parent,
112  int fileno, unsigned int lineno,
113  TraceLine* line, TraceLineJump* lineJump)
114  : QTreeWidgetItem(parent)
115 {
116  _view = sv;
117  _lineno = lineno;
118  _fileno = fileno;
119  _inside = true;
120  _line = line;
121  _lineCall = 0;
122  _lineJump = lineJump;
123 
124  setTextAlignment(0, Qt::AlignRight);
125  setTextAlignment(1, Qt::AlignRight);
126  setTextAlignment(2, Qt::AlignRight);
127 
128  //qDebug("SourceItem: (file %d, line %d) Linecall to %s",
129  // fileno, lineno, _lineCall->call()->called()->prettyName().toAscii());
130 
131  QString to;
132  if (_lineJump->lineTo()->functionSource() == _line->functionSource())
133  to = _lineJump->lineTo()->name();
134  else
135  to = _lineJump->lineTo()->prettyName();
136 
137  QString jStr;
138  if (_lineJump->isCondJump())
139  jStr = QObject::tr("Jump %1 of %2 times to %3")
140  .arg(_lineJump->followedCount().pretty())
141  .arg(_lineJump->executedCount().pretty())
142  .arg(to);
143  else
144  jStr = QObject::tr("Jump %1 times to %2")
145  .arg(_lineJump->executedCount().pretty())
146  .arg(to);
147 
148  setText(4, jStr);
149 }
150 
151 
152 void SourceItem::updateGroup()
153 {
154  if (!_lineCall) return;
155 
156  TraceFunction* f = _lineCall->call()->called();
157  QColor c = GlobalGUIConfig::functionColor(_view->groupType(), f);
158  setIcon(4, colorPixmap(10, 10, c));
159 }
160 
161 void SourceItem::updateCost()
162 {
163  _pure = SubCost(0);
164  _pure2 = SubCost(0);
165 
166  if (!_line) return;
167  if (_lineJump) return;
168 
169  ProfileCostArray* lineCost = _lineCall ? (ProfileCostArray*)_lineCall : (ProfileCostArray*)_line;
170 
171  // do not show any cost inside of cycles
172  if (_lineCall &&
173  ((_lineCall->call()->inCycle()>0) ||
174  (_lineCall->call()->isRecursion()))) {
175  QString str;
176  QPixmap p;
177 
178  QString icon = "edit-undo";
179 #if 0 // TODO
180  KIconLoader* loader = KIconLoader::global();
181  p= loader->loadIcon(icon, KIconLoader::Small, 0,
182  KIconLoader::DefaultState, QStringList(), 0, true);
183 #endif
184  if (p.isNull())
185  str = QObject::tr("(cycle)");
186 
187  setText(1, str);
188  setIcon(1, p);
189  setText(2, str);
190  setIcon(2, p);
191  return;
192  }
193 
194  ProfileCostArray* totalCost;
195  if (GlobalConfig::showExpanded())
196  totalCost = _line->functionSource()->function()->inclusive();
197  else
198  totalCost = _line->functionSource()->function()->data();
199 
200  EventType* ct = _view->eventType();
201  _pure = ct ? lineCost->subCost(ct) : SubCost(0);
202  if (_pure == 0) {
203  setText(1, QString());
204  setIcon(1, QPixmap());
205  }
206  else {
207  double total = totalCost->subCost(ct);
208  double pure = 100.0 * _pure / total;
209 
210  if (GlobalConfig::showPercentage())
211  setText(1, QString("%1")
212  .arg(pure, 0, 'f', GlobalConfig::percentPrecision()));
213  else
214  setText(1, _pure.pretty());
215 
216  setIcon(1, costPixmap(ct, lineCost, total, false));
217  }
218 
219  EventType* ct2 = _view->eventType2();
220  _pure2 = ct2 ? lineCost->subCost(ct2) : SubCost(0);
221  if (_pure2 == 0) {
222  setText(2, QString());
223  setIcon(2, QPixmap());
224  }
225  else {
226  double total = totalCost->subCost(ct2);
227  double pure2 = 100.0 * _pure2 / total;
228 
229  if (GlobalConfig::showPercentage())
230  setText(2, QString("%1")
231  .arg(pure2, 0, 'f', GlobalConfig::percentPrecision()));
232  else
233  setText(2, _pure2.pretty());
234 
235  setIcon(2, costPixmap(ct2, lineCost, total, false));
236  }
237 }
238 
239 
240 bool SourceItem::operator < ( const QTreeWidgetItem & other ) const
241 {
242  const SourceItem* si1 = this;
243  const SourceItem* si2 = (SourceItem*) &other;
244  int col = treeWidget()->sortColumn();
245 
246  if (col==1) {
247  return (si1->_pure < si2->_pure);
248  }
249  if (col==2) {
250  return (si1->_pure2 < si2->_pure2);
251  }
252  if (col==0) {
253  // Sort file numbers
254  if (si1->_fileno < si2->_fileno) return true;
255  if (si1->_fileno > si2->_fileno) return false;
256 
257  // Sort line numbers
258  if (si1->_lineno < si2->_lineno) return true;
259  if (si1->_lineno > si2->_lineno) return false;
260 
261  // Same line: code gets above calls/jumps
262  if (!si1->_lineCall && !si1->_lineJump) return true;
263  if (!si2->_lineCall && !si2->_lineJump) return false;
264 
265  // calls above jumps
266  if (si1->_lineCall && !si2->_lineCall) return true;
267  if (si2->_lineCall && !si1->_lineCall) return false;
268 
269  if (si1->_lineCall && si2->_lineCall) {
270  // Two calls: desending sort according costs
271  if (si1->_pure < si2->_pure) return true;
272  if (si1->_pure > si2->_pure) return false;
273 
274  // Two calls: sort according function names
275  TraceFunction* f1 = si1->_lineCall->call()->called();
276  TraceFunction* f2 = si2->_lineCall->call()->called();
277  if (f1->prettyName() > f2->prettyName()) return false;
278  return true;
279  }
280 
281  // Two jumps: descending sort according target line
282  return (si1->_lineJump->lineTo()->lineno() <
283  si2->_lineJump->lineTo()->lineno());
284  }
285  return QTreeWidgetItem::operator <(other);
286 }
287 
288 void SourceItem::setJumpArray(const QVector<TraceLineJump*>& a)
289 {
290  _jump = a;
291 }
292 
293 
294 
295 //
296 // SourceItemDelegate
297 //
298 
299 SourceItemDelegate::SourceItemDelegate(SourceView *parent)
300 {
301  _parent = parent;
302 }
303 
304 QSize SourceItemDelegate::sizeHint(const QStyleOptionViewItem &option,
305  const QModelIndex &index) const
306 {
307  QSize sz = QItemDelegate::sizeHint(option, index);
308 
309  int c = index.column();
310  if (c != 3) return sz;
311 
312  SourceView* sv = (SourceView*) _parent;
313  int levels = sv->arrowLevels();
314 
315  if (levels == 0)
316  return QSize(0, sz.height());
317 
318  // 10 pixels for the arrow, 1 pixel margin left and right
319  return QSize(10 + 6*levels + 2, sz.height());
320 }
321 
322 void SourceItemDelegate::paint(QPainter *painter,
323  const QStyleOptionViewItem &option,
324  const QModelIndex &index) const
325 {
326  int column = index.column();
327  SourceItem* item = static_cast<SourceItem*>(index.internalPointer());
328 
329  QColor color;
330  if ( !item->inside() || ((column==1) || (column==2)))
331  color = option.palette.color( QPalette::Button );
332  else if ((item->lineCall() || item->lineJump()) && column>2)
333  color = option.palette.color( QPalette::Midlight );
334  if (color.isValid())
335  _parent->model()->setData(index, color, Qt::BackgroundRole);
336 
337  if(column==3)
338  paintArrows(painter, option, index);
339  else
340  QItemDelegate::paint(painter, option, index);
341 }
342 
343 void SourceItemDelegate::paintArrows(QPainter *p,
344  const QStyleOptionViewItem &option,
345  const QModelIndex &index) const
346 {
347  QTreeWidget *lv = _parent;
348  if ( !lv ) return;
349  SourceView* sv = (SourceView*) lv;
350  SourceItem* item = static_cast<SourceItem*>(index.internalPointer());
351  const QRect& rect = option.rect;
352  int height = rect.height();
353 
354  p->save();
355  drawBackground(p, option, index);
356  p->translate(rect.topLeft());
357 
358  int marg = 1;
359  int yy = height/2, y1, y2;
360  QColor c;
361 
362  int start = -1, end = -1;
363 
364  TraceLineJump* lineJump = item->lineJump();
365  uint lineno = item->lineno();
366  TraceLineCall* lineCall = item->lineCall();
367 
368  // draw line borders, detect start/stop of a line
369  for(int i=0; i< item->jumpCount(); i++) {
370  TraceLineJump* jump = item->jump(i);
371  if (jump == 0) continue;
372 
373  y1 = 0;
374  y2 = height;
375  if (lineJump &&
376  (lineJump->lineTo() == jump->lineTo()) &&
377  (jump->lineFrom()->lineno() == lineno)) {
378 
379  if (start<0) start = i;
380  if (lineJump == jump) {
381  if (jump->lineTo()->lineno() <= lineno)
382  y2 = yy;
383  else
384  y1 = yy;
385  }
386  }
387  else if (!lineJump && !lineCall &&
388  (jump->lineTo()->lineno() == lineno)) {
389  if (end<0) end = i;
390  if (jump->lineFrom()->lineno() < lineno)
391  y2 = yy;
392  else
393  y1 = yy;
394  }
395 
396  c = jump->isCondJump() ? Qt::red : Qt::blue;
397  p->fillRect( marg + 6*i, y1, 4, y2, c);
398  p->setPen(c.light());
399  p->drawLine( marg + 6*i, y1, marg + 6*i, y2);
400  p->setPen(c.dark());
401  p->drawLine( marg + 6*i +3, y1, marg + 6*i +3, y2);
402  }
403 
404  // draw start/stop horizontal line
405  int x, y = yy-2, w, h = 4;
406  if (start >= 0) {
407  c = item->jump(start)->isCondJump() ? Qt::red : Qt::blue;
408  x = marg + 6*start;
409  w = 6*(sv->arrowLevels() - start) + 10;
410  p->fillRect( x, y, w, h, c);
411  p->setPen(c.light());
412  p->drawLine(x, y, x+w-1, y);
413  p->drawLine(x, y, x, y+h-1);
414  p->setPen(c.dark());
415  p->drawLine(x+w-1, y, x+w-1, y+h-1);
416  p->drawLine(x+1, y+h-1, x+w-1, y+h-1);
417  }
418  if (end >= 0) {
419  c = item->jump(end)->isCondJump() ? Qt::red : Qt::blue;
420  x = marg + 6*end;
421  w = 6*(sv->arrowLevels() - end) + 10;
422 
423  QPolygon a;
424  a.putPoints(0, 8, x,y+h,
425  x,y, x+w-8,y, x+w-8,y-2,
426  x+w,yy,
427  x+w-8,y+h+2, x+w-8,y+h,
428  x,y+h);
429  p->setBrush(c);
430  p->drawConvexPolygon(a);
431 
432  p->setPen(c.light());
433  p->drawPolyline(a.constData(), 5);
434  p->setPen(c.dark());
435  p->drawPolyline(a.constData() + 4, 2);
436  p->setPen(c.light());
437  p->drawPolyline(a.constData() + 5, 2);
438  p->setPen(c.dark());
439  p->drawPolyline(a.constData() + 6, 2);
440  }
441 
442  // draw inner vertical line for start/stop
443  // this overwrites borders of horizontal line
444  for(int i=0;i< item->jumpCount();i++) {
445  TraceLineJump* jump = item->jump(i);
446  if (jump == 0) continue;
447 
448  c = jump->isCondJump() ? Qt::red : Qt::blue;
449 
450  if (jump->lineFrom()->lineno() == lineno) {
451  bool drawUp = true;
452  if (jump->lineTo()->lineno() == lineno)
453  if (start<0) drawUp = false;
454  if (jump->lineTo()->lineno() > lineno) drawUp = false;
455  if (drawUp)
456  p->fillRect( marg + 6*i +1, 0, 2, yy, c);
457  else
458  p->fillRect( marg + 6*i +1, yy, 2, height-yy, c);
459  }
460  else if (jump->lineTo()->lineno() == lineno) {
461  if (end<0) end = i;
462  if (jump->lineFrom()->lineno() < lineno)
463  p->fillRect( marg + 6*i +1, 0, 2, yy, c);
464  else
465  p->fillRect( marg + 6*i +1, yy, 2, height-yy, c);
466  }
467  }
468  p->restore();
469 }
TraceCall::isRecursion
bool isRecursion()
Definition: tracedata.h:844
SourceItemDelegate::paintArrows
void paintArrows(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: sourceitem.cpp:343
TraceItemView::eventType2
EventType * eventType2() const
Definition: traceitemview.h:152
GlobalConfig::showPercentage
static bool showPercentage()
Definition: globalconfig.cpp:328
ProfileCostArray::subCost
SubCost subCost(EventType *)
Returns a sub cost.
Definition: costitem.cpp:591
TraceItemView::eventType
EventType * eventType() const
Definition: traceitemview.h:151
SourceItem::SourceItem
SourceItem(SourceView *sv, QTreeWidget *parent, int fileno, unsigned int lineno, bool inside, const QString &src, TraceLine *line=0)
Definition: sourceitem.cpp:41
QTreeWidget
TraceLineJump::lineTo
TraceLine * lineTo() const
Definition: tracedata.h:764
GlobalGUIConfig::functionColor
static QColor functionColor(ProfileContext::Type gt, TraceFunction *)
Definition: globalguiconfig.cpp:205
TraceFunction
A traced function.
Definition: tracedata.h:1122
TraceJumpCost::executedCount
SubCost executedCount()
Definition: tracedata.cpp:55
TraceFunctionSource::function
TraceFunction * function() const
Definition: tracedata.h:1041
TraceCallCost::callCount
SubCost callCount()
Definition: tracedata.cpp:125
SourceItem::updateCost
void updateCost()
Definition: sourceitem.cpp:161
uint64
unsigned long long uint64
Definition: subcost.h:27
SourceItem::lineno
uint lineno() const
Definition: sourceitem.h:52
TraceLineCall
A call from a line of one function to another function.
Definition: tracedata.h:808
sourceview.h
EventType
A cost type, e.g.
Definition: eventtype.h:43
SourceItem::jumpCount
int jumpCount() const
Definition: sourceitem.h:59
TraceItemView::setData
virtual void setData(TraceData *d)
Definition: traceitemview.cpp:165
TraceLine::prettyName
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
Definition: tracedata.cpp:1485
SourceItem::setJumpArray
void setJumpArray(const QVector< TraceLineJump * > &a)
Definition: sourceitem.cpp:288
ProfileCostArray
An array of basic cost metrics for a trace item.
Definition: costitem.h:144
SourceItem::inside
bool inside() const
Definition: sourceitem.h:54
SourceItem::jump
TraceLineJump * jump(int i) const
Definition: sourceitem.h:58
TraceLineCall::call
TraceCall * call() const
Definition: tracedata.h:817
listutils.h
SourceView::arrowLevels
int arrowLevels()
Definition: sourceview.h:43
TraceFunction::prettyName
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
Definition: tracedata.cpp:1889
CostItem::data
virtual TraceData * data()
Definition: costitem.cpp:111
TraceLine::lineno
uint lineno() const
Definition: tracedata.h:955
SourceItemDelegate::sizeHint
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: sourceitem.cpp:304
globalguiconfig.h
TraceLine
A source line of the program.
Definition: tracedata.h:935
SourceItem::updateGroup
void updateGroup()
Definition: sourceitem.cpp:152
TraceLineJump::isCondJump
bool isCondJump()
Definition: tracedata.h:765
TraceCall::inCycle
int inCycle()
Definition: tracedata.cpp:1202
TraceLine::name
virtual QString name() const
Returns dynamic name info (without type)
Definition: tracedata.cpp:1475
SourceItem::_jump
QVector< TraceLineJump * > _jump
Definition: sourceitem.h:68
QTreeWidgetItem
TraceLine::functionSource
TraceFunctionSource * functionSource() const
Definition: tracedata.h:954
SourceView
Definition: sourceview.h:31
SourceItem::lineCall
TraceLineCall * lineCall() const
Definition: sourceitem.h:56
SourceItemDelegate::SourceItemDelegate
SourceItemDelegate(SourceView *parent)
Definition: sourceitem.cpp:299
TraceLineJump::lineFrom
TraceLine * lineFrom() const
Definition: tracedata.h:763
GlobalConfig::showExpanded
static bool showExpanded()
Definition: globalconfig.cpp:333
GlobalConfig::percentPrecision
static int percentPrecision()
Definition: globalconfig.cpp:385
SourceItem::operator<
bool operator<(const QTreeWidgetItem &other) const
Definition: sourceitem.cpp:240
SubCost
Cost event counter, simple wrapper around a 64bit entity.
Definition: subcost.h:32
SourceItem::lineJump
TraceLineJump * lineJump() const
Definition: sourceitem.h:57
TraceCall::called
TraceFunction * called(bool skipCycle=false) const
Definition: tracedata.cpp:1235
sourceitem.h
TraceFunction::addPrettyLocation
void addPrettyLocation(QString &, int maxFiles=1) const
Definition: tracedata.cpp:2055
SubCost::pretty
QString pretty(char sep= ' ') const
Convert SubCost value into a QString, spaced every 3 digits.
Definition: subcost.cpp:46
SourceItemDelegate::paint
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: sourceitem.cpp:322
TraceJumpCost::followedCount
SubCost followedCount()
Definition: tracedata.cpp:62
TraceItemView::groupType
ProfileContext::Type groupType() const
Definition: traceitemview.h:153
costPixmap
QPixmap costPixmap(EventType *ct, ProfileCostArray *cost, double total, bool framed)
Definition: listutils.cpp:217
colorPixmap
QPixmap colorPixmap(int w, int h, QColor c)
Definition: listutils.cpp:32
TraceCall::calledName
QString calledName(bool skipCycle=false) const
Definition: tracedata.cpp:1264
TraceLineJump
A jump from one line to another inside of a function.
Definition: tracedata.h:754
SourceItem
Definition: sourceitem.h:33
SourceItemDelegate::_parent
SourceView * _parent
Definition: sourceitem.h:98
TraceInclusiveCost::inclusive
ProfileCostArray * inclusive()
Definition: tracedata.cpp:163
SourceItem::line
TraceLine * line() const
Definition: sourceitem.h:55
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:03:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kcachegrind

Skip menu "kcachegrind"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdesdk API Reference

Skip menu "kdesdk API Reference"
  • kapptemplate
  • kcachegrind
  • kompare
  • lokalize
  • okteta
  • umbrello
  •   umbrello

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal