mainwindow.cpp
main.cpp
retracer.cpp
+ searchwidget.cpp
settingsdialog.cpp
shaderssourcewidget.cpp
tracedialog.cpp
ui/retracerdialog.ui
ui/settings.ui
ui/tracedialog.ui
+ ui/searchwidget.ui
ui/shaderssourcewidget.ui
)
emit framesAdded(0, m_frames.count());
}
+ApiTraceCall * ApiTrace::callWithIndex(int idx) const
+{
+ for (int i = 0; i < m_calls.count(); ++i) {
+ ApiTraceCall *call = m_calls[i];
+ if (call->index == idx)
+ return call;
+ }
+ return NULL;
+}
+
#include "apitrace.moc"
QList<ApiTraceCall*> calls() const;
ApiTraceCall *callAt(int idx) const;
+ ApiTraceCall *callWithIndex(int idx) const;
int numCalls() const;
QList<ApiTraceFrame*> frames() const;
}
}
-QModelIndex ApiTraceFilter::callIndex(int callNum) const
+QModelIndex ApiTraceFilter::callIndex(int callIdx) const
{
ApiTraceModel *model = static_cast<ApiTraceModel *>(sourceModel());
- QModelIndex index = model->callIndex(callNum);
+ QModelIndex index = model->callIndex(callIdx);
return mapFromSource(index);
}
QModelIndex ApiTraceModel::callIndex(int callNum) const
{
- ApiTraceCall *call = m_trace->callAt(callNum);
+ ApiTraceCall *call = m_trace->callWithIndex(callNum);
if (!call) {
+ qDebug()<<"couldn't find call at "<<callNum;
return QModelIndex();
}
#include "imageviewer.h"
#include "jumpwidget.h"
#include "retracer.h"
+#include "searchwidget.h"
#include "settingsdialog.h"
#include "shaderssourcewidget.h"
#include "tracedialog.h"
m_ui.centralLayout->addWidget(m_jumpWidget);
m_jumpWidget->hide();
+ m_searchWidget = new SearchWidget(this);
+ m_ui.centralLayout->addWidget(m_searchWidget);
+ m_searchWidget->hide();
+
m_traceProcess = new TraceProcess(this);
new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_G),
this, SLOT(slotGoTo()));
+ new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F),
+ this, SLOT(slotSearch()));
}
void MainWindow::initConnections()
connect(m_jumpWidget, SIGNAL(jumpTo(int)),
SLOT(slotJumpTo(int)));
+ connect(m_searchWidget, SIGNAL(searchNext(const QString&, Qt::CaseSensitivity)),
+ SLOT(slotSearchNext(const QString&, Qt::CaseSensitivity)));
+ connect(m_searchWidget, SIGNAL(searchPrev(const QString&, Qt::CaseSensitivity)),
+ SLOT(slotSearchPrev(const QString&, Qt::CaseSensitivity)));
+
connect(m_traceProcess, SIGNAL(tracedFile(const QString&)),
SLOT(createdTrace(const QString&)));
connect(m_traceProcess, SIGNAL(error(const QString&)),
void MainWindow::slotGoTo()
{
+ m_searchWidget->hide();
m_jumpWidget->show();
}
msg);
}
+void MainWindow::slotSearch()
+{
+ m_jumpWidget->hide();
+ m_searchWidget->show();
+}
+
+void MainWindow::slotSearchNext(const QString &str, Qt::CaseSensitivity sensitivity)
+{
+ QModelIndex index = m_ui.callView->currentIndex();
+ ApiTraceEvent *event =
+ index.data(ApiTraceModel::EventRole).value<ApiTraceEvent*>();
+ ApiTraceCall *call = 0;
+
+ if (event->type() == ApiTraceCall::Call)
+ call = static_cast<ApiTraceCall*>(event);
+ else {
+ Q_ASSERT(event->type() == ApiTraceCall::Frame);
+ ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
+ call = frame->calls.value(0);
+ }
+
+ if (!call) {
+ m_searchWidget->setFound(false);
+ return;
+ }
+ const QList<ApiTraceCall*> &calls = m_trace->calls();
+ int callNum = calls.indexOf(call);
+
+ for (int i = callNum + 1; i < calls.count(); ++i) {
+ ApiTraceCall *testCall = calls[i];
+ QString txt = testCall->filterText();
+ if (txt.contains(str, sensitivity)) {
+ QModelIndex index = m_proxyModel->callIndex(testCall->index);
+ /* if it's not valid it means that the proxy model has already
+ * filtered it out */
+ if (index.isValid()) {
+ m_ui.callView->setCurrentIndex(index);
+ m_searchWidget->setFound(true);
+ return;
+ }
+ }
+ }
+ m_searchWidget->setFound(false);
+}
+
+void MainWindow::slotSearchPrev(const QString &str, Qt::CaseSensitivity sensitivity)
+{
+ QModelIndex index = m_ui.callView->currentIndex();
+ ApiTraceEvent *event =
+ index.data(ApiTraceModel::EventRole).value<ApiTraceEvent*>();
+ ApiTraceCall *call = 0;
+
+ if (event->type() == ApiTraceCall::Call)
+ call = static_cast<ApiTraceCall*>(event);
+ else {
+ Q_ASSERT(event->type() == ApiTraceCall::Frame);
+ ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
+ call = frame->calls.value(0);
+ }
+
+ if (!call) {
+ m_searchWidget->setFound(false);
+ return;
+ }
+ const QList<ApiTraceCall*> &calls = m_trace->calls();
+ int callNum = calls.indexOf(call);
+
+ for (int i = callNum - 1; i >= 0; --i) {
+ ApiTraceCall *testCall = calls[i];
+ QString txt = testCall->filterText();
+ if (txt.contains(str, sensitivity)) {
+ QModelIndex index = m_proxyModel->callIndex(testCall->index);
+ /* if it's not valid it means that the proxy model has already
+ * filtered it out */
+ if (index.isValid()) {
+ m_ui.callView->setCurrentIndex(index);
+ m_searchWidget->setFound(true);
+ return;
+ }
+ }
+ }
+ m_searchWidget->setFound(false);
+}
+
#include "mainwindow.moc"
class QProgressBar;
class QUrl;
class Retracer;
+class SearchWidget;
class ShadersSourceWidget;
class TraceProcess;
class VertexDataInterpreter;
void slotJumpTo(int callNum);
void createdTrace(const QString &path);
void traceError(const QString &msg);
+ void slotSearch();
+ void slotSearchNext(const QString &str, Qt::CaseSensitivity sensitivity);
+ void slotSearchPrev(const QString &str, Qt::CaseSensitivity sensitivity);
private:
void initObjects();
ImageViewer *m_imageViewer;
JumpWidget *m_jumpWidget;
+ SearchWidget *m_searchWidget;
TraceProcess *m_traceProcess;
};
<file>resources/dialog-information.png</file>
<file>resources/document-new.png</file>
<file>resources/document-open.png</file>
+ <file>resources/go-down-search.png</file>
+ <file>resources/go-up-search.png</file>
<file>resources/media-playback-start.png</file>
<file>resources/media-playback-stop.png</file>
<file>resources/media-record.png</file>
--- /dev/null
+#include "searchwidget.h"
+
+#include <QDebug>
+#include <QKeyEvent>
+
+SearchWidget::SearchWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ m_ui.setupUi(this);
+
+ m_ui.notFoundLabel->hide();
+ m_origPalette = m_ui.lineEdit->palette();
+
+ connect(m_ui.nextButton, SIGNAL(clicked()),
+ SLOT(slotSearchNext()));
+ connect(m_ui.prevButton, SIGNAL(clicked()),
+ SLOT(slotSearchPrev()));
+ connect(m_ui.closeButton, SIGNAL(clicked()),
+ SLOT(slotCancel()));
+ connect(m_ui.lineEdit, SIGNAL(returnPressed()),
+ SLOT(slotSearchNext()));
+
+ installEventFilter(this);
+}
+
+void SearchWidget::slotSearchNext()
+{
+ QString txt = m_ui.lineEdit->text();
+ if (!txt.isEmpty())
+ emit searchNext(txt, caseSensitivity());
+}
+
+void SearchWidget::slotSearchPrev()
+{
+ QString txt = m_ui.lineEdit->text();
+ if (!txt.isEmpty())
+ emit searchPrev(txt, caseSensitivity());
+}
+
+void SearchWidget::slotCancel()
+{
+ hide();
+}
+
+void SearchWidget::showEvent(QShowEvent *event)
+{
+ m_ui.lineEdit->selectAll();
+ m_ui.lineEdit->setFocus(Qt::ShortcutFocusReason);
+ m_ui.lineEdit->setPalette(m_origPalette);
+ return QWidget::showEvent(event);
+}
+
+Qt::CaseSensitivity SearchWidget::caseSensitivity() const
+{
+ if (m_ui.caseSensitiveBox->isChecked())
+ return Qt::CaseSensitive;
+ else
+ return Qt::CaseInsensitive;
+}
+
+bool SearchWidget::eventFilter(QObject *object, QEvent* event)
+{
+ if (event->type() == QEvent::KeyPress) {
+ if ((static_cast<QKeyEvent*>(event))->key() == Qt::Key_Escape) {
+ hide();
+ }
+ }
+ return QWidget::eventFilter(object, event);
+}
+
+void SearchWidget::setFound(bool found)
+{
+ QPalette pal = m_origPalette;
+ pal.setColor(QPalette::Active, QPalette::Base,
+ found ? Qt::white : QColor(255, 102, 102));
+ m_ui.lineEdit->setPalette(pal);
+ m_ui.notFoundLabel->setVisible(!found);
+}
+
+#include "searchwidget.moc"
--- /dev/null
+#ifndef SEARCHWIDGET_H
+#define SEARCHWIDGET_H
+
+#include "ui_searchwidget.h"
+#include <QPalette>
+#include <QWidget>
+
+class QShowEvent;
+
+class SearchWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ SearchWidget(QWidget *parent=0);
+
+ void setFound(bool f);
+signals:
+ void searchNext(const QString &str, Qt::CaseSensitivity cs = Qt::CaseInsensitive);
+ void searchPrev(const QString &str, Qt::CaseSensitivity cs = Qt::CaseInsensitive);
+
+private slots:
+ void slotSearchNext();
+ void slotSearchPrev();
+ void slotCancel();
+
+protected:
+ virtual bool eventFilter(QObject *object, QEvent* event);
+ virtual void showEvent(QShowEvent *event);
+
+private:
+ Qt::CaseSensitivity caseSensitivity() const;
+private:
+ Ui_SearchWidget m_ui;
+ QPalette m_origPalette;
+};
+
+#endif
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SearchWidget</class>
+ <widget class="QWidget" name="SearchWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>547</width>
+ <height>33</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QToolButton" name="closeButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../qapitrace.qrc">
+ <normaloff>:/resources/dialog-close.png</normaloff>:/resources/dialog-close.png</iconset>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::NoArrow</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>170</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="prevButton">
+ <property name="toolTip">
+ <string>Find previous occurance of the string</string>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../qapitrace.qrc">
+ <normaloff>:/resources/go-up-search.png</normaloff>:/resources/go-up-search.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="nextButton">
+ <property name="toolTip">
+ <string>Find next occurance of the text</string>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../qapitrace.qrc">
+ <normaloff>:/resources/go-down-search.png</normaloff>:/resources/go-down-search.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="caseSensitiveBox">
+ <property name="text">
+ <string>Case Sensitive</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="notFoundLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>50</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="text">
+ <string><b>Text not found</b></string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="indent">
+ <number>30</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../qapitrace.qrc"/>
+ </resources>
+ <connections/>
+</ui>