blob: db5741790c213ca85946cbc60fbf4d16739c22d3 [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 Rusinf682e192011-09-07 01:36:41 -040027 connect(m_loader, SIGNAL(finishedParsing()),
28 this, SLOT(finishedParsing()));
Zack Rusinad513b32011-09-25 14:33:41 -040029 connect(this, SIGNAL(loaderSearch(ApiTrace::SearchRequest)),
30 m_loader, SLOT(search(ApiTrace::SearchRequest)));
Zack Rusin8f98c3a2011-09-11 18:21:29 -040031 connect(m_loader,
Zack Rusinad513b32011-09-25 14:33:41 -040032 SIGNAL(searchResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)),
Zack Rusin8f98c3a2011-09-11 18:21:29 -040033 this,
Zack Rusinad513b32011-09-25 14:33:41 -040034 SLOT(loaderSearchResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)));
Zack Rusin93e4d152011-09-13 02:23:39 -040035 connect(this, SIGNAL(loaderFindFrameStart(ApiTraceFrame*)),
36 m_loader, SLOT(findFrameStart(ApiTraceFrame*)));
37 connect(this, SIGNAL(loaderFindFrameEnd(ApiTraceFrame*)),
38 m_loader, SLOT(findFrameEnd(ApiTraceFrame*)));
39 connect(m_loader, SIGNAL(foundFrameStart(ApiTraceFrame*)),
40 this, SIGNAL(foundFrameStart(ApiTraceFrame*)));
41 connect(m_loader, SIGNAL(foundFrameEnd(ApiTraceFrame*)),
42 this, SIGNAL(foundFrameEnd(ApiTraceFrame*)));
Zack Rusinda7579b2011-09-13 17:33:05 -040043 connect(this, SIGNAL(loaderFindCallIndex(int)),
44 m_loader, SLOT(findCallIndex(int)));
45 connect(m_loader, SIGNAL(foundCallIndex(ApiTraceCall*)),
46 this, SIGNAL(foundCallIndex(ApiTraceCall*)));
Zack Rusin8f98c3a2011-09-11 18:21:29 -040047
Zack Rusinebf971e2011-09-06 17:44:43 -040048
49 connect(m_loader, SIGNAL(startedParsing()),
Zack Rusinde4ea412011-03-30 11:30:08 -040050 this, SIGNAL(startedLoadingTrace()));
Zack Rusinebf971e2011-09-06 17:44:43 -040051 connect(m_loader, SIGNAL(parsed(int)),
52 this, SIGNAL(loaded(int)));
53 connect(m_loader, SIGNAL(finishedParsing()),
Zack Rusinde4ea412011-03-30 11:30:08 -040054 this, SIGNAL(finishedLoadingTrace()));
Zack Rusind809a062011-04-17 23:30:58 -040055
Zack Rusinebf971e2011-09-06 17:44:43 -040056
Zack Rusind809a062011-04-17 23:30:58 -040057 m_saver = new SaverThread(this);
Zack Rusin9af5bff2011-04-18 01:05:50 -040058 connect(m_saver, SIGNAL(traceSaved()),
59 this, SLOT(slotSaved()));
60 connect(m_saver, SIGNAL(traceSaved()),
61 this, SIGNAL(saved()));
Zack Rusinebf971e2011-09-06 17:44:43 -040062
63 m_loaderThread = new QThread();
64 m_loader->moveToThread(m_loaderThread);
65 m_loaderThread->start();
Zack Rusinf6667d12011-03-30 11:03:37 -040066}
67
68ApiTrace::~ApiTrace()
69{
Zack Rusinebf971e2011-09-06 17:44:43 -040070 m_loaderThread->quit();
71 m_loaderThread->deleteLater();
Zack Rusinf6667d12011-03-30 11:03:37 -040072 qDeleteAll(m_frames);
73 delete m_loader;
Zack Rusind809a062011-04-17 23:30:58 -040074 delete m_saver;
Zack Rusinf6667d12011-03-30 11:03:37 -040075}
76
Zack Rusinf6667d12011-03-30 11:03:37 -040077bool ApiTrace::isEmpty() const
78{
Zack Rusinc1743432011-09-13 17:58:58 -040079 return m_frames.isEmpty();
Zack Rusinf6667d12011-03-30 11:03:37 -040080}
81
82QString ApiTrace::fileName() const
83{
Zack Rusinc5929572011-09-19 03:04:40 -040084 if (edited()) {
Zack Rusin63efea82011-04-17 17:10:45 -040085 return m_tempFileName;
Zack Rusinc5929572011-09-19 03:04:40 -040086 }
Zack Rusin63efea82011-04-17 17:10:45 -040087
Zack Rusinf6667d12011-03-30 11:03:37 -040088 return m_fileName;
89}
90
José Fonseca34500442012-03-24 07:56:45 +000091const QList<ApiTraceFrame*> & ApiTrace::frames() const
Zack Rusinf6667d12011-03-30 11:03:37 -040092{
93 return m_frames;
94}
95
96ApiTraceFrame * ApiTrace::frameAt(int idx) const
97{
98 return m_frames.value(idx);
99}
100
101int ApiTrace::numFrames() const
102{
103 return m_frames.count();
104}
105
106int ApiTrace::numCallsInFrame(int idx) const
107{
108 const ApiTraceFrame *frame = frameAt(idx);
Zack Rusinc5929572011-09-19 03:04:40 -0400109 if (frame) {
Zack Rusind9d9d222013-10-11 18:02:26 -0400110 return frame->numTotalCalls();
Zack Rusinc5929572011-09-19 03:04:40 -0400111 } else {
Zack Rusinf6667d12011-03-30 11:03:37 -0400112 return 0;
Zack Rusinc5929572011-09-19 03:04:40 -0400113 }
Zack Rusinf6667d12011-03-30 11:03:37 -0400114}
115
116void ApiTrace::setFileName(const QString &name)
117{
118 if (m_fileName != name) {
119 m_fileName = name;
Zack Rusindaf82af2011-09-24 13:42:53 -0400120 m_tempFileName = QString();
Zack Rusinf6667d12011-03-30 11:03:37 -0400121
Zack Rusinca164112011-04-11 02:23:09 -0400122 m_frames.clear();
Zack Rusin30069572011-04-20 18:21:11 -0400123 m_errors.clear();
124 m_editedCalls.clear();
Zack Rusindaf82af2011-09-24 13:42:53 -0400125 m_queuedErrors.clear();
Zack Rusin30069572011-04-20 18:21:11 -0400126 m_needsSaving = false;
Zack Rusinf6667d12011-03-30 11:03:37 -0400127 emit invalidated();
128
Zack Rusinebf971e2011-09-06 17:44:43 -0400129 emit loadTrace(m_fileName);
Zack Rusinf6667d12011-03-30 11:03:37 -0400130 }
131}
132
Zack Rusinf6667d12011-03-30 11:03:37 -0400133void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
134{
135 int currentFrames = m_frames.count();
136 int numNewFrames = frames.count();
Zack Rusinb56e03d2011-04-20 23:58:52 -0400137
138 emit beginAddingFrames(currentFrames, numNewFrames);
139
Zack Rusinf6667d12011-03-30 11:03:37 -0400140 m_frames += frames;
141
Zack Rusinf6667d12011-03-30 11:03:37 -0400142 foreach(ApiTraceFrame *frame, frames) {
Zack Rusinebf971e2011-09-06 17:44:43 -0400143 frame->setParentTrace(this);
Zack Rusinf6667d12011-03-30 11:03:37 -0400144 }
145
Zack Rusinb56e03d2011-04-20 23:58:52 -0400146 emit endAddingFrames();
Zack Rusinf6667d12011-03-30 11:03:37 -0400147}
148
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400149ApiTraceCall * ApiTrace::callWithIndex(int idx) const
150{
Zack Rusinc1743432011-09-13 17:58:58 -0400151 for (int i = 0; i < m_frames.count(); ++i) {
152 ApiTraceCall *call = m_frames[i]->callWithIndex(idx);
Zack Rusinc5929572011-09-19 03:04:40 -0400153 if (call) {
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400154 return call;
Zack Rusinc5929572011-09-19 03:04:40 -0400155 }
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400156 }
157 return NULL;
158}
159
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400160ApiTraceState ApiTrace::defaultState() const
161{
162 ApiTraceFrame *frame = frameAt(0);
Zack Rusinc5929572011-09-19 03:04:40 -0400163 if (!frame || !frame->isLoaded() || frame->isEmpty()) {
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400164 return ApiTraceState();
Zack Rusinc5929572011-09-19 03:04:40 -0400165 }
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400166
Zack Rusin851d0b02011-09-14 22:04:07 -0400167 ApiTraceCall *firstCall = frame->calls().first();
168 if (!firstCall->hasState()) {
169 return ApiTraceState();
170 }
171
172 return *firstCall->state();
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400173}
174
Zack Rusin661842d2011-04-17 01:59:16 -0400175void ApiTrace::callEdited(ApiTraceCall *call)
176{
Zack Rusin63efea82011-04-17 17:10:45 -0400177 if (!m_editedCalls.contains(call)) {
178 //lets generate a temp filename
179 QString tempPath = QDir::tempPath();
Zack Rusin63efea82011-04-17 17:10:45 -0400180 m_tempFileName = QString::fromLatin1("%1/%2.edited")
181 .arg(tempPath)
182 .arg(m_fileName);
Zack Rusin63efea82011-04-17 17:10:45 -0400183 }
Zack Rusin661842d2011-04-17 01:59:16 -0400184 m_editedCalls.insert(call);
Zack Rusin9af5bff2011-04-18 01:05:50 -0400185 m_needsSaving = true;
Zack Rusin63efea82011-04-17 17:10:45 -0400186
Zack Rusin661842d2011-04-17 01:59:16 -0400187 emit changed(call);
188}
189
190void ApiTrace::callReverted(ApiTraceCall *call)
191{
192 m_editedCalls.remove(call);
Zack Rusin63efea82011-04-17 17:10:45 -0400193
194 if (m_editedCalls.isEmpty()) {
195 m_needsSaving = false;
196 }
Zack Rusin661842d2011-04-17 01:59:16 -0400197 emit changed(call);
198}
199
Zack Rusin0ddd2502011-04-17 02:34:45 -0400200bool ApiTrace::edited() const
Zack Rusin661842d2011-04-17 01:59:16 -0400201{
202 return !m_editedCalls.isEmpty();
203}
204
Zack Rusin63efea82011-04-17 17:10:45 -0400205bool ApiTrace::needsSaving() const
206{
207 return m_needsSaving;
208}
209
210void ApiTrace::save()
211{
212 QFileInfo fi(m_tempFileName);
213 QDir dir;
Zack Rusin9af5bff2011-04-18 01:05:50 -0400214 emit startedSaving();
Zack Rusin63efea82011-04-17 17:10:45 -0400215 dir.mkpath(fi.absolutePath());
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400216 m_saver->saveFile(m_tempFileName,
217 m_fileName,
218 m_editedCalls);
Zack Rusin63efea82011-04-17 17:10:45 -0400219}
220
Zack Rusin9af5bff2011-04-18 01:05:50 -0400221void ApiTrace::slotSaved()
222{
223 m_needsSaving = false;
224}
225
226bool ApiTrace::isSaving() const
227{
228 return m_saver->isRunning();
229}
230
Zack Rusincc0b4912011-04-19 01:59:20 -0400231bool ApiTrace::hasErrors() const
232{
James Benton6a319062012-08-09 16:22:50 +0100233 return !m_errors.isEmpty() || !m_queuedErrors.isEmpty();
Zack Rusincc0b4912011-04-19 01:59:20 -0400234}
235
Zack Rusin3176ebe2011-09-06 21:11:36 -0400236void ApiTrace::loadFrame(ApiTraceFrame *frame)
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400237{
Zack Rusin18d094e2011-10-07 23:55:55 -0400238 if (!isFrameLoading(frame)) {
239 Q_ASSERT(!frame->isLoaded());
240 m_loadingFrames.insert(frame);
241 emit requestFrame(frame);
242 }
Zack Rusin35c27932011-08-28 21:16:22 -0400243}
244
José Fonseca67964382012-03-27 23:54:30 +0100245void ApiTrace::guessedApi(int api)
246{
247 m_api = static_cast<trace::API>(api);
248}
249
250trace::API ApiTrace::api() const
251{
252 return m_api;
253}
254
Zack Rusinf682e192011-09-07 01:36:41 -0400255void ApiTrace::finishedParsing()
256{
José Fonseca0b08bc62012-03-22 16:22:33 +0000257 if (!m_frames.isEmpty()) {
258 ApiTraceFrame *firstFrame = m_frames[0];
259 if (firstFrame && !firstFrame->isLoaded()) {
260 loadFrame(firstFrame);
261 }
Zack Rusinf682e192011-09-07 01:36:41 -0400262 }
263}
264
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400265void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame,
Zack Rusind9d9d222013-10-11 18:02:26 -0400266 const QVector<ApiTraceCall*> &topLevelItems,
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400267 const QVector<ApiTraceCall*> &calls,
268 quint64 binaryDataSize)
Zack Rusinf682e192011-09-07 01:36:41 -0400269{
José Fonsecacaa84282013-04-11 18:54:06 +0100270 Q_ASSERT(frame->numChildrenToLoad() >= calls.size());
Zack Rusin18d094e2011-10-07 23:55:55 -0400271
272 if (!frame->isLoaded()) {
273 emit beginLoadingFrame(frame, calls.size());
Zack Rusind9d9d222013-10-11 18:02:26 -0400274 frame->setCalls(topLevelItems, calls, binaryDataSize);
Zack Rusin18d094e2011-10-07 23:55:55 -0400275 emit endLoadingFrame(frame);
276 m_loadingFrames.remove(frame);
277 }
Zack Rusin10fd4772011-09-14 01:45:12 -0400278
279 if (!m_queuedErrors.isEmpty()) {
280 QList< QPair<ApiTraceFrame*, ApiTraceError> >::iterator itr;
281 for (itr = m_queuedErrors.begin(); itr != m_queuedErrors.end();
282 ++itr) {
283 const ApiTraceError &error = (*itr).second;
284 if ((*itr).first == frame) {
285 ApiTraceCall *call = frame->callWithIndex(error.callIndex);
286
287 if (!call) {
288 continue;
289 }
290
291 call->setError(error.message);
292 m_queuedErrors.erase(itr);
293
294 if (call->hasError()) {
295 m_errors.insert(call);
296 } else {
297 m_errors.remove(call);
298 }
299 emit changed(call);
300 }
301 }
302 }
Zack Rusinf682e192011-09-07 01:36:41 -0400303}
304
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400305void ApiTrace::findNext(ApiTraceFrame *frame,
306 ApiTraceCall *from,
307 const QString &str,
308 Qt::CaseSensitivity sensitivity)
309{
310 ApiTraceCall *foundCall = 0;
311 int frameIdx = m_frames.indexOf(frame);
Zack Rusinad513b32011-09-25 14:33:41 -0400312 SearchRequest request(SearchRequest::Next,
313 frame, from, str, sensitivity);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400314
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400315 if (frame->isLoaded()) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400316 foundCall = frame->findNextCall(from, str, sensitivity);
317 if (foundCall) {
Zack Rusinad513b32011-09-25 14:33:41 -0400318 emit findResult(request, SearchResult_Found, foundCall);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400319 return;
320 }
321
322 //if the frame is loaded we already searched it above
323 // so skip it
324 frameIdx += 1;
325 }
326
Zack Rusinad513b32011-09-25 14:33:41 -0400327 //for the rest of the frames we search from beginning
328 request.from = 0;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400329 for (int i = frameIdx; i < m_frames.count(); ++i) {
330 ApiTraceFrame *frame = m_frames[i];
Zack Rusinad513b32011-09-25 14:33:41 -0400331 request.frame = frame;
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400332 if (!frame->isLoaded()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400333 emit loaderSearch(request);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400334 return;
335 } else {
336 ApiTraceCall *call = frame->findNextCall(0, str, sensitivity);
337 if (call) {
Zack Rusinad513b32011-09-25 14:33:41 -0400338 emit findResult(request, SearchResult_Found, call);
Zack Rusin121e3162011-09-13 01:35:12 -0400339 return;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400340 }
341 }
342 }
Zack Rusinad513b32011-09-25 14:33:41 -0400343 emit findResult(request, SearchResult_Wrapped, 0);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400344}
345
346void ApiTrace::findPrev(ApiTraceFrame *frame,
347 ApiTraceCall *from,
348 const QString &str,
349 Qt::CaseSensitivity sensitivity)
350{
351 ApiTraceCall *foundCall = 0;
352 int frameIdx = m_frames.indexOf(frame);
Zack Rusinad513b32011-09-25 14:33:41 -0400353 SearchRequest request(SearchRequest::Prev,
354 frame, from, str, sensitivity);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400355
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400356 if (frame->isLoaded()) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400357 foundCall = frame->findPrevCall(from, str, sensitivity);
358 if (foundCall) {
Zack Rusinad513b32011-09-25 14:33:41 -0400359 emit findResult(request, SearchResult_Found, foundCall);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400360 return;
361 }
362
363 //if the frame is loaded we already searched it above
364 // so skip it
365 frameIdx -= 1;
366 }
367
Zack Rusinad513b32011-09-25 14:33:41 -0400368 request.from = 0;
Zack Rusin121e3162011-09-13 01:35:12 -0400369 for (int i = frameIdx; i >= 0; --i) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400370 ApiTraceFrame *frame = m_frames[i];
Zack Rusinad513b32011-09-25 14:33:41 -0400371 request.frame = frame;
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400372 if (!frame->isLoaded()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400373 emit loaderSearch(request);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400374 return;
375 } else {
376 ApiTraceCall *call = frame->findPrevCall(0, str, sensitivity);
377 if (call) {
Zack Rusinad513b32011-09-25 14:33:41 -0400378 emit findResult(request, SearchResult_Found, call);
Zack Rusin121e3162011-09-13 01:35:12 -0400379 return;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400380 }
381 }
382 }
Zack Rusinad513b32011-09-25 14:33:41 -0400383 emit findResult(request, SearchResult_Wrapped, 0);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400384}
385
Zack Rusinad513b32011-09-25 14:33:41 -0400386void ApiTrace::loaderSearchResult(const ApiTrace::SearchRequest &request,
387 ApiTrace::SearchResult result,
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400388 ApiTraceCall *call)
389{
390 //qDebug()<<"Search result = "<<result
391 // <<", call is = "<<call;
Zack Rusinad513b32011-09-25 14:33:41 -0400392 emit findResult(request, result, call);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400393}
394
Zack Rusin93e4d152011-09-13 02:23:39 -0400395void ApiTrace::findFrameStart(ApiTraceFrame *frame)
396{
Alexandr Akulich05b07162012-12-07 16:58:14 +0600397 if (!frame)
398 return;
399
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400400 if (frame->isLoaded()) {
Zack Rusin93e4d152011-09-13 02:23:39 -0400401 emit foundFrameStart(frame);
402 } else {
403 emit loaderFindFrameStart(frame);
404 }
405}
406
407void ApiTrace::findFrameEnd(ApiTraceFrame *frame)
408{
Alexandr Akulich05b07162012-12-07 16:58:14 +0600409 if (!frame)
410 return;
411
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400412 if (frame->isLoaded()) {
Zack Rusin93e4d152011-09-13 02:23:39 -0400413 emit foundFrameEnd(frame);
414 } else {
415 emit loaderFindFrameEnd(frame);
416 }
417}
418
Zack Rusinda7579b2011-09-13 17:33:05 -0400419void ApiTrace::findCallIndex(int index)
420{
421 int frameIdx = callInFrame(index);
422 ApiTraceFrame *frame = 0;
423
424 if (frameIdx < 0) {
425 emit foundCallIndex(0);
426 return;
427 }
428
429 frame = m_frames[frameIdx];
430
431 if (frame) {
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400432 if (frame->isLoaded()) {
Zack Rusinda7579b2011-09-13 17:33:05 -0400433 ApiTraceCall *call = frame->callWithIndex(index);
434 emit foundCallIndex(call);
435 } else {
436 emit loaderFindCallIndex(index);
437 }
438 }
439}
440
441int ApiTrace::callInFrame(int callIdx) const
442{
443 unsigned numCalls = 0;
444
Dan McCabe6cc6dac2012-03-22 12:18:55 +0000445 for (int frameIdx = 0; frameIdx < m_frames.size(); ++frameIdx) {
Zack Rusinda7579b2011-09-13 17:33:05 -0400446 const ApiTraceFrame *frame = m_frames[frameIdx];
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400447 unsigned numCallsInFrame = frame->isLoaded()
Zack Rusind9d9d222013-10-11 18:02:26 -0400448 ? frame->numTotalCalls()
Zack Rusinda7579b2011-09-13 17:33:05 -0400449 : frame->numChildrenToLoad();
450 unsigned firstCall = numCalls;
451 unsigned endCall = numCalls + numCallsInFrame;
452 if (firstCall <= callIdx && endCall > callIdx) {
453 return frameIdx;
454 }
455 numCalls = endCall;
456 }
457
458 return -1;
459}
460
Zack Rusin10fd4772011-09-14 01:45:12 -0400461void ApiTrace::setCallError(const ApiTraceError &error)
462{
463 int frameIdx = callInFrame(error.callIndex);
464 ApiTraceFrame *frame = 0;
465
466 if (frameIdx < 0) {
467 return;
468 }
469 frame = m_frames[frameIdx];
470
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400471 if (frame->isLoaded()) {
Zack Rusin10fd4772011-09-14 01:45:12 -0400472 ApiTraceCall *call = frame->callWithIndex(error.callIndex);
473 call->setError(error.message);
474 if (call->hasError()) {
475 m_errors.insert(call);
476 } else {
477 m_errors.remove(call);
478 }
479 emit changed(call);
480 } else {
Zack Rusin18d094e2011-10-07 23:55:55 -0400481 loadFrame(frame);
Zack Rusin10fd4772011-09-14 01:45:12 -0400482 m_queuedErrors.append(qMakePair(frame, error));
483 }
484}
485
Zack Rusin18d094e2011-10-07 23:55:55 -0400486bool ApiTrace::isFrameLoading(ApiTraceFrame *frame) const
487{
488 return m_loadingFrames.contains(frame);
489}
490
Dan McCabe10bd4242012-03-05 17:20:40 -0800491void ApiTrace::bindThumbnailsToFrames(const QList<QImage> &thumbnails)
492{
493 QList<ApiTraceFrame *> frames = m_frames;
494
495 QList<QImage>::const_iterator thumbnail = thumbnails.begin();
496
497 foreach (ApiTraceFrame *frame, frames) {
498 if (thumbnail != thumbnails.end()) {
499 frame->setThumbnail(*thumbnail);
500
501 ++thumbnail;
502
503 emit changed(frame);
504 }
505 }
506}
507
Zack Rusinf6667d12011-03-30 11:03:37 -0400508#include "apitrace.moc"