From 10bd424f3acbbf4275c160302898018ce795d17d Mon Sep 17 00:00:00 2001 From: Dan McCabe Date: Mon, 5 Mar 2012 17:20:40 -0800 Subject: [PATCH] Display captured snapshots as thumbnails. Once snapshots are captured after being generated by glretrace, they are then displayed in the GUI app, qapitrace. The retracer passes a list of thumbnails to the main window. The main window in turn binds those thumbnails to the ApiTraceFrames for later display. When the ApiTrace events are displayed, if a frame is being display, its thumbnail is queried. That thumbnail is then displayed at the front of the line for a frame. --- gui/apicalldelegate.cpp | 13 ++++++++++++- gui/apitrace.cpp | 17 +++++++++++++++++ gui/apitrace.h | 3 ++- gui/apitracecall.cpp | 10 ++++++++++ gui/apitracecall.h | 5 +++++ gui/apitracemodel.cpp | 21 +++++++++++++++++++-- gui/apitracemodel.h | 2 ++ gui/mainwindow.cpp | 17 +++++++++++------ gui/mainwindow.h | 2 +- 9 files changed, 79 insertions(+), 11 deletions(-) diff --git a/gui/apicalldelegate.cpp b/gui/apicalldelegate.cpp index 11ed3a5..221462e 100644 --- a/gui/apicalldelegate.cpp +++ b/gui/apicalldelegate.cpp @@ -27,12 +27,23 @@ void ApiCallDelegate::paint(QPainter *painter, Q_ASSERT(index.column() == 0); if (event) { - QPoint offset; + QPoint offset = QPoint(0, 0); QStaticText text = event->staticText(); //text.setTextWidth(option.rect.width()); //QStyledItemDelegate::paint(painter, option, index); QStyle *style = QApplication::style(); style->drawControl(QStyle::CE_ItemViewItem, &option, painter, 0); + + // draw thumbnail of frame + if(event->type() == ApiTraceEvent::Frame) { + ApiTraceFrame *frame = static_cast(event); + QImage thumbnail = frame->thumbnail(); + if (!thumbnail.isNull()) { + painter->drawImage(option.rect.topLeft() + offset, thumbnail); + offset += QPoint(option.rect.height() + 16, 0); + } + } + if (event->hasState()) { QPixmap px = m_stateEmblem.pixmap(option.rect.height(), option.rect.height()); diff --git a/gui/apitrace.cpp b/gui/apitrace.cpp index 5758b07..5db54d8 100644 --- a/gui/apitrace.cpp +++ b/gui/apitrace.cpp @@ -496,4 +496,21 @@ bool ApiTrace::isFrameLoading(ApiTraceFrame *frame) const return m_loadingFrames.contains(frame); } +void ApiTrace::bindThumbnailsToFrames(const QList &thumbnails) +{ + QList frames = m_frames; + + QList::const_iterator thumbnail = thumbnails.begin(); + + foreach (ApiTraceFrame *frame, frames) { + if (thumbnail != thumbnails.end()) { + frame->setThumbnail(*thumbnail); + + ++thumbnail; + + emit changed(frame); + } + } +} + #include "apitrace.moc" diff --git a/gui/apitrace.h b/gui/apitrace.h index 2833f60..ed137ed 100644 --- a/gui/apitrace.h +++ b/gui/apitrace.h @@ -100,6 +100,7 @@ public slots: void findCallIndex(int index); void setCallError(const ApiTraceError &error); + void bindThumbnailsToFrames(const QList &thumbnails); signals: void loadTrace(const QString &name); @@ -109,7 +110,7 @@ signals: void finishedLoadingTrace(); void invalidated(); void framesInvalidated(); - void changed(ApiTraceCall *call); + void changed(ApiTraceEvent *event); void startedSaving(); void saved(); void findResult(const ApiTrace::SearchRequest &request, diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp index 267dc09..4d91001 100644 --- a/gui/apitracecall.cpp +++ b/gui/apitracecall.cpp @@ -1197,3 +1197,13 @@ unsigned ApiTraceFrame::lastCallIndex() const return m_lastCallIndex; } } + +void ApiTraceFrame::setThumbnail(QImage thumbnail) +{ + m_thumbnail = thumbnail; +} + +QImage ApiTraceFrame::thumbnail() const +{ + return m_thumbnail; +} diff --git a/gui/apitracecall.h b/gui/apitracecall.h index 3a9faaf..8d0e6db 100644 --- a/gui/apitracecall.h +++ b/gui/apitracecall.h @@ -335,6 +335,10 @@ public: void setLastCallIndex(unsigned index); unsigned lastCallIndex() const; + + void setThumbnail(QImage thumbnail); + QImage thumbnail() const; + private: ApiTrace *m_parentTrace; quint64 m_binaryDataSize; @@ -342,6 +346,7 @@ private: bool m_loaded; unsigned m_callsToLoad; unsigned m_lastCallIndex; + QImage m_thumbnail; }; Q_DECLARE_METATYPE(ApiTraceFrame*); diff --git a/gui/apitracemodel.cpp b/gui/apitracemodel.cpp index 7303ae1..9103da5 100644 --- a/gui/apitracemodel.cpp +++ b/gui/apitracemodel.cpp @@ -248,8 +248,8 @@ void ApiTraceModel::setApiTrace(ApiTrace *trace) this, SLOT(beginAddingFrames(int, int))); connect(m_trace, SIGNAL(endAddingFrames()), this, SLOT(endAddingFrames())); - connect(m_trace, SIGNAL(changed(ApiTraceCall*)), - this, SLOT(callChanged(ApiTraceCall*))); + connect(m_trace, SIGNAL(changed(ApiTraceEvent*)), + this, SLOT(changed(ApiTraceEvent*))); connect(m_trace, SIGNAL(beginLoadingFrame(ApiTraceFrame*,int)), this, SLOT(beginLoadingFrame(ApiTraceFrame*,int))); connect(m_trace, SIGNAL(endLoadingFrame(ApiTraceFrame*)), @@ -318,6 +318,15 @@ QModelIndex ApiTraceModel::indexForCall(ApiTraceCall *call) const return createIndex(row, 0, call); } +void ApiTraceModel::changed(ApiTraceEvent *event) +{ + if (event->type() == ApiTraceEvent::Call) { + callChanged(static_cast(event)); + } else if (event->type() == ApiTraceEvent::Frame) { + frameChanged(static_cast(event)); + } +} + void ApiTraceModel::callChanged(ApiTraceCall *call) { ApiTrace *trace = call->parentFrame()->parentTrace(); @@ -339,6 +348,14 @@ void ApiTraceModel::callChanged(ApiTraceCall *call) emit dataChanged(index, index); } +void ApiTraceModel::frameChanged(ApiTraceFrame *frame) +{ + const QList frames = m_trace->frames(); + int row = frames.indexOf(frame); + QModelIndex index = createIndex(row, 0, frame); + emit dataChanged(index, index); +} + void ApiTraceModel::endAddingFrames() { endInsertRows(); diff --git a/gui/apitracemodel.h b/gui/apitracemodel.h index fe6b5ce..e7354aa 100644 --- a/gui/apitracemodel.h +++ b/gui/apitracemodel.h @@ -54,7 +54,9 @@ private slots: void invalidateFrames(); void beginAddingFrames(int oldCount, int numAdded); void endAddingFrames(); + void changed(ApiTraceEvent *event); void callChanged(ApiTraceCall *call); + void frameChanged(ApiTraceFrame *frame); void beginLoadingFrame(ApiTraceFrame *frame, int numAdded); void endLoadingFrame(ApiTraceFrame *frame); diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 9a177f6..b7916b6 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -732,8 +732,8 @@ void MainWindow::initConnections() this, SLOT(slotStartedSaving())); connect(m_trace, SIGNAL(saved()), this, SLOT(slotSaved())); - connect(m_trace, SIGNAL(changed(ApiTraceCall*)), - this, SLOT(slotTraceChanged(ApiTraceCall*))); + connect(m_trace, SIGNAL(changed(ApiTraceEvent*)), + this, SLOT(slotTraceChanged(ApiTraceEvent*))); connect(m_trace, SIGNAL(findResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)), this, SLOT(slotSearchResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*))); connect(m_trace, SIGNAL(foundFrameStart(ApiTraceFrame*)), @@ -849,6 +849,8 @@ void MainWindow::replayStateFound(ApiTraceState *state) void MainWindow::replayThumbnailsFound(const QList &thumbnails) { m_thumbnails = thumbnails; + + m_trace->bindThumbnailsToFrames(thumbnails); } void MainWindow::slotGoTo() @@ -1026,11 +1028,14 @@ ApiTraceFrame * MainWindow::selectedFrame() const return NULL; } -void MainWindow::slotTraceChanged(ApiTraceCall *call) +void MainWindow::slotTraceChanged(ApiTraceEvent *event) { - Q_ASSERT(call); - if (call == m_selectedEvent) { - m_ui.detailsWebView->setHtml(call->toHtml()); + Q_ASSERT(event); + if (event == m_selectedEvent) { + if (event->type() == ApiTraceEvent::Call) { + ApiTraceCall *call = static_cast(event); + m_ui.detailsWebView->setHtml(call->toHtml()); + } } } diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 568f692..3bd9edb 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -74,7 +74,7 @@ private slots: void slotSaved(); void slotGoFrameStart(); void slotGoFrameEnd(); - void slotTraceChanged(ApiTraceCall *call); + void slotTraceChanged(ApiTraceEvent *event); void slotRetraceErrors(const QList &errors); void slotErrorSelected(QTreeWidgetItem *current); void slotSearchResult(const ApiTrace::SearchRequest &request, -- 2.7.4