summaryrefslogtreecommitdiffstats
path: root/tdecachegrind/tdecachegrind/coverageview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdecachegrind/tdecachegrind/coverageview.cpp')
-rw-r--r--tdecachegrind/tdecachegrind/coverageview.cpp321
1 files changed, 321 insertions, 0 deletions
diff --git a/tdecachegrind/tdecachegrind/coverageview.cpp b/tdecachegrind/tdecachegrind/coverageview.cpp
new file mode 100644
index 00000000..6657e923
--- /dev/null
+++ b/tdecachegrind/tdecachegrind/coverageview.cpp
@@ -0,0 +1,321 @@
+/* This file is part of KCachegrind.
+ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
+
+ KCachegrind is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation, version 2.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/*
+ * Coverage Views
+ */
+
+#include <tqwhatsthis.h>
+#include <tqpopupmenu.h>
+#include <klocale.h>
+
+#include "configuration.h"
+#include "coverageitem.h"
+#include "coverage.h"
+#include "coverageview.h"
+
+
+
+//
+// CoverageView
+//
+
+
+CoverageView::CoverageView(bool showCallers, TraceItemView* parentView,
+ TQWidget* parent, const char* name)
+ : TQListView(parent, name), TraceItemView(parentView)
+{
+ _showCallers = showCallers;
+
+
+ addColumn( i18n( "Incl." ) );
+ if (_showCallers) {
+ addColumn( i18n( "Distance" ) );
+ addColumn( i18n( "Called" ) );
+ addColumn( i18n( "Caller" ) );
+ }
+ else {
+ addColumn( i18n( "Self" ) );
+ addColumn( i18n( "Distance" ) );
+ addColumn( i18n( "Calling" ) );
+ addColumn( i18n( "Callee" ) );
+ setColumnAlignment(3, TQt::AlignRight);
+ }
+
+ setSorting(0,false);
+ setColumnAlignment(0, TQt::AlignRight);
+ setColumnAlignment(1, TQt::AlignRight);
+ setColumnAlignment(2, TQt::AlignRight);
+ setAllColumnsShowFocus(true);
+ setResizeMode(TQListView::LastColumn);
+ setMinimumHeight(50);
+
+ connect( this,
+ TQT_SIGNAL( selectionChanged(TQListViewItem*) ),
+ TQT_SLOT( selectedSlot(TQListViewItem*) ) );
+
+ connect( this,
+ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
+ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int)));
+
+ connect(this,
+ TQT_SIGNAL(doubleClicked(TQListViewItem*)),
+ TQT_SLOT(activatedSlot(TQListViewItem*)));
+
+ connect(this,
+ TQT_SIGNAL(returnPressed(TQListViewItem*)),
+ TQT_SLOT(activatedSlot(TQListViewItem*)));
+
+ TQWhatsThis::add( this, whatsThis() );
+}
+
+TQString CoverageView::whatsThis() const
+{
+ return _showCallers ?
+ i18n( "<b>List of all Callers</b>"
+ "<p>This list shows all functions calling the "
+ "current selected one, either directly or with "
+ "several functions in-between on the stack; the "
+ "number of functions in-between plus one "
+ "is called the <em>Distance</em> (e.g. "
+ "for function A,B,C there exists a call from "
+ "A to C when A calls B and B calls C, i.e. "
+ "A => B => C. The distance here is 2).</p>"
+
+ "<p>Absolute cost shown is the cost spent in the "
+ "selected function while a listed function is active; "
+ "relative cost is the percentage of all cost spent in "
+ "the selected function while the listed one is "
+ "active. The cost graphic shows logarithmic "
+ "percentage with a different color for each "
+ "distance.</p>"
+
+ "<p>As there can be many calls from the same function, "
+ "the distance column sometimes shows "
+ "the range of distances for all "
+ "calls happening; then, in parentheses, there is the "
+ "medium distance, i.e. the distance where most of the "
+ "call costs happened.</p>"
+
+ "<p>Selecting a function makes it the current selected "
+ "one of this information panel. "
+ "If there are two panels (Split mode), the "
+ "function of the other panel is changed instead.</p>") :
+
+ i18n( "<b>List of all Callees</b>"
+ "<p>This list shows all functions called by the "
+ "current selected one, either directly or with "
+ "several function in-between on the stack; the "
+ "number of function in-between plus one "
+ "is called the <em>Distance</em> (e.g. "
+ "for function A,B,C there exists a call from "
+ "A to C when A calls B and B calls C, i.e. "
+ "A => B => C. The distance here is 2).</p>"
+
+ "<p>Absolute cost shown is the cost spent in the "
+ "listed function while the selected is active; "
+ "relative cost is the percentage of all cost spent in "
+ "the listed function while the selected one is active. "
+ "The cost graphic always shows logarithmic "
+ "percentage with a different color for each "
+ "distance.</p>"
+
+ "<p>As there can be many calls to the same function, "
+ "the distance column sometimes shows "
+ "the range of distances for all "
+ "calls happening; then, in parentheses, there is the "
+ "medium distance, i.e. the distance where most of the "
+ "call costs happened.</p>"
+
+ "<p>Selecting a function makes it the current selected "
+ "one of this information panel. "
+ "If there are two panels (Split mode), the "
+ "function of the other panel is changed instead.</p>");
+}
+
+void CoverageView::context(TQListViewItem* i, const TQPoint & p, int c)
+{
+ TQPopupMenu popup;
+
+ TraceFunction* f = 0;
+ if (i) {
+ f = _showCallers ?
+ ((CallerCoverageItem*)i)->function() :
+ ((CalleeCoverageItem*)i)->function();
+ }
+
+ if (f) {
+ TQString name = f->name();
+ if ((int)name.length()>Configuration::maxSymbolLength())
+ name = name.left(Configuration::maxSymbolLength()) + "...";
+ popup.insertItem(i18n("Go to '%1'").arg(name), 93);
+ popup.insertSeparator();
+ }
+
+ if ((c == 0) || (!_showCallers && c == 1)) {
+ addCostMenu(&popup, false);
+ popup.insertSeparator();
+ }
+ addGoMenu(&popup);
+
+ int r = popup.exec(p);
+ if (r == 93) activated(f);
+}
+
+void CoverageView::selectedSlot(TQListViewItem * i)
+{
+ TraceFunction* f = 0;
+ if (i) {
+ f = _showCallers ?
+ ((CallerCoverageItem*)i)->function() :
+ ((CalleeCoverageItem*)i)->function();
+ }
+
+ if (f) {
+ _selectedItem = f;
+ selected(f);
+ }
+}
+
+void CoverageView::activatedSlot(TQListViewItem * i)
+{
+ TraceFunction* f = 0;
+ if (i) {
+ f = _showCallers ?
+ ((CallerCoverageItem*)i)->function() :
+ ((CalleeCoverageItem*)i)->function();
+ }
+
+ if (f) activated(f);
+}
+
+TraceItem* CoverageView::canShow(TraceItem* i)
+{
+ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType;
+
+ switch(t) {
+ case TraceItem::Function:
+ case TraceItem::FunctionCycle:
+ return i;
+ default:
+ break;
+ }
+ return 0;
+}
+
+void CoverageView::doUpdate(int changeType)
+{
+ // Special case ?
+ if (changeType == selectedItemChanged) {
+
+ if (!_selectedItem) {
+ clearSelection();
+ return;
+ }
+
+ TraceFunction* f = 0;
+ TQListViewItem* i = TQListView::selectedItem();
+ if (i) {
+ f = _showCallers ?
+ ((CallerCoverageItem*)i)->function() :
+ ((CalleeCoverageItem*)i)->function();
+ }
+ if (f == _selectedItem) return;
+
+ TQListViewItem *item;
+ for (item = firstChild();item;item = item->nextSibling()) {
+ f = _showCallers ?
+ ((CallerCoverageItem*)item)->function() :
+ ((CalleeCoverageItem*)item)->function();
+ if (f == _selectedItem) {
+ ensureItemVisible(item);
+ setCurrentItem(item);
+ break;
+ }
+ }
+ return;
+ }
+
+ if (changeType == groupTypeChanged) {
+ TQListViewItem *item;
+ for (item = firstChild();item;item = item->nextSibling()) {
+ if (_showCallers)
+ ((CallerCoverageItem*)item)->setGroupType(_groupType);
+ else
+ ((CalleeCoverageItem*)item)->setGroupType(_groupType);
+ }
+ return;
+ }
+
+ refresh();
+}
+
+void CoverageView::refresh()
+{
+ clear();
+ setColumnWidth(0, 50);
+ if (!_showCallers)
+ setColumnWidth(1, 50);
+
+ if (!_data || !_activeItem) return;
+
+ TraceItem::CostType t = _activeItem->type();
+ TraceFunction* f = 0;
+ if (t == TraceItem::Function) f = (TraceFunction*) _activeItem;
+ if (t == TraceItem::FunctionCycle) f = (TraceFunction*) _activeItem;
+ if (!f) return;
+
+ TraceFunction* ff;
+ TraceFunctionList l;
+
+ _hc.clear(Configuration::maxListCount());
+ SubCost realSum = f->inclusive()->subCost(_costType);
+
+ if (_showCallers)
+ l = Coverage::coverage(f, Coverage::Caller, _costType);
+ else
+ l = Coverage::coverage(f, Coverage::Called, _costType);
+
+ for (ff=l.first();ff;ff=l.next()) {
+ Coverage* c = (Coverage*) ff->assoziation(Coverage::Rtti);
+ if (c && (c->inclusive()>0.0))
+ _hc.addCost(ff, SubCost(realSum * c->inclusive()));
+ }
+
+ for(int i=0;i<_hc.realCount();i++) {
+ ff = (TraceFunction*) _hc[i];
+ Coverage* c = (Coverage*) ff->assoziation(Coverage::Rtti);
+ if (_showCallers)
+ new CallerCoverageItem(this, c, f, _costType, _groupType);
+ else
+ new CalleeCoverageItem(this, c, f, _costType, _groupType);
+ }
+ if (_hc.hasMore()) {
+ // a placeholder for all the functions skipped ...
+ ff = (TraceFunction*) _hc[_hc.maxSize()-1];
+ Coverage* c = (Coverage*) ff->assoziation(Coverage::Rtti);
+ if (_showCallers)
+ new CallerCoverageItem(this, _hc.count() - _hc.maxSize(),
+ c, f, _costType, _groupType);
+ else
+ new CalleeCoverageItem(this, _hc.count() - _hc.maxSize(),
+ c, f, _costType, _groupType);
+ }
+}
+
+#include "coverageview.moc"