]> git.cworth.org Git - apitrace/blob - gui/mainwindow.cpp
Let retrace dump state.
[apitrace] / gui / mainwindow.cpp
1 #include "mainwindow.h"
2
3 #include "apitrace.h"
4 #include "apitracecall.h"
5 #include "apicalldelegate.h"
6 #include "apitracemodel.h"
7 #include "apitracefilter.h"
8
9 #include <QAction>
10 #include <QDebug>
11 #include <QDir>
12 #include <QFileDialog>
13 #include <QLineEdit>
14 #include <QMessageBox>
15 #include <QProcess>
16 #include <QProgressBar>
17 #include <QToolBar>
18 #include <QWebView>
19
20
21 MainWindow::MainWindow()
22     : QMainWindow(),
23       m_replayProcess(0),
24       m_findingState(false)
25 {
26     m_ui.setupUi(this);
27
28     m_trace = new ApiTrace();
29     connect(m_trace, SIGNAL(startedLoadingTrace()),
30             this, SLOT(startedLoadingTrace()));
31     connect(m_trace, SIGNAL(finishedLoadingTrace()),
32             this, SLOT(finishedLoadingTrace()));
33
34     m_model = new ApiTraceModel();
35     m_model->setApiTrace(m_trace);
36     m_proxyModel = new ApiTraceFilter();
37     m_proxyModel->setSourceModel(m_model);
38     m_ui.callView->setModel(m_proxyModel);
39     m_ui.callView->setItemDelegate(new ApiCallDelegate);
40     for (int column = 0; column < m_model->columnCount(); ++column)
41         m_ui.callView->resizeColumnToContents(column);
42
43     QToolBar *toolBar = addToolBar(tr("Navigation"));
44     m_filterEdit = new QLineEdit(toolBar);
45     toolBar->addWidget(m_filterEdit);
46
47     m_progressBar = new QProgressBar();
48     m_progressBar->setRange(0, 0);
49     statusBar()->addPermanentWidget(m_progressBar);
50     m_progressBar->hide();
51
52     m_ui.detailsDock->hide();
53
54     connect(m_ui.actionOpen, SIGNAL(triggered()),
55             this, SLOT(openTrace()));
56     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()));
63     connect(m_ui.actionLookupState, SIGNAL(triggered()),
64             this, SLOT(lookupState()));
65
66     connect(m_ui.callView, SIGNAL(activated(const QModelIndex &)),
67             this, SLOT(callItemSelected(const QModelIndex &)));
68     connect(m_filterEdit, SIGNAL(returnPressed()),
69             this, SLOT(filterTrace()));
70 }
71
72 void 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
83     newTraceFile(fileName);
84 }
85
86 void MainWindow::loadTrace(const QString &fileName)
87 {
88     if (!QFile::exists(fileName)) {
89         QMessageBox::warning(this, tr("File Missing"),
90                              tr("File '%1' doesn't exist.").arg(fileName));
91         return;
92     }
93     qDebug()<< "Loading  : " <<fileName;
94
95     m_progressBar->setValue(0);
96     newTraceFile(fileName);
97 }
98
99 void MainWindow::callItemSelected(const QModelIndex &index)
100 {
101     ApiTraceCall *call = index.data().value<ApiTraceCall*>();
102     if (call) {
103         m_ui.detailsWebView->setHtml(call->toHtml());
104         m_ui.detailsDock->show();
105         m_currentFrame = call->parentFrame;
106     } else {
107         m_currentFrame = index.data().value<ApiTraceFrame*>();
108         m_ui.detailsDock->hide();
109     }
110 }
111
112 void MainWindow::filterTrace()
113 {
114     m_proxyModel->setFilterString(m_filterEdit->text());
115 }
116
117 void MainWindow::replayStart()
118 {
119     replayTrace(false);
120 }
121
122 void MainWindow::replayStop()
123 {
124     if (m_replayProcess) {
125         m_replayProcess->kill();
126
127         m_ui.actionStop->setEnabled(false);
128         m_ui.actionReplay->setEnabled(true);
129         m_ui.actionLookupState->setEnabled(true);
130     }
131 }
132
133 void MainWindow::newTraceFile(const QString &fileName)
134 {
135     m_traceFileName = fileName;
136     m_trace->setFileName(fileName);
137
138     if (m_traceFileName.isEmpty()) {
139         m_ui.actionReplay->setEnabled(false);
140         m_ui.actionLookupState->setEnabled(false);
141     } else {
142         m_ui.actionReplay->setEnabled(true);
143         m_ui.actionLookupState->setEnabled(true);
144     }
145 }
146
147 void MainWindow::replayFinished()
148 {
149     m_ui.actionStop->setEnabled(false);
150     m_ui.actionReplay->setEnabled(true);
151     m_ui.actionLookupState->setEnabled(true);
152
153     QByteArray output = m_replayProcess->readAllStandardOutput();
154
155 #if 1
156     qDebug()<<"Process finished = ";
157     qDebug()<<"\terr = "<<m_replayProcess->readAllStandardError();
158     qDebug()<<"\tout = "<<output;
159 #endif
160
161     if (m_findingState) {
162         qDebug()<<"json parse";
163     } else if (output.length() < 80) {
164         statusBar()->showMessage(output);
165     }
166 }
167
168 void MainWindow::replayError(QProcess::ProcessError err)
169 {
170     m_ui.actionStop->setEnabled(false);
171     m_ui.actionReplay->setEnabled(true);
172     m_ui.actionLookupState->setEnabled(true);
173     m_findingState = false;
174
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
183 void 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
192 void 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
203 void 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
243 void 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
255 #include "mainwindow.moc"