Commit 292b4847 authored by Christian Stenger's avatar Christian Stenger
Browse files

Add capability to store/copy output from results pane



Change-Id: Ie32a374cac851009df3d2289f471bbb697788198
Reviewed-by: default avatarRiitta-Leena Miettinen <riitta-leena.miettinen@theqtcompany.com>
Reviewed-by: default avatarDavid Schulz <david.schulz@theqtcompany.com>
Reviewed-by: default avatarNiels Weber <niels.weber@theqtcompany.com>
parent 0d114c60
......@@ -28,15 +28,19 @@
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <texteditor/texteditor.h>
#include <utils/itemviews.h>
#include <utils/theme/theme.h>
#include <QApplication>
#include <QClipboard>
#include <QDebug>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QMenu>
#include <QMessageBox>
#include <QScrollBar>
#include <QToolButton>
#include <QVBoxLayout>
......@@ -44,11 +48,24 @@
namespace Autotest {
namespace Internal {
ResultsTreeView::ResultsTreeView(QWidget *parent)
: Utils::TreeView(parent)
{}
void ResultsTreeView::keyPressEvent(QKeyEvent *event)
{
if (event->matches(QKeySequence::Copy)) {
emit copyShortcutTriggered();
event->accept();
}
}
TestResultsPane::TestResultsPane(QObject *parent) :
Core::IOutputPane(parent),
m_context(new Core::IContext(this)),
m_wasVisibleBefore(false),
m_autoScroll(false)
m_autoScroll(false),
m_testRunning(false)
{
m_outputWidget = new QWidget;
QVBoxLayout *outputLayout = new QVBoxLayout;
......@@ -74,9 +91,10 @@ TestResultsPane::TestResultsPane(QObject *parent) :
outputLayout->addWidget(m_summaryWidget);
m_treeView = new Utils::TreeView(m_outputWidget);
m_treeView = new ResultsTreeView(m_outputWidget);
m_treeView->setHeaderHidden(true);
m_treeView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
m_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
m_model = new TestResultModel(this);
m_filterModel = new TestResultFilterModel(m_model, this);
m_filterModel->setDynamicSortFilter(true);
......@@ -91,6 +109,11 @@ TestResultsPane::TestResultsPane(QObject *parent) :
connect(m_treeView, &Utils::TreeView::activated, this, &TestResultsPane::onItemActivated);
connect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged,
trd, &TestResultDelegate::currentChanged);
connect(m_treeView, &Utils::TreeView::customContextMenuRequested,
this, &TestResultsPane::onCustomContextMenuRequested);
connect(m_treeView, &ResultsTreeView::copyShortcutTriggered, [this] () {
onCopyItemTriggered(m_treeView->currentIndex());
});
connect(TestRunner::instance(), &TestRunner::testRunStarted,
this, &TestResultsPane::onTestRunStarted);
connect(TestRunner::instance(), &TestRunner::testRunFinished,
......@@ -375,6 +398,7 @@ void TestResultsPane::filterMenuTriggered(QAction *action)
void TestResultsPane::onTestRunStarted()
{
m_testRunning = true;
m_stopTestRun->setEnabled(true);
m_runAll->setEnabled(false);
m_runSelected->setEnabled(false);
......@@ -383,6 +407,7 @@ void TestResultsPane::onTestRunStarted()
void TestResultsPane::onTestRunFinished()
{
m_testRunning = false;
m_stopTestRun->setEnabled(false);
m_runAll->setEnabled(true);
m_runSelected->setEnabled(true);
......@@ -406,5 +431,68 @@ void TestResultsPane::onTestTreeModelChanged()
m_runSelected->setEnabled(enable);
}
void TestResultsPane::onCustomContextMenuRequested(const QPoint &pos)
{
const bool resultsAvailable = m_filterModel->hasResults();
const bool enabled = !m_testRunning && resultsAvailable;
const QModelIndex clicked = m_treeView->indexAt(pos);
QMenu menu;
QAction *action = new QAction(tr("Copy"), &menu);
action->setShortcut(QKeySequence(QKeySequence::Copy));
action->setEnabled(resultsAvailable);
connect(action, &QAction::triggered, [this, clicked] () {
onCopyItemTriggered(clicked);
});
menu.addAction(action);
action = new QAction(tr("Copy All"), &menu);
action->setEnabled(enabled);
connect(action, &QAction::triggered, this, &TestResultsPane::onCopyWholeTriggered);
menu.addAction(action);
action = new QAction(tr("Save Output to File..."), &menu);
action->setEnabled(enabled);
connect(action, &QAction::triggered, this, &TestResultsPane::onSaveWholeTriggered);
menu.addAction(action);
menu.exec(m_treeView->mapToGlobal(pos));
}
void TestResultsPane::onCopyItemTriggered(const QModelIndex &idx)
{
const TestResult result = m_filterModel->testResult(idx);
QApplication::clipboard()->setText(TestResultDelegate::outputString(result, true));
}
void TestResultsPane::onCopyWholeTriggered()
{
QApplication::clipboard()->setText(getWholeOutput());
}
void TestResultsPane::onSaveWholeTriggered()
{
const QString fileName = QFileDialog::getSaveFileName(Core::ICore::dialogParent(),
tr("Save Output To..."));
Utils::FileSaver saver(fileName, QIODevice::Text);
if (!saver.write(getWholeOutput().toUtf8()) || !saver.finalize()) {
QMessageBox::critical(Core::ICore::dialogParent(), tr("Error"),
tr("Failed to write \"%1\".\n\n%2").arg(fileName)
.arg(saver.errorString()));
}
}
// helper for onCopyWholeTriggered() and onSaveWholeTriggered()
QString TestResultsPane::getWholeOutput()
{
QString output;
const QModelIndex invalid; // practically the invisible root item
for (int row = 0, count = m_model->rowCount(invalid); row < count; ++row) {
const TestResult result = m_model->testResult(m_model->index(row, 0, invalid));
output.append(TestResult::resultToString(result.result())).append(QLatin1Char('\t'));
output.append(TestResultDelegate::outputString(result, true)).append(QLatin1Char('\n'));
}
return output;
}
} // namespace Internal
} // namespace Autotest
......@@ -22,9 +22,12 @@
#include <coreplugin/ioutputpane.h>
#include <utils/itemviews.h>
QT_BEGIN_NAMESPACE
class QAction;
class QFrame;
class QKeyEvent;
class QLabel;
class QModelIndex;
class QMenu;
......@@ -35,10 +38,6 @@ namespace Core {
class IContext;
}
namespace Utils {
class TreeView;
}
namespace Autotest {
namespace Internal {
......@@ -46,6 +45,19 @@ class TestResult;
class TestResultModel;
class TestResultFilterModel;
class ResultsTreeView : public Utils::TreeView
{
Q_OBJECT
public:
ResultsTreeView(QWidget *parent = 0);
signals:
void copyShortcutTriggered();
protected:
void keyPressEvent(QKeyEvent *event);
};
class TestResultsPane : public Core::IOutputPane
{
Q_OBJECT
......@@ -90,11 +102,16 @@ private:
void onTestRunFinished();
void onScrollBarRangeChanged(int, int max);
void onTestTreeModelChanged();
void onCustomContextMenuRequested(const QPoint &pos);
void onCopyItemTriggered(const QModelIndex &idx);
void onCopyWholeTriggered();
void onSaveWholeTriggered();
QString getWholeOutput();
QWidget *m_outputWidget;
QFrame *m_summaryWidget;
QLabel *m_summaryLabel;
Utils::TreeView *m_treeView;
ResultsTreeView *m_treeView;
TestResultModel *m_model;
TestResultFilterModel *m_filterModel;
Core::IContext *m_context;
......@@ -106,6 +123,7 @@ private:
bool m_wasVisibleBefore;
bool m_autoScroll;
bool m_atEnd;
bool m_testRunning;
};
} // namespace Internal
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment