blob: 3f840eee4c213943bb70c803f5efe8e9bc7b1b37 [file] [log] [blame]
Zack Rusinf6667d12011-03-30 11:03:37 -04001#include "apitrace.h"
2
Zack Rusinebf971e2011-09-06 17:44:43 -04003#include "traceloader.h"
Zack Rusind809a062011-04-17 23:30:58 -04004#include "saverthread.h"
Zack Rusinf6667d12011-03-30 11:03:37 -04005
Zack Rusin3176ebe2011-09-06 21:11:36 -04006#include <QDebug>
Zack Rusin63efea82011-04-17 17:10:45 -04007#include <QDir>
Zack Rusinebf971e2011-09-06 17:44:43 -04008#include <QThread>
Zack Rusin63efea82011-04-17 17:10:45 -04009
Zack Rusinf6667d12011-03-30 11:03:37 -040010ApiTrace::ApiTrace()
José Fonseca5cd8d992012-03-25 23:12:20 +010011 : m_needsSaving(false)
Zack Rusinf6667d12011-03-30 11:03:37 -040012{
Zack Rusinebf971e2011-09-06 17:44:43 -040013 m_loader = new TraceLoader();
Zack Rusinf682e192011-09-07 01:36:41 -040014
Zack Rusinebf971e2011-09-06 17:44:43 -040015 connect(this, SIGNAL(loadTrace(QString)),
16 m_loader, SLOT(loadTrace(QString)));
Zack Rusin3176ebe2011-09-06 21:11:36 -040017 connect(this, SIGNAL(requestFrame(ApiTraceFrame*)),
18 m_loader, SLOT(loadFrame(ApiTraceFrame*)));
Zack Rusinebf971e2011-09-06 17:44:43 -040019 connect(m_loader, SIGNAL(framesLoaded(const QList<ApiTraceFrame*>)),
Zack Rusinf6667d12011-03-30 11:03:37 -040020 this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
Zack Rusin8f98c3a2011-09-11 18:21:29 -040021 connect(m_loader,
Zack Rusind9d9d222013-10-11 18:02:26 -040022 SIGNAL(frameContentsLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>, QVector<ApiTraceCall*>,quint64)),
Zack Rusin8f98c3a2011-09-11 18:21:29 -040023 this,
Zack Rusind9d9d222013-10-11 18:02:26 -040024 SLOT(loaderFrameLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,QVector<ApiTraceCall*>,quint64)));
José Fonseca67964382012-03-27 23:54:30 +010025 connect(m_loader, SIGNAL(guessedApi(int)),
26 this, SLOT(guessedApi(int)));
Zack Rusinad513b32011-09-25 14:33:41 -040027 connect(this, SIGNAL(loaderSearch(ApiTrace::SearchRequest)),
28 m_loader, SLOT(search(ApiTrace::SearchRequest)));
Zack Rusin8f98c3a2011-09-11 18:21:29 -040029 connect(m_loader,
Zack Rusinad513b32011-09-25 14:33:41 -040030 SIGNAL(searchResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)),
Zack Rusin8f98c3a2011-09-11 18:21:29 -040031 this,
Zack Rusinad513b32011-09-25 14:33:41 -040032 SLOT(loaderSearchResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)));
Zack Rusin93e4d152011-09-13 02:23:39 -040033 connect(this, SIGNAL(loaderFindFrameStart(ApiTraceFrame*)),
34 m_loader, SLOT(findFrameStart(ApiTraceFrame*)));
35 connect(this, SIGNAL(loaderFindFrameEnd(ApiTraceFrame*)),
36 m_loader, SLOT(findFrameEnd(ApiTraceFrame*)));
37 connect(m_loader, SIGNAL(foundFrameStart(ApiTraceFrame*)),
38 this, SIGNAL(foundFrameStart(ApiTraceFrame*)));
39 connect(m_loader, SIGNAL(foundFrameEnd(ApiTraceFrame*)),
40 this, SIGNAL(foundFrameEnd(ApiTraceFrame*)));
Zack Rusinda7579b2011-09-13 17:33:05 -040041 connect(this, SIGNAL(loaderFindCallIndex(int)),
42 m_loader, SLOT(findCallIndex(int)));
43 connect(m_loader, SIGNAL(foundCallIndex(ApiTraceCall*)),
44 this, SIGNAL(foundCallIndex(ApiTraceCall*)));
Zack Rusin8f98c3a2011-09-11 18:21:29 -040045
Zack Rusinebf971e2011-09-06 17:44:43 -040046
47 connect(m_loader, SIGNAL(startedParsing()),
Zack Rusinde4ea412011-03-30 11:30:08 -040048 this, SIGNAL(startedLoadingTrace()));
Zack Rusinebf971e2011-09-06 17:44:43 -040049 connect(m_loader, SIGNAL(parsed(int)),
50 this, SIGNAL(loaded(int)));
51 connect(m_loader, SIGNAL(finishedParsing()),
Zack Rusinde4ea412011-03-30 11:30:08 -040052 this, SIGNAL(finishedLoadingTrace()));
Zack Rusind809a062011-04-17 23:30:58 -040053
Zack Rusinebf971e2011-09-06 17:44:43 -040054
Zack Rusind809a062011-04-17 23:30:58 -040055 m_saver = new SaverThread(this);
Zack Rusin9af5bff2011-04-18 01:05:50 -040056 connect(m_saver, SIGNAL(traceSaved()),
57 this, SLOT(slotSaved()));
58 connect(m_saver, SIGNAL(traceSaved()),
59 this, SIGNAL(saved()));
Zack Rusinebf971e2011-09-06 17:44:43 -040060
61 m_loaderThread = new QThread();
62 m_loader->moveToThread(m_loaderThread);
63 m_loaderThread->start();
Zack Rusinf6667d12011-03-30 11:03:37 -040064}
65
66ApiTrace::~ApiTrace()
67{
Zack Rusinebf971e2011-09-06 17:44:43 -040068 m_loaderThread->quit();
69 m_loaderThread->deleteLater();
Zack Rusinf6667d12011-03-30 11:03:37 -040070 qDeleteAll(m_frames);
71 delete m_loader;
Zack Rusind809a062011-04-17 23:30:58 -040072 delete m_saver;
Zack Rusinf6667d12011-03-30 11:03:37 -040073}
74
Zack Rusinf6667d12011-03-30 11:03:37 -040075bool ApiTrace::isEmpty() const
76{
Zack Rusinc1743432011-09-13 17:58:58 -040077 return m_frames.isEmpty();
Zack Rusinf6667d12011-03-30 11:03:37 -040078}
79
80QString ApiTrace::fileName() const
81{
Zack Rusinc5929572011-09-19 03:04:40 -040082 if (edited()) {
Zack Rusin63efea82011-04-17 17:10:45 -040083 return m_tempFileName;
Zack Rusinc5929572011-09-19 03:04:40 -040084 }
Zack Rusin63efea82011-04-17 17:10:45 -040085
Zack Rusinf6667d12011-03-30 11:03:37 -040086 return m_fileName;
87}
88
José Fonseca34500442012-03-24 07:56:45 +000089const QList<ApiTraceFrame*> & ApiTrace::frames() const
Zack Rusinf6667d12011-03-30 11:03:37 -040090{
91 return m_frames;
92}
93
94ApiTraceFrame * ApiTrace::frameAt(int idx) const
95{
96 return m_frames.value(idx);
97}
98
99int ApiTrace::numFrames() const
100{
101 return m_frames.count();
102}
103
104int ApiTrace::numCallsInFrame(int idx) const
105{
106 const ApiTraceFrame *frame = frameAt(idx);
Zack Rusinc5929572011-09-19 03:04:40 -0400107 if (frame) {
Zack Rusind9d9d222013-10-11 18:02:26 -0400108 return frame->numTotalCalls();
Zack Rusinc5929572011-09-19 03:04:40 -0400109 } else {
Zack Rusinf6667d12011-03-30 11:03:37 -0400110 return 0;
Zack Rusinc5929572011-09-19 03:04:40 -0400111 }
Zack Rusinf6667d12011-03-30 11:03:37 -0400112}
113
114void ApiTrace::setFileName(const QString &name)
115{
116 if (m_fileName != name) {
117 m_fileName = name;
Zack Rusindaf82af2011-09-24 13:42:53 -0400118 m_tempFileName = QString();
Zack Rusinf6667d12011-03-30 11:03:37 -0400119
Zack Rusinca164112011-04-11 02:23:09 -0400120 m_frames.clear();
Zack Rusin30069572011-04-20 18:21:11 -0400121 m_errors.clear();
122 m_editedCalls.clear();
Zack Rusindaf82af2011-09-24 13:42:53 -0400123 m_queuedErrors.clear();
Zack Rusin30069572011-04-20 18:21:11 -0400124 m_needsSaving = false;
Zack Rusinf6667d12011-03-30 11:03:37 -0400125 emit invalidated();
126
Zack Rusinebf971e2011-09-06 17:44:43 -0400127 emit loadTrace(m_fileName);
Zack Rusinf6667d12011-03-30 11:03:37 -0400128 }
129}
130
Zack Rusinf6667d12011-03-30 11:03:37 -0400131void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
132{
133 int currentFrames = m_frames.count();
134 int numNewFrames = frames.count();
Zack Rusinb56e03d2011-04-20 23:58:52 -0400135
136 emit beginAddingFrames(currentFrames, numNewFrames);
137
Zack Rusinf6667d12011-03-30 11:03:37 -0400138 m_frames += frames;
139
Zack Rusinf6667d12011-03-30 11:03:37 -0400140 foreach(ApiTraceFrame *frame, frames) {
Zack Rusinebf971e2011-09-06 17:44:43 -0400141 frame->setParentTrace(this);
Zack Rusinf6667d12011-03-30 11:03:37 -0400142 }
143
Zack Rusinb56e03d2011-04-20 23:58:52 -0400144 emit endAddingFrames();
Zack Rusinf6667d12011-03-30 11:03:37 -0400145}
146
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400147ApiTraceCall * ApiTrace::callWithIndex(int idx) const
148{
Zack Rusinc1743432011-09-13 17:58:58 -0400149 for (int i = 0; i < m_frames.count(); ++i) {
150 ApiTraceCall *call = m_frames[i]->callWithIndex(idx);
Zack Rusinc5929572011-09-19 03:04:40 -0400151 if (call) {
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400152 return call;
Zack Rusinc5929572011-09-19 03:04:40 -0400153 }
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400154 }
155 return NULL;
156}
157
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400158ApiTraceState ApiTrace::defaultState() const
159{
160 ApiTraceFrame *frame = frameAt(0);
Zack Rusinc5929572011-09-19 03:04:40 -0400161 if (!frame || !frame->isLoaded() || frame->isEmpty()) {
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400162 return ApiTraceState();
Zack Rusinc5929572011-09-19 03:04:40 -0400163 }
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400164
Zack Rusin851d0b02011-09-14 22:04:07 -0400165 ApiTraceCall *firstCall = frame->calls().first();
166 if (!firstCall->hasState()) {
167 return ApiTraceState();
168 }
169
170 return *firstCall->state();
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400171}
172
Zack Rusin661842d2011-04-17 01:59:16 -0400173void ApiTrace::callEdited(ApiTraceCall *call)
174{
Zack Rusin63efea82011-04-17 17:10:45 -0400175 if (!m_editedCalls.contains(call)) {
176 //lets generate a temp filename
177 QString tempPath = QDir::tempPath();
Zack Rusin63efea82011-04-17 17:10:45 -0400178 m_tempFileName = QString::fromLatin1("%1/%2.edited")
179 .arg(tempPath)
180 .arg(m_fileName);
Zack Rusin63efea82011-04-17 17:10:45 -0400181 }
Zack Rusin661842d2011-04-17 01:59:16 -0400182 m_editedCalls.insert(call);
Zack Rusin9af5bff2011-04-18 01:05:50 -0400183 m_needsSaving = true;
Zack Rusin63efea82011-04-17 17:10:45 -0400184
Zack Rusin661842d2011-04-17 01:59:16 -0400185 emit changed(call);
186}
187
188void ApiTrace::callReverted(ApiTraceCall *call)
189{
190 m_editedCalls.remove(call);
Zack Rusin63efea82011-04-17 17:10:45 -0400191
192 if (m_editedCalls.isEmpty()) {
193 m_needsSaving = false;
194 }
Zack Rusin661842d2011-04-17 01:59:16 -0400195 emit changed(call);
196}
197
Zack Rusin0ddd2502011-04-17 02:34:45 -0400198bool ApiTrace::edited() const
Zack Rusin661842d2011-04-17 01:59:16 -0400199{
200 return !m_editedCalls.isEmpty();
201}
202
Zack Rusin63efea82011-04-17 17:10:45 -0400203bool ApiTrace::needsSaving() const
204{
205 return m_needsSaving;
206}
207
208void ApiTrace::save()
209{
210 QFileInfo fi(m_tempFileName);
211 QDir dir;
Zack Rusin9af5bff2011-04-18 01:05:50 -0400212 emit startedSaving();
Zack Rusin63efea82011-04-17 17:10:45 -0400213 dir.mkpath(fi.absolutePath());
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400214 m_saver->saveFile(m_tempFileName,
215 m_fileName,
216 m_editedCalls);
Zack Rusin63efea82011-04-17 17:10:45 -0400217}
218
Zack Rusin9af5bff2011-04-18 01:05:50 -0400219void ApiTrace::slotSaved()
220{
221 m_needsSaving = false;
222}
223
224bool ApiTrace::isSaving() const
225{
226 return m_saver->isRunning();
227}
228
Zack Rusincc0b4912011-04-19 01:59:20 -0400229bool ApiTrace::hasErrors() const
230{
James Benton6a319062012-08-09 16:22:50 +0100231 return !m_errors.isEmpty() || !m_queuedErrors.isEmpty();
Zack Rusincc0b4912011-04-19 01:59:20 -0400232}
233
Zack Rusin3176ebe2011-09-06 21:11:36 -0400234void ApiTrace::loadFrame(ApiTraceFrame *frame)
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400235{
Zack Rusin18d094e2011-10-07 23:55:55 -0400236 if (!isFrameLoading(frame)) {
237 Q_ASSERT(!frame->isLoaded());
238 m_loadingFrames.insert(frame);
239 emit requestFrame(frame);
240 }
Zack Rusin35c27932011-08-28 21:16:22 -0400241}
242
José Fonseca67964382012-03-27 23:54:30 +0100243void ApiTrace::guessedApi(int api)
244{
245 m_api = static_cast<trace::API>(api);
246}
247
248trace::API ApiTrace::api() const
249{
250 return m_api;
251}
252
Zack Rusinf682e192011-09-07 01:36:41 -0400253void ApiTrace::finishedParsing()
254{
José Fonseca0b08bc62012-03-22 16:22:33 +0000255 if (!m_frames.isEmpty()) {
256 ApiTraceFrame *firstFrame = m_frames[0];
257 if (firstFrame && !firstFrame->isLoaded()) {
258 loadFrame(firstFrame);
259 }
Zack Rusinf682e192011-09-07 01:36:41 -0400260 }
261}
262
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400263void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame,
Zack Rusind9d9d222013-10-11 18:02:26 -0400264 const QVector<ApiTraceCall*> &topLevelItems,
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400265 const QVector<ApiTraceCall*> &calls,
266 quint64 binaryDataSize)
Zack Rusinf682e192011-09-07 01:36:41 -0400267{
José Fonsecacaa84282013-04-11 18:54:06 +0100268 Q_ASSERT(frame->numChildrenToLoad() >= calls.size());
Zack Rusin18d094e2011-10-07 23:55:55 -0400269
270 if (!frame->isLoaded()) {
271 emit beginLoadingFrame(frame, calls.size());
Zack Rusind9d9d222013-10-11 18:02:26 -0400272 frame->setCalls(topLevelItems, calls, binaryDataSize);
Zack Rusin18d094e2011-10-07 23:55:55 -0400273 emit endLoadingFrame(frame);
274 m_loadingFrames.remove(frame);
275 }
Zack Rusin10fd4772011-09-14 01:45:12 -0400276
277 if (!m_queuedErrors.isEmpty()) {
278 QList< QPair<ApiTraceFrame*, ApiTraceError> >::iterator itr;
279 for (itr = m_queuedErrors.begin(); itr != m_queuedErrors.end();
280 ++itr) {
281 const ApiTraceError &error = (*itr).second;
282 if ((*itr).first == frame) {
283 ApiTraceCall *call = frame->callWithIndex(error.callIndex);
284
285 if (!call) {
286 continue;
287 }
288
289 call->setError(error.message);
290 m_queuedErrors.erase(itr);
291
292 if (call->hasError()) {
293 m_errors.insert(call);
294 } else {
295 m_errors.remove(call);
296 }
297 emit changed(call);
298 }
299 }
300 }
Zack Rusinf682e192011-09-07 01:36:41 -0400301}
302
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400303void ApiTrace::findNext(ApiTraceFrame *frame,
304 ApiTraceCall *from,
305 const QString &str,
306 Qt::CaseSensitivity sensitivity)
307{
308 ApiTraceCall *foundCall = 0;
309 int frameIdx = m_frames.indexOf(frame);
Zack Rusinad513b32011-09-25 14:33:41 -0400310 SearchRequest request(SearchRequest::Next,
311 frame, from, str, sensitivity);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400312
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400313 if (frame->isLoaded()) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400314 foundCall = frame->findNextCall(from, str, sensitivity);
315 if (foundCall) {
Zack Rusinad513b32011-09-25 14:33:41 -0400316 emit findResult(request, SearchResult_Found, foundCall);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400317 return;
318 }
319
320 //if the frame is loaded we already searched it above
321 // so skip it
322 frameIdx += 1;
323 }
324
Zack Rusinad513b32011-09-25 14:33:41 -0400325 //for the rest of the frames we search from beginning
326 request.from = 0;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400327 for (int i = frameIdx; i < m_frames.count(); ++i) {
328 ApiTraceFrame *frame = m_frames[i];
Zack Rusinad513b32011-09-25 14:33:41 -0400329 request.frame = frame;
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400330 if (!frame->isLoaded()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400331 emit loaderSearch(request);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400332 return;
333 } else {
334 ApiTraceCall *call = frame->findNextCall(0, str, sensitivity);
335 if (call) {
Zack Rusinad513b32011-09-25 14:33:41 -0400336 emit findResult(request, SearchResult_Found, call);
Zack Rusin121e3162011-09-13 01:35:12 -0400337 return;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400338 }
339 }
340 }
Zack Rusinad513b32011-09-25 14:33:41 -0400341 emit findResult(request, SearchResult_Wrapped, 0);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400342}
343
344void ApiTrace::findPrev(ApiTraceFrame *frame,
345 ApiTraceCall *from,
346 const QString &str,
347 Qt::CaseSensitivity sensitivity)
348{
349 ApiTraceCall *foundCall = 0;
350 int frameIdx = m_frames.indexOf(frame);
Zack Rusinad513b32011-09-25 14:33:41 -0400351 SearchRequest request(SearchRequest::Prev,
352 frame, from, str, sensitivity);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400353
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400354 if (frame->isLoaded()) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400355 foundCall = frame->findPrevCall(from, str, sensitivity);
356 if (foundCall) {
Zack Rusinad513b32011-09-25 14:33:41 -0400357 emit findResult(request, SearchResult_Found, foundCall);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400358 return;
359 }
360
361 //if the frame is loaded we already searched it above
362 // so skip it
363 frameIdx -= 1;
364 }
365
Zack Rusinad513b32011-09-25 14:33:41 -0400366 request.from = 0;
Zack Rusin121e3162011-09-13 01:35:12 -0400367 for (int i = frameIdx; i >= 0; --i) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400368 ApiTraceFrame *frame = m_frames[i];
Zack Rusinad513b32011-09-25 14:33:41 -0400369 request.frame = frame;
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400370 if (!frame->isLoaded()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400371 emit loaderSearch(request);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400372 return;
373 } else {
374 ApiTraceCall *call = frame->findPrevCall(0, str, sensitivity);
375 if (call) {
Zack Rusinad513b32011-09-25 14:33:41 -0400376 emit findResult(request, SearchResult_Found, call);
Zack Rusin121e3162011-09-13 01:35:12 -0400377 return;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400378 }
379 }
380 }
Zack Rusinad513b32011-09-25 14:33:41 -0400381 emit findResult(request, SearchResult_Wrapped, 0);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400382}
383
Zack Rusinad513b32011-09-25 14:33:41 -0400384void ApiTrace::loaderSearchResult(const ApiTrace::SearchRequest &request,
385 ApiTrace::SearchResult result,
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400386 ApiTraceCall *call)
387{
388 //qDebug()<<"Search result = "<<result
389 // <<", call is = "<<call;
Zack Rusinad513b32011-09-25 14:33:41 -0400390 emit findResult(request, result, call);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400391}
392
Zack Rusin93e4d152011-09-13 02:23:39 -0400393void ApiTrace::findFrameStart(ApiTraceFrame *frame)
394{
Alexandr Akulich05b07162012-12-07 16:58:14 +0600395 if (!frame)
396 return;
397
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400398 if (frame->isLoaded()) {
Zack Rusin93e4d152011-09-13 02:23:39 -0400399 emit foundFrameStart(frame);
400 } else {
401 emit loaderFindFrameStart(frame);
402 }
403}
404
405void ApiTrace::findFrameEnd(ApiTraceFrame *frame)
406{
Alexandr Akulich05b07162012-12-07 16:58:14 +0600407 if (!frame)
408 return;
409
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400410 if (frame->isLoaded()) {
Zack Rusin93e4d152011-09-13 02:23:39 -0400411 emit foundFrameEnd(frame);
412 } else {
413 emit loaderFindFrameEnd(frame);
414 }
415}
416
Zack Rusinda7579b2011-09-13 17:33:05 -0400417void ApiTrace::findCallIndex(int index)
418{
419 int frameIdx = callInFrame(index);
420 ApiTraceFrame *frame = 0;
421
422 if (frameIdx < 0) {
423 emit foundCallIndex(0);
424 return;
425 }
426
427 frame = m_frames[frameIdx];
428
429 if (frame) {
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400430 if (frame->isLoaded()) {
Zack Rusinda7579b2011-09-13 17:33:05 -0400431 ApiTraceCall *call = frame->callWithIndex(index);
432 emit foundCallIndex(call);
433 } else {
434 emit loaderFindCallIndex(index);
435 }
436 }
437}
438
439int ApiTrace::callInFrame(int callIdx) const
440{
441 unsigned numCalls = 0;
442
Dan McCabe6cc6dac2012-03-22 12:18:55 +0000443 for (int frameIdx = 0; frameIdx < m_frames.size(); ++frameIdx) {
Zack Rusinda7579b2011-09-13 17:33:05 -0400444 const ApiTraceFrame *frame = m_frames[frameIdx];
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400445 unsigned numCallsInFrame = frame->isLoaded()
Zack Rusind9d9d222013-10-11 18:02:26 -0400446 ? frame->numTotalCalls()
Zack Rusinda7579b2011-09-13 17:33:05 -0400447 : frame->numChildrenToLoad();
448 unsigned firstCall = numCalls;
449 unsigned endCall = numCalls + numCallsInFrame;
450 if (firstCall <= callIdx && endCall > callIdx) {
451 return frameIdx;
452 }
453 numCalls = endCall;
454 }
455
456 return -1;
457}
458
Zack Rusin10fd4772011-09-14 01:45:12 -0400459void ApiTrace::setCallError(const ApiTraceError &error)
460{
461 int frameIdx = callInFrame(error.callIndex);
462 ApiTraceFrame *frame = 0;
463
464 if (frameIdx < 0) {
465 return;
466 }
467 frame = m_frames[frameIdx];
468
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400469 if (frame->isLoaded()) {
Zack Rusin10fd4772011-09-14 01:45:12 -0400470 ApiTraceCall *call = frame->callWithIndex(error.callIndex);
471 call->setError(error.message);
472 if (call->hasError()) {
473 m_errors.insert(call);
474 } else {
475 m_errors.remove(call);
476 }
477 emit changed(call);
478 } else {
Zack Rusin18d094e2011-10-07 23:55:55 -0400479 loadFrame(frame);
Zack Rusin10fd4772011-09-14 01:45:12 -0400480 m_queuedErrors.append(qMakePair(frame, error));
481 }
482}
483
Zack Rusin18d094e2011-10-07 23:55:55 -0400484bool ApiTrace::isFrameLoading(ApiTraceFrame *frame) const
485{
486 return m_loadingFrames.contains(frame);
487}
488
Dan McCabe10bd4242012-03-05 17:20:40 -0800489void ApiTrace::bindThumbnailsToFrames(const QList<QImage> &thumbnails)
490{
491 QList<ApiTraceFrame *> frames = m_frames;
492
493 QList<QImage>::const_iterator thumbnail = thumbnails.begin();
494
495 foreach (ApiTraceFrame *frame, frames) {
496 if (thumbnail != thumbnails.end()) {
497 frame->setThumbnail(*thumbnail);
498
499 ++thumbnail;
500
501 emit changed(frame);
502 }
503 }
504}
505
Zack Rusinf6667d12011-03-30 11:03:37 -0400506#include "apitrace.moc"