blob: 472ff27a4cac4a8fe78c2aef8472026df776fc65 [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
9#include <QAction>
10#include <QDebug>
11#include <QDir>
12#include <QFileDialog>
Zack Rusin27cb2c42011-03-27 23:53:36 -040013#include <QLineEdit>
14#include <QMessageBox>
15#include <QProcess>
Zack Rusinde4ea412011-03-30 11:30:08 -040016#include <QProgressBar>
Zack Rusinea295452011-03-27 02:22:13 -040017#include <QToolBar>
Zack Rusin96130ac2011-03-27 01:48:36 -040018#include <QWebView>
Zack Rusin601e8372011-03-24 22:23:21 -040019
20
21MainWindow::MainWindow()
Zack Rusin27cb2c42011-03-27 23:53:36 -040022 : QMainWindow(),
Zack Rusin2caa06d2011-03-30 18:30:20 -040023 m_replayProcess(0),
24 m_findingState(false)
Zack Rusin601e8372011-03-24 22:23:21 -040025{
26 m_ui.setupUi(this);
27
Zack Rusinf6667d12011-03-30 11:03:37 -040028 m_trace = new ApiTrace();
Zack Rusinde4ea412011-03-30 11:30:08 -040029 connect(m_trace, SIGNAL(startedLoadingTrace()),
30 this, SLOT(startedLoadingTrace()));
31 connect(m_trace, SIGNAL(finishedLoadingTrace()),
32 this, SLOT(finishedLoadingTrace()));
Zack Rusinf6667d12011-03-30 11:03:37 -040033
Zack Rusin601e8372011-03-24 22:23:21 -040034 m_model = new ApiTraceModel();
Zack Rusinf6667d12011-03-30 11:03:37 -040035 m_model->setApiTrace(m_trace);
Zack Rusin91065372011-03-26 01:54:10 -040036 m_proxyModel = new ApiTraceFilter();
37 m_proxyModel->setSourceModel(m_model);
Zack Rusin96130ac2011-03-27 01:48:36 -040038 m_ui.callView->setModel(m_proxyModel);
Zack Rusin18eade52011-03-26 14:23:35 -040039 m_ui.callView->setItemDelegate(new ApiCallDelegate);
Zack Rusin601e8372011-03-24 22:23:21 -040040 for (int column = 0; column < m_model->columnCount(); ++column)
41 m_ui.callView->resizeColumnToContents(column);
42
Zack Rusinea295452011-03-27 02:22:13 -040043 QToolBar *toolBar = addToolBar(tr("Navigation"));
44 m_filterEdit = new QLineEdit(toolBar);
45 toolBar->addWidget(m_filterEdit);
46
Zack Rusinde4ea412011-03-30 11:30:08 -040047 m_progressBar = new QProgressBar();
48 m_progressBar->setRange(0, 0);
49 statusBar()->addPermanentWidget(m_progressBar);
50 m_progressBar->hide();
51
Zack Rusin96130ac2011-03-27 01:48:36 -040052 m_ui.detailsDock->hide();
53
Zack Rusin601e8372011-03-24 22:23:21 -040054 connect(m_ui.actionOpen, SIGNAL(triggered()),
55 this, SLOT(openTrace()));
Zack Rusin27cb2c42011-03-27 23:53:36 -040056 connect(m_ui.actionQuit, SIGNAL(triggered()),
57 this, SLOT(close()));
58
59 connect(m_ui.actionReplay, SIGNAL(triggered()),
60 this, SLOT(replayStart()));
61 connect(m_ui.actionStop, SIGNAL(triggered()),
62 this, SLOT(replayStop()));
Zack Rusin2caa06d2011-03-30 18:30:20 -040063 connect(m_ui.actionLookupState, SIGNAL(triggered()),
64 this, SLOT(lookupState()));
Zack Rusin27cb2c42011-03-27 23:53:36 -040065
Zack Rusin96130ac2011-03-27 01:48:36 -040066 connect(m_ui.callView, SIGNAL(activated(const QModelIndex &)),
67 this, SLOT(callItemSelected(const QModelIndex &)));
Zack Rusinea295452011-03-27 02:22:13 -040068 connect(m_filterEdit, SIGNAL(returnPressed()),
69 this, SLOT(filterTrace()));
Zack Rusin601e8372011-03-24 22:23:21 -040070}
71
72void MainWindow::openTrace()
73{
74 QString fileName =
75 QFileDialog::getOpenFileName(
76 this,
77 tr("Open Trace"),
78 QDir::homePath(),
79 tr("Trace Files (*.trace)"));
80
81 qDebug()<< "File name : " <<fileName;
82
Zack Rusin27cb2c42011-03-27 23:53:36 -040083 newTraceFile(fileName);
Zack Rusin601e8372011-03-24 22:23:21 -040084}
85
86void MainWindow::loadTrace(const QString &fileName)
87{
Zack Rusin27cb2c42011-03-27 23:53:36 -040088 if (!QFile::exists(fileName)) {
89 QMessageBox::warning(this, tr("File Missing"),
90 tr("File '%1' doesn't exist.").arg(fileName));
91 return;
92 }
Zack Rusin601e8372011-03-24 22:23:21 -040093 qDebug()<< "Loading : " <<fileName;
94
Zack Rusinde4ea412011-03-30 11:30:08 -040095 m_progressBar->setValue(0);
Zack Rusin27cb2c42011-03-27 23:53:36 -040096 newTraceFile(fileName);
Zack Rusin601e8372011-03-24 22:23:21 -040097}
98
Zack Rusin96130ac2011-03-27 01:48:36 -040099void MainWindow::callItemSelected(const QModelIndex &index)
100{
101 ApiTraceCall *call = index.data().value<ApiTraceCall*>();
102 if (call) {
Zack Rusin27cb2c42011-03-27 23:53:36 -0400103 m_ui.detailsWebView->setHtml(call->toHtml());
Zack Rusin96130ac2011-03-27 01:48:36 -0400104 m_ui.detailsDock->show();
Zack Rusin2caa06d2011-03-30 18:30:20 -0400105 m_currentFrame = call->parentFrame;
Zack Rusin96130ac2011-03-27 01:48:36 -0400106 } else {
Zack Rusin2caa06d2011-03-30 18:30:20 -0400107 m_currentFrame = index.data().value<ApiTraceFrame*>();
Zack Rusin96130ac2011-03-27 01:48:36 -0400108 m_ui.detailsDock->hide();
109 }
110}
111
Zack Rusinea295452011-03-27 02:22:13 -0400112void MainWindow::filterTrace()
113{
114 m_proxyModel->setFilterString(m_filterEdit->text());
115}
116
Zack Rusin27cb2c42011-03-27 23:53:36 -0400117void MainWindow::replayStart()
118{
Zack Rusin2caa06d2011-03-30 18:30:20 -0400119 replayTrace(false);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400120}
121
122void MainWindow::replayStop()
123{
124 if (m_replayProcess) {
125 m_replayProcess->kill();
126
127 m_ui.actionStop->setEnabled(false);
128 m_ui.actionReplay->setEnabled(true);
Zack Rusin2caa06d2011-03-30 18:30:20 -0400129 m_ui.actionLookupState->setEnabled(true);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400130 }
131}
132
133void MainWindow::newTraceFile(const QString &fileName)
134{
135 m_traceFileName = fileName;
Zack Rusinf6667d12011-03-30 11:03:37 -0400136 m_trace->setFileName(fileName);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400137
138 if (m_traceFileName.isEmpty()) {
139 m_ui.actionReplay->setEnabled(false);
Zack Rusin2caa06d2011-03-30 18:30:20 -0400140 m_ui.actionLookupState->setEnabled(false);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400141 } else {
142 m_ui.actionReplay->setEnabled(true);
Zack Rusin2caa06d2011-03-30 18:30:20 -0400143 m_ui.actionLookupState->setEnabled(true);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400144 }
145}
146
147void MainWindow::replayFinished()
148{
149 m_ui.actionStop->setEnabled(false);
150 m_ui.actionReplay->setEnabled(true);
Zack Rusin2caa06d2011-03-30 18:30:20 -0400151 m_ui.actionLookupState->setEnabled(true);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400152
Zack Rusin2caa06d2011-03-30 18:30:20 -0400153 QByteArray output = m_replayProcess->readAllStandardOutput();
Zack Rusin27cb2c42011-03-27 23:53:36 -0400154
Zack Rusin2caa06d2011-03-30 18:30:20 -0400155#if 1
Zack Rusin27cb2c42011-03-27 23:53:36 -0400156 qDebug()<<"Process finished = ";
157 qDebug()<<"\terr = "<<m_replayProcess->readAllStandardError();
158 qDebug()<<"\tout = "<<output;
159#endif
160
Zack Rusin2caa06d2011-03-30 18:30:20 -0400161 if (m_findingState) {
162 qDebug()<<"json parse";
163 } else if (output.length() < 80) {
Zack Rusin27cb2c42011-03-27 23:53:36 -0400164 statusBar()->showMessage(output);
165 }
166}
167
168void MainWindow::replayError(QProcess::ProcessError err)
169{
170 m_ui.actionStop->setEnabled(false);
171 m_ui.actionReplay->setEnabled(true);
Zack Rusin2caa06d2011-03-30 18:30:20 -0400172 m_ui.actionLookupState->setEnabled(true);
173 m_findingState = false;
Zack Rusin27cb2c42011-03-27 23:53:36 -0400174
175 qDebug()<<"Process error = "<<err;
176 qDebug()<<"\terr = "<<m_replayProcess->readAllStandardError();
177 qDebug()<<"\tout = "<<m_replayProcess->readAllStandardOutput();
178 QMessageBox::warning(
179 this, tr("Replay Failed"),
180 tr("Couldn't execute the replay file '%1'").arg(m_traceFileName));
181}
182
Zack Rusinde4ea412011-03-30 11:30:08 -0400183void MainWindow::startedLoadingTrace()
184{
185 Q_ASSERT(m_trace);
186 m_progressBar->show();
187 QFileInfo info(m_trace->fileName());
188 statusBar()->showMessage(
189 tr("Loading %1...").arg(info.fileName()));
190}
191
192void MainWindow::finishedLoadingTrace()
193{
194 m_progressBar->hide();
195 if (!m_trace) {
196 return;
197 }
198 QFileInfo info(m_trace->fileName());
199 statusBar()->showMessage(
200 tr("Loaded %1").arg(info.fileName()), 3000);
201}
202
Zack Rusin2caa06d2011-03-30 18:30:20 -0400203void MainWindow::replayTrace(bool dumpState)
204{
205 if (!m_replayProcess) {
206#ifdef Q_OS_WIN
207 QString format = QLatin1String("%1;");
208#else
209 QString format = QLatin1String("%1:");
210#endif
211 QString buildPath = format.arg(BUILD_DIR);
212 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
213 env.insert("PATH", buildPath + env.value("PATH"));
214
215 qputenv("PATH", env.value("PATH").toLatin1());
216
217 m_replayProcess = new QProcess(this);
218 m_replayProcess->setProcessEnvironment(env);
219
220 connect(m_replayProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
221 this, SLOT(replayFinished()));
222 connect(m_replayProcess, SIGNAL(error(QProcess::ProcessError)),
223 this, SLOT(replayError(QProcess::ProcessError)));
224 }
225
226 if (m_traceFileName.isEmpty())
227 return;
228
229 QStringList arguments;
230 if (dumpState &&
231 m_currentFrame && !m_currentFrame->calls.isEmpty()) {
232 arguments << QLatin1String("-D");
233 arguments << QString::number(m_currentFrame->calls.first()->index);
234 }
235 arguments << m_traceFileName;
236
237 m_replayProcess->start(QLatin1String("glretrace"),
238 arguments);
239
240 m_ui.actionStop->setEnabled(true);
241}
242
243void MainWindow::lookupState()
244{
245 if (!m_currentFrame) {
246 QMessageBox::warning(
247 this, tr("Unknown Frame"),
248 tr("To inspect the state select a frame in the trace."));
249 return;
250 }
251 m_findingState = true;
252 replayTrace(true);
253}
254
Zack Rusin601e8372011-03-24 22:23:21 -0400255#include "mainwindow.moc"