3 #include "traceloader.h"
4 #include "saverthread.h"
11 : m_needsSaving(false)
13 m_loader = new TraceLoader();
15 connect(this, SIGNAL(loadTrace(QString)),
16 m_loader, SLOT(loadTrace(QString)));
17 connect(this, SIGNAL(requestFrame(ApiTraceFrame*)),
18 m_loader, SLOT(loadFrame(ApiTraceFrame*)));
19 connect(m_loader, SIGNAL(framesLoaded(const QList<ApiTraceFrame*>)),
20 this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
22 SIGNAL(frameContentsLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,quint64)),
24 SLOT(loaderFrameLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,quint64)));
25 connect(m_loader, SIGNAL(finishedParsing()),
26 this, SLOT(finishedParsing()));
27 connect(this, SIGNAL(loaderSearch(ApiTrace::SearchRequest)),
28 m_loader, SLOT(search(ApiTrace::SearchRequest)));
30 SIGNAL(searchResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)),
32 SLOT(loaderSearchResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)));
33 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*)));
41 connect(this, SIGNAL(loaderFindCallIndex(int)),
42 m_loader, SLOT(findCallIndex(int)));
43 connect(m_loader, SIGNAL(foundCallIndex(ApiTraceCall*)),
44 this, SIGNAL(foundCallIndex(ApiTraceCall*)));
47 connect(m_loader, SIGNAL(startedParsing()),
48 this, SIGNAL(startedLoadingTrace()));
49 connect(m_loader, SIGNAL(parsed(int)),
50 this, SIGNAL(loaded(int)));
51 connect(m_loader, SIGNAL(finishedParsing()),
52 this, SIGNAL(finishedLoadingTrace()));
55 m_saver = new SaverThread(this);
56 connect(m_saver, SIGNAL(traceSaved()),
57 this, SLOT(slotSaved()));
58 connect(m_saver, SIGNAL(traceSaved()),
59 this, SIGNAL(saved()));
61 m_loaderThread = new QThread();
62 m_loader->moveToThread(m_loaderThread);
63 m_loaderThread->start();
68 m_loaderThread->quit();
69 m_loaderThread->deleteLater();
75 bool ApiTrace::isEmpty() const
77 return m_frames.isEmpty();
80 QString ApiTrace::fileName() const
83 return m_tempFileName;
89 const QList<ApiTraceFrame*> & ApiTrace::frames() const
94 ApiTraceFrame * ApiTrace::frameAt(int idx) const
96 return m_frames.value(idx);
99 int ApiTrace::numFrames() const
101 return m_frames.count();
104 int ApiTrace::numCallsInFrame(int idx) const
106 const ApiTraceFrame *frame = frameAt(idx);
108 return frame->numChildren();
114 void ApiTrace::setFileName(const QString &name)
116 if (m_fileName != name) {
118 m_tempFileName = QString();
122 m_editedCalls.clear();
123 m_queuedErrors.clear();
124 m_needsSaving = false;
127 emit loadTrace(m_fileName);
131 void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
133 int currentFrames = m_frames.count();
134 int numNewFrames = frames.count();
136 emit beginAddingFrames(currentFrames, numNewFrames);
140 foreach(ApiTraceFrame *frame, frames) {
141 frame->setParentTrace(this);
144 emit endAddingFrames();
147 ApiTraceCall * ApiTrace::callWithIndex(int idx) const
149 for (int i = 0; i < m_frames.count(); ++i) {
150 ApiTraceCall *call = m_frames[i]->callWithIndex(idx);
158 ApiTraceState ApiTrace::defaultState() const
160 ApiTraceFrame *frame = frameAt(0);
161 if (!frame || !frame->isLoaded() || frame->isEmpty()) {
162 return ApiTraceState();
165 ApiTraceCall *firstCall = frame->calls().first();
166 if (!firstCall->hasState()) {
167 return ApiTraceState();
170 return *firstCall->state();
173 void ApiTrace::callEdited(ApiTraceCall *call)
175 if (!m_editedCalls.contains(call)) {
176 //lets generate a temp filename
177 QString tempPath = QDir::tempPath();
178 m_tempFileName = QString::fromLatin1("%1/%2.edited")
182 m_editedCalls.insert(call);
183 m_needsSaving = true;
188 void ApiTrace::callReverted(ApiTraceCall *call)
190 m_editedCalls.remove(call);
192 if (m_editedCalls.isEmpty()) {
193 m_needsSaving = false;
198 bool ApiTrace::edited() const
200 return !m_editedCalls.isEmpty();
203 bool ApiTrace::needsSaving() const
205 return m_needsSaving;
208 void ApiTrace::save()
210 QFileInfo fi(m_tempFileName);
212 emit startedSaving();
213 dir.mkpath(fi.absolutePath());
214 m_saver->saveFile(m_tempFileName,
219 void ApiTrace::slotSaved()
221 m_needsSaving = false;
224 bool ApiTrace::isSaving() const
226 return m_saver->isRunning();
229 bool ApiTrace::hasErrors() const
231 return !m_errors.isEmpty();
234 void ApiTrace::loadFrame(ApiTraceFrame *frame)
236 if (!isFrameLoading(frame)) {
237 Q_ASSERT(!frame->isLoaded());
238 m_loadingFrames.insert(frame);
239 emit requestFrame(frame);
243 void ApiTrace::finishedParsing()
245 if (!m_frames.isEmpty()) {
246 ApiTraceFrame *firstFrame = m_frames[0];
247 if (firstFrame && !firstFrame->isLoaded()) {
248 loadFrame(firstFrame);
253 void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame,
254 const QVector<ApiTraceCall*> &calls,
255 quint64 binaryDataSize)
257 Q_ASSERT(frame->numChildrenToLoad() == calls.size());
259 if (!frame->isLoaded()) {
260 emit beginLoadingFrame(frame, calls.size());
261 frame->setCalls(calls, binaryDataSize);
262 emit endLoadingFrame(frame);
263 m_loadingFrames.remove(frame);
266 if (!m_queuedErrors.isEmpty()) {
267 QList< QPair<ApiTraceFrame*, ApiTraceError> >::iterator itr;
268 for (itr = m_queuedErrors.begin(); itr != m_queuedErrors.end();
270 const ApiTraceError &error = (*itr).second;
271 if ((*itr).first == frame) {
272 ApiTraceCall *call = frame->callWithIndex(error.callIndex);
278 call->setError(error.message);
279 m_queuedErrors.erase(itr);
281 if (call->hasError()) {
282 m_errors.insert(call);
284 m_errors.remove(call);
292 void ApiTrace::findNext(ApiTraceFrame *frame,
295 Qt::CaseSensitivity sensitivity)
297 ApiTraceCall *foundCall = 0;
298 int frameIdx = m_frames.indexOf(frame);
299 SearchRequest request(SearchRequest::Next,
300 frame, from, str, sensitivity);
302 if (frame->isLoaded()) {
303 foundCall = frame->findNextCall(from, str, sensitivity);
305 emit findResult(request, SearchResult_Found, foundCall);
309 //if the frame is loaded we already searched it above
314 //for the rest of the frames we search from beginning
316 for (int i = frameIdx; i < m_frames.count(); ++i) {
317 ApiTraceFrame *frame = m_frames[i];
318 request.frame = frame;
319 if (!frame->isLoaded()) {
320 emit loaderSearch(request);
323 ApiTraceCall *call = frame->findNextCall(0, str, sensitivity);
325 emit findResult(request, SearchResult_Found, call);
330 emit findResult(request, SearchResult_Wrapped, 0);
333 void ApiTrace::findPrev(ApiTraceFrame *frame,
336 Qt::CaseSensitivity sensitivity)
338 ApiTraceCall *foundCall = 0;
339 int frameIdx = m_frames.indexOf(frame);
340 SearchRequest request(SearchRequest::Prev,
341 frame, from, str, sensitivity);
343 if (frame->isLoaded()) {
344 foundCall = frame->findPrevCall(from, str, sensitivity);
346 emit findResult(request, SearchResult_Found, foundCall);
350 //if the frame is loaded we already searched it above
356 for (int i = frameIdx; i >= 0; --i) {
357 ApiTraceFrame *frame = m_frames[i];
358 request.frame = frame;
359 if (!frame->isLoaded()) {
360 emit loaderSearch(request);
363 ApiTraceCall *call = frame->findPrevCall(0, str, sensitivity);
365 emit findResult(request, SearchResult_Found, call);
370 emit findResult(request, SearchResult_Wrapped, 0);
373 void ApiTrace::loaderSearchResult(const ApiTrace::SearchRequest &request,
374 ApiTrace::SearchResult result,
377 //qDebug()<<"Search result = "<<result
378 // <<", call is = "<<call;
379 emit findResult(request, result, call);
382 void ApiTrace::findFrameStart(ApiTraceFrame *frame)
384 if (frame->isLoaded()) {
385 emit foundFrameStart(frame);
387 emit loaderFindFrameStart(frame);
391 void ApiTrace::findFrameEnd(ApiTraceFrame *frame)
393 if (frame->isLoaded()) {
394 emit foundFrameEnd(frame);
396 emit loaderFindFrameEnd(frame);
400 void ApiTrace::findCallIndex(int index)
402 int frameIdx = callInFrame(index);
403 ApiTraceFrame *frame = 0;
406 emit foundCallIndex(0);
410 frame = m_frames[frameIdx];
413 if (frame->isLoaded()) {
414 ApiTraceCall *call = frame->callWithIndex(index);
415 emit foundCallIndex(call);
417 emit loaderFindCallIndex(index);
422 int ApiTrace::callInFrame(int callIdx) const
424 unsigned numCalls = 0;
426 for (int frameIdx = 0; frameIdx < m_frames.size(); ++frameIdx) {
427 const ApiTraceFrame *frame = m_frames[frameIdx];
428 unsigned numCallsInFrame = frame->isLoaded()
429 ? frame->numChildren()
430 : frame->numChildrenToLoad();
431 unsigned firstCall = numCalls;
432 unsigned endCall = numCalls + numCallsInFrame;
433 if (firstCall <= callIdx && endCall > callIdx) {
442 void ApiTrace::setCallError(const ApiTraceError &error)
444 int frameIdx = callInFrame(error.callIndex);
445 ApiTraceFrame *frame = 0;
450 frame = m_frames[frameIdx];
452 if (frame->isLoaded()) {
453 ApiTraceCall *call = frame->callWithIndex(error.callIndex);
454 call->setError(error.message);
455 if (call->hasError()) {
456 m_errors.insert(call);
458 m_errors.remove(call);
463 m_queuedErrors.append(qMakePair(frame, error));
467 bool ApiTrace::isFrameLoading(ApiTraceFrame *frame) const
469 return m_loadingFrames.contains(frame);
472 void ApiTrace::bindThumbnailsToFrames(const QList<QImage> &thumbnails)
474 QList<ApiTraceFrame *> frames = m_frames;
476 QList<QImage>::const_iterator thumbnail = thumbnails.begin();
478 foreach (ApiTraceFrame *frame, frames) {
479 if (thumbnail != thumbnails.end()) {
480 frame->setThumbnail(*thumbnail);
489 #include "apitrace.moc"