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