]> git.cworth.org Git - apitrace/commitdiff
Add a search widget and fix go to.
authorZack Rusin <zack@kde.org>
Wed, 13 Apr 2011 03:21:52 +0000 (23:21 -0400)
committerZack Rusin <zack@kde.org>
Wed, 13 Apr 2011 03:23:01 +0000 (23:23 -0400)
go to wasn't indexing the call indexes but the row counts, which
don't always match. also adding a nice search widget to search for
specific calls within the view.

13 files changed:
gui/CMakeLists.txt
gui/apitrace.cpp
gui/apitrace.h
gui/apitracefilter.cpp
gui/apitracemodel.cpp
gui/mainwindow.cpp
gui/mainwindow.h
gui/qapitrace.qrc
gui/resources/go-down-search.png [new file with mode: 0644]
gui/resources/go-up-search.png [new file with mode: 0644]
gui/searchwidget.cpp [new file with mode: 0644]
gui/searchwidget.h [new file with mode: 0644]
gui/ui/searchwidget.ui [new file with mode: 0644]

index 15d14ce6edaf22bd46a72de003b274162a9964fb..6787043cd5c32ea046dad76d06181c212e5b594b 100644 (file)
@@ -15,6 +15,7 @@ set(qapitrace_SRCS
    mainwindow.cpp
    main.cpp
    retracer.cpp
+   searchwidget.cpp
    settingsdialog.cpp
    shaderssourcewidget.cpp
    tracedialog.cpp
@@ -33,6 +34,7 @@ set(qapitrace_UIS
    ui/retracerdialog.ui
    ui/settings.ui
    ui/tracedialog.ui
+   ui/searchwidget.ui
    ui/shaderssourcewidget.ui
    )
 
index 6cc360b642e3b8fe3f8d24824ffe5670a7bfd7ba..03ff02e1ab0655c48bcbf4ddccc93cc8f4bed3e5 100644 (file)
@@ -171,4 +171,14 @@ void ApiTrace::detectFrames()
     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"
index a46e8e0a83a963852e342a9cf109db719b0f4b21..f1f6811919ba12a970317df4d35b3b4e9038bceb 100644 (file)
@@ -31,6 +31,7 @@ public:
 
     QList<ApiTraceCall*> calls() const;
     ApiTraceCall *callAt(int idx) const;
+    ApiTraceCall *callWithIndex(int idx) const;
     int numCalls() const;
 
     QList<ApiTraceFrame*> frames() const;
index 5c804508d19835d1f2cb42da69d6e3d18563962c..7580bba2dd899e12d5dcfe5f011e1c8754d783c2 100644 (file)
@@ -89,10 +89,10 @@ void ApiTraceFilter::setFilterOptions(ApiTraceFilter::FilterOptions opts)
     }
 }
 
-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);
 }
 
index eb29a0e2e2f21c7d97ed4c04789b6cc6378c3246..2b4b6bb2126ae52900e7592c5b397103bda14333 100644 (file)
@@ -255,9 +255,10 @@ void ApiTraceModel::stateSetOnEvent(ApiTraceEvent *event)
 
 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();
     }
 
index 2627cb5c45cb869c667867927bd3dbdb7f978cfe..35c287ac2af78e10a2a4cc74db802f8e388899ee 100644 (file)
@@ -8,6 +8,7 @@
 #include "imageviewer.h"
 #include "jumpwidget.h"
 #include "retracer.h"
+#include "searchwidget.h"
 #include "settingsdialog.h"
 #include "shaderssourcewidget.h"
 #include "tracedialog.h"
@@ -518,10 +519,16 @@ void MainWindow::initObjects()
     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()
@@ -584,6 +591,11 @@ 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&)),
@@ -603,6 +615,7 @@ void MainWindow::replayStateFound(const ApiTraceState &state)
 
 void MainWindow::slotGoTo()
 {
+    m_searchWidget->hide();
     m_jumpWidget->show();
 }
 
@@ -628,4 +641,88 @@ void MainWindow::traceError(const QString &msg)
             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"
index bd483ed2dab1cb1a4149d5ec4b4f4d6b31cf190f..ae284410d5fa9ed6a525349af435a5f8738063ed 100644 (file)
@@ -19,6 +19,7 @@ class QModelIndex;
 class QProgressBar;
 class QUrl;
 class Retracer;
+class SearchWidget;
 class ShadersSourceWidget;
 class TraceProcess;
 class VertexDataInterpreter;
@@ -54,6 +55,9 @@ private slots:
     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();
@@ -86,6 +90,7 @@ private:
     ImageViewer *m_imageViewer;
 
     JumpWidget *m_jumpWidget;
+    SearchWidget *m_searchWidget;
 
     TraceProcess *m_traceProcess;
 };
index c5fc6f77ac859b8e3d1bc8411c41bfa35082f960..a989c425506c6ae89b66320a763d59d17e5d9015 100644 (file)
@@ -5,6 +5,8 @@
     <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>
diff --git a/gui/resources/go-down-search.png b/gui/resources/go-down-search.png
new file mode 100644 (file)
index 0000000..a1b1255
Binary files /dev/null and b/gui/resources/go-down-search.png differ
diff --git a/gui/resources/go-up-search.png b/gui/resources/go-up-search.png
new file mode 100644 (file)
index 0000000..80c32a4
Binary files /dev/null and b/gui/resources/go-up-search.png differ
diff --git a/gui/searchwidget.cpp b/gui/searchwidget.cpp
new file mode 100644 (file)
index 0000000..6f9bc94
--- /dev/null
@@ -0,0 +1,80 @@
+#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"
diff --git a/gui/searchwidget.h b/gui/searchwidget.h
new file mode 100644 (file)
index 0000000..d105303
--- /dev/null
@@ -0,0 +1,37 @@
+#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
diff --git a/gui/ui/searchwidget.ui b/gui/ui/searchwidget.ui
new file mode 100644 (file)
index 0000000..c13feac
--- /dev/null
@@ -0,0 +1,150 @@
+<?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>&lt;b&gt;Text not found&lt;/b&gt;</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>