diff options
-rw-r--r-- | plugins/autotest/testresult.h | 2 | ||||
-rw-r--r-- | plugins/autotest/testresultdelegate.cpp | 10 | ||||
-rw-r--r-- | plugins/autotest/testresultmodel.cpp | 58 | ||||
-rw-r--r-- | plugins/autotest/testresultmodel.h | 25 | ||||
-rw-r--r-- | plugins/autotest/testresultspane.cpp | 66 | ||||
-rw-r--r-- | plugins/autotest/testresultspane.h | 8 | ||||
-rw-r--r-- | plugins/autotest/testtreemodel.cpp | 25 |
7 files changed, 163 insertions, 31 deletions
diff --git a/plugins/autotest/testresult.h b/plugins/autotest/testresult.h index dc47691664..b8b6a2dd1a 100644 --- a/plugins/autotest/testresult.h +++ b/plugins/autotest/testresult.h @@ -76,4 +76,6 @@ bool operator==(const TestResult &t1, const TestResult &t2); } // namespace Internal } // namespace Autotest +Q_DECLARE_METATYPE(Autotest::Internal::ResultType) + #endif // TESTRESULT_H diff --git a/plugins/autotest/testresultdelegate.cpp b/plugins/autotest/testresultdelegate.cpp index 1f423d2e3a..4231278276 100644 --- a/plugins/autotest/testresultdelegate.cpp +++ b/plugins/autotest/testresultdelegate.cpp @@ -64,9 +64,10 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op painter->drawRect(opt.rect); painter->setPen(foreground); - TestResultModel *resultModel = static_cast<TestResultModel *>(view->model()); + TestResultFilterModel *resultFilterModel = static_cast<TestResultFilterModel *>(view->model()); + TestResultModel *resultModel = static_cast<TestResultModel *>(resultFilterModel->sourceModel()); LayoutPositions positions(opt, resultModel); - TestResult testResult = resultModel->testResult(index); + TestResult testResult = resultModel->testResult(resultFilterModel->mapToSource(index)); ResultType type = testResult.result(); QIcon icon = index.data(Qt::DecorationRole).value<QIcon>(); @@ -176,13 +177,14 @@ QSize TestResultDelegate::sizeHint(const QStyleOptionViewItem &option, const QMo QFontMetrics fm(opt.font); int fontHeight = fm.height(); - TestResultModel *resultModel = static_cast<TestResultModel *>(view->model()); + TestResultFilterModel *resultFilterModel = static_cast<TestResultFilterModel *>(view->model()); + TestResultModel *resultModel = static_cast<TestResultModel *>(resultFilterModel->sourceModel()); LayoutPositions positions(opt, resultModel); QSize s; s.setWidth(opt.rect.width()); if (selected) { - TestResult testResult = resultModel->testResult(index); + TestResult testResult = resultModel->testResult(resultFilterModel->mapToSource(index)); QString output; switch (testResult.result()) { diff --git a/plugins/autotest/testresultmodel.cpp b/plugins/autotest/testresultmodel.cpp index 1867987aa1..9c7291d2e1 100644 --- a/plugins/autotest/testresultmodel.cpp +++ b/plugins/autotest/testresultmodel.cpp @@ -21,6 +21,7 @@ #include <QDebug> #include <QFontMetrics> #include <QIcon> +#include <QSortFilterProxyModel> namespace Autotest { namespace Internal { @@ -70,7 +71,7 @@ static QIcon testResultIcon(ResultType result) { QIcon(QLatin1String(":/images/debug.png")), QIcon(QLatin1String(":/images/warn.png")), QIcon(QLatin1String(":/images/fatal.png")), - }; + }; // provide an icon for unknown?? if (result < 0 || result >= MESSAGE_INTERNAL) return QIcon(); @@ -116,6 +117,9 @@ void TestResultModel::clearTestResults() return; beginRemoveRows(QModelIndex(), 0, m_testResults.size() - 1); m_testResults.clear(); + m_lastMaxWidthIndex = 0; + m_maxWidthOfFileName = 0; + m_widthOfLineNumber = 0; endRemoveRows(); } @@ -159,5 +163,57 @@ int TestResultModel::maxWidthOfLineNumber(const QFont &font) return m_widthOfLineNumber; } +/********************************** Filter Model **********************************/ + +TestResultFilterModel::TestResultFilterModel(TestResultModel *sourceModel, QObject *parent) + : QSortFilterProxyModel(parent), + m_sourceModel(sourceModel) +{ + setSourceModel(sourceModel); + enableAllResultTypes(); +} + +void TestResultFilterModel::enableAllResultTypes() +{ + m_enabled << ResultType::PASS << ResultType::FAIL << ResultType::EXPECTED_FAIL + << ResultType::UNEXPECTED_PASS << ResultType::SKIP << ResultType::MESSAGE_DEBUG + << ResultType::MESSAGE_WARN << ResultType::MESSAGE_INTERNAL + << ResultType::MESSAGE_FATAL << ResultType::UNKNOWN; + invalidateFilter(); +} + +void TestResultFilterModel::toggleTestResultType(ResultType type) +{ + if (m_enabled.contains(type)) { + m_enabled.remove(type); + } else { + m_enabled.insert(type); + } + invalidateFilter(); +} + +void TestResultFilterModel::clearTestResults() +{ + m_sourceModel->clearTestResults(); +} + +bool TestResultFilterModel::hasResults() +{ + return rowCount(QModelIndex()); +} + +TestResult TestResultFilterModel::testResult(const QModelIndex &index) const +{ + return m_sourceModel->testResult(mapToSource(index)); +} + +bool TestResultFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + QModelIndex index = m_sourceModel->index(sourceRow, 0, sourceParent); + if (!index.isValid()) + return false; + return m_enabled.contains(m_sourceModel->testResult(index).result()); +} + } // namespace Internal } // namespace Autotest diff --git a/plugins/autotest/testresultmodel.h b/plugins/autotest/testresultmodel.h index fa35820554..c0a71fe44b 100644 --- a/plugins/autotest/testresultmodel.h +++ b/plugins/autotest/testresultmodel.h @@ -22,7 +22,9 @@ #include "testresult.h" #include <QAbstractItemModel> +#include <QSortFilterProxyModel> #include <QFont> +#include <QSet> namespace Autotest { namespace Internal { @@ -48,6 +50,9 @@ public: int maxWidthOfFileName(const QFont &font); int maxWidthOfLineNumber(const QFont &font); + void enableAllResultTypes(); + void toggleTestResultType(ResultType type); + signals: public slots: @@ -60,6 +65,26 @@ private: QFont m_measurementFont; }; +class TestResultFilterModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + TestResultFilterModel(TestResultModel *sourceModel, QObject *parent = 0); + + void enableAllResultTypes(); + void toggleTestResultType(ResultType type); + void clearTestResults(); + bool hasResults(); + TestResult testResult(const QModelIndex &index) const; + +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; + +private: + TestResultModel *m_sourceModel; + QSet<ResultType> m_enabled; +}; + } // namespace Internal } // namespace Autotest diff --git a/plugins/autotest/testresultspane.cpp b/plugins/autotest/testresultspane.cpp index 100de73e58..244b775f93 100644 --- a/plugins/autotest/testresultspane.cpp +++ b/plugins/autotest/testresultspane.cpp @@ -22,12 +22,14 @@ #include "testrunner.h" #include "testtreemodel.h" +#include <coreplugin/coreconstants.h> #include <coreplugin/icontext.h> #include <texteditor/texteditor.h> #include <utils/itemviews.h> +#include <QDebug> #include <QToolButton> namespace Autotest { @@ -39,7 +41,9 @@ TestResultsPane::TestResultsPane(QObject *parent) : { m_listView = new Utils::ListView; m_model = new TestResultModel(this); - m_listView->setModel(m_model); + m_filterModel = new TestResultFilterModel(m_model, this); + m_filterModel->setDynamicSortFilter(true); + m_listView->setModel(m_filterModel); TestResultDelegate *trd = new TestResultDelegate(this); m_listView->setItemDelegate(trd); @@ -61,6 +65,17 @@ void TestResultsPane::createToolButtons() m_runSelected->setIcon(QIcon(QLatin1String(":/images/runselected.png"))); m_runSelected->setToolTip(tr("Run Selected Tests")); connect(m_runSelected, &QToolButton::clicked, this, &TestResultsPane::onRunSelectedTriggered); + + m_filterButton = new QToolButton(m_listView); + m_filterButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_FILTER))); + m_filterButton->setToolTip(tr("Filter Test Results")); + m_filterButton->setProperty("noArrow", true); + m_filterButton->setAutoRaise(true); + m_filterButton->setPopupMode(QToolButton::InstantPopup); + m_filterMenu = new QMenu(m_filterButton); + initializeFilterMenu(); + connect(m_filterMenu, &QMenu::triggered, this, &TestResultsPane::filterMenuTriggered); + m_filterButton->setMenu(m_filterMenu); } static TestResultsPane *m_instance = 0; @@ -99,7 +114,7 @@ QWidget *TestResultsPane::outputWidget(QWidget *parent) QList<QWidget *> TestResultsPane::toolBarWidgets() const { - return QList<QWidget *>() << m_runAll << m_runSelected; // add filter as well + return QList<QWidget *>() << m_runAll << m_runSelected << m_filterButton; } QString TestResultsPane::displayName() const @@ -114,7 +129,7 @@ int TestResultsPane::priorityInStatusBar() const void TestResultsPane::clearContents() { - m_model->clearTestResults(); + m_filterModel->clearTestResults(); navigateStateChanged(); } @@ -143,12 +158,12 @@ bool TestResultsPane::canNavigate() const bool TestResultsPane::canNext() const { - return m_model->hasResults(); + return m_filterModel->hasResults(); } bool TestResultsPane::canPrevious() const { - return m_model->hasResults(); + return m_filterModel->hasResults(); } void TestResultsPane::goToNext() @@ -159,11 +174,11 @@ void TestResultsPane::goToNext() QModelIndex currentIndex = m_listView->currentIndex(); if (currentIndex.isValid()) { int row = currentIndex.row() + 1; - if (row == m_model->rowCount(QModelIndex())) + if (row == m_filterModel->rowCount(QModelIndex())) row = 0; - currentIndex = m_model->index(row, 0, QModelIndex()); + currentIndex = m_filterModel->index(row, 0, QModelIndex()); } else { - currentIndex = m_model->index(0, 0, QModelIndex()); + currentIndex = m_filterModel->index(0, 0, QModelIndex()); } m_listView->setCurrentIndex(currentIndex); onItemActivated(currentIndex); @@ -178,10 +193,10 @@ void TestResultsPane::goToPrev() if (currentIndex.isValid()) { int row = currentIndex.row() - 1; if (row < 0) - row = m_model->rowCount(QModelIndex()) - 1; - currentIndex = m_model->index(row, 0, QModelIndex()); + row = m_filterModel->rowCount(QModelIndex()) - 1; + currentIndex = m_filterModel->index(row, 0, QModelIndex()); } else { - currentIndex = m_model->index(m_model->rowCount(QModelIndex()) - 1, 0, QModelIndex()); + currentIndex = m_filterModel->index(m_filterModel->rowCount(QModelIndex()) - 1, 0, QModelIndex()); } m_listView->setCurrentIndex(currentIndex); onItemActivated(currentIndex); @@ -192,7 +207,7 @@ void TestResultsPane::onItemActivated(const QModelIndex &index) if (!index.isValid()) return; - TestResult tr = m_model->testResult(index); + TestResult tr = m_filterModel->testResult(index); if (!tr.fileName().isEmpty()) Core::EditorManager::openEditorAt(tr.fileName(), tr.line(), 0); } @@ -209,7 +224,34 @@ void TestResultsPane::onRunSelectedTriggered() TestRunner *runner = TestRunner::instance(); runner->setSelectedTests(TestTreeModel::instance()->getSelectedTests()); runner->runTests(); +} + +void TestResultsPane::initializeFilterMenu() +{ + QMap<ResultType, QString> textAndType; + textAndType.clear(); + textAndType.insert(ResultType::PASS, QLatin1String("Pass")); + textAndType.insert(ResultType::FAIL, QLatin1String("Fail")); + textAndType.insert(ResultType::EXPECTED_FAIL, QLatin1String("Expected Fail")); + textAndType.insert(ResultType::UNEXPECTED_PASS, QLatin1String("Unexpected Pass")); + textAndType.insert(ResultType::SKIP, QLatin1String("Skip")); + textAndType.insert(ResultType::MESSAGE_DEBUG, QLatin1String("Debug Messages")); + textAndType.insert(ResultType::MESSAGE_WARN, QLatin1String("Warning Messages")); + textAndType.insert(ResultType::MESSAGE_INTERNAL, QLatin1String("Internal Messages")); + foreach (ResultType result, textAndType.keys()) { + QAction *action = new QAction(m_filterMenu); + action->setText(textAndType.value(result)); + action->setCheckable(true); + action->setChecked(true); + action->setData(result); + m_filterMenu->addAction(action); + } +} +void TestResultsPane::filterMenuTriggered(QAction *action) +{ + m_filterModel->toggleTestResultType(static_cast<ResultType>(action->data().value<int>())); + navigateStateChanged(); } } // namespace Internal diff --git a/plugins/autotest/testresultspane.h b/plugins/autotest/testresultspane.h index 28aff09103..86936223ac 100644 --- a/plugins/autotest/testresultspane.h +++ b/plugins/autotest/testresultspane.h @@ -22,7 +22,9 @@ #include <coreplugin/ioutputpane.h> QT_BEGIN_NAMESPACE +class QAction; class QModelIndex; +class QMenu; class QToolButton; QT_END_NAMESPACE @@ -39,6 +41,7 @@ namespace Internal { class TestResult; class TestResultModel; +class TestResultFilterModel; class TestResultsPane : public Core::IOutputPane { @@ -73,6 +76,8 @@ private slots: void onItemActivated(const QModelIndex &index); void onRunAllTriggered(); void onRunSelectedTriggered(); + void initializeFilterMenu(); + void filterMenuTriggered(QAction *action); private: explicit TestResultsPane(QObject *parent = 0); @@ -80,9 +85,12 @@ private: Utils::ListView *m_listView; TestResultModel *m_model; + TestResultFilterModel *m_filterModel; Core::IContext *m_context; QToolButton *m_runAll; QToolButton *m_runSelected; + QToolButton *m_filterButton; + QMenu *m_filterMenu; }; } // namespace Internal diff --git a/plugins/autotest/testtreemodel.cpp b/plugins/autotest/testtreemodel.cpp index 7cf8d2888d..fe9a091b55 100644 --- a/plugins/autotest/testtreemodel.cpp +++ b/plugins/autotest/testtreemodel.cpp @@ -20,9 +20,7 @@ #include "testtreeitem.h" #include "testtreemodel.h" -#include <texteditor/texteditor.h> - -#include <QIcon> +#include <cpptools/cppmodelmanager.h> #include <projectexplorer/buildtargetinfo.h> #include <projectexplorer/environmentaspect.h> @@ -32,7 +30,11 @@ #include <projectexplorer/session.h> #include <projectexplorer/target.h> -#include <cpptools/cppmodelmanager.h> +#include <texteditor/texteditor.h> + +#include <utils/fileutils.h> + +#include <QIcon> namespace Autotest { namespace Internal { @@ -276,16 +278,11 @@ static void addProjectInformation(TestConfiguration *config, const QString &file if (ProjectExplorer::LocalApplicationRunConfiguration *localRunConfiguration = qobject_cast<ProjectExplorer::LocalApplicationRunConfiguration *>(rc)) { if (localRunConfiguration->executable() == targetFile) { - workDir = localRunConfiguration->workingDirectory(); - QList<ProjectExplorer::IRunConfigurationAspect *> aspects - = localRunConfiguration->extraAspects(); - foreach (ProjectExplorer::IRunConfigurationAspect *aspect, aspects) { - if (ProjectExplorer::EnvironmentAspect *asp - = qobject_cast<ProjectExplorer::EnvironmentAspect *>(aspect)) { - env = asp->environment(); - break; - } - } + workDir = Utils::FileUtils::normalizePathName( + localRunConfiguration->workingDirectory()); + ProjectExplorer::EnvironmentAspect *envAsp + = localRunConfiguration->extraAspect<ProjectExplorer::EnvironmentAspect>(); + env = envAsp->environment(); break; } } |