1 #include "mainwindow.h"
4 #include "apitracecall.h"
5 #include "apicalldelegate.h"
6 #include "apitracemodel.h"
7 #include "apitracefilter.h"
9 #include <qjson/parser.h>
14 #include <QFileDialog>
16 #include <QMessageBox>
18 #include <QProgressBar>
23 MainWindow::MainWindow()
28 m_findingState(false),
29 m_jsonParser(new QJson::Parser())
32 m_ui.stateTreeWidget->sortByColumn(0, Qt::AscendingOrder);
34 m_trace = new ApiTrace();
35 connect(m_trace, SIGNAL(startedLoadingTrace()),
36 this, SLOT(startedLoadingTrace()));
37 connect(m_trace, SIGNAL(finishedLoadingTrace()),
38 this, SLOT(finishedLoadingTrace()));
40 m_model = new ApiTraceModel();
41 m_model->setApiTrace(m_trace);
42 m_proxyModel = new ApiTraceFilter();
43 m_proxyModel->setSourceModel(m_model);
44 m_ui.callView->setModel(m_proxyModel);
45 m_ui.callView->setItemDelegate(new ApiCallDelegate);
46 for (int column = 0; column < m_model->columnCount(); ++column)
47 m_ui.callView->resizeColumnToContents(column);
49 QToolBar *toolBar = addToolBar(tr("Navigation"));
50 m_filterEdit = new QLineEdit(toolBar);
51 toolBar->addWidget(m_filterEdit);
53 m_progressBar = new QProgressBar();
54 m_progressBar->setRange(0, 0);
55 statusBar()->addPermanentWidget(m_progressBar);
56 m_progressBar->hide();
58 m_ui.detailsDock->hide();
59 m_ui.stateDock->hide();
61 connect(m_ui.actionOpen, SIGNAL(triggered()),
62 this, SLOT(openTrace()));
63 connect(m_ui.actionQuit, SIGNAL(triggered()),
66 connect(m_ui.actionReplay, SIGNAL(triggered()),
67 this, SLOT(replayStart()));
68 connect(m_ui.actionStop, SIGNAL(triggered()),
69 this, SLOT(replayStop()));
70 connect(m_ui.actionLookupState, SIGNAL(triggered()),
71 this, SLOT(lookupState()));
73 connect(m_ui.callView, SIGNAL(activated(const QModelIndex &)),
74 this, SLOT(callItemSelected(const QModelIndex &)));
75 connect(m_filterEdit, SIGNAL(returnPressed()),
76 this, SLOT(filterTrace()));
79 void MainWindow::openTrace()
82 QFileDialog::getOpenFileName(
86 tr("Trace Files (*.trace)"));
88 qDebug()<< "File name : " <<fileName;
90 newTraceFile(fileName);
93 void MainWindow::loadTrace(const QString &fileName)
95 if (!QFile::exists(fileName)) {
96 QMessageBox::warning(this, tr("File Missing"),
97 tr("File '%1' doesn't exist.").arg(fileName));
100 qDebug()<< "Loading : " <<fileName;
102 m_progressBar->setValue(0);
103 newTraceFile(fileName);
106 void MainWindow::callItemSelected(const QModelIndex &index)
108 ApiTraceCall *call = index.data().value<ApiTraceCall*>();
110 m_ui.detailsWebView->setHtml(call->toHtml());
111 m_ui.detailsDock->show();
112 m_selectedEvent = call;
114 m_selectedEvent = index.data().value<ApiTraceFrame*>();
115 m_ui.detailsDock->hide();
117 if (m_selectedEvent && !m_selectedEvent->state().isEmpty()) {
120 m_ui.stateDock->hide();
123 void MainWindow::filterTrace()
125 m_proxyModel->setFilterString(m_filterEdit->text());
128 void MainWindow::replayStart()
133 void MainWindow::replayStop()
135 if (m_replayProcess) {
136 m_replayProcess->kill();
138 m_ui.actionStop->setEnabled(false);
139 m_ui.actionReplay->setEnabled(true);
140 m_ui.actionLookupState->setEnabled(true);
144 void MainWindow::newTraceFile(const QString &fileName)
146 m_traceFileName = fileName;
147 m_trace->setFileName(fileName);
149 if (m_traceFileName.isEmpty()) {
150 m_ui.actionReplay->setEnabled(false);
151 m_ui.actionLookupState->setEnabled(false);
153 m_ui.actionReplay->setEnabled(true);
154 m_ui.actionLookupState->setEnabled(true);
158 void MainWindow::replayFinished()
160 m_ui.actionStop->setEnabled(false);
161 m_ui.actionReplay->setEnabled(true);
162 m_ui.actionLookupState->setEnabled(true);
164 QByteArray output = m_replayProcess->readAllStandardOutput();
167 qDebug()<<"Process finished = ";
168 qDebug()<<"\terr = "<<m_replayProcess->readAllStandardError();
169 qDebug()<<"\tout = "<<output;
172 if (m_findingState) {
174 QVariantMap parsedJson = m_jsonParser->parse(output, &ok).toMap();
175 parseState(parsedJson[QLatin1String("parameters")].toMap());
176 } else if (output.length() < 80) {
177 statusBar()->showMessage(output);
180 m_findingState = false;
183 void MainWindow::replayError(QProcess::ProcessError err)
185 m_ui.actionStop->setEnabled(false);
186 m_ui.actionReplay->setEnabled(true);
187 m_ui.actionLookupState->setEnabled(true);
188 m_findingState = false;
191 qDebug()<<"Process error = "<<err;
192 qDebug()<<"\terr = "<<m_replayProcess->readAllStandardError();
193 qDebug()<<"\tout = "<<m_replayProcess->readAllStandardOutput();
194 QMessageBox::warning(
195 this, tr("Replay Failed"),
196 tr("Couldn't execute the replay file '%1'").arg(m_traceFileName));
199 void MainWindow::startedLoadingTrace()
202 m_progressBar->show();
203 QFileInfo info(m_trace->fileName());
204 statusBar()->showMessage(
205 tr("Loading %1...").arg(info.fileName()));
208 void MainWindow::finishedLoadingTrace()
210 m_progressBar->hide();
214 QFileInfo info(m_trace->fileName());
215 statusBar()->showMessage(
216 tr("Loaded %1").arg(info.fileName()), 3000);
219 void MainWindow::replayTrace(bool dumpState)
221 if (!m_replayProcess) {
223 QString format = QLatin1String("%1;");
225 QString format = QLatin1String("%1:");
227 QString buildPath = format.arg(BUILD_DIR);
228 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
229 env.insert("PATH", buildPath + env.value("PATH"));
231 qputenv("PATH", env.value("PATH").toLatin1());
233 m_replayProcess = new QProcess(this);
234 m_replayProcess->setProcessEnvironment(env);
236 connect(m_replayProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
237 this, SLOT(replayFinished()));
238 connect(m_replayProcess, SIGNAL(error(QProcess::ProcessError)),
239 this, SLOT(replayError(QProcess::ProcessError)));
242 if (m_traceFileName.isEmpty())
245 QStringList arguments;
249 if (m_selectedEvent->type() == ApiTraceEvent::Call) {
250 index = static_cast<ApiTraceCall*>(m_selectedEvent)->index;
251 } else if (m_selectedEvent->type() == ApiTraceEvent::Frame) {
252 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(m_selectedEvent);
253 if (frame->calls.isEmpty()) {
254 //XXX i guess we could still get the current state
255 qDebug()<<"tried to get a state for an empty frame";
258 index = frame->calls.first()->index;
260 qDebug()<<"Unknown event type";
263 arguments << QLatin1String("-D");
264 arguments << QString::number(index);
266 arguments << m_traceFileName;
268 m_replayProcess->start(QLatin1String("glretrace"),
271 m_ui.actionStop->setEnabled(true);
274 void MainWindow::lookupState()
276 if (!m_selectedEvent) {
277 QMessageBox::warning(
278 this, tr("Unknown Event"),
279 tr("To inspect the state select an event in the event list."));
282 m_stateEvent = m_selectedEvent;
283 m_findingState = true;
287 MainWindow::~MainWindow()
292 void MainWindow::parseState(const QVariantMap ¶ms)
294 QVariantMap::const_iterator itr;
296 m_stateEvent->setState(params);
297 if (m_selectedEvent == m_stateEvent) {
300 m_ui.stateDock->hide();
305 variantToString(const QVariant &var, QString &str)
307 if (var.type() == QVariant::List) {
308 QVariantList lst = var.toList();
309 str += QLatin1String("[");
310 for (int i = 0; i < lst.count(); ++i) {
311 QVariant val = lst[i];
312 variantToString(val, str);
313 if (i < lst.count() - 1)
314 str += QLatin1String(", ");
316 str += QLatin1String("]");
317 } else if (var.type() == QVariant::Map) {
318 Q_ASSERT(!"unsupported state type");
319 } else if (var.type() == QVariant::Hash) {
320 Q_ASSERT(!"unsupported state type");
322 str += var.toString();
326 void MainWindow::fillStateForFrame()
328 QVariantMap::const_iterator itr;
331 if (!m_selectedEvent || m_selectedEvent->state().isEmpty())
334 m_ui.stateTreeWidget->clear();
335 params = m_selectedEvent->state();
336 QList<QTreeWidgetItem *> items;
337 for (itr = params.constBegin(); itr != params.constEnd(); ++itr) {
338 QString key = itr.key();
341 variantToString(itr.value(), val);
342 //qDebug()<<"key = "<<key;
343 //qDebug()<<"val = "<<val;
347 items.append(new QTreeWidgetItem((QTreeWidget*)0, lst));
349 m_ui.stateTreeWidget->insertTopLevelItems(0, items);
350 m_ui.stateDock->show();
353 #include "mainwindow.moc"