You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdesdk/tdecachegrind/tdecachegrind/partgraph.cpp

535 lines
11 KiB

/* 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.
*/
/*
* TracePart as Nested Area
*/
#include <klocale.h>
#include "partgraph.h"
#include "configuration.h"
#include "listutils.h"
// PartAreaWidget
PartAreaWidget::PartAreaWidget(TQWidget* parent, const char* name)
: TreeMapWidget(new BasePartItem(), parent, name)
{
_data = 0;
_function = 0;
_costType = 0;
_groupType = TraceCost::NoCostType;
_visualisation = NoVisualisation;
_zoomFunction = false;
_callLevels = 1;
}
void PartAreaWidget::setData(TraceData* data)
{
if (data == _data) return;
_data = data;
_function = 0;
_hiddenParts.clear();
((BasePartItem*)base())->setData(data);
}
void PartAreaWidget::changeHidden(const TracePartList& list)
{
_hiddenParts = list;
base()->refresh();
}
void PartAreaWidget::setCostType(TraceCostType* ct)
{
_costType = ct;
// this resizes items
base()->redraw();
}
void PartAreaWidget::setVisualisation(VisualisationMode m)
{
_visualisation = m;
refreshParts();
}
void PartAreaWidget::setZoomFunction(bool zoomFunction)
{
_zoomFunction = zoomFunction;
refreshParts();
}
void PartAreaWidget::setCallLevels(int callLevels)
{
_callLevels = callLevels;
refreshParts();
}
void PartAreaWidget::refreshParts()
{
// rebuild only subparts to keep part selection state
TreeMapItem* i;
TreeMapItemList* l = base()->children();
if (l)
for (i=l->first();i;i=l->next())
i->refresh();
// but resize part areas
base()->redraw();
}
void PartAreaWidget::setFunction(TraceFunction* f)
{
_function = f;
if (_visualisation == PartAreaWidget::Inclusive)
refreshParts();
}
void PartAreaWidget::setGroupType(TraceCost::CostType gt)
{
_groupType = gt;
// rebuild hierarchy below parts.
// thus, selected parts stay selected
TreeMapItem* i;
TreeMapItemList* l = base()->children();
if (l)
for (i=l->first();i;i=l->next())
i->refresh();
base()->redraw();
}
bool PartAreaWidget::isHidden(TracePart* part) const
{
return (_hiddenParts.containsRef(part)>0);
}
TQColor PartAreaWidget::groupColor(TraceFunction* f) const
{
if (!f)
return colorGroup().button();
return Configuration::functionColor(_groupType, f);
}
TQString PartAreaWidget::tipString(TreeMapItem* i) const
{
TQString tip, itemTip;
int count = 0;
//tqDebug("PartAreaWidget::tipString for '%s'", i->name().ascii());
// first, SubPartItem's
while (i && count<Configuration::maxSymbolCount() && i->rtti() == 3) {
itemTip = i->text(0);
if ((int)itemTip.length()>Configuration::maxSymbolLength())
itemTip = itemTip.left(Configuration::maxSymbolLength()) + "...";
if (!i->text(1).isEmpty())
itemTip += " (" + i->text(1) + ")";
if (!tip.isEmpty())
itemTip += "\n";
tip = itemTip + tip;
i = i->parent();
count++;
}
// skip to part
while (i && i->rtti()==3) i = i->parent();
if (i && i->rtti()==2) {
itemTip = i18n("Profile Part %1").arg(i->text(0));
if (!i->text(1).isEmpty())
itemTip += " (" + i->text(1) + ")";
if (!tip.isEmpty())
itemTip += "\n";
tip = itemTip + tip;
}
// tqDebug("PartAreaWidget:: tip %s, itemTip %s",
// tip.ascii(), itemTip.ascii());
return tip;
}
// BasePartItem
BasePartItem::BasePartItem()
: TreeMapItem()
{
_data = 0;
setSorting(-1);
}
void BasePartItem::setData(TraceData* data)
{
if (data == _data) return;
_data = data;
refresh();
}
TreeMapItemList* BasePartItem::children()
{
if (!_data) return _children;
if (!initialized()) {
// tqDebug("Create Parts (%s)", name().ascii());
PartAreaWidget* w = (PartAreaWidget*) widget();
TracePart* part;
TracePartList l = _data->parts();
for (part=l.first();part;part=l.next())
if (!w->isHidden(part))
addItem(new PartItem(part));
}
return _children;
}
TQString BasePartItem::text(int textNo) const
{
if (textNo == 0) {
if (!_data)
return i18n("(no trace)");
if (_data->parts().count() == 0)
return i18n("(no part)");
}
return TQString();
}
TQColor BasePartItem::backColor() const
{
return widget()->colorGroup().base();
}
double BasePartItem::value() const
{
if (!_data) return 0;
PartAreaWidget* w = (PartAreaWidget*) widget();
return (double)_data->subCost(w->costType());
}
// PartItem
PartItem::PartItem(TracePart* p)
{
_p = p;
_factor=1;
}
TQString PartItem::text(int textNo) const
{
if (textNo == 0)
return _p->prettyName();
if (textNo != 1)
return TQString();
TraceCostType* ct;
PartAreaWidget* w = (PartAreaWidget*)widget();
SubCost v;
ct = w->costType();
v = _p->subCost(ct);
if (Configuration::showPercentage()) {
TraceCost* t = _p->data()->totals();
double p = 100.0 * v / t->subCost(ct);
return TQString("%1 %")
.arg(p, 0, 'f', Configuration::percentPrecision());
}
return v.pretty();
}
TQPixmap PartItem::pixmap(int i) const
{
if (i != 1) return TQPixmap();
// Cost pixmap
TraceCostType* ct = ((PartAreaWidget*)widget())->costType();
return costPixmap( ct, _p, (double) (_p->data()->totals()->subCost(ct)), false );
}
double PartItem::value() const
{
PartAreaWidget* w = (PartAreaWidget*)widget();
TraceCostType* ct = w->costType();
if ((w->visualisation() == PartAreaWidget::Inclusive) &&
w->zoomFunction()) {
// use value of zoomed function
TraceFunction* f = w->function();
if (f) {
TracePartFunction* pf = (TracePartFunction*) f->findDepFromPart(_p);
if (pf)
return (double) pf->inclusive()->subCost(ct);
// when function is not available in part, hide part
return 0.0;
}
}
return (double) _p->subCost(ct);
}
double PartItem::sum() const
{
PartAreaWidget* w = (PartAreaWidget*)widget();
if (w->visualisation() == PartAreaWidget::Inclusive) {
double s = value();
//tqDebug("PartItem::sum [part %s]: %d", _p->name().ascii(), s);
return s;
}
return 0.0;
}
TreeMapItemList* PartItem::children()
{
if (initialized()) return _children;
TraceCost* c;
// tqDebug("Create Part subitems (%s)", name().ascii());
PartAreaWidget* w = (PartAreaWidget*)widget();
if (w->visualisation() == PartAreaWidget::Inclusive) {
TraceFunction* f = w->function();
if (f) {
c = f->findDepFromPart(_p);
if (c) addItem(new SubPartItem(c));
}
return _children;
}
switch( ((PartAreaWidget*)widget())->groupType() ) {
case TraceCost::Object:
{
TraceObjectMap::Iterator it;
for ( it = _p->data()->objectMap().begin();
it != _p->data()->objectMap().end(); ++it ) {
c = (*it).findDepFromPart(_p);
if (c)
addItem(new SubPartItem(c));
}
}
break;
case TraceCost::Class:
{
TraceClassMap::Iterator it;
for ( it = _p->data()->classMap().begin();
it != _p->data()->classMap().end(); ++it ) {
c = (*it).findDepFromPart(_p);
if (c)
addItem(new SubPartItem(c));
}
}
break;
case TraceCost::File:
{
TraceFileMap::Iterator it;
for ( it = _p->data()->fileMap().begin();
it != _p->data()->fileMap().end(); ++it ) {
c = (*it).findDepFromPart(_p);
if (c)
addItem(new SubPartItem(c));
}
}
break;
case TraceCost::Function:
{
TraceFunctionMap::Iterator it;
for ( it = _p->data()->functionMap().begin();
it != _p->data()->functionMap().end(); ++it ) {
c = (*it).findDepFromPart(_p);
if (c)
addItem(new SubPartItem(c));
}
}
break;
default:
break;
}
return _children;
}
TQColor PartItem::backColor() const
{
PartAreaWidget* w = (PartAreaWidget*)widget();
return w->groupColor(0);
}
// SubPartItem
SubPartItem::SubPartItem(TraceCost* c)
{
_partCostItem = c;
_factor=1;
}
TQString SubPartItem::text(int textNo) const
{
if (textNo == 0) {
if (!_partCostItem)
return i18n("(unknown)");
return _partCostItem->dependant()->prettyName();
}
if (textNo != 1)
return TQString();
TraceCostType* ct;
PartAreaWidget* w = (PartAreaWidget*)widget();
SubCost v;
ct = w->costType();
if (w->visualisation() == PartAreaWidget::Inclusive)
v = ((TracePartFunction*)_partCostItem)->inclusive()->subCost(ct);
else
v = _partCostItem->subCost(ct);
if (Configuration::showPercentage()) {
TraceCost* t = Configuration::showExpanded() ?
_partCostItem->part() : _partCostItem->part()->data()->totals();
double p = 100.0 * v / t->subCost(ct);
return TQString("%1 %")
.arg(p, 0, 'f', Configuration::percentPrecision());
}
return v.pretty();
}
TQPixmap SubPartItem::pixmap(int i) const
{
if (i != 1) return TQPixmap();
// Cost pixmap
PartAreaWidget* w = (PartAreaWidget*)widget();
TraceCostType* ct = w->costType();
TraceCost* t = Configuration::showExpanded() ?
_partCostItem->part() : _partCostItem->part()->data()->totals();
TraceCost* c;
if (w->visualisation() == PartAreaWidget::Inclusive)
c = ((TracePartFunction*)_partCostItem)->inclusive();
else
c = _partCostItem;
return costPixmap( ct, c, (double) (t->subCost(ct)), false );
}
double SubPartItem::value() const
{
TraceCostType* ct;
PartAreaWidget* w = (PartAreaWidget*)widget();
ct = w->costType();
if (w->visualisation() == PartAreaWidget::Inclusive)
return (double)
((TracePartFunction*)_partCostItem)->inclusive()->subCost(ct);
return (double) _partCostItem->subCost(ct);
}
double SubPartItem::sum() const
{
PartAreaWidget* w = (PartAreaWidget*)widget();
if (w->visualisation() == PartAreaWidget::Inclusive) {
double s = value();
//tqDebug("SubPartItem::sum [Cost %s]: %d", _cost->name().ascii(), s);
return s;
}
return 0.0;
}
TreeMapItemList* SubPartItem::children()
{
if (!initialized()) {
// tqDebug("Create Part sub-subitems (%s)", name().ascii());
PartAreaWidget* w = (PartAreaWidget*)widget();
if (depth()-2 > w->callLevels())
return _children;
if (w->visualisation() == PartAreaWidget::Inclusive) {
TracePartCall* call;
TracePartCallList l;
setSum(value());
l = ((TracePartFunction*)_partCostItem)->partCallings();
for (call=l.first();call;call=l.next()) {
TraceFunction* called = call->call()->called();
TraceCost* partCalled = called->findDepFromPart(call->part());
if (partCalled)
addItem(new SubPartItem(partCalled));
}
}
}
return _children;
}
TQColor SubPartItem::backColor() const
{
PartAreaWidget* w = (PartAreaWidget*)widget();
if (w->visualisation() == PartAreaWidget::Inclusive)
return w->groupColor((TraceFunction*)(_partCostItem->dependant()));
return Configuration::groupColor(_partCostItem->dependant());
}
#include "partgraph.moc"