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.
872 lines
23 KiB
872 lines
23 KiB
/* This file is part of KCachegrind.
|
|
Copyright (C) 2002, 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.
|
|
*/
|
|
|
|
/*
|
|
* For function selection, to be put into a TQDockWindow
|
|
*/
|
|
|
|
#include <tqtimer.h>
|
|
#include <tqlistview.h>
|
|
#include <tqlabel.h>
|
|
#include <tqpushbutton.h>
|
|
#include <tqcombobox.h>
|
|
#include <tqlineedit.h>
|
|
#include <tqregexp.h>
|
|
#include <tqpopupmenu.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include "traceitemview.h"
|
|
#include "stackbrowser.h"
|
|
#include "functionselection.h"
|
|
#include "partgraph.h"
|
|
#include "functionitem.h"
|
|
#include "costlistitem.h"
|
|
#include "configuration.h"
|
|
#include "toplevel.h"
|
|
|
|
FunctionSelection::FunctionSelection( TopLevel* top,
|
|
TQWidget* parent, const char* name)
|
|
: FunctionSelectionBase(parent, name), TraceItemView(0, top)
|
|
{
|
|
_group = 0;
|
|
_inSetGroup = false;
|
|
_inSetFunction = false;
|
|
|
|
TQStringList args;
|
|
args << i18n("(No Grouping)")
|
|
<< TraceCost::i18nTypeName(TraceItem::Object)
|
|
<< TraceCost::i18nTypeName(TraceItem::File)
|
|
<< TraceCost::i18nTypeName(TraceItem::Class)
|
|
<< TraceCost::i18nTypeName(TraceItem::FunctionCycle);
|
|
|
|
groupBox->insertStringList(args);
|
|
// this needs same order of grouptype actionlist!
|
|
connect(groupBox, TQT_SIGNAL(activated(int)),
|
|
top, TQT_SLOT(groupTypeSelected(int)));
|
|
|
|
// search while typing...
|
|
connect(searchEdit, TQT_SIGNAL(textChanged(const TQString&)),
|
|
this, TQT_SLOT(searchChanged(const TQString&)));
|
|
connect(&_searchTimer, TQT_SIGNAL(timeout()),
|
|
this, TQT_SLOT(queryDelayed()));
|
|
// select first matching group/function on return
|
|
connect(searchEdit, TQT_SIGNAL(returnPressed()),
|
|
this, TQT_SLOT(searchReturnPressed()));
|
|
searchEdit->setMinimumWidth(50);
|
|
|
|
// we start with desending cost sorting
|
|
functionList->setSorting(0,false);
|
|
functionList->setColumnAlignment(0, TQt::AlignRight);
|
|
functionList->setColumnAlignment(1, TQt::AlignRight);
|
|
functionList->setColumnAlignment(2, TQt::AlignRight);
|
|
functionList->setAllColumnsShowFocus(true);
|
|
// functionList->setShowSortIndicator(true);
|
|
// we can have very long function and location names
|
|
functionList->setColumnWidthMode(3, TQListView::Manual);
|
|
functionList->setColumnWidth(3, 200);
|
|
functionList->setColumnWidthMode(4, TQListView::Manual);
|
|
functionList->setColumnWidth(4, 200);
|
|
|
|
groupList->setSorting(0,false);
|
|
groupList->setColumnAlignment(0, TQt::AlignRight);
|
|
groupList->setAllColumnsShowFocus(true);
|
|
// groupList->setShowSortIndicator(true);
|
|
groupList->setResizeMode(TQListView::LastColumn);
|
|
|
|
#if 0
|
|
// single click press activation
|
|
connect(functionList, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
|
|
this, TQT_SLOT(functionActivated(TQListViewItem*)));
|
|
connect(functionList,
|
|
TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
|
|
this, TQT_SLOT(functionContext(TQListViewItem*, const TQPoint &, int)));
|
|
#else
|
|
// single click release activation
|
|
connect(functionList, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
|
|
this, TQT_SLOT(functionSelected(TQListViewItem*)));
|
|
connect(functionList, TQT_SIGNAL(clicked(TQListViewItem*)),
|
|
this, TQT_SLOT(functionActivated(TQListViewItem*)));
|
|
connect(functionList, TQT_SIGNAL(returnPressed(TQListViewItem*)),
|
|
this, TQT_SLOT(functionActivated(TQListViewItem*)));
|
|
connect(functionList,
|
|
TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
|
|
this, TQT_SLOT(functionContext(TQListViewItem*, const TQPoint &, int)));
|
|
#endif
|
|
|
|
connect(groupList, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
|
|
this, TQT_SLOT(groupSelected(TQListViewItem*)));
|
|
connect(groupList, TQT_SIGNAL(doubleClicked(TQListViewItem*)),
|
|
this, TQT_SLOT(groupDoubleClicked(TQListViewItem*)));
|
|
connect(groupList, TQT_SIGNAL(returnPressed(TQListViewItem*)),
|
|
this, TQT_SLOT(groupDoubleClicked(TQListViewItem*)));
|
|
connect(groupList,
|
|
TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
|
|
this, TQT_SLOT(groupContext(TQListViewItem*, const TQPoint &, int)));
|
|
|
|
// start hidden
|
|
groupList->hide();
|
|
}
|
|
|
|
FunctionSelection::~FunctionSelection()
|
|
{
|
|
}
|
|
|
|
void FunctionSelection::searchReturnPressed()
|
|
{
|
|
query(searchEdit->text());
|
|
|
|
TQListViewItem* item;
|
|
if (_groupType != TraceItem::Function) {
|
|
// if current group not matching, select first matching group
|
|
item = groupList->currentItem();
|
|
if (!item || !item->isVisible()) {
|
|
item = groupList->firstChild();
|
|
for (;item;item = item->nextSibling())
|
|
if (item->isVisible()) break;
|
|
if (!item) return;
|
|
|
|
setGroup(((CostListItem*)item)->costItem());
|
|
return;
|
|
}
|
|
}
|
|
|
|
functionActivated(functionList->firstChild());
|
|
}
|
|
|
|
// trigger the query after some delay, dependent on length
|
|
void FunctionSelection::searchChanged(const TQString& q)
|
|
{
|
|
_searchDelayed = q;
|
|
int ms = 100;
|
|
if (q.length()<5) ms = 200;
|
|
if (q.length()<2) ms = 300;
|
|
_searchTimer.start(ms,true);
|
|
}
|
|
|
|
void FunctionSelection::queryDelayed()
|
|
{
|
|
query(_searchDelayed);
|
|
}
|
|
|
|
void FunctionSelection::functionContext(TQListViewItem* i,
|
|
const TQPoint & p, int c)
|
|
{
|
|
TQPopupMenu popup;
|
|
TraceFunction* f = 0;
|
|
|
|
if (i) {
|
|
f = ((FunctionItem*) i)->function();
|
|
if (f) {
|
|
popup.insertItem(i18n("Go to %1").tqarg(f->prettyName()), 93);
|
|
popup.insertSeparator();
|
|
}
|
|
}
|
|
|
|
if ((c == 0) || (c == 1)) {
|
|
addCostMenu(&popup,false);
|
|
popup.insertSeparator();
|
|
}
|
|
addGroupMenu(&popup);
|
|
popup.insertSeparator();
|
|
addGoMenu(&popup);
|
|
|
|
int r = popup.exec(p);
|
|
if (r == 93) activated(f);
|
|
}
|
|
|
|
void FunctionSelection::groupContext(TQListViewItem* /*i*/,
|
|
const TQPoint & p, int c)
|
|
{
|
|
TQPopupMenu popup;
|
|
|
|
#if 0
|
|
TraceCostItem* g = 0;
|
|
if (i) {
|
|
g = ((CostListItem*) i)->costItem();
|
|
if (!g) {
|
|
popup.insertItem(i18n("Show All Items"), 93);
|
|
popup.insertSeparator();
|
|
}
|
|
}
|
|
#endif
|
|
if (c == 0) {
|
|
addCostMenu(&popup,false);
|
|
popup.insertSeparator();
|
|
}
|
|
addGroupMenu(&popup);
|
|
popup.insertSeparator();
|
|
addGoMenu(&popup);
|
|
|
|
popup.exec(p);
|
|
}
|
|
|
|
|
|
void FunctionSelection::addGroupMenu(TQPopupMenu* popup)
|
|
{
|
|
TQPopupMenu *popup1 = new TQPopupMenu(popup);
|
|
popup1->setCheckable(true);
|
|
|
|
if (_groupType != TraceItem::Function) {
|
|
popup1->insertItem(i18n("No Grouping"),0);
|
|
popup1->insertSeparator();
|
|
}
|
|
popup1->insertItem(TraceCost::i18nTypeName(TraceItem::Object),1);
|
|
popup1->insertItem(TraceCost::i18nTypeName(TraceItem::File),2);
|
|
popup1->insertItem(TraceCost::i18nTypeName(TraceItem::Class),3);
|
|
popup1->insertItem(TraceCost::i18nTypeName(TraceItem::FunctionCycle),4);
|
|
switch(_groupType) {
|
|
case TraceItem::Object: popup1->setItemChecked(1, true); break;
|
|
case TraceItem::File: popup1->setItemChecked(2, true); break;
|
|
case TraceItem::Class: popup1->setItemChecked(3, true); break;
|
|
case TraceItem::FunctionCycle: popup1->setItemChecked(4, true); break;
|
|
default: break;
|
|
}
|
|
connect(popup1,TQT_SIGNAL(activated(int)),
|
|
_topLevel,TQT_SLOT(groupTypeSelected(int)));
|
|
|
|
popup->insertItem(i18n("Grouping"), popup1);
|
|
}
|
|
|
|
|
|
TraceItem* FunctionSelection::canShow(TraceItem* i)
|
|
{
|
|
TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType;
|
|
|
|
switch(t) {
|
|
case TraceItem::Function:
|
|
case TraceItem::FunctionCycle:
|
|
case TraceItem::Object:
|
|
case TraceItem::File:
|
|
case TraceItem::Class:
|
|
break;
|
|
|
|
case TraceItem::Instr:
|
|
i = ((TraceInstr*)i)->function();
|
|
break;
|
|
|
|
case TraceItem::Line:
|
|
i = ((TraceLine*)i)->functionSource()->function();
|
|
break;
|
|
|
|
default:
|
|
i = 0;
|
|
break;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
|
|
void FunctionSelection::doUpdate(int changeType)
|
|
{
|
|
// Special case ?
|
|
if (changeType == selectedItemChanged) return;
|
|
|
|
// we don't show cost 2 at all...
|
|
if (changeType == costType2Changed) return;
|
|
|
|
if (changeType == activeItemChanged) {
|
|
if (_activeItem ==0) {
|
|
functionList->clearSelection();
|
|
return;
|
|
}
|
|
switch(_activeItem->type()) {
|
|
case TraceItem::Object:
|
|
case TraceItem::File:
|
|
case TraceItem::Class:
|
|
setGroup((TraceCostItem*)_activeItem);
|
|
return;
|
|
default: break;
|
|
}
|
|
|
|
// active item is a function
|
|
TraceFunction* f = (TraceFunction*) _activeItem;
|
|
|
|
// if already current, nothing to do
|
|
TQListViewItem* i = functionList->currentItem();
|
|
if (i && (((FunctionItem*)i)->function() == f)) {
|
|
functionList->setSelected(i,true);
|
|
return;
|
|
}
|
|
|
|
// reset searchEdit (as not activated from this view)
|
|
_searchString = TQString();
|
|
query(TQString());
|
|
|
|
// select cost item group of function
|
|
switch(_groupType) {
|
|
case TraceItem::Object: setGroup(f->object()); break;
|
|
case TraceItem::Class: setGroup(f->cls()); break;
|
|
case TraceItem::File: setGroup(f->file()); break;
|
|
case TraceItem::FunctionCycle: setGroup(f->cycle()); break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
TQListViewItem* item = functionList->firstChild();
|
|
for (;item;item = item->nextSibling())
|
|
if (((FunctionItem*)item)->function() == f)
|
|
break;
|
|
|
|
if (!item)
|
|
item = new FunctionItem(functionList, f, _costType, _groupType);
|
|
|
|
functionList->ensureItemVisible(item);
|
|
// prohibit signalling of a function selection
|
|
_inSetFunction = true;
|
|
functionList->setSelected(item, true);
|
|
_inSetFunction = false;
|
|
|
|
return;
|
|
}
|
|
|
|
if (changeType & groupTypeChanged) {
|
|
if (_activeItem && (_activeItem->type() == TraceItem::Function)) {
|
|
TraceFunction* f = (TraceFunction*) _activeItem;
|
|
|
|
// select cost item group of function
|
|
switch(_groupType) {
|
|
case TraceItem::Object: _group = f->object(); break;
|
|
case TraceItem::Class: _group = f->cls(); break;
|
|
case TraceItem::File: _group = f->file(); break;
|
|
case TraceItem::FunctionCycle: _group = f->cycle(); break;
|
|
default:
|
|
_group = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
int id;
|
|
switch(_groupType) {
|
|
case TraceItem::Object: id = 1; break;
|
|
case TraceItem::File: id = 2; break;
|
|
case TraceItem::Class: id = 3; break;
|
|
case TraceItem::FunctionCycle: id = 4; break;
|
|
default: id = 0; break;
|
|
}
|
|
groupBox->setCurrentItem(id);
|
|
|
|
if (_groupType == TraceItem::Function)
|
|
groupList->hide();
|
|
else
|
|
groupList->show();
|
|
}
|
|
|
|
// reset searchEdit
|
|
_searchString = TQString();
|
|
query(TQString());
|
|
|
|
refresh();
|
|
}
|
|
|
|
|
|
/*
|
|
* This set/selects a group of the set available within the
|
|
* current group type
|
|
*/
|
|
void FunctionSelection::setGroup(TraceCostItem* g)
|
|
{
|
|
if (!g) return;
|
|
if (g->type() != _groupType) return;
|
|
if (g == _group) return;
|
|
_group = g;
|
|
|
|
TQListViewItem* item = groupList->firstChild();
|
|
for (;item;item = item->nextSibling())
|
|
if (((CostListItem*)item)->costItem() == g)
|
|
break;
|
|
|
|
if (item) {
|
|
groupList->ensureItemVisible(item);
|
|
// prohibit signalling of a group selection
|
|
_inSetGroup = true;
|
|
groupList->setSelected(item, true);
|
|
_inSetGroup = false;
|
|
}
|
|
else
|
|
groupList->clearSelection();
|
|
}
|
|
|
|
|
|
void FunctionSelection::refresh()
|
|
{
|
|
groupList->setUpdatesEnabled(false);
|
|
groupList->clear();
|
|
|
|
// make cost columns as small as possible:
|
|
// the new functions make them as wide as needed
|
|
groupList->setColumnWidth(0, 50);
|
|
|
|
groupList->setColumnText(1, TraceItem::i18nTypeName(_groupType));
|
|
|
|
if (!_data || _data->parts().count()==0) {
|
|
functionList->clear();
|
|
groupList->setUpdatesEnabled(true);
|
|
groupList->tqrepaint();
|
|
|
|
// this clears all other lists
|
|
functionList->setSelected(functionList->firstChild(), true);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
qDebug("FunctionSelection::fillLists (%s)",
|
|
_data->command().ascii());
|
|
*/
|
|
|
|
TraceObjectMap::Iterator oit;
|
|
TraceClassMap::Iterator cit;
|
|
TraceFileMap::Iterator fit;
|
|
TQListViewItem *i = 0, *item = 0, *fitem = 0;
|
|
|
|
// Fill up group list.
|
|
// Always show group of current function, even if cost below low limit.
|
|
//
|
|
|
|
_hc.clear(Configuration::maxListCount());
|
|
|
|
TraceCostItem *group;
|
|
|
|
// update group from _activeItem if possible
|
|
if (_activeItem && (_activeItem->type() == _groupType))
|
|
_group = (TraceCostItem*) _activeItem;
|
|
|
|
switch(_groupType) {
|
|
case TraceItem::Object:
|
|
|
|
for ( oit = _data->objectMap().begin();
|
|
oit != _data->objectMap().end(); ++oit )
|
|
_hc.addCost(&(*oit), (*oit).subCost(_costType));
|
|
break;
|
|
|
|
case TraceItem::Class:
|
|
|
|
for ( cit = _data->classMap().begin();
|
|
cit != _data->classMap().end(); ++cit )
|
|
_hc.addCost(&(*cit), (*cit).subCost(_costType));
|
|
break;
|
|
|
|
case TraceItem::File:
|
|
|
|
for ( fit = _data->fileMap().begin();
|
|
fit != _data->fileMap().end(); ++fit )
|
|
_hc.addCost(&(*fit), (*fit).subCost(_costType));
|
|
break;
|
|
|
|
case TraceItem::FunctionCycle:
|
|
{
|
|
// add all cycles
|
|
TraceFunctionCycleList l = _data->functionCycles();
|
|
for (group=l.first();group;group=l.next())
|
|
_hc.addCost(group, group->subCost(_costType));
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
{
|
|
TQListViewItem* oldItem = functionList->selectedItem();
|
|
TraceFunction* oldFunction = 0;
|
|
int oldPos = 0;
|
|
if (oldItem) {
|
|
oldFunction = ((FunctionItem*)oldItem)->function();
|
|
oldPos = oldItem->itemPos();
|
|
oldPos -= functionList->contentsY();
|
|
if (oldPos < 0 || oldPos > functionList->height())
|
|
oldFunction = 0;
|
|
}
|
|
|
|
// switching off TQListView updates is buggy with some QT versions...
|
|
//functionList->setUpdatesEnabled(false);
|
|
functionList->clear();
|
|
setCostColumnWidths();
|
|
|
|
if (0) qDebug("Function %s at %d, Item %p",
|
|
oldFunction ? oldFunction->name().ascii() : "-",
|
|
oldPos, (void*)oldItem);
|
|
|
|
TraceFunctionMap::Iterator it;
|
|
TraceFunction *f;
|
|
i = 0;
|
|
fitem = 0;
|
|
for ( it = _data->functionMap().begin();
|
|
it != _data->functionMap().end(); ++it )
|
|
_hc.addCost(&(*it), (*it).inclusive()->subCost(_costType));
|
|
|
|
TraceFunctionCycleList l = _data->functionCycles();
|
|
for (f=l.first();f;f=l.next())
|
|
_hc.addCost(f, f->inclusive()->subCost(_costType));
|
|
|
|
if (_activeItem &&
|
|
((_activeItem->type() == TraceItem::Function) ||
|
|
(_activeItem->type() == TraceItem::FunctionCycle)))
|
|
fitem = new FunctionItem(functionList, (TraceFunction*)_activeItem,
|
|
_costType, _groupType);
|
|
|
|
for(int i=0;i<_hc.realCount();i++) {
|
|
f = (TraceFunction*)_hc[i];
|
|
if (f == _activeItem) continue;
|
|
new FunctionItem(functionList, f, _costType, _groupType);
|
|
}
|
|
if (_hc.hasMore()) {
|
|
// a placeholder for all the cost items skipped ...
|
|
new FunctionItem(functionList, _hc.count() - _hc.maxSize(),
|
|
(TraceFunction*)_hc[_hc.maxSize()-1], _costType);
|
|
}
|
|
functionList->sort();
|
|
|
|
if (fitem && oldFunction) {
|
|
_inSetFunction = true;
|
|
functionList->setSelected(fitem, true);
|
|
_inSetFunction = false;
|
|
int newPos = functionList->itemPos(fitem) - functionList->contentsY();
|
|
functionList->scrollBy(0, newPos-oldPos);
|
|
}
|
|
else if (fitem) {
|
|
functionList->ensureItemVisible(fitem);
|
|
_inSetFunction = true;
|
|
functionList->setSelected(fitem, true);
|
|
_inSetFunction = false;
|
|
}
|
|
else
|
|
functionList->clearSelection();
|
|
|
|
//functionList->setUpdatesEnabled(true);
|
|
//functionList->tqrepaint();
|
|
groupList->setUpdatesEnabled(true);
|
|
groupList->tqrepaint();
|
|
return;
|
|
}
|
|
}
|
|
|
|
// we always put group of active item in list, even if
|
|
// it would be skipped because of small costs
|
|
if (_group)
|
|
item = new CostListItem(groupList, _group, _costType);
|
|
|
|
for(int i=0;i<_hc.realCount();i++) {
|
|
group = (TraceCostItem*)_hc[i];
|
|
// don't put group of active item twice into list
|
|
if (group == _group) continue;
|
|
new CostListItem(groupList, group, _costType);
|
|
}
|
|
if (_hc.hasMore()) {
|
|
// a placeholder for all the cost items skipped ...
|
|
new CostListItem(groupList, _hc.count() - _hc.maxSize(),
|
|
(TraceCostItem*)_hc[_hc.maxSize()-1], _costType);
|
|
}
|
|
groupList->sort();
|
|
if (item) {
|
|
groupList->ensureItemVisible(item);
|
|
_inSetGroup = true;
|
|
groupList->setSelected(item, true);
|
|
_inSetGroup = false;
|
|
}
|
|
else
|
|
groupList->clearSelection();
|
|
|
|
groupList->setUpdatesEnabled(true);
|
|
groupList->tqrepaint();
|
|
}
|
|
|
|
|
|
void FunctionSelection::groupSelected(TQListViewItem* i)
|
|
{
|
|
if (!i) return;
|
|
if (!_data) return;
|
|
|
|
TraceCostItem* g = ((CostListItem*) i)->costItem();
|
|
if (!g) return;
|
|
|
|
_group = g;
|
|
|
|
TraceFunctionList list;
|
|
|
|
switch(g->type()) {
|
|
case TraceItem::Object:
|
|
list = ((TraceObject*)g)->functions();
|
|
break;
|
|
case TraceItem::Class:
|
|
list = ((TraceClass*)g)->functions();
|
|
break;
|
|
case TraceItem::File:
|
|
list = ((TraceFile*)g)->functions();
|
|
break;
|
|
case TraceItem::FunctionCycle:
|
|
list = ((TraceFunctionCycle*)g)->members();
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
// switching off TQListView updates is buggy with some QT versions...
|
|
//functionList->setUpdatesEnabled(false);
|
|
|
|
functionList->clear();
|
|
setCostColumnWidths();
|
|
|
|
double total;
|
|
if (Configuration::showExpanded())
|
|
total = (double) g->subCost(_costType);
|
|
else
|
|
total = (double) _data->subCost(_costType);
|
|
#if 0
|
|
if (total == 0.0) {
|
|
functionList->setUpdatesEnabled(true);
|
|
functionList->tqrepaint();
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
TQRegExp re(_searchString, false, true);
|
|
|
|
FunctionItem* fitem = 0;
|
|
TraceFunction *f;
|
|
_hc.clear(Configuration::maxListCount());
|
|
for (f=list.first();f;f=list.next()) {
|
|
if (re.search(f->prettyName())<0) continue;
|
|
|
|
_hc.addCost(f, f->inclusive()->subCost(_costType));
|
|
if (_activeItem == f)
|
|
fitem = new FunctionItem(functionList, (TraceFunction*)_activeItem,
|
|
_costType, _groupType);
|
|
}
|
|
|
|
for(int i=0;i<_hc.realCount();i++) {
|
|
if (_activeItem == (TraceFunction*)_hc[i]) continue;
|
|
new FunctionItem(functionList, (TraceFunction*)_hc[i],
|
|
_costType, _groupType);
|
|
}
|
|
|
|
if (_hc.hasMore()) {
|
|
// a placeholder for all the functions skipped ...
|
|
new FunctionItem(functionList, _hc.count() - _hc.maxSize(),
|
|
(TraceFunction*)_hc[_hc.maxSize()-1], _costType);
|
|
}
|
|
functionList->sort();
|
|
|
|
if (fitem) {
|
|
functionList->ensureItemVisible(fitem);
|
|
_inSetFunction = true;
|
|
functionList->setSelected(fitem, true);
|
|
_inSetFunction = false;
|
|
}
|
|
|
|
//functionList->setUpdatesEnabled(true);
|
|
//functionList->tqrepaint();
|
|
|
|
// Don't emit signal if cost item was changed programatically
|
|
if (!_inSetGroup) {
|
|
_selectedItem = g;
|
|
selected(g);
|
|
}
|
|
}
|
|
|
|
void FunctionSelection::groupDoubleClicked(TQListViewItem* i)
|
|
{
|
|
if (!i) return;
|
|
if (!_data) return;
|
|
TraceCostItem* g = ((CostListItem*) i)->costItem();
|
|
|
|
if (!g) return;
|
|
// group must be selected first
|
|
if (g != _group) return;
|
|
|
|
activated(g);
|
|
}
|
|
|
|
|
|
TraceCostItem* FunctionSelection::group(TQString s)
|
|
{
|
|
TQListViewItem *item;
|
|
item = groupList->firstChild();
|
|
for(;item;item = item->nextSibling())
|
|
if (((CostListItem*)item)->costItem()->name() == s)
|
|
return ((CostListItem*)item)->costItem();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
void FunctionSelection::functionSelected(TQListViewItem* i)
|
|
{
|
|
if (!i) return;
|
|
if (!_data) return;
|
|
|
|
TraceFunction* f = ((FunctionItem*) i)->function();
|
|
if (!f) return;
|
|
|
|
//qDebug("FunctionSelection::functionSelected %s", f->name().ascii());
|
|
|
|
// Don't emit signal if function was changed programatically
|
|
if (!_inSetFunction) {
|
|
_selectedItem = f;
|
|
selected(f);
|
|
}
|
|
}
|
|
|
|
void FunctionSelection::functionActivated(TQListViewItem* i)
|
|
{
|
|
if (!i) return;
|
|
if (!_data) return;
|
|
TraceFunction* f = ((FunctionItem*) i)->function();
|
|
|
|
if (!f) return;
|
|
|
|
if (!_inSetFunction)
|
|
activated(f);
|
|
}
|
|
|
|
void FunctionSelection::updateGroupSizes(bool hideEmpty)
|
|
{
|
|
TQListViewItem* item = groupList->firstChild();
|
|
for (;item;item = item->nextSibling()) {
|
|
CostListItem* i = (CostListItem*)item;
|
|
int size = (_groupSize.contains(i->costItem())) ?
|
|
_groupSize[i->costItem()] : -1;
|
|
i->setSize(size);
|
|
i->setVisible(!hideEmpty || (size>0));
|
|
}
|
|
}
|
|
|
|
void FunctionSelection::query(TQString query)
|
|
{
|
|
if (searchEdit->text() != query)
|
|
searchEdit->setText(query);
|
|
if (_searchString == query) {
|
|
// when resetting query, get rid of group sizes
|
|
if (query.isEmpty()) {
|
|
_groupSize.clear();
|
|
updateGroupSizes(false);
|
|
}
|
|
return;
|
|
}
|
|
_searchString = query;
|
|
|
|
TQRegExp re(query, false, true);
|
|
_groupSize.clear();
|
|
|
|
TraceFunction* f = 0;
|
|
TraceFunctionList list2;
|
|
|
|
_hc.clear(Configuration::maxListCount());
|
|
|
|
TraceFunctionMap::Iterator it;
|
|
for ( it = _data->functionMap().begin();
|
|
it != _data->functionMap().end(); ++it ) {
|
|
f = &(*it);
|
|
if (re.search(f->prettyName())>=0) {
|
|
if (_group) {
|
|
if (_groupType==TraceItem::Object) {
|
|
if (_groupSize.contains(f->object()))
|
|
_groupSize[f->object()]++;
|
|
else
|
|
_groupSize[f->object()] = 1;
|
|
if (f->object() != _group) continue;
|
|
}
|
|
else if (_groupType==TraceItem::Class) {
|
|
if (_groupSize.contains(f->cls()))
|
|
_groupSize[f->cls()]++;
|
|
else
|
|
_groupSize[f->cls()] = 1;
|
|
if (f->cls() != _group) continue;
|
|
}
|
|
else if (_groupType==TraceItem::File) {
|
|
if (_groupSize.contains(f->file()))
|
|
_groupSize[f->file()]++;
|
|
else
|
|
_groupSize[f->file()] = 1;
|
|
if (f->file() != _group) continue;
|
|
}
|
|
else if (_groupType==TraceItem::FunctionCycle) {
|
|
if (_groupSize.contains(f->cycle()))
|
|
_groupSize[f->cycle()]++;
|
|
else
|
|
_groupSize[f->cycle()] = 1;
|
|
if (f->cycle() != _group) continue;
|
|
}
|
|
}
|
|
_hc.addCost(f, f->inclusive()->subCost(_costType));
|
|
}
|
|
}
|
|
|
|
updateGroupSizes(true);
|
|
|
|
FunctionItem *fi, *item = 0;
|
|
|
|
functionList->clear();
|
|
setCostColumnWidths();
|
|
|
|
for(int i=0;i<_hc.realCount();i++) {
|
|
fi = new FunctionItem(functionList, (TraceFunction*)_hc[i],
|
|
_costType, _groupType);
|
|
if (_activeItem == f) item = fi;
|
|
}
|
|
if (_hc.hasMore()) {
|
|
// a placeholder for all the functions skipped ...
|
|
new FunctionItem(functionList, _hc.count() - _hc.maxSize(),
|
|
(TraceFunction*)_hc[_hc.maxSize()-1], _costType);
|
|
}
|
|
|
|
functionList->sort();
|
|
|
|
|
|
if (item) {
|
|
functionList->ensureItemVisible(item);
|
|
_inSetFunction = true;
|
|
functionList->setSelected(item, true);
|
|
_inSetFunction = false;
|
|
}
|
|
else {
|
|
// this emits a function selection
|
|
functionList->setSelected(functionList->firstChild(), true);
|
|
}
|
|
}
|
|
|
|
bool FunctionSelection::setTopFunction()
|
|
{
|
|
TQListViewItem* i = functionList->firstChild();
|
|
// this emits a function selection
|
|
functionList->setSelected(i, true);
|
|
functionActivated(i);
|
|
return i!=0;
|
|
}
|
|
|
|
void FunctionSelection::setCostColumnWidths()
|
|
{
|
|
if (_costType && (_costType->subCost(_data->callMax())>0) ) {
|
|
functionList->setColumnWidthMode(0, TQListView::Maximum);
|
|
functionList->setColumnWidth(0,50);
|
|
functionList->setColumnWidthMode(2, TQListView::Maximum);
|
|
functionList->setColumnWidth(2,50);
|
|
}
|
|
else {
|
|
functionList->setColumnWidthMode(0, TQListView::Manual);
|
|
functionList->setColumnWidth(0,0);
|
|
functionList->setColumnWidthMode(2, TQListView::Manual);
|
|
functionList->setColumnWidth(2,0);
|
|
}
|
|
|
|
functionList->setColumnWidth(1, 50);
|
|
}
|
|
|
|
|
|
|
|
#include "functionselection.moc"
|