+bool ApiTrace::needsSaving() const
+{
+ return m_needsSaving;
+}
+
+void ApiTrace::save()
+{
+ QFileInfo fi(m_tempFileName);
+ QDir dir;
+ emit startedSaving();
+ dir.mkpath(fi.absolutePath());
+ m_saver->saveFile(m_tempFileName,
+ m_fileName,
+ m_editedCalls);
+}
+
+void ApiTrace::slotSaved()
+{
+ m_needsSaving = false;
+}
+
+bool ApiTrace::isSaving() const
+{
+ return m_saver->isRunning();
+}
+
+void ApiTrace::callError(ApiTraceCall *call)
+{
+ Q_ASSERT(call);
+
+ if (call->hasError())
+ m_errors.insert(call);
+ else
+ m_errors.remove(call);
+
+ emit changed(call);
+}
+
+bool ApiTrace::hasErrors() const
+{
+ return !m_errors.isEmpty();
+}
+
+void ApiTrace::loadFrame(ApiTraceFrame *frame)
+{
+ Q_ASSERT(!frame->loaded());
+ emit requestFrame(frame);
+}
+
+void ApiTrace::finishedParsing()
+{
+ ApiTraceFrame *firstFrame = m_frames[0];
+ if (firstFrame && !firstFrame->loaded()) {
+ loadFrame(firstFrame);
+ }
+}
+
+void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame,
+ const QVector<ApiTraceCall*> &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);
+ return;
+ }
+ }
+ }
+ 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);
+ return;
+ }
+ }
+ }
+ emit findResult(SearchWrapped, 0);
+}
+
+void ApiTrace::loaderSearchResult(ApiTrace::SearchResult result,
+ ApiTraceCall *call)
+{
+ //qDebug()<<"Search result = "<<result
+ // <<", call is = "<<call;
+ emit findResult(result, call);
+}
+
+void ApiTrace::findFrameStart(ApiTraceFrame *frame)
+{
+ if (frame->loaded()) {
+ emit foundFrameStart(frame);
+ } else {
+ emit loaderFindFrameStart(frame);
+ }
+}
+
+void ApiTrace::findFrameEnd(ApiTraceFrame *frame)
+{
+ if (frame->loaded()) {
+ 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->loaded()) {
+ 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->loaded()
+ ? frame->numChildren()
+ : frame->numChildrenToLoad();
+ unsigned firstCall = numCalls;
+ unsigned endCall = numCalls + numCallsInFrame;
+ if (firstCall <= callIdx && endCall > callIdx) {
+ return frameIdx;
+ }
+ numCalls = endCall;
+ }
+
+ return -1;
+}
+