+ if (!frame->isLoaded()) {
+ emit beginLoadingFrame(frame, calls.size());
+ frame->setCalls(topLevelItems, calls, binaryDataSize);
+ emit endLoadingFrame(frame);
+ m_loadingFrames.remove(frame);
+ }
+
+ if (!m_queuedErrors.isEmpty()) {
+ QList< QPair<ApiTraceFrame*, ApiTraceError> >::iterator itr;
+ for (itr = m_queuedErrors.begin(); itr != m_queuedErrors.end();
+ ++itr) {
+ const ApiTraceError &error = (*itr).second;
+ if ((*itr).first == frame) {
+ ApiTraceCall *call = frame->callWithIndex(error.callIndex);
+
+ if (!call) {
+ continue;
+ }
+
+ call->setError(error.message);
+ m_queuedErrors.erase(itr);
+
+ if (call->hasError()) {
+ m_errors.insert(call);
+ } else {
+ m_errors.remove(call);
+ }
+ emit changed(call);
+ }
+ }
+ }
+}
+
+void ApiTrace::findNext(ApiTraceFrame *frame,
+ ApiTraceCall *from,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity)
+{
+ ApiTraceCall *foundCall = 0;
+ int frameIdx = m_frames.indexOf(frame);
+ SearchRequest request(SearchRequest::Next,
+ frame, from, str, sensitivity);
+
+ if (frame->isLoaded()) {
+ foundCall = frame->findNextCall(from, str, sensitivity);
+ if (foundCall) {
+ emit findResult(request, SearchResult_Found, foundCall);
+ return;
+ }
+
+ //if the frame is loaded we already searched it above
+ // so skip it
+ frameIdx += 1;
+ }
+
+ //for the rest of the frames we search from beginning
+ request.from = 0;
+ for (int i = frameIdx; i < m_frames.count(); ++i) {
+ ApiTraceFrame *frame = m_frames[i];
+ request.frame = frame;
+ if (!frame->isLoaded()) {
+ emit loaderSearch(request);
+ return;
+ } else {
+ ApiTraceCall *call = frame->findNextCall(0, str, sensitivity);
+ if (call) {
+ emit findResult(request, SearchResult_Found, call);
+ return;
+ }
+ }
+ }
+ emit findResult(request, SearchResult_Wrapped, 0);
+}
+
+void ApiTrace::findPrev(ApiTraceFrame *frame,
+ ApiTraceCall *from,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity)
+{
+ ApiTraceCall *foundCall = 0;
+ int frameIdx = m_frames.indexOf(frame);
+ SearchRequest request(SearchRequest::Prev,
+ frame, from, str, sensitivity);
+
+ if (frame->isLoaded()) {
+ foundCall = frame->findPrevCall(from, str, sensitivity);
+ if (foundCall) {
+ emit findResult(request, SearchResult_Found, foundCall);
+ return;
+ }
+
+ //if the frame is loaded we already searched it above
+ // so skip it
+ frameIdx -= 1;
+ }
+
+ request.from = 0;
+ for (int i = frameIdx; i >= 0; --i) {
+ ApiTraceFrame *frame = m_frames[i];
+ request.frame = frame;
+ if (!frame->isLoaded()) {
+ emit loaderSearch(request);
+ return;
+ } else {
+ ApiTraceCall *call = frame->findPrevCall(0, str, sensitivity);
+ if (call) {
+ emit findResult(request, SearchResult_Found, call);
+ return;
+ }
+ }
+ }
+ emit findResult(request, SearchResult_Wrapped, 0);
+}
+
+void ApiTrace::loaderSearchResult(const ApiTrace::SearchRequest &request,
+ ApiTrace::SearchResult result,
+ ApiTraceCall *call)
+{
+ //qDebug()<<"Search result = "<<result
+ // <<", call is = "<<call;
+ emit findResult(request, result, call);
+}
+
+void ApiTrace::findFrameStart(ApiTraceFrame *frame)
+{
+ if (!frame)
+ return;
+
+ if (frame->isLoaded()) {
+ emit foundFrameStart(frame);
+ } else {
+ emit loaderFindFrameStart(frame);
+ }
+}
+
+void ApiTrace::findFrameEnd(ApiTraceFrame *frame)
+{
+ if (!frame)
+ return;
+
+ if (frame->isLoaded()) {
+ emit foundFrameEnd(frame);
+ } else {
+ emit loaderFindFrameEnd(frame);
+ }
+}
+
+void ApiTrace::findCallIndex(int index)
+{
+ int frameIdx = callInFrame(index);
+ ApiTraceFrame *frame = 0;
+
+ if (frameIdx < 0) {
+ emit foundCallIndex(0);
+ return;
+ }
+
+ frame = m_frames[frameIdx];
+
+ if (frame) {
+ if (frame->isLoaded()) {
+ ApiTraceCall *call = frame->callWithIndex(index);
+ emit foundCallIndex(call);
+ } else {
+ emit loaderFindCallIndex(index);
+ }
+ }
+}
+
+int ApiTrace::callInFrame(int callIdx) const
+{
+ unsigned numCalls = 0;
+
+ for (int frameIdx = 0; frameIdx < m_frames.size(); ++frameIdx) {
+ const ApiTraceFrame *frame = m_frames[frameIdx];
+ unsigned numCallsInFrame = frame->isLoaded()
+ ? frame->numTotalCalls()
+ : frame->numChildrenToLoad();
+ unsigned firstCall = numCalls;
+ unsigned endCall = numCalls + numCallsInFrame;
+ if (firstCall <= callIdx && endCall > callIdx) {
+ return frameIdx;
+ }
+ numCalls = endCall;
+ }
+
+ return -1;
+}
+
+void ApiTrace::setCallError(const ApiTraceError &error)
+{
+ int frameIdx = callInFrame(error.callIndex);
+ ApiTraceFrame *frame = 0;
+
+ if (frameIdx < 0) {
+ return;
+ }
+ frame = m_frames[frameIdx];
+
+ if (frame->isLoaded()) {
+ ApiTraceCall *call = frame->callWithIndex(error.callIndex);
+ call->setError(error.message);
+ if (call->hasError()) {
+ m_errors.insert(call);
+ } else {
+ m_errors.remove(call);
+ }
+ emit changed(call);
+ } else {
+ loadFrame(frame);
+ m_queuedErrors.append(qMakePair(frame, error));
+ }
+}
+
+bool ApiTrace::isFrameLoading(ApiTraceFrame *frame) const
+{
+ return m_loadingFrames.contains(frame);
+}
+
+void ApiTrace::bindThumbnailsToFrames(const QList<QImage> &thumbnails)
+{
+ QList<ApiTraceFrame *> frames = m_frames;
+
+ QList<QImage>::const_iterator thumbnail = thumbnails.begin();
+
+ foreach (ApiTraceFrame *frame, frames) {
+ if (thumbnail != thumbnails.end()) {
+ frame->setThumbnail(*thumbnail);
+
+ ++thumbnail;
+
+ emit changed(frame);
+ }
+ }