From 8f98c3a529e7ef88e4111ef22cf8411916a9a065 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sun, 11 Sep 2011 18:21:29 -0400 Subject: [PATCH] Implement find next for the on-demand-loaded files. Find next now works. Find previous hasn't been implemented yet but the entire infrastructure is there. --- gui/apitrace.cpp | 101 +++++++++++++++++++++- gui/apitrace.h | 32 ++++++- gui/apitracecall.cpp | 52 ++++++++++++ gui/apitracecall.h | 11 +++ gui/main.cpp | 8 ++ gui/mainwindow.cpp | 197 ++++++++++++++++++++++--------------------- gui/mainwindow.h | 12 +++ gui/traceloader.cpp | 167 ++++++++++++++++++++++++++---------- gui/traceloader.h | 18 +++- 9 files changed, 452 insertions(+), 146 deletions(-) diff --git a/gui/apitrace.cpp b/gui/apitrace.cpp index 958009b..bff1686 100644 --- a/gui/apitrace.cpp +++ b/gui/apitrace.cpp @@ -19,10 +19,21 @@ ApiTrace::ApiTrace() m_loader, SLOT(loadFrame(ApiTraceFrame*))); connect(m_loader, SIGNAL(framesLoaded(const QList)), this, SLOT(addFrames(const QList))); - connect(m_loader, SIGNAL(frameLoaded(ApiTraceFrame*)), - this, SLOT(frameLoadFinished(ApiTraceFrame*))); + connect(m_loader, + SIGNAL(frameContentsLoaded(ApiTraceFrame*,QVector,quint64)), + this, + SLOT(loaderFrameLoaded(ApiTraceFrame*,QVector,quint64))); connect(m_loader, SIGNAL(finishedParsing()), this, SLOT(finishedParsing())); + connect(this, SIGNAL(loaderSearchNext(int,QString,Qt::CaseSensitivity)), + m_loader, SLOT(searchNext(int,QString,Qt::CaseSensitivity))); + connect(this, SIGNAL(loaderSearchPrev(int,QString,Qt::CaseSensitivity)), + m_loader, SLOT(searchPrev(int,QString,Qt::CaseSensitivity))); + connect(m_loader, + SIGNAL(searchResult(ApiTrace::SearchResult,ApiTraceCall*)), + this, + SLOT(loaderSearchResult(ApiTrace::SearchResult,ApiTraceCall*))); + connect(m_loader, SIGNAL(startedParsing()), this, SIGNAL(startedLoadingTrace())); @@ -306,7 +317,6 @@ bool ApiTrace::hasErrors() const void ApiTrace::loadFrame(ApiTraceFrame *frame) { Q_ASSERT(!frame->loaded()); - emit beginLoadingFrame(frame, frame->numChildrenToLoad()); emit requestFrame(frame); } @@ -318,9 +328,92 @@ void ApiTrace::finishedParsing() } } -void ApiTrace::frameLoadFinished(ApiTraceFrame *frame) +void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame, + const QVector &calls, + quint64 binaryDataSize) { + Q_ASSERT(frame->numChildrenToLoad() == calls.size()); + emit beginLoadingFrame(frame, calls.size()); + frame->setCalls(calls, binaryDataSize); emit endLoadingFrame(frame); } +void ApiTrace::findNext(ApiTraceFrame *frame, + ApiTraceCall *from, + const QString &str, + Qt::CaseSensitivity sensitivity) +{ + ApiTraceCall *foundCall = 0; + int frameIdx = m_frames.indexOf(frame); + + if (frame->loaded()) { + foundCall = frame->findNextCall(from, str, sensitivity); + if (foundCall) { + emit findResult(SearchFound, foundCall); + return; + } + + //if the frame is loaded we already searched it above + // so skip it + frameIdx += 1; + } + + for (int i = frameIdx; i < m_frames.count(); ++i) { + ApiTraceFrame *frame = m_frames[i]; + if (!frame->loaded()) { + emit loaderSearchNext(i, str, sensitivity); + return; + } else { + ApiTraceCall *call = frame->findNextCall(0, str, sensitivity); + if (call) { + emit findResult(SearchFound, call); + } + } + } + emit findResult(SearchWrapped, 0); +} + +void ApiTrace::findPrev(ApiTraceFrame *frame, + ApiTraceCall *from, + const QString &str, + Qt::CaseSensitivity sensitivity) +{ + ApiTraceCall *foundCall = 0; + int frameIdx = m_frames.indexOf(frame); + + if (frame->loaded()) { + foundCall = frame->findPrevCall(from, str, sensitivity); + if (foundCall) { + emit findResult(SearchFound, foundCall); + return; + } + + //if the frame is loaded we already searched it above + // so skip it + frameIdx -= 1; + } + + for (int i = frameIdx; i <= 0; --i) { + ApiTraceFrame *frame = m_frames[i]; + if (!frame->loaded()) { + emit loaderSearchPrev(i, str, sensitivity); + return; + } else { + ApiTraceCall *call = frame->findPrevCall(0, str, sensitivity); + if (call) { + emit findResult(SearchFound, call); + } + } + } + emit findResult(SearchWrapped, 0); +} + +void ApiTrace::loaderSearchResult(ApiTrace::SearchResult result, + ApiTraceCall *call) +{ + //qDebug()<<"Search result = "< &frames); void slotSaved(); void finishedParsing(); - void frameLoadFinished(ApiTraceFrame *frame); + void loaderFrameLoaded(ApiTraceFrame *frame, + const QVector &calls, + quint64 binaryDataSize); + void loaderSearchResult(ApiTrace::SearchResult result, + ApiTraceCall *call); private: void detectFrames(); diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp index 5925045..b26514d 100644 --- a/gui/apitracecall.cpp +++ b/gui/apitracecall.cpp @@ -919,6 +919,14 @@ int ApiTraceCall::numChildren() const return 0; } +bool ApiTraceCall::contains(const QString &str, + Qt::CaseSensitivity sensitivity) const +{ + QString txt = searchText(); + return txt.contains(str, sensitivity); +} + + ApiTraceFrame::ApiTraceFrame(ApiTrace *parentTrace) : ApiTraceEvent(ApiTraceEvent::Frame), m_parentTrace(parentTrace), @@ -1044,3 +1052,47 @@ int ApiTraceFrame::numChildrenToLoad() const { return m_callsToLoad; } + +ApiTraceCall * +ApiTraceFrame::findNextCall(ApiTraceCall *from, + const QString &str, + Qt::CaseSensitivity sensitivity) const +{ + Q_ASSERT(m_loaded); + + int callIndex = 0; + + if (from) { + callIndex = m_calls.indexOf(from) + 1; + } + + for (int i = callIndex; i < m_calls.count(); ++i) { + ApiTraceCall *call = m_calls[i]; + if (call->contains(str, sensitivity)) { + return call; + } + } + return 0; +} + +ApiTraceCall * +ApiTraceFrame::findPrevCall(ApiTraceCall *from, + const QString &str, + Qt::CaseSensitivity sensitivity) const +{ + Q_ASSERT(m_loaded); + + int callIndex = m_calls.count() - 1; + + if (from) { + callIndex = m_calls.indexOf(from) - 1; + } + + for (int i = callIndex; i >= 0; --i) { + ApiTraceCall *call = m_calls[i]; + if (call->contains(str, sensitivity)) { + return call; + } + } + return 0; +} diff --git a/gui/apitracecall.h b/gui/apitracecall.h index ca4c354..adfa1b0 100644 --- a/gui/apitracecall.h +++ b/gui/apitracecall.h @@ -259,6 +259,9 @@ public: QVector editedValues() const; void revert(); + bool contains(const QString &str, + Qt::CaseSensitivity sensitivity) const; + ApiTrace *parentTrace() const; QString toHtml() const; @@ -306,6 +309,14 @@ public: void setCalls(const QVector &calls, quint64 binaryDataSize); + ApiTraceCall *findNextCall(ApiTraceCall *from, + const QString &str, + Qt::CaseSensitivity sensitivity) const; + + ApiTraceCall *findPrevCall(ApiTraceCall *from, + const QString &str, + Qt::CaseSensitivity sensitivity) const; + int binaryDataSize() const; bool loaded() const; diff --git a/gui/main.cpp b/gui/main.cpp index 3f8cfa6..6043b75 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -1,5 +1,6 @@ #include "mainwindow.h" +#include "apitrace.h" #include "apitracecall.h" #include @@ -7,13 +8,20 @@ #include Q_DECLARE_METATYPE(QList); +Q_DECLARE_METATYPE(QVector); +Q_DECLARE_METATYPE(Qt::CaseSensitivity); +Q_DECLARE_METATYPE(ApiTrace::SearchResult); + int main(int argc, char **argv) { QApplication app(argc, argv); qRegisterMetaType >(); + qRegisterMetaType >(); qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); MainWindow window; window.show(); diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index e5f6d9b..9dc530d 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -592,10 +592,10 @@ void MainWindow::showSelectedSurface() ImageViewer *viewer = new ImageViewer(this); QString title; - if (currentCall()) { + if (selectedCall()) { title = tr("QApiTrace - Surface at %1 (%2)") - .arg(currentCall()->name()) - .arg(currentCall()->index()); + .arg(selectedCall()->name()) + .arg(selectedCall()->index()); } else { title = tr("QApiTrace - Surface Viewer"); } @@ -692,6 +692,8 @@ void MainWindow::initConnections() this, SLOT(slotSaved())); connect(m_trace, SIGNAL(changed(ApiTraceCall*)), this, SLOT(slotTraceChanged(ApiTraceCall*))); + connect(m_trace, SIGNAL(findResult(ApiTrace::SearchResult,ApiTraceCall*)), + this, SLOT(slotSearchResult(ApiTrace::SearchResult,ApiTraceCall*))); connect(m_retracer, SIGNAL(finished(const QString&)), this, SLOT(replayFinished(const QString&))); @@ -831,103 +833,31 @@ void MainWindow::slotSearch() void MainWindow::slotSearchNext(const QString &str, Qt::CaseSensitivity sensitivity) { - QModelIndex index = m_ui.callView->currentIndex(); - ApiTraceEvent *event = 0; - - - if (!index.isValid()) { - index = m_proxyModel->index(0, 0, QModelIndex()); - if (!index.isValid()) { - qDebug()<<"no currently valid index"; - m_searchWidget->setFound(false); - return; - } - } - - event = index.data(ApiTraceModel::EventRole).value(); - ApiTraceCall *call = 0; + ApiTraceCall *call = currentCall(); + ApiTraceFrame *frame = currentFrame(); - if (event->type() == ApiTraceCall::Call) - call = static_cast(event); - else { - Q_ASSERT(event->type() == ApiTraceCall::Frame); - ApiTraceFrame *frame = static_cast(event); - call = frame->call(0); + Q_ASSERT(call || frame); + if (!frame) { + frame = call->parentFrame(); } + Q_ASSERT(frame); - if (!call) { - m_searchWidget->setFound(false); - return; - } - const QVector &calls = m_trace->calls(); - int callNum = calls.indexOf(call); - - for (int i = callNum + 1; i < calls.count(); ++i) { - ApiTraceCall *testCall = calls[i]; - QModelIndex index = m_proxyModel->indexForCall(testCall); - /* if it's not valid it means that the proxy model has already - * filtered it out */ - if (index.isValid()) { - QString txt = testCall->searchText(); - if (txt.contains(str, sensitivity)) { - m_ui.callView->setCurrentIndex(index); - m_searchWidget->setFound(true); - return; - } - } - } - m_searchWidget->setFound(false); + m_trace->findNext(frame, call, str, sensitivity); } void MainWindow::slotSearchPrev(const QString &str, Qt::CaseSensitivity sensitivity) { - QModelIndex index = m_ui.callView->currentIndex(); - ApiTraceEvent *event = 0; - + ApiTraceCall *call = currentCall(); + ApiTraceFrame *frame = currentFrame(); - if (!index.isValid()) { - index = m_proxyModel->index(0, 0, QModelIndex()); - if (!index.isValid()) { - qDebug()<<"no currently valid index"; - m_searchWidget->setFound(false); - return; - } + Q_ASSERT(call || frame); + if (!frame) { + frame = call->parentFrame(); } + Q_ASSERT(frame); - event = index.data(ApiTraceModel::EventRole).value(); - ApiTraceCall *call = 0; - - if (event->type() == ApiTraceCall::Call) - call = static_cast(event); - else { - Q_ASSERT(event->type() == ApiTraceCall::Frame); - ApiTraceFrame *frame = static_cast(event); - call = frame->call(0); - } - - if (!call) { - m_searchWidget->setFound(false); - return; - } - const QVector &calls = m_trace->calls(); - int callNum = calls.indexOf(call); - - for (int i = callNum - 1; i >= 0; --i) { - ApiTraceCall *testCall = calls[i]; - QModelIndex index = m_proxyModel->indexForCall(testCall); - /* if it's not valid it means that the proxy model has already - * filtered it out */ - if (index.isValid()) { - QString txt = testCall->searchText(); - if (txt.contains(str, sensitivity)) { - m_ui.callView->setCurrentIndex(index); - m_searchWidget->setFound(true); - return; - } - } - } - m_searchWidget->setFound(false); + m_trace->findPrev(frame, call, str, sensitivity); } void MainWindow::fillState(bool nonDefaults) @@ -1000,7 +930,7 @@ void MainWindow::slotSaved() void MainWindow::slotGoFrameStart() { - ApiTraceFrame *frame = currentFrame(); + ApiTraceFrame *frame = selectedFrame(); if (!frame || frame->isEmpty()) { return; } @@ -1022,7 +952,7 @@ void MainWindow::slotGoFrameStart() void MainWindow::slotGoFrameEnd() { - ApiTraceFrame *frame = currentFrame(); + ApiTraceFrame *frame = selectedFrame(); if (!frame || frame->isEmpty()) { return; } @@ -1041,7 +971,7 @@ void MainWindow::slotGoFrameEnd() } while (itr != calls.constBegin()); } -ApiTraceFrame * MainWindow::currentFrame() const +ApiTraceFrame * MainWindow::selectedFrame() const { if (m_selectedEvent) { if (m_selectedEvent->type() == ApiTraceEvent::Frame) { @@ -1099,7 +1029,7 @@ void MainWindow::slotErrorSelected(QTreeWidgetItem *current) } } -ApiTraceCall * MainWindow::currentCall() const +ApiTraceCall * MainWindow::selectedCall() const { if (m_selectedEvent && m_selectedEvent->type() == ApiTraceEvent::Call) { @@ -1120,11 +1050,11 @@ void MainWindow::saveSelectedSurface() QImage img = var.value(); QString imageIndex; - if (currentCall()) { + if (selectedCall()) { imageIndex = tr("_call_%1") - .arg(currentCall()->index()); - } else if (currentFrame()) { - ApiTraceCall *firstCall = currentFrame()->call(0); + .arg(selectedCall()->index()); + } else if (selectedFrame()) { + ApiTraceCall *firstCall = selectedFrame()->call(0); if (firstCall) { imageIndex = tr("_frame_%1") .arg(firstCall->index()); @@ -1166,4 +1096,77 @@ void MainWindow::loadProgess(int percent) m_progressBar->setValue(percent); } +void MainWindow::slotSearchResult(ApiTrace::SearchResult result, + ApiTraceCall *call) +{ + switch (result) { + case ApiTrace::SearchNotFound: + m_searchWidget->setFound(false); + break; + case ApiTrace::SearchFound: { + QModelIndex index = m_proxyModel->indexForCall(call); + m_ui.callView->setCurrentIndex(index); + m_searchWidget->setFound(true); + } + break; + case ApiTrace::SearchWrapped: + m_searchWidget->setFound(false); + break; + } +} + +ApiTraceFrame * MainWindow::currentFrame() const +{ + QModelIndex index = m_ui.callView->currentIndex(); + ApiTraceEvent *event = 0; + + if (!index.isValid()) { + index = m_proxyModel->index(0, 0, QModelIndex()); + if (!index.isValid()) { + qDebug()<<"no currently valid index"; + return 0; + } + } + + event = index.data(ApiTraceModel::EventRole).value(); + Q_ASSERT(event); + if (!event) { + return 0; + } + + ApiTraceFrame *frame = 0; + if (event->type() == ApiTraceCall::Frame) { + frame = static_cast(event); + } + return frame; +} + +ApiTraceCall * MainWindow::currentCall() const +{ + QModelIndex index = m_ui.callView->currentIndex(); + ApiTraceEvent *event = 0; + + if (!index.isValid()) { + index = m_proxyModel->index(0, 0, QModelIndex()); + if (!index.isValid()) { + qDebug()<<"no currently valid index"; + return 0; + } + } + + event = index.data(ApiTraceModel::EventRole).value(); + Q_ASSERT(event); + if (!event) { + return 0; + } + + ApiTraceCall *call = 0; + if (event->type() == ApiTraceCall::Call) { + call = static_cast(event); + } + + return call; + +} + #include "mainwindow.moc" diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 00fe04b..e5b19b4 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -3,6 +3,8 @@ #include "ui_mainwindow.h" +#include "apitrace.h" + #include #include @@ -71,6 +73,8 @@ private slots: void slotTraceChanged(ApiTraceCall *call); void slotRetraceErrors(const QList &errors); void slotErrorSelected(QTreeWidgetItem *current); + void slotSearchResult(ApiTrace::SearchResult result, + ApiTraceCall *call); private: void initObjects(); @@ -78,9 +82,17 @@ private: void newTraceFile(const QString &fileName); void replayTrace(bool dumpState); void fillStateForFrame(); + + /* there's a difference between selected frame/call and + * current call/frame. the former implies actual selection + * the latter might be just a highlight, e.g. during searching + */ + ApiTraceFrame *selectedFrame() const; + ApiTraceCall *selectedCall() const; ApiTraceFrame *currentFrame() const; ApiTraceCall *currentCall() const; + private: Ui_MainWindow m_ui; ShadersSourceWidget *m_sourcesWidget; diff --git a/gui/traceloader.cpp b/gui/traceloader.cpp index a6ffd29..11847ff 100644 --- a/gui/traceloader.cpp +++ b/gui/traceloader.cpp @@ -56,49 +56,7 @@ void TraceLoader::loadTrace(const QString &filename) void TraceLoader::loadFrame(ApiTraceFrame *currentFrame) { - if (m_parser.supportsOffsets()) { - unsigned frameIdx = currentFrame->number; - int numOfCalls = numberOfCallsInFrame(frameIdx); - - if (numOfCalls) { - quint64 binaryDataSize = 0; - QVector calls(numOfCalls); - const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx]; - - m_parser.setBookmark(frameBookmark.start); - - Trace::Call *call; - int parsedCalls = 0; - while ((call = m_parser.parse_call())) { - ApiTraceCall *apiCall = - apiCallFromTraceCall(call, m_helpHash, - currentFrame, this); - calls[parsedCalls] = apiCall; - Q_ASSERT(calls[parsedCalls]); - if (apiCall->hasBinaryData()) { - QByteArray data = - apiCall->arguments()[ - apiCall->binaryDataIndex()].toByteArray(); - binaryDataSize += data.size(); - } - - ++parsedCalls; - - delete call; - - if (ApiTrace::isCallAFrameMarker(apiCall, m_frameMarker)) { - break; - } - - } - assert(parsedCalls == numOfCalls); - Q_ASSERT(parsedCalls == calls.size()); - Q_ASSERT(parsedCalls == currentFrame->numChildrenToLoad()); - calls.squeeze(); - currentFrame->setCalls(calls, binaryDataSize); - emit frameLoaded(currentFrame); - } - } + fetchFrameContents(currentFrame); } void TraceLoader::setFrameMarker(ApiTrace::FrameMarker marker) @@ -188,6 +146,7 @@ void TraceLoader::scanTrace() currentFrame->setNumChildren(numOfCalls); frames.append(currentFrame); + m_createdFrames.append(currentFrame); m_frameBookmarks[numOfFrames] = frameBookmark; ++numOfFrames; @@ -211,6 +170,7 @@ void TraceLoader::scanTrace() currentFrame->setNumChildren(numOfCalls); frames.append(currentFrame); + m_createdFrames.append(currentFrame); m_frameBookmarks[numOfFrames] = frameBookmark; ++numOfFrames; } @@ -312,4 +272,125 @@ void TraceLoader::addEnumSignature(unsigned id, ApiTraceEnumSignature *signature m_enumSignatures[id] = signature; } +void TraceLoader::searchNext(int startFrame, + const QString &str, + Qt::CaseSensitivity sensitivity) +{ + Q_ASSERT(m_parser.supportsOffsets()); + if (m_parser.supportsOffsets()) { + const FrameBookmark &frameBookmark = m_frameBookmarks[startFrame]; + m_parser.setBookmark(frameBookmark.start); + Trace::Call *call = 0; + while ((call = m_parser.parse_call())) { + + if (callContains(call, str, sensitivity)) { + unsigned frameIdx = callInFrame(call->no); + ApiTraceFrame *frame = m_createdFrames[frameIdx]; + const QVector calls = + fetchFrameContents(frame); + for (int i = 0; i < calls.count(); ++i) { + if (calls[i]->index() == call->no) { + emit searchResult(ApiTrace::SearchFound, calls[i]); + break; + } + } + delete call; + return; + } + + delete call; + } + } + emit searchResult(ApiTrace::SearchNotFound, 0); +} + +void TraceLoader::searchPrev(int startFrame, + const QString &str, + Qt::CaseSensitivity sensitivity) +{ +} + +int TraceLoader::callInFrame(int callIdx) const +{ + unsigned numCalls = 0; + + for (int frameIdx = 0; frameIdx <= m_frameBookmarks.size(); ++frameIdx) { + const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx]; + unsigned firstCall = numCalls; + unsigned endCall = numCalls + frameBookmark.numberOfCalls; + if (firstCall <= callIdx && endCall > callIdx) { + return frameIdx; + } + numCalls = endCall; + } + Q_ASSERT(!"call not in the trace"); + return 0; +} + +bool TraceLoader::callContains(Trace::Call *call, + const QString &str, + Qt::CaseSensitivity sensitivity) +{ + /* + * FIXME: do string comparison directly on Trace::Call + */ + ApiTraceCall *apiCall = apiCallFromTraceCall(call, m_helpHash, + 0, this); + bool result = apiCall->contains(str, sensitivity); + delete apiCall; + return result; +} + +QVector +TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame) +{ + Q_ASSERT(currentFrame); + if (m_parser.supportsOffsets()) { + unsigned frameIdx = currentFrame->number; + int numOfCalls = numberOfCallsInFrame(frameIdx); + + if (numOfCalls) { + quint64 binaryDataSize = 0; + QVector calls(numOfCalls); + const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx]; + + m_parser.setBookmark(frameBookmark.start); + + Trace::Call *call; + int parsedCalls = 0; + while ((call = m_parser.parse_call())) { + ApiTraceCall *apiCall = + apiCallFromTraceCall(call, m_helpHash, + currentFrame, this); + calls[parsedCalls] = apiCall; + Q_ASSERT(calls[parsedCalls]); + if (apiCall->hasBinaryData()) { + QByteArray data = + apiCall->arguments()[ + apiCall->binaryDataIndex()].toByteArray(); + binaryDataSize += data.size(); + } + + ++parsedCalls; + + delete call; + + if (ApiTrace::isCallAFrameMarker(apiCall, m_frameMarker)) { + break; + } + + } + assert(parsedCalls == numOfCalls); + Q_ASSERT(parsedCalls == calls.size()); + calls.squeeze(); + + Q_ASSERT(parsedCalls == currentFrame->numChildrenToLoad()); + emit frameContentsLoaded(currentFrame, + calls, binaryDataSize); + return calls; + } + } + return QVector(); +} + #include "traceloader.moc" diff --git a/gui/traceloader.h b/gui/traceloader.h index 86b7526..c83cf47 100644 --- a/gui/traceloader.h +++ b/gui/traceloader.h @@ -28,6 +28,12 @@ public slots: void loadTrace(const QString &filename); void loadFrame(ApiTraceFrame *frame); void setFrameMarker(ApiTrace::FrameMarker marker); + void searchNext(int startFrame, + const QString &str, + Qt::CaseSensitivity sensitivity); + void searchPrev(int startFrame, + const QString &str, + Qt::CaseSensitivity sensitivity); signals: void startedParsing(); @@ -35,8 +41,11 @@ signals: void finishedParsing(); void framesLoaded(const QList &frames); - void frameLoaded(ApiTraceFrame *frame); + void frameContentsLoaded(ApiTraceFrame *frame, + const QVector &calls, + quint64 binaryDataSize); + void searchResult(ApiTrace::SearchResult result, ApiTraceCall *call); private: struct FrameBookmark { FrameBookmark() @@ -58,6 +67,12 @@ private: void scanTrace(); void parseTrace(); + int callInFrame(int callIdx) const; + bool callContains(Trace::Call *call, + const QString &str, + Qt::CaseSensitivity sensitivity); + QVector fetchFrameContents(ApiTraceFrame *frame); + private: Trace::Parser m_parser; QString m_fileName; @@ -65,6 +80,7 @@ private: typedef QMap FrameBookmarks; FrameBookmarks m_frameBookmarks; + QList m_createdFrames; QHash m_helpHash; -- 2.43.0