Add auto-scroll feature for results pane

Change-Id: Iff209384c2bf30b3ce2b9241ce1c719a44592e65
Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
Christian Stenger
2015-04-16 08:54:41 +02:00
parent eeccdfbd54
commit 0afd504748
6 changed files with 256 additions and 264 deletions

View File

@@ -37,6 +37,7 @@
#include <QDebug> #include <QDebug>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QMenu> #include <QMenu>
#include <QScrollBar>
#include <QToolButton> #include <QToolButton>
#include <QVBoxLayout> #include <QVBoxLayout>
@@ -46,7 +47,8 @@ namespace Internal {
TestResultsPane::TestResultsPane(QObject *parent) : TestResultsPane::TestResultsPane(QObject *parent) :
Core::IOutputPane(parent), Core::IOutputPane(parent),
m_context(new Core::IContext(this)), m_context(new Core::IContext(this)),
m_wasVisibleBefore(false) m_wasVisibleBefore(false),
m_autoScroll(false)
{ {
m_outputWidget = new QWidget; m_outputWidget = new QWidget;
QVBoxLayout *outputLayout = new QVBoxLayout; QVBoxLayout *outputLayout = new QVBoxLayout;
@@ -144,6 +146,9 @@ TestResultsPane::~TestResultsPane()
void TestResultsPane::addTestResult(const TestResult &result) void TestResultsPane::addTestResult(const TestResult &result)
{ {
const QScrollBar *scrollBar = m_treeView->verticalScrollBar();
m_atEnd = scrollBar ? scrollBar->value() == scrollBar->maximum() : true;
m_model->addTestResult(result); m_model->addTestResult(result);
if (!m_treeView->isVisible()) if (!m_treeView->isVisible())
popup(Core::IOutputPane::NoModeSwitch); popup(Core::IOutputPane::NoModeSwitch);
@@ -181,6 +186,9 @@ void TestResultsPane::clearContents()
m_filterModel->clearTestResults(); m_filterModel->clearTestResults();
navigateStateChanged(); navigateStateChanged();
m_summaryWidget->setVisible(false); m_summaryWidget->setVisible(false);
m_autoScroll = AutotestPlugin::instance()->settings()->autoScroll;
connect(m_treeView->verticalScrollBar(), &QScrollBar::rangeChanged,
this, &TestResultsPane::onScrollBarRangeChanged, Qt::UniqueConnection);
} }
void TestResultsPane::visibilityChanged(bool visible) void TestResultsPane::visibilityChanged(bool visible)
@@ -381,6 +389,14 @@ void TestResultsPane::onTestRunFinished()
updateSummaryLabel(); updateSummaryLabel();
m_summaryWidget->setVisible(true); m_summaryWidget->setVisible(true);
m_model->removeCurrentTestMessage(); m_model->removeCurrentTestMessage();
disconnect(m_treeView->verticalScrollBar(), &QScrollBar::rangeChanged,
this, &TestResultsPane::onScrollBarRangeChanged);
}
void TestResultsPane::onScrollBarRangeChanged(int, int max)
{
if (m_autoScroll && m_atEnd)
m_treeView->verticalScrollBar()->setValue(max);
} }
void TestResultsPane::onTestTreeModelChanged() void TestResultsPane::onTestTreeModelChanged()

View File

@@ -88,6 +88,7 @@ private:
void createToolButtons(); void createToolButtons();
void onTestRunStarted(); void onTestRunStarted();
void onTestRunFinished(); void onTestRunFinished();
void onScrollBarRangeChanged(int, int max);
void onTestTreeModelChanged(); void onTestTreeModelChanged();
QWidget *m_outputWidget; QWidget *m_outputWidget;
@@ -103,6 +104,8 @@ private:
QToolButton *m_filterButton; QToolButton *m_filterButton;
QMenu *m_filterMenu; QMenu *m_filterMenu;
bool m_wasVisibleBefore; bool m_wasVisibleBefore;
bool m_autoScroll;
bool m_atEnd;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -30,11 +30,12 @@ static const char metricsKey[] = "Metrics";
static const char omitInternalKey[] = "OmitInternal"; static const char omitInternalKey[] = "OmitInternal";
static const char omitRunConfigWarnKey[] = "OmitRCWarnings"; static const char omitRunConfigWarnKey[] = "OmitRCWarnings";
static const char limitResultOutputKey[] = "LimitResultOutput"; static const char limitResultOutputKey[] = "LimitResultOutput";
static const char autoScrollKey[] = "AutoScrollResults";
static const int defaultTimeout = 60000; static const int defaultTimeout = 60000;
TestSettings::TestSettings() TestSettings::TestSettings()
: timeout(defaultTimeout), metrics(Walltime), omitInternalMssg(true), omitRunConfigWarn(false), : timeout(defaultTimeout), metrics(Walltime), omitInternalMssg(true), omitRunConfigWarn(false),
limitResultOutput(true) limitResultOutput(true), autoScroll(true)
{ {
} }
@@ -46,6 +47,7 @@ void TestSettings::toSettings(QSettings *s) const
s->setValue(QLatin1String(omitInternalKey), omitInternalMssg); s->setValue(QLatin1String(omitInternalKey), omitInternalMssg);
s->setValue(QLatin1String(omitRunConfigWarnKey), omitRunConfigWarn); s->setValue(QLatin1String(omitRunConfigWarnKey), omitRunConfigWarn);
s->setValue(QLatin1String(limitResultOutputKey), limitResultOutput); s->setValue(QLatin1String(limitResultOutputKey), limitResultOutput);
s->setValue(QLatin1String(autoScrollKey), autoScroll);
s->endGroup(); s->endGroup();
} }
@@ -75,6 +77,7 @@ void TestSettings::fromSettings(const QSettings *s)
omitInternalMssg = s->value(root + QLatin1String(omitInternalKey), true).toBool(); omitInternalMssg = s->value(root + QLatin1String(omitInternalKey), true).toBool();
omitRunConfigWarn = s->value(root + QLatin1String(omitRunConfigWarnKey), false).toBool(); omitRunConfigWarn = s->value(root + QLatin1String(omitRunConfigWarnKey), false).toBool();
limitResultOutput = s->value(root + QLatin1String(limitResultOutputKey), true).toBool(); limitResultOutput = s->value(root + QLatin1String(limitResultOutputKey), true).toBool();
autoScroll = s->value(root + QLatin1String(autoScrollKey), true).toBool();
} }
bool TestSettings::equals(const TestSettings &rhs) const bool TestSettings::equals(const TestSettings &rhs) const
@@ -82,7 +85,8 @@ bool TestSettings::equals(const TestSettings &rhs) const
return timeout == rhs.timeout && metrics == rhs.metrics return timeout == rhs.timeout && metrics == rhs.metrics
&& omitInternalMssg == rhs.omitInternalMssg && omitInternalMssg == rhs.omitInternalMssg
&& omitRunConfigWarn == rhs.omitRunConfigWarn && omitRunConfigWarn == rhs.omitRunConfigWarn
&& limitResultOutput == rhs.limitResultOutput; && limitResultOutput == rhs.limitResultOutput
&& autoScroll == rhs.autoScroll;
} }
QString TestSettings::metricsTypeToOption(const MetricsType type) QString TestSettings::metricsTypeToOption(const MetricsType type)

View File

@@ -50,6 +50,7 @@ struct TestSettings
bool omitInternalMssg; bool omitInternalMssg;
bool omitRunConfigWarn; bool omitRunConfigWarn;
bool limitResultOutput; bool limitResultOutput;
bool autoScroll;
}; };
inline bool operator==(const TestSettings &s1, const TestSettings &s2) { return s1.equals(s2); } inline bool operator==(const TestSettings &s1, const TestSettings &s2) { return s1.equals(s2); }

View File

@@ -42,6 +42,7 @@ void TestSettingsWidget::setSettings(const TestSettings &settings)
m_ui.omitInternalMsgCB->setChecked(settings.omitInternalMssg); m_ui.omitInternalMsgCB->setChecked(settings.omitInternalMssg);
m_ui.omitRunConfigWarnCB->setChecked(settings.omitRunConfigWarn); m_ui.omitRunConfigWarnCB->setChecked(settings.omitRunConfigWarn);
m_ui.limitResultOutputCB->setChecked(settings.limitResultOutput); m_ui.limitResultOutputCB->setChecked(settings.limitResultOutput);
m_ui.autoScrollCB->setChecked(settings.autoScroll);
switch (settings.metrics) { switch (settings.metrics) {
case MetricsType::Walltime: case MetricsType::Walltime:
@@ -71,6 +72,7 @@ TestSettings TestSettingsWidget::settings() const
result.omitInternalMssg = m_ui.omitInternalMsgCB->isChecked(); result.omitInternalMssg = m_ui.omitInternalMsgCB->isChecked();
result.omitRunConfigWarn = m_ui.omitRunConfigWarnCB->isChecked(); result.omitRunConfigWarn = m_ui.omitRunConfigWarnCB->isChecked();
result.limitResultOutput = m_ui.limitResultOutputCB->isChecked(); result.limitResultOutput = m_ui.limitResultOutputCB->isChecked();
result.autoScroll = m_ui.autoScrollCB->isChecked();
if (m_ui.walltimeRB->isChecked()) if (m_ui.walltimeRB->isChecked())
result.metrics = MetricsType::Walltime; result.metrics = MetricsType::Walltime;

View File

@@ -6,289 +6,255 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>463</width> <width>407</width>
<height>338</height> <height>228</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<widget class="QWidget" name="layoutWidget"> <layout class="QVBoxLayout" name="verticalLayout_5">
<property name="geometry"> <item>
<rect> <layout class="QHBoxLayout" name="horizontalLayout_2">
<x>9</x> <item>
<y>10</y> <widget class="QLabel" name="label">
<width>435</width> <property name="toolTip">
<height>307</height> <string>Timeout used when executing each test case.</string>
</rect> </property>
</property> <property name="text">
<layout class="QVBoxLayout" name="verticalLayout_4"> <string>Timeout:</string>
<item> </property>
<layout class="QHBoxLayout" name="horizontalLayout_3"> </widget>
<item> </item>
<layout class="QVBoxLayout" name="verticalLayout_2"> <item>
<item> <widget class="QSpinBox" name="timeoutSpin">
<layout class="QHBoxLayout" name="horizontalLayout"> <property name="toolTip">
<string>Timeout used when executing test cases. This will apply for each test case on its own, not the whole project.</string>
</property>
<property name="suffix">
<string> s</string>
</property>
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>36000</number>
</property>
<property name="value">
<number>60</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Benchmark Metrics</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item> <item>
<widget class="QLabel" name="label"> <widget class="QRadioButton" name="walltimeRB">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip"> <property name="toolTip">
<string>Timeout used when executing each test case.</string> <string>Uses walltime metrics for executing benchmarks (default).</string>
</property> </property>
<property name="text"> <property name="text">
<string>Timeout:</string> <string>Walltime</string>
</property>
<property name="checked">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QSpinBox" name="timeoutSpin"> <widget class="QRadioButton" name="tickcounterRB">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip"> <property name="toolTip">
<string>Timeout used when executing test cases. This will apply for each test case on its own, not the whole project.</string> <string>Uses tick counter when executing benchmarks.</string>
</property> </property>
<property name="suffix"> <property name="text">
<string> s</string> <string>Tick counter</string>
</property> </property>
<property name="minimum"> </widget>
<number>5</number> </item>
<item>
<widget class="QRadioButton" name="eventCounterRB">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="maximum"> <property name="toolTip">
<number>36000</number> <string>Uses event counter when executing benchmarks.</string>
</property> </property>
<property name="value"> <property name="text">
<number>60</number> <string>Event counter</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="callgrindRB">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Uses Valgrind Callgrind when executing benchmarks (it must be installed).</string>
</property>
<property name="text">
<string>Callgrind</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="perfRB">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Uses Perf when executing benchmarks (it must be installed).</string>
</property>
<property name="text">
<string>Perf</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </widget>
</layout> </item>
</item> <item>
<item> <spacer name="verticalSpacer_2">
<spacer name="horizontalSpacer_3"> <property name="orientation">
<property name="orientation"> <enum>Qt::Vertical</enum>
<enum>Qt::Horizontal</enum> </property>
</property> <property name="sizeHint" stdset="0">
<property name="sizeType"> <size>
<enum>QSizePolicy::Fixed</enum> <width>20</width>
</property> <height>40</height>
<property name="sizeHint" stdset="0"> </size>
<size> </property>
<width>40</width> </spacer>
<height>20</height> </item>
</size> </layout>
</property> </item>
</spacer> <item>
</item> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_3"> <widget class="QGroupBox" name="groupBox_2">
<item> <property name="title">
<widget class="QCheckBox" name="omitInternalMsgCB"> <string>General</string>
<property name="toolTip"> </property>
<string>Hides internal messages by default. You can still enable them by using the test results filter.</string> <layout class="QVBoxLayout" name="verticalLayout">
</property> <item>
<property name="text"> <widget class="QCheckBox" name="omitInternalMsgCB">
<string>Omit internal messages</string> <property name="toolTip">
</property> <string>Hides internal messages by default. You can still enable them by using the test results filter.</string>
<property name="checked"> </property>
<bool>true</bool> <property name="text">
</property> <string>Omit internal messages</string>
</widget> </property>
</item> <property name="checked">
<item> <bool>true</bool>
<widget class="QCheckBox" name="omitRunConfigWarnCB"> </property>
<property name="toolTip"> </widget>
<string>Hides warnings related to a guessed run configuration.</string> </item>
</property> <item>
<property name="text"> <widget class="QCheckBox" name="omitRunConfigWarnCB">
<string>Omit run configuration warnings</string> <property name="toolTip">
</property> <string>Hides warnings related to a guessed run configuration.</string>
</widget> </property>
</item> <property name="text">
<item> <string>Omit run configuration warnings</string>
<widget class="QCheckBox" name="limitResultOutputCB"> </property>
<property name="toolTip"> </widget>
<string>Limit result output to 100000 characters.</string> </item>
</property> <item>
<property name="text"> <widget class="QCheckBox" name="limitResultOutputCB">
<string>Limit result output</string> <property name="toolTip">
</property> <string>Limit result output to 100000 characters.</string>
<property name="checked"> </property>
<bool>true</bool> <property name="text">
</property> <string>Limit result output</string>
</widget> </property>
</item> <property name="checked">
</layout> <bool>true</bool>
</item> </property>
<item> </widget>
<spacer name="horizontalSpacer"> </item>
<property name="orientation"> <item>
<enum>Qt::Horizontal</enum> <widget class="QCheckBox" name="autoScrollCB">
</property> <property name="toolTip">
<property name="sizeHint" stdset="0"> <string>Automatically scroll down when new items are added and scrollbar is at bottom.</string>
<size> </property>
<width>40</width> <property name="text">
<height>20</height> <string>Automatically scroll results</string>
</size> </property>
</property> <property name="checked">
</spacer> <bool>true</bool>
</item> </property>
</layout> </widget>
</item> </item>
<item> </layout>
<spacer name="verticalSpacer"> </widget>
<property name="orientation"> </item>
<enum>Qt::Vertical</enum> <item>
</property> <spacer name="verticalSpacer">
<property name="sizeType"> <property name="orientation">
<enum>QSizePolicy::Fixed</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>20</height> <height>40</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
<item> </layout>
<layout class="QHBoxLayout" name="horizontalLayout_4"> </item>
<item> </layout>
<widget class="QGroupBox" name="groupBox"> </item>
<property name="sizePolicy"> </layout>
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Benchmark Metrics</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="walltimeRB">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Uses walltime metrics for executing benchmarks (default).</string>
</property>
<property name="text">
<string>Walltime</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="tickcounterRB">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Uses tick counter when executing benchmarks.</string>
</property>
<property name="text">
<string>Tick counter</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="eventCounterRB">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Uses event counter when executing benchmarks.</string>
</property>
<property name="text">
<string>Event counter</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="callgrindRB">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Uses Valgrind Callgrind when executing benchmarks (it must be installed).</string>
</property>
<property name="text">
<string>Callgrind</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="perfRB">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Uses Perf when executing benchmarks (it must be installed).</string>
</property>
<property name="text">
<string>Perf</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget> </widget>
<resources/> <resources/>
<connections/> <connections/>