QmlProfiler: add functionality to search for notes

Added a text field to search for notes within the timeline's events.

Task-number: QTCREATORBUG-13417
Change-Id: Ic121ec8ade42b1ef99d5da13d1f732761d244327
Reviewed-by: Ulf Hermann <ulf.hermann@theqtcompany.com>
This commit is contained in:
Joerg Bornemann
2015-01-30 16:52:11 +01:00
parent 4caee9fcbf
commit 1d14dbf1aa
7 changed files with 111 additions and 0 deletions

View File

@@ -71,6 +71,7 @@
#include <QFileDialog>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QMessageBox>
#include <QTcpServer>
@@ -108,6 +109,12 @@ public:
QTime m_recordingElapsedTime;
QLabel *m_timeLabel;
// search field
QToolButton *m_searchButton;
QLineEdit *m_searchField;
QTimer *m_searchFieldTimer;
int m_lastSearchResult;
// save and load actions
QAction *m_saveQmlTrace;
QAction *m_loadQmlTrace;
@@ -126,6 +133,10 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
d->m_featuresMenu = 0;
d->m_clearButton = 0;
d->m_timeLabel = 0;
d->m_searchButton = 0;
d->m_searchField = 0;
d->m_searchFieldTimer = 0;
d->m_lastSearchResult = -1;
d->m_profilerState = new QmlProfilerStateManager(this);
connect(d->m_profilerState, SIGNAL(stateChanged()), this, SLOT(profilerStateChanged()));
@@ -285,6 +296,32 @@ QWidget *QmlProfilerTool::createWidgets()
updateTimeDisplay();
layout->addWidget(d->m_timeLabel);
d->m_searchButton = new QToolButton;
d->m_searchButton->setIcon(QIcon(QStringLiteral(":/timeline/ico_zoom.png")));
d->m_searchButton->setToolTip(tr("Toggle the event search field."));
d->m_searchButton->setCheckable(true);
layout->addWidget(d->m_searchButton);
d->m_searchField = new QLineEdit;
d->m_searchField->setToolTip(tr("Find events that have a specific note."));
d->m_searchField->hide();
layout->addWidget(d->m_searchField);
connect(d->m_searchButton, &QToolButton::toggled, [this] (bool checked) {
d->m_searchField->setVisible(checked);
if (checked) {
d->m_searchButton->setText(d->m_searchButton->text() + QLatin1Char(':'));
d->m_searchField->setFocus();
d->m_searchField->selectAll();
} else {
QString str = d->m_searchButton->text();
str.chop(1);
d->m_searchButton->setText(str);
}
});
connect(d->m_searchField, &QLineEdit::returnPressed, this, &QmlProfilerTool::findEvent);
layout->addStretch();
toolbarWidget->setLayout(layout);
// When the widgets are requested we assume that the session data
@@ -399,6 +436,45 @@ void QmlProfilerTool::updateTimeDisplay()
d->m_timeLabel->setText(tr("Elapsed: %1").arg(profilerTimeStr));
}
void QmlProfilerTool::findEvent()
{
const QString substr = d->m_searchField->text();
QmlProfilerNotesModel *model = d->m_profilerModelManager->notesModel();
bool found = false;
forever {
for (int i = d->m_lastSearchResult + 1; i < model->count(); ++i) {
if (model->text(i).contains(substr)) {
d->m_lastSearchResult = i;
found = true;
break;
}
}
if (found || d->m_lastSearchResult == -1)
break;
d->m_lastSearchResult = -1;
}
if (found) {
emit selectTimelineElement(model->timelineModel(d->m_lastSearchResult),
model->timelineIndex(d->m_lastSearchResult));
d->m_searchField->setFocus();
} else {
QPalette p = d->m_searchField->palette();
p.setColor(QPalette::Text, Qt::red);
d->m_searchField->setPalette(p);
if (!d->m_searchFieldTimer) {
d->m_searchFieldTimer = new QTimer(this);
connect(d->m_searchFieldTimer, &QTimer::timeout, [this] () {
d->m_searchField->setPalette(d->m_searchField->parentWidget()->palette());
});
}
if (d->m_searchFieldTimer->isActive())
d->m_searchFieldTimer->stop();
d->m_searchFieldTimer->start(1500);
}
}
void QmlProfilerTool::clearData()
{
d->m_profilerModelManager->clear();

View File

@@ -65,6 +65,9 @@ public:
static void logError(const QString &msg);
static void showNonmodalWarning(const QString &warningMsg);
signals:
void selectTimelineElement(int modelId, int eventIndex);
public slots:
void profilerStateChanged();
void clientRecordingChanged();
@@ -82,6 +85,7 @@ private slots:
void showErrorDialog(const QString &error);
void profilerDataModelStateChanged();
void updateTimeDisplay();
void findEvent();
void showSaveOption();
void showLoadOption();

View File

@@ -123,6 +123,8 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, Analyzer::IAnalyzerT
d->m_modelProxy = new Timeline::TimelineModelAggregator(modelManager->notesModel(), this);
d->m_modelManager = modelManager;
connect(qobject_cast<QmlProfilerTool *>(profilerTool), &QmlProfilerTool::selectTimelineElement,
this, &QmlProfilerTraceView::selectByEventIndex);
connect(modelManager,SIGNAL(dataAvailable()), d->m_modelProxy,SIGNAL(dataAvailable()));
// external models pushed on top
@@ -218,6 +220,19 @@ void QmlProfilerTraceView::selectBySourceLocation(const QString &filename, int l
}
}
void QmlProfilerTraceView::selectByEventIndex(int modelId, int eventIndex)
{
QQuickItem *rootObject = d->m_mainView->rootObject();
if (!rootObject)
return;
const int modelIndex = d->m_modelProxy->modelIndexById(modelId);
QTC_ASSERT(modelIndex != -1, return);
QMetaObject::invokeMethod(rootObject, "selectByIndices",
Q_ARG(QVariant, QVariant(modelIndex)),
Q_ARG(QVariant, QVariant(eventIndex)));
}
/////////////////////////////////////////////////////////
// Goto source location
void QmlProfilerTraceView::updateCursorPosition()

View File

@@ -65,6 +65,7 @@ public slots:
void clear();
void selectByTypeId(int typeId);
void selectBySourceLocation(const QString &filename, int line, int column);
void selectByEventIndex(int modelId, int eventIndex);
private slots:
void updateCursorPosition();