forked from qt-creator/qt-creator
AutoTest: Display results duration if possible
Some test frameworks provide duration information and we gather and display them rather hidden. Display duration of the test execution more prominent if it is available and the user has not turned off feature. Task-number: QTCREATORBUG-31242 Change-Id: I27641a5f811299e5876cce9e4739078fe3c2ae19 Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -28,12 +28,12 @@ GTestOutputReader::GTestOutputReader(Process *testApplication,
|
|||||||
void GTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
void GTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
||||||
{
|
{
|
||||||
static const QRegularExpression newTestStarts("^\\[-{10}\\] \\d+ tests? from (.*)$");
|
static const QRegularExpression newTestStarts("^\\[-{10}\\] \\d+ tests? from (.*)$");
|
||||||
static const QRegularExpression testEnds("^\\[-{10}\\] \\d+ tests? from (.*) \\((.*)\\)$");
|
static const QRegularExpression testEnds("^\\[-{10}\\] \\d+ tests? from (.*) \\(((\\d+) .*)\\)$");
|
||||||
static const QRegularExpression newTestSetStarts("^\\[ RUN \\] (.*)$");
|
static const QRegularExpression newTestSetStarts("^\\[ RUN \\] (.*)$");
|
||||||
static const QRegularExpression testSetSuccess("^\\[ OK \\] (.*) \\((.*)\\)$");
|
static const QRegularExpression testSetSuccess("^\\[ OK \\] (.*) \\((.*)\\)$");
|
||||||
static const QRegularExpression testSetFail("^\\[ FAILED \\] (.*) \\((\\d+ ms)\\)$");
|
static const QRegularExpression testSetFail("^\\[ FAILED \\] (.*) \\(((\\d+) ms)\\)$");
|
||||||
static const QRegularExpression testDeath("^\\[ DEATH \\] (.*)$");
|
static const QRegularExpression testDeath("^\\[ DEATH \\] (.*)$");
|
||||||
static const QRegularExpression testSetSkipped("^\\[ SKIPPED \\] (.*) \\((\\d+ ms)\\)$");
|
static const QRegularExpression testSetSkipped("^\\[ SKIPPED \\] (.*) \\(((\\d+) ms)\\)$");
|
||||||
static const QRegularExpression disabledTests("^ YOU HAVE (\\d+) DISABLED TESTS?$");
|
static const QRegularExpression disabledTests("^ YOU HAVE (\\d+) DISABLED TESTS?$");
|
||||||
static const QRegularExpression iterations("^Repeating all tests "
|
static const QRegularExpression iterations("^Repeating all tests "
|
||||||
"\\(iteration (\\d+)\\) \\. \\. \\.$");
|
"\\(iteration (\\d+)\\) \\. \\. \\.$");
|
||||||
@@ -70,6 +70,7 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
TestResult testResult = createDefaultResult();
|
TestResult testResult = createDefaultResult();
|
||||||
testResult.setResult(ResultType::TestEnd);
|
testResult.setResult(ResultType::TestEnd);
|
||||||
testResult.setDescription(Tr::tr("Test execution took %1.").arg(match.captured(2)));
|
testResult.setDescription(Tr::tr("Test execution took %1.").arg(match.captured(2)));
|
||||||
|
testResult.setDuration(match.captured(3));
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
m_currentTestSuite.clear();
|
m_currentTestSuite.clear();
|
||||||
m_currentTestCase.clear();
|
m_currentTestCase.clear();
|
||||||
@@ -102,6 +103,7 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
testResult = createDefaultResult();
|
testResult = createDefaultResult();
|
||||||
testResult.setResult(ResultType::MessageInternal);
|
testResult.setResult(ResultType::MessageInternal);
|
||||||
testResult.setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
|
testResult.setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
|
||||||
|
testResult.setDuration(match.captured(3));
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
// TODO: bump progress?
|
// TODO: bump progress?
|
||||||
} else if (ExactMatch match = testSetFail.match(line)) {
|
} else if (ExactMatch match = testSetFail.match(line)) {
|
||||||
@@ -127,6 +129,7 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
testResult = createDefaultResult();
|
testResult = createDefaultResult();
|
||||||
testResult.setResult(ResultType::MessageInternal);
|
testResult.setResult(ResultType::MessageInternal);
|
||||||
testResult.setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
|
testResult.setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
|
||||||
|
testResult.setDuration(match.captured(3));
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
} else if (ExactMatch match = logging.match(line)) {
|
} else if (ExactMatch match = logging.match(line)) {
|
||||||
const QString severity = match.captured(1).trimmed();
|
const QString severity = match.captured(1).trimmed();
|
||||||
|
@@ -475,6 +475,8 @@ void QtTestOutputReader::sendCompleteInformation()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
testResult.setDescription(m_description);
|
testResult.setDescription(m_description);
|
||||||
|
if (!m_duration.isEmpty())
|
||||||
|
testResult.setDuration(m_duration);
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,6 +512,7 @@ void QtTestOutputReader::sendFinishMessage(bool isFunction)
|
|||||||
if (!m_duration.isEmpty()) {
|
if (!m_duration.isEmpty()) {
|
||||||
result.setDescription(isFunction ? Tr::tr("Execution took %1 ms.").arg(m_duration)
|
result.setDescription(isFunction ? Tr::tr("Execution took %1 ms.").arg(m_duration)
|
||||||
: Tr::tr("Test execution took %1 ms.").arg(m_duration));
|
: Tr::tr("Test execution took %1 ms.").arg(m_duration));
|
||||||
|
result.setDuration(m_duration);
|
||||||
} else {
|
} else {
|
||||||
result.setDescription(isFunction ? Tr::tr("Test function finished.")
|
result.setDescription(isFunction ? Tr::tr("Test function finished.")
|
||||||
: Tr::tr("Test finished."));
|
: Tr::tr("Test finished."));
|
||||||
|
@@ -96,11 +96,13 @@ public:
|
|||||||
QString description() const { return m_description; }
|
QString description() const { return m_description; }
|
||||||
Utils::FilePath fileName() const { return m_file; }
|
Utils::FilePath fileName() const { return m_file; }
|
||||||
int line() const { return m_line; }
|
int line() const { return m_line; }
|
||||||
|
std::optional<QString> duration() const { return m_duration; }
|
||||||
QVariant extraData() const { return m_hooks.extraData; }
|
QVariant extraData() const { return m_hooks.extraData; }
|
||||||
|
|
||||||
void setDescription(const QString &description) { m_description = description; }
|
void setDescription(const QString &description) { m_description = description; }
|
||||||
void setFileName(const Utils::FilePath &fileName) { m_file = fileName; }
|
void setFileName(const Utils::FilePath &fileName) { m_file = fileName; }
|
||||||
void setLine(int line) { m_line = line; }
|
void setLine(int line) { m_line = line; }
|
||||||
|
void setDuration(const QString &milliSeconds) { m_duration.emplace(milliSeconds); }
|
||||||
void setResult(ResultType type) { m_result = type; }
|
void setResult(ResultType type) { m_result = type; }
|
||||||
|
|
||||||
static ResultType resultFromString(const QString &resultString);
|
static ResultType resultFromString(const QString &resultString);
|
||||||
@@ -114,6 +116,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<QString> m_id = {};
|
std::optional<QString> m_id = {};
|
||||||
|
std::optional<QString> m_duration;
|
||||||
QString m_name;
|
QString m_name;
|
||||||
ResultType m_result = ResultType::Invalid; // the real result..
|
ResultType m_result = ResultType::Invalid; // the real result..
|
||||||
QString m_description;
|
QString m_description;
|
||||||
|
@@ -49,7 +49,7 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
|||||||
painter->fillRect(opt.rect, background);
|
painter->fillRect(opt.rect, background);
|
||||||
painter->setPen(foreground);
|
painter->setPen(foreground);
|
||||||
|
|
||||||
const LayoutPositions positions(opt, resultFilterModel);
|
const LayoutPositions positions(opt, resultFilterModel, m_showDuration);
|
||||||
const TestResult testResult = resultFilterModel->testResult(index);
|
const TestResult testResult = resultFilterModel->testResult(index);
|
||||||
QTC_ASSERT(testResult.isValid(), painter->restore(); return);
|
QTC_ASSERT(testResult.isValid(), painter->restore(); return);
|
||||||
|
|
||||||
@@ -90,6 +90,16 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
|||||||
fm.elidedText(output.left(2000), Qt::ElideRight, positions.textAreaWidth()));
|
fm.elidedText(output.left(2000), Qt::ElideRight, positions.textAreaWidth()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (testResult.result() == ResultType::TestStart && m_showDuration && testResult.duration()) {
|
||||||
|
const QString txt = testResult.duration().value() + " ms";
|
||||||
|
QPen tmp = painter->pen();
|
||||||
|
painter->setPen(opt.palette.mid().color());
|
||||||
|
painter->setClipRect(positions.durationArea());
|
||||||
|
option.widget->style()->drawItemText(painter, positions.durationArea(), Qt::AlignRight,
|
||||||
|
opt.palette, true, txt);
|
||||||
|
painter->setPen(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
const QString file = testResult.fileName().fileName();
|
const QString file = testResult.fileName().fileName();
|
||||||
painter->setClipRect(positions.fileArea());
|
painter->setClipRect(positions.fileArea());
|
||||||
painter->drawText(positions.fileAreaLeft(), positions.top() + fm.ascent(), file);
|
painter->drawText(positions.fileAreaLeft(), positions.top() + fm.ascent(), file);
|
||||||
@@ -119,7 +129,7 @@ QSize TestResultDelegate::sizeHint(const QStyleOptionViewItem &option, const QMo
|
|||||||
QFontMetrics fm(opt.font);
|
QFontMetrics fm(opt.font);
|
||||||
int fontHeight = fm.height();
|
int fontHeight = fm.height();
|
||||||
TestResultFilterModel *resultFilterModel = static_cast<TestResultFilterModel *>(view->model());
|
TestResultFilterModel *resultFilterModel = static_cast<TestResultFilterModel *>(view->model());
|
||||||
LayoutPositions positions(opt, resultFilterModel);
|
LayoutPositions positions(opt, resultFilterModel, m_showDuration);
|
||||||
const int depth = resultFilterModel->itemForIndex(index)->level() + 1;
|
const int depth = resultFilterModel->itemForIndex(index)->level() + 1;
|
||||||
const int indentation = depth * view->style()->pixelMetric(QStyle::PM_TreeViewIndentation, &opt);
|
const int indentation = depth * view->style()->pixelMetric(QStyle::PM_TreeViewIndentation, &opt);
|
||||||
|
|
||||||
|
@@ -21,6 +21,7 @@ public:
|
|||||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||||
void clearCache();
|
void clearCache();
|
||||||
|
void setShowDuration(bool showDuration) { m_showDuration = showDuration; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void limitTextOutput(QString &output) const;
|
void limitTextOutput(QString &output) const;
|
||||||
@@ -32,43 +33,57 @@ private:
|
|||||||
mutable QTextLayout m_lastCalculatedLayout;
|
mutable QTextLayout m_lastCalculatedLayout;
|
||||||
mutable int m_lastCalculatedHeight = 0;
|
mutable int m_lastCalculatedHeight = 0;
|
||||||
mutable int m_lastWidth = -1;
|
mutable int m_lastWidth = -1;
|
||||||
|
bool m_showDuration = true;
|
||||||
|
|
||||||
class LayoutPositions
|
class LayoutPositions
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LayoutPositions(QStyleOptionViewItem &options, const TestResultFilterModel *filterModel)
|
LayoutPositions(QStyleOptionViewItem &options, const TestResultFilterModel *filterModel,
|
||||||
|
bool showDuration)
|
||||||
: m_top(options.rect.top()),
|
: m_top(options.rect.top()),
|
||||||
m_left(options.rect.left()),
|
m_left(options.rect.left()),
|
||||||
m_right(options.rect.right())
|
m_right(options.rect.right()),
|
||||||
|
m_showDuration(showDuration)
|
||||||
{
|
{
|
||||||
TestResultModel *srcModel = static_cast<TestResultModel *>(filterModel->sourceModel());
|
TestResultModel *srcModel = static_cast<TestResultModel *>(filterModel->sourceModel());
|
||||||
m_maxFileLength = srcModel->maxWidthOfFileName(options.font);
|
m_maxFileLength = srcModel->maxWidthOfFileName(options.font);
|
||||||
m_maxLineLength = srcModel->maxWidthOfLineNumber(options.font);
|
m_maxLineLength = srcModel->maxWidthOfLineNumber(options.font);
|
||||||
m_realFileLength = m_maxFileLength;
|
m_realFileLength = m_maxFileLength;
|
||||||
m_typeAreaWidth = QFontMetrics(options.font).horizontalAdvance("XXXXXXXX");
|
m_typeAreaWidth = QFontMetrics(options.font).horizontalAdvance("XXXXXXXX");
|
||||||
|
m_durationAreaWidth = QFontMetrics(options.font).horizontalAdvance("XXXXXXXX ms");
|
||||||
|
|
||||||
int flexibleArea = lineAreaLeft() - textAreaLeft() - ITEM_SPACING;
|
int flexibleArea = (m_showDuration ? durationAreaLeft() : fileAreaLeft())
|
||||||
|
- textAreaLeft() - ItemSpacing;
|
||||||
if (m_maxFileLength > flexibleArea / 2)
|
if (m_maxFileLength > flexibleArea / 2)
|
||||||
m_realFileLength = flexibleArea / 2;
|
m_realFileLength = flexibleArea / 2;
|
||||||
m_fontHeight = QFontMetrics(options.font).height();
|
m_fontHeight = QFontMetrics(options.font).height();
|
||||||
}
|
}
|
||||||
|
|
||||||
int top() const { return m_top + ITEM_MARGIN; }
|
int top() const { return m_top + ItemMargin; }
|
||||||
int left() const { return m_left + ITEM_MARGIN; }
|
int left() const { return m_left + ItemMargin; }
|
||||||
int right() const { return m_right - ITEM_MARGIN; }
|
int right() const { return m_right - ItemMargin; }
|
||||||
int minimumHeight() const { return ICON_SIZE + 2 * ITEM_MARGIN; }
|
int minimumHeight() const { return IconSize + 2 * ItemMargin; }
|
||||||
|
|
||||||
int iconSize() const { return ICON_SIZE; }
|
int iconSize() const { return IconSize; }
|
||||||
int typeAreaLeft() const { return left() + ICON_SIZE + ITEM_SPACING; }
|
int typeAreaLeft() const { return left() + IconSize + ItemSpacing; }
|
||||||
int textAreaLeft() const { return typeAreaLeft() + m_typeAreaWidth + ITEM_SPACING; }
|
int textAreaLeft() const { return typeAreaLeft() + m_typeAreaWidth + ItemSpacing; }
|
||||||
int textAreaWidth() const { return fileAreaLeft() - ITEM_SPACING - textAreaLeft(); }
|
int textAreaWidth() const
|
||||||
int fileAreaLeft() const { return lineAreaLeft() - ITEM_SPACING - m_realFileLength; }
|
{
|
||||||
|
if (m_showDuration)
|
||||||
|
return durationAreaLeft() - 3 * ItemSpacing - textAreaLeft();
|
||||||
|
return fileAreaLeft() - ItemSpacing - textAreaLeft();
|
||||||
|
}
|
||||||
|
int durationAreaLeft() const { return fileAreaLeft() - 3 * ItemSpacing - m_durationAreaWidth; }
|
||||||
|
int durationAreaWidth() const { return m_durationAreaWidth; }
|
||||||
|
int fileAreaLeft() const { return lineAreaLeft() - ItemSpacing - m_realFileLength; }
|
||||||
int lineAreaLeft() const { return right() - m_maxLineLength; }
|
int lineAreaLeft() const { return right() - m_maxLineLength; }
|
||||||
|
|
||||||
QRect textArea() const { return QRect(textAreaLeft(), top(),
|
QRect textArea() const { return QRect(textAreaLeft(), top(),
|
||||||
textAreaWidth(), m_fontHeight); }
|
textAreaWidth(), m_fontHeight); }
|
||||||
|
QRect durationArea() const { return QRect(durationAreaLeft(), top(),
|
||||||
|
durationAreaWidth(), m_fontHeight); }
|
||||||
QRect fileArea() const { return QRect(fileAreaLeft(), top(),
|
QRect fileArea() const { return QRect(fileAreaLeft(), top(),
|
||||||
m_realFileLength + ITEM_SPACING, m_fontHeight); }
|
m_realFileLength + ItemSpacing, m_fontHeight); }
|
||||||
|
|
||||||
QRect lineArea() const { return QRect(lineAreaLeft(), top(),
|
QRect lineArea() const { return QRect(lineAreaLeft(), top(),
|
||||||
m_maxLineLength, m_fontHeight); }
|
m_maxLineLength, m_fontHeight); }
|
||||||
@@ -82,10 +97,12 @@ private:
|
|||||||
int m_right;
|
int m_right;
|
||||||
int m_fontHeight;
|
int m_fontHeight;
|
||||||
int m_typeAreaWidth;
|
int m_typeAreaWidth;
|
||||||
|
int m_durationAreaWidth;
|
||||||
|
bool m_showDuration;
|
||||||
|
|
||||||
static const int ICON_SIZE = 16;
|
static constexpr int IconSize = 16;
|
||||||
static const int ITEM_MARGIN = 2;
|
static constexpr int ItemMargin = 2;
|
||||||
static const int ITEM_SPACING = 4;
|
static constexpr int ItemSpacing = 4;
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@@ -117,12 +117,16 @@ static bool isSignificant(ResultType type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TestResultItem::updateResult(bool &changed, ResultType addedChildType,
|
void TestResultItem::updateResult(bool &changed, ResultType addedChildType,
|
||||||
const std::optional<SummaryEvaluation> &summary)
|
const std::optional<SummaryEvaluation> &summary,
|
||||||
|
const std::optional<QString> duration)
|
||||||
{
|
{
|
||||||
changed = false;
|
changed = false;
|
||||||
if (m_testResult.result() != ResultType::TestStart)
|
if (m_testResult.result() != ResultType::TestStart)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (addedChildType == ResultType::TestEnd && duration)
|
||||||
|
m_testResult.setDuration(*duration);
|
||||||
|
|
||||||
if (!isSignificant(addedChildType) || (addedChildType == ResultType::TestStart && !summary))
|
if (!isSignificant(addedChildType) || (addedChildType == ResultType::TestStart && !summary))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -244,7 +248,8 @@ void TestResultModel::updateParent(const TestResultItem *item)
|
|||||||
if (parentItem == rootItem()) // do not update invisible root item
|
if (parentItem == rootItem()) // do not update invisible root item
|
||||||
return;
|
return;
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
parentItem->updateResult(changed, item->testResult().result(), item->summaryResult());
|
parentItem->updateResult(changed, item->testResult().result(), item->summaryResult(),
|
||||||
|
item->testResult().duration());
|
||||||
bool changedType = parentItem->updateDescendantTypes(item->testResult().result());
|
bool changedType = parentItem->updateDescendantTypes(item->testResult().result());
|
||||||
if (!changed && !changedType)
|
if (!changed && !changedType)
|
||||||
return;
|
return;
|
||||||
|
@@ -37,7 +37,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void updateResult(bool &changed, ResultType addedChildType,
|
void updateResult(bool &changed, ResultType addedChildType,
|
||||||
const std::optional<SummaryEvaluation> &summary);
|
const std::optional<SummaryEvaluation> &summary,
|
||||||
|
const std::optional<QString> duration);
|
||||||
|
|
||||||
TestResultItem *intermediateFor(const TestResultItem *item) const;
|
TestResultItem *intermediateFor(const TestResultItem *item) const;
|
||||||
TestResultItem *createAndAddIntermediateFor(const TestResultItem *child);
|
TestResultItem *createAndAddIntermediateFor(const TestResultItem *child);
|
||||||
|
@@ -213,6 +213,22 @@ void TestResultsPane::createToolButtons()
|
|||||||
m_outputToggleButton->setToolTip(Tr::tr("Switch Between Visual and Text Display"));
|
m_outputToggleButton->setToolTip(Tr::tr("Switch Between Visual and Text Display"));
|
||||||
m_outputToggleButton->setEnabled(true);
|
m_outputToggleButton->setEnabled(true);
|
||||||
connect(m_outputToggleButton, &QToolButton::clicked, this, &TestResultsPane::toggleOutputStyle);
|
connect(m_outputToggleButton, &QToolButton::clicked, this, &TestResultsPane::toggleOutputStyle);
|
||||||
|
m_showDurationButton = new QToolButton(m_treeView);
|
||||||
|
auto icon = Utils::Icon({{":/utils/images/stopwatch.png", Utils::Theme::IconsBaseColor}});
|
||||||
|
m_showDurationButton->setIcon(icon.icon());
|
||||||
|
m_showDurationButton->setToolTip(Tr::tr("Show Durations"));
|
||||||
|
m_showDurationButton->setCheckable(true);
|
||||||
|
m_showDurationButton->setChecked(true);
|
||||||
|
connect(m_showDurationButton, &QToolButton::toggled, this, [this](bool checked) {
|
||||||
|
if (auto trd = qobject_cast<TestResultDelegate *>(m_treeView->itemDelegate())) {
|
||||||
|
trd->setShowDuration(checked);
|
||||||
|
if (auto rowCount = m_model->rowCount()) {
|
||||||
|
QModelIndex tl = m_model->index(0, 0);
|
||||||
|
QModelIndex br = m_model->index(rowCount - 1, 0);
|
||||||
|
emit m_model->dataChanged(tl, br, {Qt::DisplayRole});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static TestResultsPane *s_instance = nullptr;
|
static TestResultsPane *s_instance = nullptr;
|
||||||
@@ -272,7 +288,8 @@ QWidget *TestResultsPane::outputWidget(QWidget *parent)
|
|||||||
QList<QWidget *> TestResultsPane::toolBarWidgets() const
|
QList<QWidget *> TestResultsPane::toolBarWidgets() const
|
||||||
{
|
{
|
||||||
QList<QWidget *> result = {m_expandCollapse, m_runAll, m_runSelected, m_runFailed,
|
QList<QWidget *> result = {m_expandCollapse, m_runAll, m_runSelected, m_runFailed,
|
||||||
m_runFile, m_stopTestRun, m_outputToggleButton, m_filterButton};
|
m_runFile, m_stopTestRun, m_showDurationButton,
|
||||||
|
m_outputToggleButton, m_filterButton};
|
||||||
for (QWidget *widget : IOutputPane::toolBarWidgets())
|
for (QWidget *widget : IOutputPane::toolBarWidgets())
|
||||||
result.append(widget);
|
result.append(widget);
|
||||||
return result;
|
return result;
|
||||||
|
@@ -115,6 +115,7 @@ private:
|
|||||||
QToolButton *m_stopTestRun;
|
QToolButton *m_stopTestRun;
|
||||||
QToolButton *m_filterButton;
|
QToolButton *m_filterButton;
|
||||||
QToolButton *m_outputToggleButton;
|
QToolButton *m_outputToggleButton;
|
||||||
|
QToolButton *m_showDurationButton;
|
||||||
Core::OutputWindow *m_textOutput;
|
Core::OutputWindow *m_textOutput;
|
||||||
QMenu *m_filterMenu;
|
QMenu *m_filterMenu;
|
||||||
bool m_autoScroll = false;
|
bool m_autoScroll = false;
|
||||||
|
Reference in New Issue
Block a user