QmlProfiler: link views when selecting event

Change-Id: I4dbb09d459e033fae2fceb24ab5e4b0e7de38179
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
This commit is contained in:
Christiaan Janssen
2013-07-10 16:47:16 +02:00
committed by Kai Koehne
parent a90a841d42
commit 832e2b8d39
19 changed files with 149 additions and 62 deletions

View File

@@ -91,6 +91,8 @@ public:
// returned map should contain "file", "line", "column" properties, or be empty // returned map should contain "file", "line", "column" properties, or be empty
Q_INVOKABLE virtual const QVariantMap getEventLocation(int index) const = 0; Q_INVOKABLE virtual const QVariantMap getEventLocation(int index) const = 0;
Q_INVOKABLE virtual int getEventIdForHash(const QString &eventHash) const = 0;
Q_INVOKABLE virtual int getEventIdForLocation(const QString &filename, int line, int column) const = 0;
signals: signals:
void countChanged(); void countChanged();

View File

@@ -152,10 +152,12 @@ Rectangle {
// ***** functions // ***** functions
function gotoSourceLocation(file,line,column) { function gotoSourceLocation(file,line,column) {
root.fileName = file; if (file !== undefined) {
root.lineNumber = line; root.fileName = file;
root.columnNumber = column; root.lineNumber = line;
root.updateCursorPosition(); root.columnNumber = column;
root.updateCursorPosition();
}
} }
function clearData() { function clearData() {
@@ -293,7 +295,14 @@ Rectangle {
rangeDetails.isBindingLoop = false; rangeDetails.isBindingLoop = false;
} }
function selectNextWithId( eventId ) function selectNextByHash(hash) {
var eventId = qmlProfilerModelProxy.getEventIdForHash(hash);
if (eventId !== -1) {
selectNextById(eventId);
}
}
function selectNextById(eventId)
{ {
// this is a slot responding to events from the other pane // this is a slot responding to events from the other pane
// which tracks only events from the basic model // which tracks only events from the basic model
@@ -327,9 +336,9 @@ Rectangle {
onSelectedItemChanged: { onSelectedItemChanged: {
if (selectedItem != -1 && !lockItemSelection) { if (selectedItem != -1 && !lockItemSelection) {
lockItemSelection = true; lockItemSelection = true;
/* // update in other views
selectedEventChanged( qmlProfilerDataModel.getEventId(selectedItem) ); var eventLocation = qmlProfilerModelProxy.getEventLocation(view.selectedModel, view.selectedItem);
*/ gotoSourceLocation(eventLocation.file, eventLocation.line, eventLocation.column);
lockItemSelection = false; lockItemSelection = false;
} }
} }

View File

@@ -128,7 +128,7 @@ QmlProfilerEventsWidget::QmlProfilerEventsWidget(QWidget *parent,
d->m_eventTree = new QmlProfilerEventsMainView(this, d->modelProxy); d->m_eventTree = new QmlProfilerEventsMainView(this, d->modelProxy);
connect(d->m_eventTree, SIGNAL(gotoSourceLocation(QString,int,int)), this, SIGNAL(gotoSourceLocation(QString,int,int))); connect(d->m_eventTree, SIGNAL(gotoSourceLocation(QString,int,int)), this, SIGNAL(gotoSourceLocation(QString,int,int)));
connect(d->m_eventTree, SIGNAL(showEventInTimeline(int)), this, SIGNAL(showEventInTimeline(int))); connect(d->m_eventTree, SIGNAL(eventSelected(QString)), this, SIGNAL(eventSelectedByHash(QString)));
d->m_eventChildren = new QmlProfilerEventRelativesView( d->m_eventChildren = new QmlProfilerEventRelativesView(
profilerModelManager, profilerModelManager,
@@ -283,11 +283,7 @@ void QmlProfilerEventsWidget::updateSelectedEvent(const QString &eventHash) cons
void QmlProfilerEventsWidget::selectBySourceLocation(const QString &filename, int line, int column) void QmlProfilerEventsWidget::selectBySourceLocation(const QString &filename, int line, int column)
{ {
// This slot is used to connect the javascript pane with the qml events pane d->m_eventTree->selectEventByLocation(filename, line, column);
// Our javascript trace data does not store column information
// thus we ignore it here
Q_UNUSED(column);
d->m_eventTree->selectEventByLocation(filename, line);
} }
bool QmlProfilerEventsWidget::hasGlobalStats() const bool QmlProfilerEventsWidget::hasGlobalStats() const
@@ -668,9 +664,6 @@ void QmlProfilerEventsMainView::jumpToItem(const QModelIndex &index)
// show in callers/callees subwindow // show in callers/callees subwindow
emit eventSelected(infoItem->data(EventHashStrRole).toString()); emit eventSelected(infoItem->data(EventHashStrRole).toString());
// show in timelinerenderer
emit showEventInTimeline(infoItem->data(EventIdRole).toInt());
d->m_preventSelectBounce = false; d->m_preventSelectBounce = false;
} }
@@ -686,14 +679,18 @@ void QmlProfilerEventsMainView::selectEvent(const QString &eventHash)
} }
} }
void QmlProfilerEventsMainView::selectEventByLocation(const QString &filename, int line) void QmlProfilerEventsMainView::selectEventByLocation(const QString &filename, int line, int column)
{ {
if (d->m_preventSelectBounce) if (d->m_preventSelectBounce)
return; return;
for (int i=0; i<d->m_model->rowCount(); i++) { for (int i=0; i<d->m_model->rowCount(); i++) {
QStandardItem *infoItem = d->m_model->item(i, 0); QStandardItem *infoItem = d->m_model->item(i, 0);
if (currentIndex() != d->m_model->indexFromItem(infoItem) && infoItem->data(FilenameRole).toString() == filename && infoItem->data(LineRole).toInt() == line) { if (currentIndex() != d->m_model->indexFromItem(infoItem) &&
infoItem->data(FilenameRole).toString() == filename &&
infoItem->data(LineRole).toInt() == line &&
(column == -1 ||
infoItem->data(ColumnRole).toInt() == column)) {
setCurrentIndex(d->m_model->indexFromItem(infoItem)); setCurrentIndex(d->m_model->indexFromItem(infoItem));
jumpToItem(currentIndex()); jumpToItem(currentIndex());
return; return;
@@ -710,18 +707,6 @@ QModelIndex QmlProfilerEventsMainView::selectedItem() const
return sel.first(); return sel.first();
} }
void QmlProfilerEventsMainView::changeDetailsForEvent(int eventId, const QString &newString)
{
for (int i=0; i<d->m_model->rowCount(); i++) {
QStandardItem *infoItem = d->m_model->item(i, 0);
if (infoItem->data(EventIdRole).toInt() == eventId) {
d->m_model->item(i,d->m_columnIndex[Details])->setData(QVariant(newString),Qt::DisplayRole);
d->m_model->item(i,d->m_columnIndex[Details])->setData(QVariant(newString));
return;
}
}
}
QString QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate::textForItem(QStandardItem *item, bool recursive) const QString QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate::textForItem(QStandardItem *item, bool recursive) const
{ {
QString str; QString str;
@@ -852,7 +837,6 @@ void QmlProfilerEventRelativesView::rebuildTree(QmlProfilerEventRelativesModelPr
// newRow << new EventsViewItem(QString::number(event->calls)); // newRow << new EventsViewItem(QString::number(event->calls));
// newRow << new EventsViewItem(event->reference->details); // newRow << new EventsViewItem(event->reference->details);
newRow.at(0)->setData(QVariant(key), EventHashStrRole); newRow.at(0)->setData(QVariant(key), EventHashStrRole);
// newRow.at(0)->setData(QVariant(event->reference->eventId), EventIdRole);
newRow.at(2)->setData(QVariant(event.duration)); newRow.at(2)->setData(QVariant(event.duration));
newRow.at(3)->setData(QVariant(event.calls)); newRow.at(3)->setData(QVariant(event.calls));

View File

@@ -81,7 +81,7 @@ public:
signals: signals:
void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber); void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber);
void showEventInTimeline(int eventId); void eventSelectedByHash(const QString &eventHash);
void resized(); void resized();
public slots: public slots:
@@ -129,15 +129,13 @@ public:
signals: signals:
void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber); void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber);
void eventSelected(const QString &eventHash); void eventSelected(const QString &eventHash);
void showEventInTimeline(int eventId);
public slots: public slots:
void clear(); void clear();
void jumpToItem(const QModelIndex &index); void jumpToItem(const QModelIndex &index);
void selectEvent(const QString &eventHash); void selectEvent(const QString &eventHash);
void selectEventByLocation(const QString &filename, int line); void selectEventByLocation(const QString &filename, int line, int column);
void buildModel(); void buildModel();
void changeDetailsForEvent(int eventId, const QString &newString);
private slots: private slots:
void profilerDataModelStateChanged(); void profilerDataModelStateChanged();

View File

@@ -421,6 +421,18 @@ const QVariantMap PaintEventsModelProxy::getEventLocation(int /*index*/) const
return map; return map;
} }
int PaintEventsModelProxy::getEventIdForHash(const QString &/*eventHash*/) const
{
// paint events do not have an eventHash
return -1;
}
int PaintEventsModelProxy::getEventIdForLocation(const QString &/*filename*/, int /*line*/, int /*column*/) const
{
// paint events do not have a defined location
return -1;
}
} }
} }

View File

@@ -102,6 +102,8 @@ public:
Q_INVOKABLE const QVariantList getLabelsForCategory(int category) const; Q_INVOKABLE const QVariantList getLabelsForCategory(int category) const;
Q_INVOKABLE const QVariantList getEventDetails(int index) const; Q_INVOKABLE const QVariantList getEventDetails(int index) const;
Q_INVOKABLE const QVariantMap getEventLocation(int index) const; Q_INVOKABLE const QVariantMap getEventLocation(int index) const;
Q_INVOKABLE int getEventIdForHash(const QString &eventHash) const;
Q_INVOKABLE int getEventIdForLocation(const QString &filename, int line, int column) const;
private slots: private slots:
bool eventAccepted(const QmlProfilerSimpleModel::QmlEventData &event) const; bool eventAccepted(const QmlProfilerSimpleModel::QmlEventData &event) const;

View File

@@ -670,5 +670,24 @@ const QVariantMap BasicTimelineModel::getEventLocation(int index) const
return result; return result;
} }
int BasicTimelineModel::getEventIdForHash(const QString &eventHash) const
{
return d->eventHashes.indexOf(eventHash);
}
int BasicTimelineModel::getEventIdForLocation(const QString &filename, int line, int column) const
{
// if this is called from v8 view, we don't have the column number, it will be -1
foreach (const QmlRangeEventData &eventData, d->eventDict) {
if (eventData.location.filename == filename &&
eventData.location.line == line &&
(column == -1 || eventData.location.column == column))
return eventData.eventId;
}
return -1;
}
} }
} }

View File

@@ -125,6 +125,9 @@ public:
Q_INVOKABLE const QVariantList getEventDetails(int index) const; Q_INVOKABLE const QVariantList getEventDetails(int index) const;
Q_INVOKABLE const QVariantMap getEventLocation(int index) const; Q_INVOKABLE const QVariantMap getEventLocation(int index) const;
Q_INVOKABLE int getEventIdForHash(const QString &eventHash) const;
Q_INVOKABLE int getEventIdForLocation(const QString &filename, int line, int column) const;
private slots: private slots:
bool eventAccepted(const QmlProfilerSimpleModel::QmlEventData &event) const; bool eventAccepted(const QmlProfilerSimpleModel::QmlEventData &event) const;
protected slots: protected slots:

View File

@@ -378,12 +378,25 @@ void QmlProfilerTraceView::clearDisplay()
QMetaObject::invokeMethod(d->m_overview->rootObject(), "clearDisplay"); QMetaObject::invokeMethod(d->m_overview->rootObject(), "clearDisplay");
} }
void QmlProfilerTraceView::selectNextEventWithId(int eventId) void QmlProfilerTraceView::selectNextEventByHash(const QString &hash)
{ {
QGraphicsObject *rootObject = d->m_mainView->rootObject(); QGraphicsObject *rootObject = d->m_mainView->rootObject();
if (rootObject) if (rootObject)
QMetaObject::invokeMethod(rootObject, "selectNextWithId", QMetaObject::invokeMethod(rootObject, "selectNextByHash",
Q_ARG(QVariant,QVariant(eventId))); Q_ARG(QVariant,QVariant(hash)));
}
void QmlProfilerTraceView::selectNextEventByLocation(const QString &filename, const int line, const int column)
{
int eventId = d->m_modelProxy->getEventIdForLocation(filename, line, column);
if (eventId != -1) {
QGraphicsObject *rootObject = d->m_mainView->rootObject();
if (rootObject)
QMetaObject::invokeMethod(rootObject, "selectNextById",
Q_ARG(QVariant,QVariant(eventId)));
}
} }
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////

View File

@@ -99,7 +99,8 @@ public:
public slots: public slots:
void clearDisplay(); void clearDisplay();
void selectNextEventWithId(int eventId); void selectNextEventByHash(const QString &eventHash);
void selectNextEventByLocation(const QString &filename, const int line, const int column);
private slots: private slots:
void updateCursorPosition(); void updateCursorPosition();

View File

@@ -105,11 +105,21 @@ void QmlProfilerViewManager::createViews()
d->profilerModelManager); d->profilerModelManager);
connect(d->eventsView, SIGNAL(gotoSourceLocation(QString,int,int)), this, connect(d->eventsView, SIGNAL(gotoSourceLocation(QString,int,int)), this,
SIGNAL(gotoSourceLocation(QString,int,int))); SIGNAL(gotoSourceLocation(QString,int,int)));
connect(d->eventsView, SIGNAL(showEventInTimeline(int)), d->traceView, connect(d->eventsView, SIGNAL(eventSelectedByHash(QString)), d->traceView,
SLOT(selectNextEventWithId(int))); SLOT(selectNextEventByHash(QString)));
connect(d->traceView, SIGNAL(gotoSourceLocation(QString,int,int)),
d->eventsView, SLOT(selectBySourceLocation(QString,int,int)));
d->v8profilerView = new QV8ProfilerEventsWidget(mw, d->profilerTool, this, d->v8profilerView = new QV8ProfilerEventsWidget(mw, d->profilerTool, this,
d->profilerModelManager); d->profilerModelManager);
connect(d->traceView, SIGNAL(gotoSourceLocation(QString,int,int)),
d->v8profilerView, SLOT(selectBySourceLocation(QString,int,int)));
connect(d->v8profilerView, SIGNAL(gotoSourceLocation(QString,int,int)),
d->traceView, SLOT(selectNextEventByLocation(QString,int,int)));
connect(d->v8profilerView, SIGNAL(gotoSourceLocation(QString,int,int)),
d->eventsView, SLOT(selectBySourceLocation(QString,int,int)));
connect(d->eventsView, SIGNAL(gotoSourceLocation(QString,int,int)),
d->v8profilerView, SLOT(selectBySourceLocation(QString,int,int)));
QDockWidget *eventsDock = AnalyzerManager::createDockWidget QDockWidget *eventsDock = AnalyzerManager::createDockWidget
(d->profilerTool, tr("Events"), d->eventsView, Qt::BottomDockWidgetArea); (d->profilerTool, tr("Events"), d->eventsView, Qt::BottomDockWidgetArea);

View File

@@ -464,7 +464,7 @@ void QV8ProfilerEventsMainView::QV8ProfilerEventsMainViewPrivate::buildV8ModelFr
newRow.at(0)->setData(QString::fromLatin1("%1:%2").arg(v8event->filename, QString::number(v8event->line)), EventHashStrRole); newRow.at(0)->setData(QString::fromLatin1("%1:%2").arg(v8event->filename, QString::number(v8event->line)), EventHashStrRole);
newRow.at(0)->setData(QVariant(v8event->filename), FilenameRole); newRow.at(0)->setData(QVariant(v8event->filename), FilenameRole);
newRow.at(0)->setData(QVariant(v8event->line), LineRole); newRow.at(0)->setData(QVariant(v8event->line), LineRole);
newRow.at(0)->setData(QVariant(0),ColumnRole); // v8 events have no column info newRow.at(0)->setData(QVariant(-1),ColumnRole); // v8 events have no column info
newRow.at(0)->setData(QVariant(v8event->eventId), EventIdRole); newRow.at(0)->setData(QVariant(v8event->eventId), EventIdRole);
// append // append
@@ -527,9 +527,6 @@ void QV8ProfilerEventsMainView::jumpToItem(const QModelIndex &index)
// show in callers/callees subwindow // show in callers/callees subwindow
emit eventSelected(infoItem->data(EventIdRole).toInt()); emit eventSelected(infoItem->data(EventIdRole).toInt());
// show in timelinerenderer
emit showEventInTimeline(infoItem->data(EventIdRole).toInt());
d->m_preventSelectBounce = false; d->m_preventSelectBounce = false;
} }
@@ -552,7 +549,9 @@ void QV8ProfilerEventsMainView::selectEventByLocation(const QString &filename, i
for (int i=0; i<d->m_model->rowCount(); i++) { for (int i=0; i<d->m_model->rowCount(); i++) {
QStandardItem *infoItem = d->m_model->item(i, 0); QStandardItem *infoItem = d->m_model->item(i, 0);
if (currentIndex() != d->m_model->indexFromItem(infoItem) && infoItem->data(FilenameRole).toString() == filename && infoItem->data(LineRole).toInt() == line) { if (currentIndex() != d->m_model->indexFromItem(infoItem) &&
infoItem->data(FilenameRole).toString() == filename &&
infoItem->data(LineRole).toInt() == line) {
setCurrentIndex(d->m_model->indexFromItem(infoItem)); setCurrentIndex(d->m_model->indexFromItem(infoItem));
jumpToItem(currentIndex()); jumpToItem(currentIndex());
return; return;
@@ -569,18 +568,6 @@ QModelIndex QV8ProfilerEventsMainView::selectedItem() const
return sel.first(); return sel.first();
} }
void QV8ProfilerEventsMainView::changeDetailsForEvent(int eventId, const QString &newString)
{
for (int i=0; i<d->m_model->rowCount(); i++) {
QStandardItem *infoItem = d->m_model->item(i, 0);
if (infoItem->data(EventIdRole).toInt() == eventId) {
d->m_model->item(i,d->m_columnIndex[Details])->setData(QVariant(newString),Qt::DisplayRole);
d->m_model->item(i,d->m_columnIndex[Details])->setData(QVariant(newString));
return;
}
}
}
QString QV8ProfilerEventsMainView::QV8ProfilerEventsMainViewPrivate::textForItem(QStandardItem *item, bool recursive = true) const QString QV8ProfilerEventsMainView::QV8ProfilerEventsMainViewPrivate::textForItem(QStandardItem *item, bool recursive = true) const
{ {
QString str; QString str;

View File

@@ -111,7 +111,6 @@ public:
signals: signals:
void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber); void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber);
void eventSelected(int eventId); void eventSelected(int eventId);
void showEventInTimeline(int eventId);
public slots: public slots:
void clear(); void clear();
@@ -119,7 +118,6 @@ public slots:
void selectEvent(int eventId); void selectEvent(int eventId);
void selectEventByLocation(const QString &filename, int line); void selectEventByLocation(const QString &filename, int line);
void buildModel(); void buildModel();
void changeDetailsForEvent(int eventId, const QString &newString);
private: private:
void setHeaderLabels(); void setHeaderLabels();

View File

@@ -152,7 +152,7 @@ bool TimelineModelAggregator::isEmpty() const
return true; return true;
} }
bool TimelineModelAggregator::eventAccepted(const QmlProfilerSimpleModel::QmlEventData &event) const bool TimelineModelAggregator::eventAccepted(const QmlProfilerSimpleModel::QmlEventData &/*event*/) const
{ {
// accept all events // accept all events
return true; return true;
@@ -319,6 +319,26 @@ const QVariantMap TimelineModelAggregator::getEventLocation(int modelIndex, int
return d->modelList[modelIndex]->getEventLocation(index); return d->modelList[modelIndex]->getEventLocation(index);
} }
int TimelineModelAggregator::getEventIdForHash(const QString &hash) const
{
foreach (const AbstractTimelineModel *model, d->modelList) {
int eventId = model->getEventIdForHash(hash);
if (eventId != -1)
return eventId;
}
return -1;
}
int TimelineModelAggregator::getEventIdForLocation(const QString &filename, int line, int column) const
{
foreach (const AbstractTimelineModel *model, d->modelList) {
int eventId = model->getEventIdForLocation(filename, line, column);
if (eventId != -1)
return eventId;
}
return -1;
}
void TimelineModelAggregator::dataChanged() void TimelineModelAggregator::dataChanged()
{ {
// this is a slot connected for every modelproxy // this is a slot connected for every modelproxy

View File

@@ -95,6 +95,9 @@ public:
Q_INVOKABLE const QVariantList getEventDetails(int modelIndex, int index) const; Q_INVOKABLE const QVariantList getEventDetails(int modelIndex, int index) const;
Q_INVOKABLE const QVariantMap getEventLocation(int modelIndex, int index) const; Q_INVOKABLE const QVariantMap getEventLocation(int modelIndex, int index) const;
Q_INVOKABLE int getEventIdForHash(const QString &hash) const;
Q_INVOKABLE int getEventIdForLocation(const QString &filename, int line, int column) const;
Q_INVOKABLE int modelIndexForCategory(int absoluteCategoryIndex) const; Q_INVOKABLE int modelIndexForCategory(int absoluteCategoryIndex) const;
Q_INVOKABLE int correctedCategoryIndexForModel(int modelIndex, int absoluteCategoryIndex) const; Q_INVOKABLE int correctedCategoryIndexForModel(int modelIndex, int absoluteCategoryIndex) const;

View File

@@ -348,6 +348,16 @@ const QVariantMap PixmapCacheModel::getEventLocation(int /*index*/) const
return map; return map;
} }
int PixmapCacheModel::getEventIdForHash(const QString &/*eventHash*/) const
{
return -1;
}
int PixmapCacheModel::getEventIdForLocation(const QString &/*filename*/, int /*line*/, int /*column*/) const
{
return -1;
}
bool compareStartTimes(const PixmapCacheModel::PixmapCacheEvent&t1, const PixmapCacheModel::PixmapCacheEvent &t2) bool compareStartTimes(const PixmapCacheModel::PixmapCacheEvent&t1, const PixmapCacheModel::PixmapCacheEvent &t2)
{ {
return t1.startTime < t2.startTime; return t1.startTime < t2.startTime;

View File

@@ -97,6 +97,9 @@ public:
Q_INVOKABLE const QVariantList getEventDetails(int index) const; Q_INVOKABLE const QVariantList getEventDetails(int index) const;
Q_INVOKABLE const QVariantMap getEventLocation(int index) const; Q_INVOKABLE const QVariantMap getEventLocation(int index) const;
Q_INVOKABLE int getEventIdForHash(const QString &eventHash) const;
Q_INVOKABLE int getEventIdForLocation(const QString &filename, int line, int column) const;
void loadData(); void loadData();
void clear(); void clear();
//signals: //signals:

View File

@@ -353,6 +353,16 @@ const QVariantMap SceneGraphTimelineModel::getEventLocation(int /*index*/) const
return map; return map;
} }
int SceneGraphTimelineModel::getEventIdForHash(const QString &) const
{
return -1;
}
int SceneGraphTimelineModel::getEventIdForLocation(const QString &/*filename*/, int /*line*/, int /*column*/) const
{
return -1;
}
bool compareStartTimes(const SceneGraphTimelineModel::SceneGraphEvent&t1, const SceneGraphTimelineModel::SceneGraphEvent &t2) bool compareStartTimes(const SceneGraphTimelineModel::SceneGraphEvent&t1, const SceneGraphTimelineModel::SceneGraphEvent &t2)
{ {
return t1.startTime < t2.startTime; return t1.startTime < t2.startTime;

View File

@@ -85,6 +85,9 @@ public:
Q_INVOKABLE const QVariantList getEventDetails(int index) const; Q_INVOKABLE const QVariantList getEventDetails(int index) const;
Q_INVOKABLE const QVariantMap getEventLocation(int index) const; Q_INVOKABLE const QVariantMap getEventLocation(int index) const;
Q_INVOKABLE int getEventIdForHash(const QString &eventHash) const;
Q_INVOKABLE int getEventIdForLocation(const QString &filename, int line, int column) const;
void loadData(); void loadData();
void clear(); void clear();
//signals: //signals: