From 145cbdc1b8ceb02ee928961e9536d66a4f90bdd5 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 6 May 2015 15:18:52 +0200 Subject: Add capability of having additional columns... ...inside the test tree. This adds an icon for running a suite or test case, opening the objects.map or recording a test case. Clicking on these icons actually does nothing except emitting respective signals. Change-Id: I5ddc76691986b71d61385856777b0c26ba9494b2 Reviewed-by: Robert Loehning --- plugins/autotest/autotest.qrc | 3 ++ plugins/autotest/images/objectsmap.png | Bin 0 -> 283 bytes plugins/autotest/images/play.png | Bin 0 -> 176 bytes plugins/autotest/images/record.png | Bin 0 -> 198 bytes plugins/autotest/testnavigationwidget.cpp | 46 +++++++++++++++++++++++++++++- plugins/autotest/testnavigationwidget.h | 4 +++ plugins/autotest/testtreeitemdelegate.cpp | 3 ++ plugins/autotest/testtreemodel.cpp | 41 ++++++++++++++++++++++++-- plugins/autotest/testtreeview.cpp | 46 ++++++++++++++++++++++++++++++ plugins/autotest/testtreeview.h | 12 ++++++++ 10 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 plugins/autotest/images/objectsmap.png create mode 100644 plugins/autotest/images/play.png create mode 100644 plugins/autotest/images/record.png diff --git a/plugins/autotest/autotest.qrc b/plugins/autotest/autotest.qrc index 2770aff5fe..49404c3083 100644 --- a/plugins/autotest/autotest.qrc +++ b/plugins/autotest/autotest.qrc @@ -21,5 +21,8 @@ images/run.png images/runselected.png images/stop.png + images/objectsmap.png + images/play.png + images/record.png diff --git a/plugins/autotest/images/objectsmap.png b/plugins/autotest/images/objectsmap.png new file mode 100644 index 0000000000..39a2a07eae Binary files /dev/null and b/plugins/autotest/images/objectsmap.png differ diff --git a/plugins/autotest/images/play.png b/plugins/autotest/images/play.png new file mode 100644 index 0000000000..893c7b40e3 Binary files /dev/null and b/plugins/autotest/images/play.png differ diff --git a/plugins/autotest/images/record.png b/plugins/autotest/images/record.png new file mode 100644 index 0000000000..45ba1ab712 Binary files /dev/null and b/plugins/autotest/images/record.png differ diff --git a/plugins/autotest/testnavigationwidget.cpp b/plugins/autotest/testnavigationwidget.cpp index c0c65eb22a..33c5f4342b 100644 --- a/plugins/autotest/testnavigationwidget.cpp +++ b/plugins/autotest/testnavigationwidget.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -45,6 +46,8 @@ namespace Autotest { namespace Internal { +const int defaultSectionSize = 18; + TestNavigationWidget::TestNavigationWidget(QWidget *parent) : QWidget(parent) { @@ -56,6 +59,14 @@ TestNavigationWidget::TestNavigationWidget(QWidget *parent) : m_view->setModel(m_sortFilterModel); m_view->setSortingEnabled(true); m_view->setItemDelegate(new TestTreeItemDelegate(this)); + QHeaderView *header = new QHeaderView(Qt::Horizontal, m_view); + header->setModel(m_model); + header->setDefaultSectionSize(0); + header->setSectionResizeMode(0, QHeaderView::Stretch); + header->setSectionResizeMode(1, QHeaderView::Fixed); + header->setSectionResizeMode(2, QHeaderView::Fixed); + m_view->setHeader(header); + m_view->setHeaderHidden(true); QVBoxLayout *layout = new QVBoxLayout; layout->setMargin(0); @@ -79,6 +90,11 @@ TestNavigationWidget::TestNavigationWidget(QWidget *parent) : this, &TestNavigationWidget::onParsingFinished); connect(m_progressTimer, &QTimer::timeout, m_progressIndicator, &Utils::ProgressIndicator::show); + + connect(m_view, &QTreeView::expanded, this, &TestNavigationWidget::onExpanded); + connect(m_view, &QTreeView::collapsed, this, &TestNavigationWidget::onCollapsed); + connect(m_model, &QAbstractItemModel::rowsInserted, this, &TestNavigationWidget::onRowsInserted); + connect(m_model, &QAbstractItemModel::rowsRemoved, this, &TestNavigationWidget::onRowsRemoved); } TestNavigationWidget::~TestNavigationWidget() @@ -93,8 +109,10 @@ bool TestNavigationWidget::handleSquishContextMenuEvent(QContextMenuEvent *event // item specific menu entries const QModelIndexList list = m_view->selectionModel()->selectedIndexes(); - if (list.size() == 1) { + // 3 columns - but we only need the data of the first column as the others contain only an icon + if (list.size() == 3) { QRect rect(m_view->visualRect(list.first())); + rect.adjust(0, 0, defaultSectionSize * 2, 0); if (rect.contains(event->pos())) { TestTreeItem::Type type = TestTreeItem::toTestType(list.first().data(TypeRole).toInt()); @@ -284,6 +302,32 @@ void TestNavigationWidget::onParsingFinished() m_progressIndicator->hide(); } +void TestNavigationWidget::onExpanded(const QModelIndex &index) +{ + if (index.data().toString().startsWith(QLatin1String("Squish"))) + m_view->header()->setDefaultSectionSize(defaultSectionSize); +} + +void TestNavigationWidget::onCollapsed(const QModelIndex &index) +{ + if (index.data().toString().startsWith(QLatin1String("Squish"))) + m_view->header()->setDefaultSectionSize(0); +} + +void TestNavigationWidget::onRowsInserted(const QModelIndex &parent, int, int) +{ + if (parent.isValid() && parent.data().toString().startsWith(QLatin1String("Squish"))) + if (m_view->isExpanded(parent) && m_model->rowCount(parent)) + m_view->header()->setDefaultSectionSize(defaultSectionSize); +} + +void TestNavigationWidget::onRowsRemoved(const QModelIndex &parent, int, int) +{ + if (parent.isValid() && parent.data().toString().startsWith(QLatin1String("Squish"))) + if (m_model->rowCount(parent) == 0) + m_view->header()->setDefaultSectionSize(0); +} + void TestNavigationWidget::initializeFilterMenu() { QAction *action = new QAction(m_filterMenu); diff --git a/plugins/autotest/testnavigationwidget.h b/plugins/autotest/testnavigationwidget.h index a2a7d2fae7..8704595564 100644 --- a/plugins/autotest/testnavigationwidget.h +++ b/plugins/autotest/testnavigationwidget.h @@ -66,6 +66,10 @@ private slots: void onFilterMenuTriggered(QAction *action); void onParsingStarted(); void onParsingFinished(); + void onExpanded(const QModelIndex &index); + void onCollapsed(const QModelIndex &index); + void onRowsInserted(const QModelIndex &parent, int, int); + void onRowsRemoved(const QModelIndex &parent, int, int); private: bool handleSquishContextMenuEvent(QContextMenuEvent *event, bool enabled); diff --git a/plugins/autotest/testtreeitemdelegate.cpp b/plugins/autotest/testtreeitemdelegate.cpp index 1e5952c7a0..6b58e3adc2 100644 --- a/plugins/autotest/testtreeitemdelegate.cpp +++ b/plugins/autotest/testtreeitemdelegate.cpp @@ -63,6 +63,9 @@ void TestTreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & } } + if (index.flags() == Qt::NoItemFlags) + opt.palette.setColor(QPalette::Text, opt.palette.color(QPalette::Active, QPalette::Text)); + QStyledItemDelegate::paint(painter, opt, index); } diff --git a/plugins/autotest/testtreemodel.cpp b/plugins/autotest/testtreemodel.cpp index 5e9aaa4aea..823508c036 100644 --- a/plugins/autotest/testtreemodel.cpp +++ b/plugins/autotest/testtreemodel.cpp @@ -191,7 +191,7 @@ int TestTreeModel::rowCount(const QModelIndex &parent) const int TestTreeModel::columnCount(const QModelIndex &) const { - return 1; + return 3; } static QIcon testTreeIcon(TestTreeItem::Type type) @@ -223,6 +223,35 @@ QVariant TestTreeModel::data(const QModelIndex &index, int role) const if (!item) return QVariant(); + if (index.column() != 0) { + TestTreeItem::Type type = item->type(); + switch (role) { + case Qt::DecorationRole: + if (type == TestTreeItem::SQUISH_SUITE) + return index.column() == 1 ? QIcon(QLatin1String(":/images/play.png")) + : QIcon(QLatin1String(":/images/objectsmap.png")); + else if (type == TestTreeItem::SQUISH_TESTCASE) + return index.column() == 1 ? QIcon(QLatin1String(":/images/play.png")) + : QIcon(QLatin1String(":/images/record.png")); + case TypeRole: + return item->type(); + case Qt::DisplayRole: + if (type == TestTreeItem::SQUISH_SUITE || type == TestTreeItem::SQUISH_TESTCASE) + return item->name(); + case Qt::ToolTipRole: + if (type == TestTreeItem::SQUISH_SUITE || type == TestTreeItem::SQUISH_TESTCASE) { + if (index.column() == 1) + return tr("Run %1").arg(item->name()); + else + return type == TestTreeItem::SQUISH_SUITE ? tr("Open objects.map") + : tr("Record %1").arg(item->name()); + } + default: + return QVariant(); + } + return QVariant(); + } + if (role == Qt::DisplayRole) { if ((item == m_autoTestRootItem && m_autoTestRootItem->childCount() == 0) || (item == m_quickTestRootItem && m_quickTestRootItem->childCount() == 0) @@ -332,7 +361,13 @@ Qt::ItemFlags TestTreeModel::flags(const QModelIndex &index) const return Qt::ItemIsEnabled | Qt::ItemIsSelectable; TestTreeItem *item = static_cast(index.internalPointer()); - switch(item->type()) { + TestTreeItem::Type type = item->type(); + if (index.column() != 0 && type != TestTreeItem::SQUISH_SUITE + && type != TestTreeItem::SQUISH_TESTCASE) + return type == TestTreeItem::ROOT ? Qt::NoItemFlags + : Qt::ItemIsEnabled | Qt::ItemIsSelectable; + + switch (type) { case TestTreeItem::TEST_CLASS: case TestTreeItem::SQUISH_SUITE: if (item->name().isEmpty()) @@ -344,7 +379,7 @@ Qt::ItemFlags TestTreeModel::flags(const QModelIndex &index) const return Qt::ItemIsEnabled | Qt::ItemIsSelectable; return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable; case TestTreeItem::ROOT: - return Qt::ItemIsEnabled; + return Qt::NoItemFlags; case TestTreeItem::TEST_DATAFUNCTION: case TestTreeItem::TEST_SPECIALFUNCTION: default: diff --git a/plugins/autotest/testtreeview.cpp b/plugins/autotest/testtreeview.cpp index 5675e9266f..62630efe26 100644 --- a/plugins/autotest/testtreeview.cpp +++ b/plugins/autotest/testtreeview.cpp @@ -97,5 +97,51 @@ void TestTreeView::changeCheckStateAll(const Qt::CheckState checkState) } } +void TestTreeView::resizeEvent(QResizeEvent *event) +{ + // override derived behavior of Utils::NavigationTreeView as we might have more than 1 column + TreeView::resizeEvent(event); +} + +void TestTreeView::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + QModelIndex index = indexAt(event->pos()); + if (index.isValid() && index.column() != 0) { + auto type = TestTreeItem::toTestType(index.data(TypeRole).toInt()); + if (index.column() > 2) + qWarning() << "Unexpected column:" << index.column(); + else if (type == TestTreeItem::SQUISH_SUITE || type == TestTreeItem::SQUISH_TESTCASE) + m_lastMousePressedIndex = index; + } + } + QTreeView::mousePressEvent(event); +} + +void TestTreeView::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + QModelIndex index = indexAt(event->pos()); + if (index.isValid() && m_lastMousePressedIndex == index) { + auto type = TestTreeItem::toTestType(index.data(TypeRole).toInt()); + if (type == TestTreeItem::SQUISH_SUITE) { + if (index.column() == 1) + emit runTestSuite(index.data().toString()); + else if (index.column() == 2) + emit openObjectsMap(index.data().toString()); + } else { + const QModelIndex &parent = index.parent(); + if (parent.isValid()) { + if (index.column() == 1) + emit runTestCase(parent.data().toString(), index.data().toString()); + else if (index.column() == 2) + emit recordTestCase(parent.data().toString(), index.data().toString()); + } + } + } + } + QTreeView::mouseReleaseEvent(event); +} + } // namespace Internal } // namespace Autotest diff --git a/plugins/autotest/testtreeview.h b/plugins/autotest/testtreeview.h index c9a4d9f9ff..cb6fc714e0 100644 --- a/plugins/autotest/testtreeview.h +++ b/plugins/autotest/testtreeview.h @@ -22,6 +22,8 @@ #include +#include + namespace Core { class IContext; } @@ -38,10 +40,20 @@ public: void selectAll(); void deselectAll(); + void resizeEvent(QResizeEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + +signals: + void runTestSuite(const QString &suiteName); + void runTestCase(const QString &suiteName, const QString &testCaseName); + void openObjectsMap(const QString &suiteName); + void recordTestCase(const QString &suiteName, const QString &testCaseName); private: void changeCheckStateAll(const Qt::CheckState checkState); Core::IContext *m_context; + QModelIndex m_lastMousePressedIndex; }; } // namespace Internal -- cgit v1.2.1