]> git.cworth.org Git - apitrace/blobdiff - gui/mainwindow.cpp
Switch list to a vector.
[apitrace] / gui / mainwindow.cpp
index 441697518e247cbf04a55ab1f76917b847964b4d..34e99f5e1b2a5e4906e0d296998db58a93b80439 100644 (file)
@@ -37,7 +37,8 @@
 MainWindow::MainWindow()
     : QMainWindow(),
       m_selectedEvent(0),
-      m_stateEvent(0)
+      m_stateEvent(0),
+      m_nonDefaultsLookupEvent(0)
 {
     m_ui.setupUi(this);
     initObjects();
@@ -74,9 +75,9 @@ void MainWindow::openTrace()
             QDir::homePath(),
             tr("Trace Files (*.trace)"));
 
-    qDebug()<< "File name : " <<fileName;
-
-    newTraceFile(fileName);
+    if (!fileName.isEmpty() && QFile::exists(fileName)) {
+        newTraceFile(fileName);
+    }
 }
 
 void MainWindow::loadTrace(const QString &fileName)
@@ -86,9 +87,7 @@ void MainWindow::loadTrace(const QString &fileName)
                              tr("File '%1' doesn't exist.").arg(fileName));
         return;
     }
-    qDebug()<< "Loading  : " <<fileName;
 
-    m_progressBar->setValue(0);
     newTraceFile(fileName);
 }
 
@@ -133,7 +132,7 @@ void MainWindow::callItemSelected(const QModelIndex &index)
         m_ui.detailsDock->hide();
         m_ui.vertexDataDock->hide();
     }
-    if (m_selectedEvent && !m_selectedEvent->state().isEmpty()) {
+    if (m_selectedEvent && m_selectedEvent->hasState()) {
         fillStateForFrame();
     } else
         m_ui.stateDock->hide();
@@ -177,6 +176,9 @@ void MainWindow::replayStop()
 
 void MainWindow::newTraceFile(const QString &fileName)
 {
+    qDebug()<< "Loading  : " <<fileName;
+
+    m_progressBar->setValue(0);
     m_trace->setFileName(fileName);
 
     if (fileName.isEmpty()) {
@@ -218,6 +220,7 @@ void MainWindow::replayError(const QString &message)
     m_ui.actionReplay->setEnabled(true);
     m_ui.actionLookupState->setEnabled(true);
     m_stateEvent = 0;
+    m_nonDefaultsLookupEvent = 0;
 
     m_progressBar->hide();
     statusBar()->showMessage(
@@ -433,13 +436,43 @@ variantToItem(const QString &key, const QVariant &var, const QVariant &defaultVa
     return item;
 }
 
-void MainWindow::fillStateForFrame()
+static void addSurfaceItem(const ApiSurface &surface,
+                           const QString &label,
+                           QTreeWidgetItem *parent,
+                           QTreeWidget *tree)
 {
-    QVariantMap params;
+    int width = surface.size().width();
+    int height = surface.size().height();
+    QIcon icon(QPixmap::fromImage(surface.thumb()));
+    QTreeWidgetItem *item = new QTreeWidgetItem(parent);
+
+    item->setIcon(0, icon);
+
+    QString descr =
+        QString::fromLatin1("%1, %2 x %3")
+        .arg(label)
+        .arg(width)
+        .arg(height);
+
+    //item->setText(1, descr);
+    QLabel *l = new QLabel(descr, tree);
+    l->setWordWrap(true);
+    tree->setItemWidget(item, 1, l);
 
-    if (!m_selectedEvent || m_selectedEvent->state().isEmpty())
+    item->setData(0, Qt::UserRole, surface.image());
+}
+
+void MainWindow::fillStateForFrame()
+{
+    if (!m_selectedEvent || !m_selectedEvent->hasState())
         return;
 
+    if (m_nonDefaultsLookupEvent) {
+        m_ui.nonDefaultsCB->blockSignals(true);
+        m_ui.nonDefaultsCB->setChecked(true);
+        m_ui.nonDefaultsCB->blockSignals(false);
+    }
+
     bool nonDefaults = m_ui.nonDefaultsCB->isChecked();
     QVariantMap defaultParams;
     if (nonDefaults) {
@@ -447,11 +480,10 @@ void MainWindow::fillStateForFrame()
         defaultParams = defaultState.parameters();
     }
 
-    const ApiTraceState &state = m_selectedEvent->state();
+    const ApiTraceState &state = *m_selectedEvent->state();
     m_ui.stateTreeWidget->clear();
-    params = state.parameters();
     QList<QTreeWidgetItem *> items;
-    variantMapToItems(params, defaultParams, items);
+    variantMapToItems(state.parameters(), defaultParams, items);
     m_ui.stateTreeWidget->insertTopLevelItems(0, items);
 
     QMap<QString, QString> shaderSources = state.shaderSources();
@@ -461,6 +493,11 @@ void MainWindow::fillStateForFrame()
         m_sourcesWidget->setShaders(shaderSources);
     }
 
+    m_ui.uniformsTreeWidget->clear();
+    QList<QTreeWidgetItem *> uniformsItems;
+    variantMapToItems(state.uniforms(), QVariantMap(), uniformsItems);
+    m_ui.uniformsTreeWidget->insertTopLevelItems(0, uniformsItems);
+
     const QList<ApiTexture> &textures =
         state.textures();
     const QList<ApiFramebuffer> &fbos =
@@ -481,20 +518,9 @@ void MainWindow::fillStateForFrame()
             for (int i = 0; i < textures.count(); ++i) {
                 const ApiTexture &texture =
                     textures[i];
-                QIcon icon(QPixmap::fromImage(texture.thumb()));
-                QTreeWidgetItem *item = new QTreeWidgetItem(textureItem);
-                item->setIcon(0, icon);
-                int width = texture.size().width();
-                int height = texture.size().height();
-                QString descr =
-                    QString::fromLatin1("%1, %2 x %3")
-                    .arg(texture.target())
-                    .arg(width)
-                    .arg(height);
-                item->setText(1, descr);
-
-                item->setData(0, Qt::UserRole,
-                              texture.image());
+                addSurfaceItem(texture, texture.label(),
+                               textureItem,
+                               m_ui.surfacesTreeWidget);
             }
         }
         if (!fbos.isEmpty()) {
@@ -507,20 +533,9 @@ void MainWindow::fillStateForFrame()
             for (int i = 0; i < fbos.count(); ++i) {
                 const ApiFramebuffer &fbo =
                     fbos[i];
-                QIcon icon(QPixmap::fromImage(fbo.thumb()));
-                QTreeWidgetItem *item = new QTreeWidgetItem(fboItem);
-                item->setIcon(0, icon);
-                int width = fbo.size().width();
-                int height = fbo.size().height();
-                QString descr =
-                    QString::fromLatin1("%1, %2 x %3")
-                    .arg(fbo.type())
-                    .arg(width)
-                    .arg(height);
-                item->setText(1, descr);
-
-                item->setData(0, Qt::UserRole,
-                              fbo.image());
+                addSurfaceItem(fbo, fbo.type(),
+                               fboItem,
+                               m_ui.surfacesTreeWidget);
             }
         }
         m_ui.surfacesTab->setEnabled(true);
@@ -549,12 +564,17 @@ void MainWindow::showSurfacesMenu(const QPoint &pos)
         return;
 
     QMenu menu(tr("Surfaces"), this);
-    //add needed actions
+
     QAction *act = menu.addAction(tr("View Image"));
     act->setStatusTip(tr("View the currently selected surface"));
     connect(act, SIGNAL(triggered()),
             SLOT(showSelectedSurface()));
 
+    act = menu.addAction(tr("Save Image"));
+    act->setStatusTip(tr("Save the currently selected surface"));
+    connect(act, SIGNAL(triggered()),
+            SLOT(saveSelectedSurface()));
+
     menu.exec(tree->viewport()->mapToGlobal(pos));
 }
 
@@ -592,6 +612,7 @@ void MainWindow::showSelectedSurface()
 void MainWindow::initObjects()
 {
     m_ui.stateTreeWidget->sortByColumn(0, Qt::AscendingOrder);
+    m_ui.uniformsTreeWidget->sortByColumn(0, Qt::AscendingOrder);
 
     m_sourcesWidget = new ShadersSourceWidget(m_ui.shadersTab);
     QVBoxLayout *layout = new QVBoxLayout;
@@ -673,8 +694,8 @@ void MainWindow::initConnections()
             this, SLOT(replayFinished(const QString&)));
     connect(m_retracer, SIGNAL(error(const QString&)),
             this, SLOT(replayError(const QString&)));
-    connect(m_retracer, SIGNAL(foundState(const ApiTraceState&)),
-            this, SLOT(replayStateFound(const ApiTraceState&)));
+    connect(m_retracer, SIGNAL(foundState(ApiTraceState*)),
+            this, SLOT(replayStateFound(ApiTraceState*)));
     connect(m_retracer, SIGNAL(retraceErrors(const QList<RetraceError>&)),
             this, SLOT(slotRetraceErrors(const QList<RetraceError>&)));
 
@@ -752,19 +773,22 @@ void MainWindow::initConnections()
             m_ui.actionShowErrorsDock, SLOT(setChecked(bool)));
     connect(m_ui.actionShowErrorsDock, SIGNAL(triggered(bool)),
             m_ui.errorsDock, SLOT(setVisible(bool)));
-    connect(m_ui.errorsTreeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
+    connect(m_ui.errorsTreeWidget,
+            SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
             this, SLOT(slotErrorSelected(QTreeWidgetItem*)));
 }
 
-void MainWindow::replayStateFound(const ApiTraceState &state)
+void MainWindow::replayStateFound(ApiTraceState *state)
 {
     m_stateEvent->setState(state);
     m_model->stateSetOnEvent(m_stateEvent);
-    if (m_selectedEvent == m_stateEvent) {
+    if (m_selectedEvent == m_stateEvent ||
+        m_nonDefaultsLookupEvent == m_selectedEvent) {
         fillStateForFrame();
     } else {
         m_ui.stateDock->hide();
     }
+    m_nonDefaultsLookupEvent = 0;
 }
 
 void MainWindow::slotGoTo()
@@ -832,7 +856,7 @@ void MainWindow::slotSearchNext(const QString &str,
         m_searchWidget->setFound(false);
         return;
     }
-    const QList<ApiTraceCall*> &calls = m_trace->calls();
+    const QVector<ApiTraceCall*> &calls = m_trace->calls();
     int callNum = calls.indexOf(call);
 
     for (int i = callNum + 1; i < calls.count(); ++i) {
@@ -841,7 +865,7 @@ void MainWindow::slotSearchNext(const QString &str,
         /* if it's not valid it means that the proxy model has already
          * filtered it out */
         if (index.isValid()) {
-            QString txt = testCall->filterText();
+            QString txt = testCall->searchText();
             if (txt.contains(str, sensitivity)) {
                 m_ui.callView->setCurrentIndex(index);
                 m_searchWidget->setFound(true);
@@ -883,7 +907,7 @@ void MainWindow::slotSearchPrev(const QString &str,
         m_searchWidget->setFound(false);
         return;
     }
-    const QList<ApiTraceCall*> &calls = m_trace->calls();
+    const QVector<ApiTraceCall*> &calls = m_trace->calls();
     int callNum = calls.indexOf(call);
 
     for (int i = callNum - 1; i >= 0; --i) {
@@ -892,7 +916,7 @@ void MainWindow::slotSearchPrev(const QString &str,
         /* if it's not valid it means that the proxy model has already
          * filtered it out */
         if (index.isValid()) {
-            QString txt = testCall->filterText();
+            QString txt = testCall->searchText();
             if (txt.contains(str, sensitivity)) {
                 m_ui.callView->setCurrentIndex(index);
                 m_searchWidget->setFound(true);
@@ -911,22 +935,12 @@ void MainWindow::fillState(bool nonDefaults)
             m_ui.nonDefaultsCB->blockSignals(true);
             m_ui.nonDefaultsCB->setChecked(false);
             m_ui.nonDefaultsCB->blockSignals(false);
-            int ret = QMessageBox::question(
-                this, tr("Empty Default State"),
-                tr("The applcation needs to figure out the "
-                   "default state for the current trace. "
-                   "This only has to be done once and "
-                   "afterwards you will be able to enable "
-                   "displaying of non default state for all calls."
-                   "\nDo you want to lookup the default state now?"),
-                QMessageBox::Yes | QMessageBox::No);
-            if (ret != QMessageBox::Yes)
-                return;
             ApiTraceFrame *firstFrame =
                 m_trace->frameAt(0);
             ApiTraceEvent *oldSelected = m_selectedEvent;
             if (!firstFrame)
                 return;
+            m_nonDefaultsLookupEvent = m_selectedEvent;
             m_selectedEvent = firstFrame;
             lookupState();
             m_selectedEvent = oldSelected;
@@ -946,12 +960,14 @@ void MainWindow::customContextMenuRequested(QPoint pos)
 
     ApiTraceEvent *event =
         index.data(ApiTraceModel::EventRole).value<ApiTraceEvent*>();
-    if (!event || event->type() != ApiTraceEvent::Call)
+    if (!event)
         return;
 
     menu.addAction(QIcon(":/resources/media-record.png"),
                    tr("Lookup state"), this, SLOT(lookupState()));
-    menu.addAction(tr("Edit"), this, SLOT(editCall()));
+    if (event->type() == ApiTraceEvent::Call) {
+        menu.addAction(tr("Edit"), this, SLOT(editCall()));
+    }
 
     menu.exec(QCursor::pos());
 }
@@ -986,8 +1002,8 @@ void MainWindow::slotGoFrameStart()
         return;
     }
 
-    QList<ApiTraceCall*>::const_iterator itr;
-    QList<ApiTraceCall*> calls = frame->calls();
+    QVector<ApiTraceCall*>::const_iterator itr;
+    QVector<ApiTraceCall*> calls = frame->calls();
 
     itr = calls.constBegin();
     while (itr != calls.constEnd()) {
@@ -1007,8 +1023,8 @@ void MainWindow::slotGoFrameEnd()
     if (!frame || frame->isEmpty()) {
         return;
     }
-    QList<ApiTraceCall*>::const_iterator itr;
-    QList<ApiTraceCall*> calls = frame->calls();
+    QVector<ApiTraceCall*>::const_iterator itr;
+    QVector<ApiTraceCall*> calls = frame->calls();
 
     itr = calls.constEnd();
     do {
@@ -1089,4 +1105,57 @@ ApiTraceCall * MainWindow::currentCall() const
     return NULL;
 }
 
+void MainWindow::saveSelectedSurface()
+{
+    QTreeWidgetItem *item =
+        m_ui.surfacesTreeWidget->currentItem();
+
+    if (!item || !m_trace)
+        return;
+
+    QVariant var = item->data(0, Qt::UserRole);
+    QImage img = var.value<QImage>();
+
+    QString imageIndex;
+    if (currentCall()) {
+        imageIndex = tr("_call_%1")
+                     .arg(currentCall()->index());
+    } else if (currentFrame()) {
+        ApiTraceCall *firstCall = currentFrame()->call(0);
+        if (firstCall) {
+            imageIndex = tr("_frame_%1")
+                         .arg(firstCall->index());
+        } else {
+            qDebug()<<"unknown frame number";
+            imageIndex = tr("_frame_%1")
+                         .arg(firstCall->index());
+        }
+    }
+
+    //which of the surfaces are we saving
+    QTreeWidgetItem *parent = item->parent();
+    int parentIndex =
+        m_ui.surfacesTreeWidget->indexOfTopLevelItem(parent);
+    if (parentIndex < 0) {
+        parentIndex = 0;
+    }
+    int childIndex = 0;
+    if (parent) {
+        childIndex = parent->indexOfChild(item);
+    } else {
+        childIndex = m_ui.surfacesTreeWidget->indexOfTopLevelItem(item);
+    }
+
+
+    QString fileName =
+        tr("%1%2-%3_%4.png")
+        .arg(m_trace->fileName())
+        .arg(imageIndex)
+        .arg(parentIndex)
+        .arg(childIndex);
+    //qDebug()<<"save "<<fileName;
+    img.save(fileName, "PNG");
+    statusBar()->showMessage( tr("Saved '%1'").arg(fileName), 5000);
+}
+
 #include "mainwindow.moc"