]> git.cworth.org Git - apitrace/blobdiff - gui/mainwindow.cpp
Add qjson dependency and cleanup the cmake qt code.
[apitrace] / gui / mainwindow.cpp
index a2fc380250fbd1733d73bc31a56d37bd8dbe4468..592841c63015b24d623e2604bddd1c9a756b2ef6 100644 (file)
@@ -1,30 +1,74 @@
 #include "mainwindow.h"
 
+#include "apitrace.h"
+#include "apitracecall.h"
 #include "apicalldelegate.h"
 #include "apitracemodel.h"
 #include "apitracefilter.h"
 
+#include <qjson/parser.h>
+
 #include <QAction>
 #include <QDebug>
 #include <QDir>
 #include <QFileDialog>
+#include <QLineEdit>
+#include <QMessageBox>
+#include <QProcess>
+#include <QProgressBar>
+#include <QToolBar>
+#include <QWebView>
 
 
 MainWindow::MainWindow()
-    : QMainWindow()
+    : QMainWindow(),
+      m_replayProcess(0),
+      m_findingState(false)
 {
     m_ui.setupUi(this);
 
+    m_trace = new ApiTrace();
+    connect(m_trace, SIGNAL(startedLoadingTrace()),
+            this, SLOT(startedLoadingTrace()));
+    connect(m_trace, SIGNAL(finishedLoadingTrace()),
+            this, SLOT(finishedLoadingTrace()));
+
     m_model = new ApiTraceModel();
+    m_model->setApiTrace(m_trace);
     m_proxyModel = new ApiTraceFilter();
     m_proxyModel->setSourceModel(m_model);
-    m_ui.callView->setModel(m_model);
+    m_ui.callView->setModel(m_proxyModel);
     m_ui.callView->setItemDelegate(new ApiCallDelegate);
     for (int column = 0; column < m_model->columnCount(); ++column)
         m_ui.callView->resizeColumnToContents(column);
 
+    QToolBar *toolBar = addToolBar(tr("Navigation"));
+    m_filterEdit = new QLineEdit(toolBar);
+    toolBar->addWidget(m_filterEdit);
+
+    m_progressBar = new QProgressBar();
+    m_progressBar->setRange(0, 0);
+    statusBar()->addPermanentWidget(m_progressBar);
+    m_progressBar->hide();
+
+    m_ui.detailsDock->hide();
+
     connect(m_ui.actionOpen, SIGNAL(triggered()),
             this, SLOT(openTrace()));
+    connect(m_ui.actionQuit, SIGNAL(triggered()),
+            this, SLOT(close()));
+
+    connect(m_ui.actionReplay, SIGNAL(triggered()),
+            this, SLOT(replayStart()));
+    connect(m_ui.actionStop, SIGNAL(triggered()),
+            this, SLOT(replayStop()));
+    connect(m_ui.actionLookupState, SIGNAL(triggered()),
+            this, SLOT(lookupState()));
+
+    connect(m_ui.callView, SIGNAL(activated(const QModelIndex &)),
+            this, SLOT(callItemSelected(const QModelIndex &)));
+    connect(m_filterEdit, SIGNAL(returnPressed()),
+            this, SLOT(filterTrace()));
 }
 
 void MainWindow::openTrace()
@@ -38,14 +82,176 @@ void MainWindow::openTrace()
 
     qDebug()<< "File name : " <<fileName;
 
-    m_model->loadTraceFile(fileName);
+    newTraceFile(fileName);
 }
 
 void MainWindow::loadTrace(const QString &fileName)
 {
+    if (!QFile::exists(fileName)) {
+        QMessageBox::warning(this, tr("File Missing"),
+                             tr("File '%1' doesn't exist.").arg(fileName));
+        return;
+    }
     qDebug()<< "Loading  : " <<fileName;
 
-    m_model->loadTraceFile(fileName);
+    m_progressBar->setValue(0);
+    newTraceFile(fileName);
+}
+
+void MainWindow::callItemSelected(const QModelIndex &index)
+{
+    ApiTraceCall *call = index.data().value<ApiTraceCall*>();
+    if (call) {
+        m_ui.detailsWebView->setHtml(call->toHtml());
+        m_ui.detailsDock->show();
+        m_currentFrame = call->parentFrame;
+    } else {
+        m_currentFrame = index.data().value<ApiTraceFrame*>();
+        m_ui.detailsDock->hide();
+    }
+}
+
+void MainWindow::filterTrace()
+{
+    m_proxyModel->setFilterString(m_filterEdit->text());
+}
+
+void MainWindow::replayStart()
+{
+    replayTrace(false);
+}
+
+void MainWindow::replayStop()
+{
+    if (m_replayProcess) {
+        m_replayProcess->kill();
+
+        m_ui.actionStop->setEnabled(false);
+        m_ui.actionReplay->setEnabled(true);
+        m_ui.actionLookupState->setEnabled(true);
+    }
+}
+
+void MainWindow::newTraceFile(const QString &fileName)
+{
+    m_traceFileName = fileName;
+    m_trace->setFileName(fileName);
+
+    if (m_traceFileName.isEmpty()) {
+        m_ui.actionReplay->setEnabled(false);
+        m_ui.actionLookupState->setEnabled(false);
+    } else {
+        m_ui.actionReplay->setEnabled(true);
+        m_ui.actionLookupState->setEnabled(true);
+    }
+}
+
+void MainWindow::replayFinished()
+{
+    m_ui.actionStop->setEnabled(false);
+    m_ui.actionReplay->setEnabled(true);
+    m_ui.actionLookupState->setEnabled(true);
+
+    QByteArray output = m_replayProcess->readAllStandardOutput();
+
+#if 1
+    qDebug()<<"Process finished = ";
+    qDebug()<<"\terr = "<<m_replayProcess->readAllStandardError();
+    qDebug()<<"\tout = "<<output;
+#endif
+
+    if (m_findingState) {
+        qDebug()<<"json parse";
+    } else if (output.length() < 80) {
+        statusBar()->showMessage(output);
+    }
+}
+
+void MainWindow::replayError(QProcess::ProcessError err)
+{
+    m_ui.actionStop->setEnabled(false);
+    m_ui.actionReplay->setEnabled(true);
+    m_ui.actionLookupState->setEnabled(true);
+    m_findingState = false;
+
+    qDebug()<<"Process error = "<<err;
+    qDebug()<<"\terr = "<<m_replayProcess->readAllStandardError();
+    qDebug()<<"\tout = "<<m_replayProcess->readAllStandardOutput();
+    QMessageBox::warning(
+        this, tr("Replay Failed"),
+        tr("Couldn't execute the replay file '%1'").arg(m_traceFileName));
+}
+
+void MainWindow::startedLoadingTrace()
+{
+    Q_ASSERT(m_trace);
+    m_progressBar->show();
+    QFileInfo info(m_trace->fileName());
+    statusBar()->showMessage(
+        tr("Loading %1...").arg(info.fileName()));
+}
+
+void MainWindow::finishedLoadingTrace()
+{
+    m_progressBar->hide();
+    if (!m_trace) {
+        return;
+    }
+    QFileInfo info(m_trace->fileName());
+    statusBar()->showMessage(
+        tr("Loaded %1").arg(info.fileName()), 3000);
+}
+
+void MainWindow::replayTrace(bool dumpState)
+{
+    if (!m_replayProcess) {
+#ifdef Q_OS_WIN
+        QString format = QLatin1String("%1;");
+#else
+        QString format = QLatin1String("%1:");
+#endif
+        QString buildPath = format.arg(BUILD_DIR);
+        QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+        env.insert("PATH", buildPath + env.value("PATH"));
+
+        qputenv("PATH", env.value("PATH").toLatin1());
+
+        m_replayProcess = new QProcess(this);
+        m_replayProcess->setProcessEnvironment(env);
+
+        connect(m_replayProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
+                this, SLOT(replayFinished()));
+        connect(m_replayProcess, SIGNAL(error(QProcess::ProcessError)),
+                this, SLOT(replayError(QProcess::ProcessError)));
+    }
+
+    if (m_traceFileName.isEmpty())
+        return;
+
+    QStringList arguments;
+    if (dumpState &&
+        m_currentFrame && !m_currentFrame->calls.isEmpty()) {
+        arguments << QLatin1String("-D");
+        arguments << QString::number(m_currentFrame->calls.first()->index);
+    }
+    arguments << m_traceFileName;
+
+    m_replayProcess->start(QLatin1String("glretrace"),
+                           arguments);
+
+    m_ui.actionStop->setEnabled(true);
+}
+
+void MainWindow::lookupState()
+{
+    if (!m_currentFrame) {
+        QMessageBox::warning(
+            this, tr("Unknown Frame"),
+            tr("To inspect the state select a frame in the trace."));
+        return;
+    }
+    m_findingState = true;
+    replayTrace(true);
 }
 
 #include "mainwindow.moc"