summaryrefslogtreecommitdiffstats
path: root/kcachegrind/kcachegrind/functionselection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kcachegrind/kcachegrind/functionselection.cpp')
-rw-r--r--kcachegrind/kcachegrind/functionselection.cpp871
1 files changed, 871 insertions, 0 deletions
diff --git a/kcachegrind/kcachegrind/functionselection.cpp b/kcachegrind/kcachegrind/functionselection.cpp
new file mode 100644
index 00000000..8c4e8a5a
--- /dev/null
+++ b/kcachegrind/kcachegrind/functionselection.cpp
@@ -0,0 +1,871 @@
+/* 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/*
+ * For function selection, to be put into a QDockWindow
+ */
+
+#include <qtimer.h>
+#include <qlistview.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qcombobox.h>
+#include <qlineedit.h>
+#include <qregexp.h>
+#include <qpopupmenu.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,
+ QWidget* parent, const char* name)
+ : FunctionSelectionBase(parent, name), TraceItemView(0, top)
+{
+ _group = 0;
+ _inSetGroup = false;
+ _inSetFunction = false;
+
+ QStringList 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, SIGNAL(activated(int)),
+ top, SLOT(groupTypeSelected(int)));
+
+ // search while typing...
+ connect(searchEdit, SIGNAL(textChanged(const QString&)),
+ this, SLOT(searchChanged(const QString&)));
+ connect(&_searchTimer, SIGNAL(timeout()),
+ this, SLOT(queryDelayed()));
+ // select first matching group/function on return
+ connect(searchEdit, SIGNAL(returnPressed()),
+ this, SLOT(searchReturnPressed()));
+ searchEdit->setMinimumWidth(50);
+
+ // we start with desending cost sorting
+ functionList->setSorting(0,false);
+ functionList->setColumnAlignment(0, Qt::AlignRight);
+ functionList->setColumnAlignment(1, Qt::AlignRight);
+ functionList->setColumnAlignment(2, Qt::AlignRight);
+ functionList->setAllColumnsShowFocus(true);
+ // functionList->setShowSortIndicator(true);
+ // we can have very long function and location names
+ functionList->setColumnWidthMode(3, QListView::Manual);
+ functionList->setColumnWidth(3, 200);
+ functionList->setColumnWidthMode(4, QListView::Manual);
+ functionList->setColumnWidth(4, 200);
+
+ groupList->setSorting(0,false);
+ groupList->setColumnAlignment(0, Qt::AlignRight);
+ groupList->setAllColumnsShowFocus(true);
+ // groupList->setShowSortIndicator(true);
+ groupList->setResizeMode(QListView::LastColumn);
+
+#if 0
+ // single click press activation
+ connect(functionList, SIGNAL(selectionChanged(QListViewItem*)),
+ this, SLOT(functionActivated(QListViewItem*)));
+ connect(functionList,
+ SIGNAL(contextMenuRequested(QListViewItem*, const QPoint &, int)),
+ this, SLOT(functionContext(QListViewItem*, const QPoint &, int)));
+#else
+ // single click release activation
+ connect(functionList, SIGNAL(selectionChanged(QListViewItem*)),
+ this, SLOT(functionSelected(QListViewItem*)));
+ connect(functionList, SIGNAL(clicked(QListViewItem*)),
+ this, SLOT(functionActivated(QListViewItem*)));
+ connect(functionList, SIGNAL(returnPressed(QListViewItem*)),
+ this, SLOT(functionActivated(QListViewItem*)));
+ connect(functionList,
+ SIGNAL(contextMenuRequested(QListViewItem*, const QPoint &, int)),
+ this, SLOT(functionContext(QListViewItem*, const QPoint &, int)));
+#endif
+
+ connect(groupList, SIGNAL(selectionChanged(QListViewItem*)),
+ this, SLOT(groupSelected(QListViewItem*)));
+ connect(groupList, SIGNAL(doubleClicked(QListViewItem*)),
+ this, SLOT(groupDoubleClicked(QListViewItem*)));
+ connect(groupList, SIGNAL(returnPressed(QListViewItem*)),
+ this, SLOT(groupDoubleClicked(QListViewItem*)));
+ connect(groupList,
+ SIGNAL(contextMenuRequested(QListViewItem*, const QPoint &, int)),
+ this, SLOT(groupContext(QListViewItem*, const QPoint &, int)));
+
+ // start hidden
+ groupList->hide();
+}
+
+FunctionSelection::~FunctionSelection()
+{
+}
+
+void FunctionSelection::searchReturnPressed()
+{
+ query(searchEdit->text());
+
+ QListViewItem* 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 QString& 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(QListViewItem* i,
+ const QPoint & p, int c)
+{
+ QPopupMenu popup;
+ TraceFunction* f = 0;
+
+ if (i) {
+ f = ((FunctionItem*) i)->function();
+ if (f) {
+ popup.insertItem(i18n("Go to %1").arg(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(QListViewItem* /*i*/,
+ const QPoint & p, int c)
+{
+ QPopupMenu 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(QPopupMenu* popup)
+{
+ QPopupMenu *popup1 = new QPopupMenu(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,SIGNAL(activated(int)),
+ _topLevel,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
+ QListViewItem* i = functionList->currentItem();
+ if (i && (((FunctionItem*)i)->function() == f)) {
+ functionList->setSelected(i,true);
+ return;
+ }
+
+ // reset searchEdit (as not activated from this view)
+ _searchString = QString::null;
+ query(QString::null);
+
+ // 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;
+ }
+
+ QListViewItem* 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 = QString::null;
+ query(QString::null);
+
+ 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;
+
+ QListViewItem* 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->repaint();
+
+ // 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;
+ QListViewItem *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:
+ {
+ QListViewItem* 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 QListView 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->repaint();
+ groupList->setUpdatesEnabled(true);
+ groupList->repaint();
+ 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->repaint();
+}
+
+
+void FunctionSelection::groupSelected(QListViewItem* 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 QListView 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->repaint();
+ return;
+ }
+#endif
+
+ QRegExp 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->repaint();
+
+ // Don't emit signal if cost item was changed programatically
+ if (!_inSetGroup) {
+ _selectedItem = g;
+ selected(g);
+ }
+}
+
+void FunctionSelection::groupDoubleClicked(QListViewItem* 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(QString s)
+{
+ QListViewItem *item;
+ item = groupList->firstChild();
+ for(;item;item = item->nextSibling())
+ if (((CostListItem*)item)->costItem()->name() == s)
+ return ((CostListItem*)item)->costItem();
+
+ return 0;
+}
+
+
+
+void FunctionSelection::functionSelected(QListViewItem* 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(QListViewItem* i)
+{
+ if (!i) return;
+ if (!_data) return;
+ TraceFunction* f = ((FunctionItem*) i)->function();
+
+ if (!f) return;
+
+ if (!_inSetFunction)
+ activated(f);
+}
+
+void FunctionSelection::updateGroupSizes(bool hideEmpty)
+{
+ QListViewItem* 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(QString 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;
+
+ QRegExp 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()
+{
+ QListViewItem* 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, QListView::Maximum);
+ functionList->setColumnWidth(0,50);
+ functionList->setColumnWidthMode(2, QListView::Maximum);
+ functionList->setColumnWidth(2,50);
+ }
+ else {
+ functionList->setColumnWidthMode(0, QListView::Manual);
+ functionList->setColumnWidth(0,0);
+ functionList->setColumnWidthMode(2, QListView::Manual);
+ functionList->setColumnWidth(2,0);
+ }
+
+ functionList->setColumnWidth(1, 50);
+}
+
+
+
+#include "functionselection.moc"