23 #define TRACE_UPDATES 0
29 #include <QApplication>
31 #include <QDockWidget>
36 #include <QProgressBar>
38 #include <QFileDialog>
42 #include <QMessageBox>
46 #ifdef QT_DBUS_SUPPORT
47 #include <QtDBus/QDBusConnection>
63 #ifdef QT_DBUS_SUPPORT
64 QDBusConnection con = QDBusConnection::sessionBus();
65 con.registerObject(
"/QCachegrind",
this,
66 QDBusConnection::ExportScriptableSlots);
70 _statusbar = statusBar();
71 _statusLabel =
new QLabel(_statusbar);
72 _statusbar->addWidget(_statusLabel, 1);
87 _multiView->setObjectName(
"MultiView");
88 setCentralWidget(_multiView);
91 restoreCurrentState(QString::null);
94 QByteArray state, geometry;
96 _forcePartDock = topConfig->
value(
"ForcePartDockVisible",
false).toBool();
97 state = topConfig->
value(
"State", QByteArray()).toByteArray();
98 geometry = topConfig->
value(
"Geometry", QByteArray()).toByteArray();
101 if (!geometry.isEmpty())
102 restoreGeometry(geometry);
103 if (!state.isEmpty())
106 setWindowIcon(QIcon(
":/app.png"));
107 setAttribute(Qt::WA_DeleteOnClose);
116 void QCGTopLevel::resetState()
118 _activeParts.clear();
119 _hiddenParts.clear();
129 _traceItemDelayed = 0;
130 _eventTypeDelayed = 0;
131 _eventType2Delayed = 0;
146 void QCGTopLevel::saveCurrentState(
const QString& postfix)
149 if (_eventType) eventType = _eventType->
name();
150 if (_eventType2) eventType2 = _eventType2->
name();
153 stateConfig->
setValue(
"EventType", eventType);
154 stateConfig->
setValue(
"EventType2", eventType2);
158 _partSelection->
saveOptions(QString(
"PartOverview"), postfix);
159 _multiView->
saveLayout(QString(
"MainView"), postfix);
160 _multiView->
saveOptions(QString(
"MainView"), postfix);
167 void QCGTopLevel::saveTraceSettings()
169 QString key = traceKey();
172 lConfig->
setValue(QString(
"Count%1").arg(key), _layoutCount);
173 lConfig->
setValue(QString(
"Current%1").arg(key), _layoutCurrent);
178 pConfig->
setValue(QString(
"EventType%1").arg(key), _eventType->
name());
180 pConfig->
setValue(QString(
"EventType2%1").arg(key), _eventType2->
name());
182 pConfig->
setValue(QString(
"GroupType%1").arg(key),
187 pConfig->
setValue(QString(
"Group%1").arg(key), _group->
name());
188 saveCurrentState(key);
197 void QCGTopLevel::restoreCurrentState(
const QString& postfix)
203 _splittedToggleAction->setChecked(_multiView->
childCount()>1);
204 _splitDirectionToggleAction->setEnabled(_multiView->
childCount()>1);
205 _splitDirectionToggleAction->setChecked(_multiView->orientation() ==
212 QMenu *popup = _sidebarMenuAction->menu();
216 action = popup->addAction(tr(
"Parts Overview"));
217 action->setCheckable(
true);
218 action->setChecked(_partDock->isVisible());
219 connect(action, SIGNAL(triggered(
bool)),
this, SLOT(
togglePartDock()));
221 action = popup->addAction(tr(
"Top Cost Call Stack"));
222 action->setCheckable(
true);
223 action->setChecked(_stackDock->isVisible());
224 connect(action, SIGNAL(triggered(
bool)),
this, SLOT(
toggleStackDock()));
226 action = popup->addAction(tr(
"Flat Profile"));
227 action->setCheckable(
true);
228 action->setChecked(_functionDock->isVisible());
234 QStringList recentFiles;
235 QMenu *popup = _recentFilesMenuAction->menu();
240 recentFiles = generalConfig->
value(
"RecentFiles",
241 QStringList()).toStringList();
242 delete generalConfig;
244 if (recentFiles.count() == 0)
245 popup->addAction(tr(
"(No recent files)"));
247 foreach(
const QString& file, recentFiles) {
249 popup->addAction(QDir::toNativeSeparators(file));
257 load(QStringList(QDir::fromNativeSeparators(action->text())));
263 _partDock =
new QDockWidget(
this);
264 _partDock->setObjectName(
"part-dock");
265 _partDock->setWindowTitle(tr(
"Parts Overview"));
267 _partDock->setWidget(_partSelection);
269 connect(_partSelection, SIGNAL(partsHideSelected()),
271 connect(_partSelection, SIGNAL(partsUnhideAll()),
275 _stackDock =
new QDockWidget(
this);
276 _stackDock->setObjectName(
"stack-dock");
278 _stackDock->setWidget(_stackSelection);
279 _stackDock->setWindowTitle(tr(
"Top Cost Call Stack"));
280 _stackSelection->setWhatsThis( tr(
281 "<b>The Top Cost Call Stack</b>"
282 "<p>This is a purely fictional 'most probable' call stack. "
283 "It is built up by starting with the current selected "
284 "function and adds the callers/callees with highest cost "
285 "at the top and to bottom.</p>"
286 "<p>The <b>Cost</b> and <b>Calls</b> columns show the "
287 "cost used for all calls from the function in the line "
289 connect(_stackSelection, SIGNAL(functionSelected(
CostItem*)),
292 connect(_upAction, SIGNAL(triggered(
bool)),
293 _stackSelection, SLOT(browserUp()) );
294 connect(_backAction, SIGNAL(triggered(
bool)),
295 _stackSelection, SLOT(browserBack()) );
296 connect(_forwardAction, SIGNAL(triggered(
bool)),
297 _stackSelection, SLOT(browserForward()));
300 _functionDock =
new QDockWidget(
this);
301 _functionDock->setObjectName(
"function-dock");
302 _functionDock->setWindowTitle(tr(
"Flat Profile"));
304 _functionDock->setWidget(_functionSelection);
306 connect(_functionDock, SIGNAL(visibilityChanged(
bool)),
310 addDockWidget(Qt::LeftDockWidgetArea, _partDock );
311 addDockWidget(Qt::LeftDockWidgetArea, _stackDock );
312 addDockWidget(Qt::LeftDockWidgetArea, _functionDock );
326 _newAction =
new QAction(tr(
"&New"),
this);
327 _newAction->setShortcuts(QKeySequence::New);
328 _newAction->setStatusTip(tr(
"Open new empty window"));
329 connect(_newAction, SIGNAL(triggered()),
this, SLOT(
newWindow()));
331 icon = QApplication::style()->standardIcon(QStyle::SP_DialogOpenButton);
332 _openAction =
new QAction(icon, tr(
"&Open..."),
this);
333 _openAction->setShortcuts(QKeySequence::Open);
334 _openAction->setStatusTip(tr(
"Open profile data file"));
335 connect(_openAction, SIGNAL(triggered()),
this, SLOT(
load()));
337 _addAction =
new QAction(tr(
"&Add..." ),
this);
338 _addAction->setStatusTip(tr(
"Add profile data to current window"));
339 connect(_addAction, SIGNAL(triggered(
bool)), SLOT(
add()));
341 _exportAction =
new QAction(tr(
"Export Graph"),
this);
342 _exportAction->setStatusTip(tr(
"Generate GraphViz file 'callgraph.dot'"));
343 connect(_exportAction, SIGNAL(triggered(
bool)), SLOT(
exportGraph()));
345 _recentFilesMenuAction =
new QAction(tr(
"Open &Recent"),
this);
346 _recentFilesMenuAction->setMenu(
new QMenu(
this));
347 connect(_recentFilesMenuAction->menu(), SIGNAL(aboutToShow()),
349 connect(_recentFilesMenuAction->menu(), SIGNAL(triggered(QAction*)),
352 _exitAction =
new QAction(tr(
"E&xit"),
this);
353 _exitAction->setShortcut(tr(
"Ctrl+Q"));
354 _exitAction->setStatusTip(tr(
"Exit the application"));
355 connect(_exitAction, SIGNAL(triggered()),
this, SLOT(close()));
358 icon = QApplication::style()->standardIcon(QStyle::SP_BrowserReload);
359 _cyclesToggleAction =
new QAction(icon, tr(
"Detect Cycles"),
this);
360 _cyclesToggleAction->setCheckable(
true);
361 _cyclesToggleAction->setStatusTip(tr(
"Do Cycle Detection"));
362 hint = tr(
"<b>Detect recursive cycles</b>"
363 "<p>If this is switched off, the treemap drawing will show "
364 "black areas when a recursive call is made instead of drawing "
365 "the recursion ad infinitum. Note that "
366 "the size of black areas often will be wrong, as inside "
367 "recursive cycles the cost of calls cannot be determined; "
368 "the error is small, "
369 "however, for false cycles (see documentation).</p>"
370 "<p>The correct handling for cycles is to detect them and "
371 "collapse all functions of a cycle into an artificial "
372 "function, which is done when this option is selected. "
373 "Unfortunately, with GUI applications, this often will "
374 "lead to huge false cycles, making the analysis impossible; "
375 "therefore, there is the option to switch this off.</p>");
376 _cyclesToggleAction->setWhatsThis(hint);
377 connect(_cyclesToggleAction, SIGNAL(triggered(
bool)),
381 _percentageToggleAction =
new QAction(QIcon(
":/percent.png"),
382 tr(
"Relative Cost"),
this);
383 _percentageToggleAction->setCheckable(
true);
384 _percentageToggleAction->setStatusTip(tr(
"Show Relative Costs"));
385 connect(_percentageToggleAction, SIGNAL(triggered(
bool)),
389 _hideTemplatesToggleAction =
new QAction(QIcon(
":/hidetemplates.png"),
390 tr(
"Shorten Templates"),
this);
391 _hideTemplatesToggleAction->setCheckable(
true);
392 _hideTemplatesToggleAction->setStatusTip(tr(
"Hide Template Parameters "
394 connect(_hideTemplatesToggleAction, SIGNAL(triggered(
bool)),
397 hint = tr(
"<b>Hide Template Parameters in C++ Symbols</b>"
398 "<p>If this is switched on, every symbol displayed will have "
399 "any C++ template parameters hidden, just showing <> "
400 "instead of a potentially nested template parameter.</p>"
401 "<p>In this mode, you can hover the mouse pointer over the "
402 "activated symbol label to show a tooltip with the "
403 "unabbreviated symbol.</p>");
404 _hideTemplatesToggleAction->setWhatsThis(hint);
406 _expandedToggleAction =
new QAction(QIcon(
":/move.png"),
407 tr(
"Relative to Parent"),
this);
408 _expandedToggleAction->setCheckable(
true);
409 _expandedToggleAction->setStatusTip(
410 tr(
"Show Percentage relative to Parent"));
411 hint = tr(
"<b>Show percentage costs relative to parent</b>"
412 "<p>If this is switched off, percentage costs are always "
413 "shown relative to the total cost of the profile part(s) "
414 "that are currently browsed. By turning on this option, "
415 "percentage cost of shown cost items will be relative "
416 "to the parent cost item.</p>"
418 "<tr><td><b>Cost Type</b></td><td><b>Parent Cost</b></td></tr>"
419 "<tr><td>Function Inclusive</td><td>Total</td></tr>"
420 "<tr><td>Function Self</td><td>Function Group (*)/Total</td></tr>"
421 "<tr><td>Call</td><td>Function Inclusive</td></tr>"
422 "<tr><td>Source Line</td><td>Function Inclusive</td></tr>"
424 "<p>(*) Only if function grouping is switched on "
425 "(e.g. ELF object grouping).</p>");
426 _expandedToggleAction->setWhatsThis( hint );
427 connect(_expandedToggleAction, SIGNAL(triggered(
bool)),
431 _splittedToggleAction =
new QAction(tr(
"Splitted Visualization"),
this);
432 _splittedToggleAction->setCheckable(
true);
433 _splittedToggleAction->setStatusTip(
434 tr(
"Show visualization of two cost items"));
435 connect(_splittedToggleAction, SIGNAL(triggered(
bool)),
438 _splitDirectionToggleAction =
new QAction(tr(
"Split Horizontal"),
this);
439 _splitDirectionToggleAction->setCheckable(
true);
440 _splitDirectionToggleAction->setStatusTip(
441 tr(
"Split visualization area horizontally"));
442 connect(_splitDirectionToggleAction, SIGNAL(triggered(
bool)),
445 _sidebarMenuAction =
new QAction(tr(
"Sidebars"),
this);
446 _sidebarMenuAction->setMenu(
new QMenu(
this));
447 connect( _sidebarMenuAction->menu(), SIGNAL( aboutToShow() ),
450 _layoutDup =
new QAction(tr(
"&Duplicate"),
this);
452 _layoutDup->setShortcut(Qt::CTRL + Qt::Key_Plus);
453 _layoutDup->setStatusTip(tr(
"Duplicate current layout"));
455 _layoutRemove =
new QAction(tr(
"&Remove"),
this);
456 connect(_layoutRemove, SIGNAL(triggered()), SLOT(
layoutRemove()));
457 _layoutRemove->setStatusTip(tr(
"Remove current layout"));
459 _layoutNext =
new QAction(tr(
"Go to &Next"),
this);
460 connect(_layoutNext, SIGNAL(triggered()), SLOT(
layoutNext()));
461 _layoutNext->setShortcut(Qt::CTRL + Qt::Key_Right);
462 _layoutNext->setStatusTip(tr(
"Switch to next layout"));
464 _layoutPrev =
new QAction(tr(
"Go to &Previous"),
this);
465 connect(_layoutPrev, SIGNAL(triggered()), SLOT(
layoutPrevious()));
466 _layoutPrev->setShortcut(Qt::CTRL + Qt::Key_Left);
467 _layoutPrev->setStatusTip(tr(
"Switch to previous layout"));
469 _layoutRestore =
new QAction(tr(
"&Restore to Default"),
this);
470 connect(_layoutRestore, SIGNAL(triggered()), SLOT(
layoutRestore()));
471 _layoutRestore->setStatusTip(tr(
"Restore layouts to default"));
473 _layoutSave =
new QAction(tr(
"&Save as Default"),
this);
474 connect(_layoutSave, SIGNAL(triggered()), SLOT(
layoutSave()));
475 _layoutSave->setStatusTip(tr(
"Save layouts as default"));
478 icon = QApplication::style()->standardIcon(QStyle::SP_ArrowUp);
479 _upAction =
new QAction(icon, tr(
"Up" ),
this );
480 _upAction->setShortcut( QKeySequence(Qt::ALT+Qt::Key_Up) );
481 _upAction->setStatusTip(tr(
"Go Up in Call Stack"));
482 _upAction->setMenu(
new QMenu(
this));
483 connect(_upAction->menu(), SIGNAL(aboutToShow()),
485 connect(_upAction->menu(), SIGNAL(triggered(QAction*)),
487 hint = tr(
"Go to last selected caller of current function");
488 _upAction->setToolTip(hint);
490 icon = QApplication::style()->standardIcon(QStyle::SP_ArrowBack);
491 _backAction =
new QAction(icon, tr(
"Back"),
this);
492 _backAction->setShortcut( QKeySequence(Qt::ALT+Qt::Key_Left) );
493 _backAction->setStatusTip(tr(
"Go Back"));
494 _backAction->setMenu(
new QMenu(
this));
495 connect(_backAction->menu(), SIGNAL(aboutToShow()),
497 connect(_backAction->menu(), SIGNAL(triggered(QAction*)),
499 hint = tr(
"Go back in function selection history");
500 _backAction->setToolTip(hint);
502 icon = QApplication::style()->standardIcon(QStyle::SP_ArrowForward);
503 _forwardAction =
new QAction(icon, tr(
"Forward"),
this);
504 _forwardAction->setShortcut( QKeySequence(Qt::ALT+Qt::Key_Right) );
505 _forwardAction->setStatusTip(tr(
"Go Forward"));
506 _forwardAction->setMenu(
new QMenu(
this));
507 connect(_forwardAction->menu(), SIGNAL(aboutToShow()),
509 connect(_forwardAction->menu(), SIGNAL(triggered(QAction*)),
511 hint = tr(
"Go forward in function selection history");
512 _forwardAction->setToolTip( hint );
515 _configureAction =
new QAction(tr(
"&Configure..."),
this);
516 _configureAction->setStatusTip(tr(
"Configure QCachegrind"));
517 connect(_configureAction, SIGNAL(triggered()),
this, SLOT(
configure()));
520 _aboutAction =
new QAction(tr(
"&About QCachegrind..."),
this);
521 _aboutAction->setStatusTip(tr(
"Show the application's About box"));
522 connect(_aboutAction, SIGNAL(triggered()),
this, SLOT(
about()));
524 _aboutQtAction =
new QAction(tr(
"About Qt..."),
this);
525 connect(_aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
528 _eventTypeBox =
new QComboBox(
this);
529 _eventTypeBox->setMinimumContentsLength(25);
530 hint = tr(
"Select primary event type of costs");
531 _eventTypeBox->setToolTip( hint );
532 connect( _eventTypeBox, SIGNAL(activated(
const QString&)),
538 QMenuBar* mBar = menuBar();
540 QMenu* fileMenu = mBar->addMenu(tr(
"&File"));
541 fileMenu->addAction(_newAction);
542 fileMenu->addAction(_openAction);
543 fileMenu->addAction(_recentFilesMenuAction);
544 fileMenu->addAction(_addAction);
545 fileMenu->addSeparator();
546 fileMenu->addAction(_exportAction);
547 fileMenu->addSeparator();
548 fileMenu->addAction(_exitAction);
550 QMenu* layoutMenu =
new QMenu(tr(
"&Layout"),
this);
551 layoutMenu->addAction(_layoutDup);
552 layoutMenu->addAction(_layoutRemove);
553 layoutMenu->addSeparator();
554 layoutMenu->addAction(_layoutPrev);
555 layoutMenu->addAction(_layoutNext);
556 layoutMenu->addSeparator();
557 layoutMenu->addAction(_layoutSave);
558 layoutMenu->addAction(_layoutRestore);
560 QMenu* viewMenu = mBar->addMenu(tr(
"&View"));
561 viewMenu->addAction(_cyclesToggleAction);
562 viewMenu->addAction(_percentageToggleAction);
563 viewMenu->addAction(_expandedToggleAction);
564 viewMenu->addAction(_hideTemplatesToggleAction);
565 viewMenu->addSeparator();
566 viewMenu->addAction(_splittedToggleAction);
567 viewMenu->addAction(_splitDirectionToggleAction);
568 viewMenu->addMenu(layoutMenu);
570 QMenu* goMenu = mBar->addMenu(tr(
"&Go"));
571 goMenu->addAction(_backAction);
572 goMenu->addAction(_forwardAction);
573 goMenu->addAction(_upAction);
575 QMenu* settingsMenu = mBar->addMenu(tr(
"&Settings"));
576 settingsMenu->addAction(_sidebarMenuAction);
577 settingsMenu->addSeparator();
578 settingsMenu->addAction(_configureAction);
580 QMenu* helpMenu = mBar->addMenu(tr(
"&Help"));
581 helpMenu->addAction(QWhatsThis::createAction(
this));
582 helpMenu->addSeparator();
583 helpMenu->addAction(_aboutAction);
584 helpMenu->addAction(_aboutQtAction);
589 QToolBar* tb =
new QToolBar(tr(
"Main Toolbar"),
this);
590 tb->setObjectName(
"main-toolbar");
591 addToolBar(Qt::TopToolBarArea, tb);
593 tb->addAction(_openAction);
596 tb->addAction(_cyclesToggleAction);
597 tb->addAction(_percentageToggleAction);
598 tb->addAction(_expandedToggleAction);
599 tb->addAction(_hideTemplatesToggleAction);
602 tb->addAction(_backAction);
603 tb->addAction(_forwardAction);
604 tb->addAction(_upAction);
607 tb->addWidget(_eventTypeBox);
613 QString text, version;
614 version = QLatin1String(
"0.7.4kde");
615 text = QString(
"<h3>QCachegrind %1</h3>").arg(version);
616 text += tr(
"<p>QCachegrind is a graphical user interface for analysing "
617 "profiling data, which helps in the performance optimization "
618 "phase of developing a computer program. "
619 "QCachegrind is open-source, and it is distributed under the "
620 "terms of the GPL v2. For details and source code, see the "
621 "<a href=\"http://kcachegrind.sf.net\">homepage</a> of the "
622 "KCachegrind project.</p>"
623 "Main author and maintainer: "
624 "<a href=\"mailto:Josef.Weidendorfer@gmx.de\">"
625 "Josef Weidendorfer</a><br>"
626 "(with lots of bug fixes and porting to Qt4 by the KDE team)");
627 QMessageBox::about(
this, tr(
"About QCachegrind"), text);
632 static QString lastPage = QString::null;
635 if (s.isEmpty()) s = lastPage;
638 if (d.exec() == QDialog::Accepted) {
647 if (!_partDock->isVisible())
655 if (!_stackDock->isVisible())
663 if (!_functionDock->isVisible())
664 _functionDock->show();
666 _functionDock->hide();
688 if (_percentageToggleAction->isChecked() != show)
689 _percentageToggleAction->setChecked(show);
690 _expandedToggleAction->setEnabled(show);
701 bool show = _hideTemplatesToggleAction->isChecked();
713 bool show = _expandedToggleAction->isChecked();
725 bool show = _cyclesToggleAction->isChecked();
758 files = QFileDialog::getOpenFileNames(
this,
759 tr(
"Open Callgrind Data"),
761 tr(
"Callgrind Files (callgrind.*);;All Files (*)"));
767 if (files.isEmpty())
return;
768 _lastFile = files[0];
770 if (_data && _data->
parts().count()>0) {
781 int filesLoaded = d->
load(files);
785 if (!addToRecentFiles)
return;
788 QStringList recentFiles;
790 recentFiles = generalConfig->
value(
"RecentFiles",
791 QStringList()).toStringList();
792 foreach(QString file, files) {
793 recentFiles.removeAll(file);
795 recentFiles.prepend(file);
796 if (recentFiles.count() >5)
797 recentFiles.removeLast();
799 generalConfig->
setValue(
"RecentFiles", recentFiles);
800 delete generalConfig;
807 files = QFileDialog::getOpenFileNames(
this,
808 tr(
"Add Callgrind Data"),
810 tr(
"Callgrind Files (callgrind.*);;All Files (*)"));
817 if (files.isEmpty())
return;
818 _lastFile = files[0];
830 int filesLoaded = d->
load(files);
837 _loadFilesDelayed << file;
839 _addToRecentFiles = addToRecentFiles;
845 _loadFilesDelayed << files;
847 _addToRecentFiles = addToRecentFiles;
853 if (_loadFilesDelayed.isEmpty())
return;
855 load(_loadFilesDelayed, _addToRecentFiles);
856 _loadFilesDelayed.clear();
862 if (!_data || !_function)
return;
864 QString n = QString(
"callgraph.dot");
865 GraphExporter ge(_data, _function, _eventType, _groupType, n);
870 QString cmd = QString(
"(dot %1 -Tps > %2.ps; xdg-open %3.ps)&")
871 .arg(n).arg(n).arg(n);
872 if (::system(QFile::encodeName( cmd ))<0)
873 qDebug() <<
"QCGTopLevel::exportGraph: can not run " << cmd;
918 if (_eventType == ct)
return false;
922 int idx = _eventTypeBox->findText(ct->
longName());
923 if (idx >=0) _eventTypeBox->setCurrentIndex(idx);
938 if (_eventType2 == ct)
return false;
941 QString longName = ct ? ct->
longName() : tr(
"(Hidden)");
987 if (_groupType == gt)
return false;
1001 if (idx==-1)
return false;
1004 if (saGroup->currentItem() != idx)
1005 saGroup->setCurrentItem(idx);
1010 _partSelection->
set(_groupType);
1011 _functionSelection->
set(_groupType);
1012 _multiView->
set(_groupType);
1031 if (_group == g)
return false;
1042 if (!_data)
return false;
1045 if (!f)
return false;
1052 if (_function == f)
return false;
1064 _backAction->setEnabled(b->
canGoBack());
1068 qDebug(
"QCGTopLevel::setFunction(%s), lastSender %s",
1070 _lastSender ? _lastSender->name() :
"0" );
1086 _eventTypeDelayed = ct;
1092 _eventType2Delayed = ct;
1108 _groupTypeDelayed = gt;
1120 qDebug(
"QCGTopLevel::setGroupDelayed(%s), sender %s",
1122 _lastSender ? _lastSender->name() :
"0" );
1136 _directionDelayed = d;
1142 switch(_directionDelayed) {
1173 if (_traceItemDelayed == i)
return;
1174 _traceItemDelayed = i;
1175 _lastSender = sender();
1177 qDebug() <<
"Selected " << (i ? i->
fullName() :
"(none)");
1180 qDebug(
"QCGTopLevel::setTraceItemDelayed(%s), sender %s",
1182 _lastSender ? _lastSender->name() :
"0" );
1190 if (!_traceItemDelayed)
return;
1192 switch(_traceItemDelayed->
type()) {
1201 _multiView->
activate(_traceItemDelayed);
1209 _multiView->
activate(_traceItemDelayed);
1216 _traceItemDelayed = 0;
1228 if (data == _data)
return;
1232 saveTraceSettings();
1237 _functionSelection->
setData(0);
1264 _eventTypes = types;
1265 _eventTypeBox->addItems(types);
1267 _stackSelection->
setData(_data);
1268 _partSelection->
setData(_data);
1269 _functionSelection->
setData(_data);
1276 restoreTraceTypes();
1278 restoreTraceSettings();
1282 caption = QDir::toNativeSeparators(_data->
traceName());
1283 if (!_data->
command().isEmpty())
1284 caption +=
" [" + _data->
command() +
']';
1286 setWindowTitle(caption);
1288 if (!_data || (!_forcePartDock && _data->
parts().count()<2))
1299 QMenu *popup1, *popup2 = 0;
1302 popup1 = popup->addMenu(tr(
"Primary Event Type"));
1303 connect(popup1, SIGNAL(triggered(QAction*)),
1307 popup2 = popup->addMenu(tr(
"Secondary Event Type"));
1308 connect(popup2, SIGNAL(triggered(QAction*)),
1312 action = popup2->addAction(tr(
"Hide"));
1313 action->setData(199);
1314 popup2->addSeparator();
1323 action = popup1->addAction(ct->
longName());
1324 action->setCheckable(
true);
1325 action->setData(100+i);
1326 if (_eventType == ct) action->setChecked(
true);
1329 action = popup2->addAction(ct->
longName());
1330 action->setCheckable(
true);
1331 action->setData(100+i);
1332 if (_eventType2 == ct) action->setChecked(
true);
1339 action = popup1->addAction(ct->
longName());
1340 action->setCheckable(
true);
1341 action->setData(200+i);
1342 if (_eventType == ct) action->setChecked(
true);
1345 action = popup2->addAction(ct->
longName());
1346 action->setCheckable(
true);
1347 action->setData(200+i);
1348 if (_eventType2 == ct) action->setChecked(
true);
1354 popup->addAction(tr(
"Show Absolute Cost"),
1357 popup->addAction(tr(
"Show Relative Cost"),
1363 if (!_data)
return false;
1364 int id = action->data().toInt(0);
1368 if (
id >=100 &&
id<199) ct = m->
realType(
id-100);
1369 if (
id >=200 &&
id<299) ct = m->
derivedType(
id-200);
1376 if (!_data)
return false;
1377 int id = action->data().toInt(0);
1381 if (
id >=100 &&
id<199) ct = m->
realType(
id-100);
1382 if (
id >=200 &&
id<299) ct = m->
derivedType(
id-200);
1392 popup->addAction(tr(
"Go Back"),
this, SLOT(
goBack()));
1394 popup->addAction(tr(
"Go Forward"),
this, SLOT(
goForward()));
1397 popup->addAction(tr(
"Go Up"),
this, SLOT(
goUp()));
1415 QString QCGTopLevel::traceKey()
1417 if (!_data || _data->
command().isEmpty())
return QString();
1419 QString name = _data->
command();
1421 for (
int l=0;l<name.length();l++)
1422 if (name[l].isLetterOrNumber()) key += name[l];
1424 return QString(
"-") + key;
1428 void QCGTopLevel::restoreTraceTypes()
1430 QString key = traceKey();
1434 groupType = pConfig->
value(QString(
"GroupType%1").arg(key),QString()).toString();
1435 eventType = pConfig->
value(QString(
"EventType%1").arg(key),QString()).toString();
1436 eventType2 = pConfig->
value(QString(
"EventType2%1").arg(key),QString()).toString();
1440 if (groupType.isEmpty())
1441 groupType = cConfig->
value(
"GroupType",QString()).toString();
1442 if (eventType.isEmpty())
1443 eventType = cConfig->
value(
"EventType",QString()).toString();
1444 if (eventType2.isEmpty())
1445 eventType2 = cConfig->
value(
"EventType2",QString()).toString();
1453 if (!_eventType && !_eventTypes.isEmpty())
1457 _layoutCount = aConfig->
value(QString(
"Count%1").arg(key), 0).toInt();
1458 _layoutCurrent = aConfig->
value(QString(
"Current%1").arg(key), 0).toInt();
1471 void QCGTopLevel::restoreTraceSettings()
1475 QString key = traceKey();
1477 restoreCurrentState(key);
1480 QString group = pConfig->
value(QString(
"Group%1").arg(key),QString()).toString();
1482 if (!group.isEmpty())
setGroup(group);
1486 if (!_traceItemDelayed) {
1494 TraceFunctionMap::Iterator it;
1497 hc.
addCost(&(*it), (*it).inclusive()->subCost(_eventType));
1511 _multiView->
saveLayout(QString(
"Layout%1-MainView").arg(_layoutCurrent),
1513 _layoutCurrent = _layoutCount;
1518 qDebug() <<
"QCGTopLevel::layoutDuplicate: count " << _layoutCount;
1523 if (_layoutCount <2)
return;
1525 int from = _layoutCount-1;
1526 if (_layoutCurrent == from) { _layoutCurrent--; from--; }
1529 _multiView->
restoreLayout(QString(
"Layout%1-MainView").arg(from),
1535 qDebug() <<
"QCGTopLevel::layoutRemove: count " << _layoutCount;
1540 if (_layoutCount <2)
return;
1542 QString key = traceKey();
1543 QString layoutPrefix = QString(
"Layout%1-MainView");
1545 _multiView->
saveLayout(layoutPrefix.arg(_layoutCurrent), key);
1547 if (_layoutCurrent == _layoutCount) _layoutCurrent = 0;
1548 _multiView->
restoreLayout(layoutPrefix.arg(_layoutCurrent), key);
1550 qDebug() <<
"QCGTopLevel::layoutNext: current " << _layoutCurrent;
1555 if (_layoutCount <2)
return;
1557 QString key = traceKey();
1558 QString layoutPrefix = QString(
"Layout%1-MainView");
1560 _multiView->
saveLayout(layoutPrefix.arg(_layoutCurrent), key);
1562 if (_layoutCurrent <0) _layoutCurrent = _layoutCount-1;
1563 _multiView->
restoreLayout(layoutPrefix.arg(_layoutCurrent), key);
1565 qDebug() <<
"QCGTopLevel::layoutPrevious: current " << _layoutCurrent;
1570 QString key = traceKey();
1571 QString layoutPrefix = QString(
"Layout%1-MainView");
1573 _multiView->
saveLayout(layoutPrefix.arg(_layoutCurrent), key);
1576 for(
int i=0;i<_layoutCount;i++) {
1578 _multiView->
saveLayout(layoutPrefix.arg(i), QString());
1581 _multiView->
restoreLayout(layoutPrefix.arg(_layoutCurrent), key);
1584 layoutConfig->
setValue(
"DefaultCount", _layoutCount);
1585 layoutConfig->
setValue(
"DefaultCurrent", _layoutCurrent);
1586 delete layoutConfig;
1592 _layoutCount = layoutConfig->
value(
"DefaultCount", 0).toInt();
1593 _layoutCurrent = layoutConfig->
value(
"DefaultCurrent", 0).toInt();
1594 delete layoutConfig;
1596 if (_layoutCount == 0) {
1601 QString layoutPrefix = QString(
"Layout%1-MainView");
1602 _multiView->
restoreLayout( layoutPrefix.arg(_layoutCurrent), traceKey());
1611 _layoutNext->setEnabled(_layoutCount>1);
1614 _layoutPrev->setEnabled(_layoutCount>1);
1617 _layoutRemove->setEnabled(_layoutCount>1);
1620 _statusbar->showMessage(tr(
"Layout Count: %1").arg(_layoutCount),
1627 if (!_data || _data->
parts().count()==0) {
1628 _statusLabel->setText(tr(
"No profile data file loaded."));
1632 QString status = QString(
"%1 [%2] - ")
1637 status += tr(
"Total %1 Cost: %2")
1649 status += tr(
"No event type selected");
1660 _statusLabel->setText(status);
1668 saveTraceSettings();
1669 saveCurrentState(QString::null);
1673 _forcePartDock =
false;
1674 if (_data && (_data->
parts().count()<2) && _partDock->isVisible())
1675 _forcePartDock=
true;
1678 topConfig->
setValue(
"ForcePartDockVisible", _forcePartDock,
false);
1679 topConfig->
setValue(
"State", saveState());
1680 topConfig->
setValue(
"Geometry", saveGeometry());
1690 if (count<1) count = 1;
1691 if (count>2) count = 2;
1695 _splittedToggleAction->setChecked(count>1);
1696 _splitDirectionToggleAction->setEnabled(count>1);
1697 _splitDirectionToggleAction->setChecked(_multiView->orientation() ==
1703 _multiView->setOrientation( _splitDirectionToggleAction->isChecked() ?
1704 Qt::Horizontal : Qt::Vertical );
1732 _activeParts = list;
1734 _partSelection->
set(list);
1736 _functionSelection->
set(list);
1737 _multiView->
set(list);
1755 if (_activeParts.contains(part) ||
1756 _hiddenParts.contains(part))
1757 newHidden.append(part);
1759 newActive.append(part);
1762 _hiddenParts = newHidden;
1766 _mainWidget1->hiddenPartsChangedSlot(_hiddenParts);
1767 _mainWidget2->hiddenPartsChangedSlot(_hiddenParts);
1783 _hiddenParts.clear();
1787 _mainWidget1->hiddenPartsChangedSlot(_hiddenParts);
1788 _mainWidget2->hiddenPartsChangedSlot(_hiddenParts);
1794 QMenu *popup = _forwardAction->menu();
1803 popup->addAction(tr(
"(No Stack)"));
1809 popup->addAction(tr(
"(No next function)"));
1821 action = popup->addAction(name);
1822 action->setData(count);
1831 QMenu *popup = _backAction->menu();
1840 popup->addAction(tr(
"(No Stack)"));
1846 popup->addAction(tr(
"(No previous function)"));
1858 action = popup->addAction(name);
1859 action->setData(count);
1868 QMenu *popup = _upAction->menu();
1877 popup->addAction(tr(
"(No Stack)"));
1882 popup->addAction(tr(
"(No Function Up)"));
1890 action = popup->addAction(name);
1891 action->setData(count);
1900 int count = action->data().toInt(0);
1917 int count = action->data().toInt(0);
1934 int count = action->data().toInt(0);
1945 while (count>0 && f) {
1958 _statusbar->showMessage(msg, ms);
1963 static bool msgUpdateNeeded =
true;
1965 if (!_statusbar)
return;
1967 if (msg.isEmpty()) {
1970 _statusbar->removeWidget(_progressBar);
1971 delete _progressBar;
1974 _statusbar->clearMessage();
1979 if (_progressMsg.isEmpty())
1980 _progressStart.start();
1982 if (msg != _progressMsg) {
1984 msgUpdateNeeded =
true;
1988 if (_progressStart.elapsed() < 500)
1991 if (!_progressBar) {
1992 _progressBar =
new QProgressBar(_statusbar);
1993 _progressBar->setMaximumSize(200, _statusbar->height()-4);
1994 _statusbar->addPermanentWidget(_progressBar, 1);
1995 _progressBar->show();
1996 msgUpdateNeeded =
true;
1999 _progressStart.restart();
2001 if (msgUpdateNeeded) {
2002 _statusbar->showMessage(msg);
2003 msgUpdateNeeded =
false;
2005 _progressBar->setValue(progress);
2008 qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
2013 showStatus(QString(
"Loading %1").arg(filename), 0);
2033 <<
":" << line <<
": " << msg;
2039 <<
":" << line <<
": " << msg;
2042 #include "qcgtoplevel.moc"
StackBrowser * browser() const
void setEventType2(EventType *)
ProfileContext::Type type()
static void setShowPercentage(bool)
TraceFunction * function()
static bool showPercentage()
void toggleHideTemplates()
void saveLayout(const QString &prefix, const QString &postfix)
virtual void loadProgress(int progress)
void recentFilesMenuAboutToShow()
void set(ProfileContext::Type g)
bool setEventType2(EventType *)
void setEventType2(EventType *t)
static QString typeName(Type)
ProfileCostArray * search(ProfileContext::Type, QString, EventType *ct=0, ProfileCostArray *parent=0)
Search for item with given name and highest subcost of given cost type.
ProfileContext::Type type() const
void setFunction(TraceFunction *)
bool setGroupType(ProfileContext::Type)
void groupTypeSelected(int)
void closeEvent(QCloseEvent *)
QString prettySubCost(EventType *)
Returns a cost attribute converted to a string (with space after every 3 digits)
void setEventType(EventType *t)
void configure(QString page=QString::null)
void partsUnhideAllSlotDelayed()
virtual void setValue(const QString &key, const QVariant &value, const QVariant &defaultValue=QVariant())
Base class for cost items.
void setGroup(TraceCostItem *)
void activePartsChangedSlot(const TracePartList &list)
static GlobalConfig * config()
void updateView(bool force=false)
int addKnownDerivedTypes()
Adds all known derived event types that can be parsed.
EventTypeSet * eventTypes()
void eventType2Selected(const QString &)
QString activePartRange()
TraceFunction * caller(TraceFunction *, bool extend)
HistoryItem * goForward()
bool activateParts(const TracePartList &)
returns true if something changed.
void setData(TraceData *)
void hiddenPartsChangedSlot(const TracePartList &list)
void setTraceItemDelayed()
EventType * typeForLong(const QString &)
static ConfigGroup * group(const QString &group, const QString &optSuffix=QString())
void partsUnhideAllSlot()
void restoreOptions(const QString &prefix, const QString &postfix)
void forwardAboutToShow()
TracePartList parts() const
virtual void loadFinished(const QString &msg)
An array of basic cost metrics for a trace item.
void backTriggered(QAction *)
void setEventTypeDelayed()
static void setShowCycles(bool)
void restoreOptions(const QString &prefix, const QString &postfix)
bool setGroup(TraceCostItem *)
void setData(TraceData *)
void updateFunctionCycles()
A class to calculate the ProfileCostArray items with highest cost.
int load(QStringList files)
Loads profile data files.
void addEventTypeMenu(QMenu *, bool)
QString fullName() const
Returns type name + dynamic name.
void eventTypeSelected(const QString &)
void setGroupTypeDelayed()
virtual QString name() const
Returns dynamic name info (without type)
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
virtual void loadError(int line, const QString &msg)
void setEventType(EventType *)
void functionVisibilityChanged(bool)
bool activate(CostItem *i)
void updateLayoutActions()
virtual void loadWarning(int line, const QString &msg)
static QString shortenSymbol(const QString &)
A group of configuration settings.
void notifyChange(int changeType)
bool setFunction(TraceFunction *)
static GlobalGUIConfig * config()
void showStatus(const QString &msg, int progress)
void loadDelayed(QString file, bool addToRecentFiles=true)
void setEventType2Delayed()
void saveOptions(const QString &prefix, const QString &postfix)
void setData(TraceData *)
void upTriggered(QAction *)
void addCost(ProfileCostArray *, SubCost)
bool setEventType(EventType *)
EventType * realType(int)
A Trace Part: All data read from a trace file, containing all costs that happened in a specified time...
void writeDot(QIODevice *=0)
static void setHideTemplates(bool)
static bool showExpanded()
QString shortTraceName() const
void restoreLayout(const QString &prefix, const QString &postfix)
static bool hideTemplates()
void setDirectionDelayed()
void recentFilesTriggered(QAction *)
const QString & longName()
QList< TracePart * > TracePartList
A class for managing a set of event types.
void toggleFunctionDock()
ProfileContext::Type groupType()
void partsHideSelectedSlotDelayed()
virtual void saveOptions()
TraceFunctionMap & functionMap()
void sidebarMenuAboutToShow()
This class holds profiling data of multiple tracefiles generated with cachegrind on one command...
void setGroupType(ProfileContext::Type)
virtual QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
void toggleSplitDirection()
EventType * derivedType(int)
void setData(TraceData *)
A TraceData object cannot be viewed many times in different toplevel windows.
static void setShowExpanded(bool)
virtual void loadStart(const QString &filename)
void saveOptions(const QString &prefix, const QString &postfix)
void forwardTriggered(QAction *)
static int maxSymbolCount()
QString traceName() const
void partsHideSelectedSlot()
void setData(TraceData *)
virtual QVariant value(const QString &key, const QVariant &defaultValue) const
void showMessage(const QString &, int msec)
void invalidateDynamicCost()