blob: 592841c63015b24d623e2604bddd1c9a756b2ef6 [file] [log] [blame]
Zack Rusin601e8372011-03-24 22:23:21 -04001#include "mainwindow.h"
2
Zack Rusinf6667d12011-03-30 11:03:37 -04003#include "apitrace.h"
Zack Rusin96130ac2011-03-27 01:48:36 -04004#include "apitracecall.h"
Zack Rusin18eade52011-03-26 14:23:35 -04005#include "apicalldelegate.h"
Zack Rusin601e8372011-03-24 22:23:21 -04006#include "apitracemodel.h"
Zack Rusin91065372011-03-26 01:54:10 -04007#include "apitracefilter.h"
Zack Rusin601e8372011-03-24 22:23:21 -04008
Zack Rusine8685f62011-03-30 20:14:01 -04009#include <qjson/parser.h>
10
Zack Rusin601e8372011-03-24 22:23:21 -040011#include <QAction>
12#include <QDebug>
13#include <QDir>
14#include <QFileDialog>
Zack Rusin27cb2c42011-03-27 23:53:36 -040015#include <QLineEdit>
16#include <QMessageBox>
17#include <QProcess>
Zack Rusinde4ea412011-03-30 11:30:08 -040018#include <QProgressBar>
Zack Rusinea295452011-03-27 02:22:13 -040019#include <QToolBar>
Zack Rusin96130ac2011-03-27 01:48:36 -040020#include <QWebView>
Zack Rusin601e8372011-03-24 22:23:21 -040021
22
23MainWindow::MainWindow()
Zack Rusin27cb2c42011-03-27 23:53:36 -040024 : QMainWindow(),
Zack Rusin2caa06d2011-03-30 18:30:20 -040025 m_replayProcess(0),
26 m_findingState(false)
Zack Rusin601e8372011-03-24 22:23:21 -040027{
28 m_ui.setupUi(this);
29
Zack Rusinf6667d12011-03-30 11:03:37 -040030 m_trace = new ApiTrace();
Zack Rusinde4ea412011-03-30 11:30:08 -040031 connect(m_trace, SIGNAL(startedLoadingTrace()),
32 this, SLOT(startedLoadingTrace()));
33 connect(m_trace, SIGNAL(finishedLoadingTrace()),
34 this, SLOT(finishedLoadingTrace()));
Zack Rusinf6667d12011-03-30 11:03:37 -040035
Zack Rusin601e8372011-03-24 22:23:21 -040036 m_model = new ApiTraceModel();
Zack Rusinf6667d12011-03-30 11:03:37 -040037 m_model->setApiTrace(m_trace);
Zack Rusin91065372011-03-26 01:54:10 -040038 m_proxyModel = new ApiTraceFilter();
39 m_proxyModel->setSourceModel(m_model);
Zack Rusin96130ac2011-03-27 01:48:36 -040040 m_ui.callView->setModel(m_proxyModel);
Zack Rusin18eade52011-03-26 14:23:35 -040041 m_ui.callView->setItemDelegate(new ApiCallDelegate);
Zack Rusin601e8372011-03-24 22:23:21 -040042 for (int column = 0; column < m_model->columnCount(); ++column)
43 m_ui.callView->resizeColumnToContents(column);
44
Zack Rusinea295452011-03-27 02:22:13 -040045 QToolBar *toolBar = addToolBar(tr("Navigation"));
46 m_filterEdit = new QLineEdit(toolBar);
47 toolBar->addWidget(m_filterEdit);
48
Zack Rusinde4ea412011-03-30 11:30:08 -040049 m_progressBar = new QProgressBar();
50 m_progressBar->setRange(0, 0);
51 statusBar()->addPermanentWidget(m_progressBar);
52 m_progressBar->hide();
53
Zack Rusin96130ac2011-03-27 01:48:36 -040054 m_ui.detailsDock->hide();
55
Zack Rusin601e8372011-03-24 22:23:21 -040056 connect(m_ui.actionOpen, SIGNAL(triggered()),
57 this, SLOT(openTrace()));
Zack Rusin27cb2c42011-03-27 23:53:36 -040058 connect(m_ui.actionQuit, SIGNAL(triggered()),
59 this, SLOT(close()));
60
61 connect(m_ui.actionReplay, SIGNAL(triggered()),
62 this, SLOT(replayStart()));
63 connect(m_ui.actionStop, SIGNAL(triggered()),
64 this, SLOT(replayStop()));
Zack Rusin2caa06d2011-03-30 18:30:20 -040065 connect(m_ui.actionLookupState, SIGNAL(triggered()),
66 this, SLOT(lookupState()));
Zack Rusin27cb2c42011-03-27 23:53:36 -040067
Zack Rusin96130ac2011-03-27 01:48:36 -040068 connect(m_ui.callView, SIGNAL(activated(const QModelIndex &)),
69 this, SLOT(callItemSelected(const QModelIndex &)));
Zack Rusinea295452011-03-27 02:22:13 -040070 connect(m_filterEdit, SIGNAL(returnPressed()),
71 this, SLOT(filterTrace()));
Zack Rusin601e8372011-03-24 22:23:21 -040072}
73
74void MainWindow::openTrace()
75{
76 QString fileName =
77 QFileDialog::getOpenFileName(
78 this,
79 tr("Open Trace"),
80 QDir::homePath(),
81 tr("Trace Files (*.trace)"));
82
83 qDebug()<< "File name : " <<fileName;
84
Zack Rusin27cb2c42011-03-27 23:53:36 -040085 newTraceFile(fileName);
Zack Rusin601e8372011-03-24 22:23:21 -040086}
87
88void MainWindow::loadTrace(const QString &fileName)
89{
Zack Rusin27cb2c42011-03-27 23:53:36 -040090 if (!QFile::exists(fileName)) {
91 QMessageBox::warning(this, tr("File Missing"),
92 tr("File '%1' doesn't exist.").arg(fileName));
93 return;
94 }
Zack Rusin601e8372011-03-24 22:23:21 -040095 qDebug()<< "Loading : " <<fileName;
96
Zack Rusinde4ea412011-03-30 11:30:08 -040097 m_progressBar->setValue(0);
Zack Rusin27cb2c42011-03-27 23:53:36 -040098 newTraceFile(fileName);
Zack Rusin601e8372011-03-24 22:23:21 -040099}
100
Zack Rusin96130ac2011-03-27 01:48:36 -0400101void MainWindow::callItemSelected(const QModelIndex &index)
102{
103 ApiTraceCall *call = index.data().value<ApiTraceCall*>();
104 if (call) {
Zack Rusin27cb2c42011-03-27 23:53:36 -0400105 m_ui.detailsWebView->setHtml(call->toHtml());
Zack Rusin96130ac2011-03-27 01:48:36 -0400106 m_ui.detailsDock->show();
Zack Rusin2caa06d2011-03-30 18:30:20 -0400107 m_currentFrame = call->parentFrame;
Zack Rusin96130ac2011-03-27 01:48:36 -0400108 } else {
Zack Rusin2caa06d2011-03-30 18:30:20 -0400109 m_currentFrame = index.data().value<ApiTraceFrame*>();
Zack Rusin96130ac2011-03-27 01:48:36 -0400110 m_ui.detailsDock->hide();
111 }
112}
113
Zack Rusinea295452011-03-27 02:22:13 -0400114void MainWindow::filterTrace()
115{
116 m_proxyModel->setFilterString(m_filterEdit->text());
117}
118
Zack Rusin27cb2c42011-03-27 23:53:36 -0400119void MainWindow::replayStart()
120{
Zack Rusin2caa06d2011-03-30 18:30:20 -0400121 replayTrace(false);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400122}
123
124void MainWindow::replayStop()
125{
126 if (m_replayProcess) {
127 m_replayProcess->kill();
128
129 m_ui.actionStop->setEnabled(false);
130 m_ui.actionReplay->setEnabled(true);
Zack Rusin2caa06d2011-03-30 18:30:20 -0400131 m_ui.actionLookupState->setEnabled(true);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400132 }
133}
134
135void MainWindow::newTraceFile(const QString &fileName)
136{
137 m_traceFileName = fileName;
Zack Rusinf6667d12011-03-30 11:03:37 -0400138 m_trace->setFileName(fileName);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400139
140 if (m_traceFileName.isEmpty()) {
141 m_ui.actionReplay->setEnabled(false);
Zack Rusin2caa06d2011-03-30 18:30:20 -0400142 m_ui.actionLookupState->setEnabled(false);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400143 } else {
144 m_ui.actionReplay->setEnabled(true);
Zack Rusin2caa06d2011-03-30 18:30:20 -0400145 m_ui.actionLookupState->setEnabled(true);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400146 }
147}
148
149void MainWindow::replayFinished()
150{
151 m_ui.actionStop->setEnabled(false);
152 m_ui.actionReplay->setEnabled(true);
Zack Rusin2caa06d2011-03-30 18:30:20 -0400153 m_ui.actionLookupState->setEnabled(true);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400154
Zack Rusin2caa06d2011-03-30 18:30:20 -0400155 QByteArray output = m_replayProcess->readAllStandardOutput();
Zack Rusin27cb2c42011-03-27 23:53:36 -0400156
Zack Rusin2caa06d2011-03-30 18:30:20 -0400157#if 1
Zack Rusin27cb2c42011-03-27 23:53:36 -0400158 qDebug()<<"Process finished = ";
159 qDebug()<<"\terr = "<<m_replayProcess->readAllStandardError();
160 qDebug()<<"\tout = "<<output;
161#endif
162
Zack Rusin2caa06d2011-03-30 18:30:20 -0400163 if (m_findingState) {
164 qDebug()<<"json parse";
165 } else if (output.length() < 80) {
Zack Rusin27cb2c42011-03-27 23:53:36 -0400166 statusBar()->showMessage(output);
167 }
168}
169
170void MainWindow::replayError(QProcess::ProcessError err)
171{
172 m_ui.actionStop->setEnabled(false);
173 m_ui.actionReplay->setEnabled(true);
Zack Rusin2caa06d2011-03-30 18:30:20 -0400174 m_ui.actionLookupState->setEnabled(true);
175 m_findingState = false;
Zack Rusin27cb2c42011-03-27 23:53:36 -0400176
177 qDebug()<<"Process error = "<<err;
178 qDebug()<<"\terr = "<<m_replayProcess->readAllStandardError();
179 qDebug()<<"\tout = "<<m_replayProcess->readAllStandardOutput();
180 QMessageBox::warning(
181 this, tr("Replay Failed"),
182 tr("Couldn't execute the replay file '%1'").arg(m_traceFileName));
183}
184
Zack Rusinde4ea412011-03-30 11:30:08 -0400185void MainWindow::startedLoadingTrace()
186{
187 Q_ASSERT(m_trace);
188 m_progressBar->show();
189 QFileInfo info(m_trace->fileName());
190 statusBar()->showMessage(
191 tr("Loading %1...").arg(info.fileName()));
192}
193
194void MainWindow::finishedLoadingTrace()
195{
196 m_progressBar->hide();
197 if (!m_trace) {
198 return;
199 }
200 QFileInfo info(m_trace->fileName());
201 statusBar()->showMessage(
202 tr("Loaded %1").arg(info.fileName()), 3000);
203}
204
Zack Rusin2caa06d2011-03-30 18:30:20 -0400205void MainWindow::replayTrace(bool dumpState)
206{
207 if (!m_replayProcess) {
208#ifdef Q_OS_WIN
209 QString format = QLatin1String("%1;");
210#else
211 QString format = QLatin1String("%1:");
212#endif
213 QString buildPath = format.arg(BUILD_DIR);
214 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
215 env.insert("PATH", buildPath + env.value("PATH"));
216
217 qputenv("PATH", env.value("PATH").toLatin1());
218
219 m_replayProcess = new QProcess(this);
220 m_replayProcess->setProcessEnvironment(env);
221
222 connect(m_replayProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
223 this, SLOT(replayFinished()));
224 connect(m_replayProcess, SIGNAL(error(QProcess::ProcessError)),
225 this, SLOT(replayError(QProcess::ProcessError)));
226 }
227
228 if (m_traceFileName.isEmpty())
229 return;
230
231 QStringList arguments;
232 if (dumpState &&
233 m_currentFrame && !m_currentFrame->calls.isEmpty()) {
234 arguments << QLatin1String("-D");
235 arguments << QString::number(m_currentFrame->calls.first()->index);
236 }
237 arguments << m_traceFileName;
238
239 m_replayProcess->start(QLatin1String("glretrace"),
240 arguments);
241
242 m_ui.actionStop->setEnabled(true);
243}
244
245void MainWindow::lookupState()
246{
247 if (!m_currentFrame) {
248 QMessageBox::warning(
249 this, tr("Unknown Frame"),
250 tr("To inspect the state select a frame in the trace."));
251 return;
252 }
253 m_findingState = true;
254 replayTrace(true);
255}
256
Zack Rusin601e8372011-03-24 22:23:21 -0400257#include "mainwindow.moc"