Git commit 6a42a65d1988468cf32a975002f72b1fa47c5409 by Miha Čančula. Committed on 28/02/2011 at 23:18. Pushed by mihac into branch 'master'. Select tests to run with checkboxes rather than hover buttons. M +1 -1 CMakeLists.txt M +18 -11 internal/runnermodel.cpp M +2 -15 internal/runnerwindow.cpp M +0 -1 internal/runnerwindow.h D +0 -70 internal/selectionmanager.cpp D +0 -61 internal/selectionmanager.h M +7 -2 internal/selectionstore.cpp M +38 -15 internal/test_p.cpp M +5 -10 internal/test_p.h M +1 -1 internal/testexecutor.cpp M +2 -2 test.cpp http://commits.kde.org/scratch/mihac/veritas/6a42a65d1988468cf32a975002f72b1fa47c5409 diff --git a/CMakeLists.txt b/CMakeLists.txt index f49b7eb..fdbe620 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ set(veritas_SRCS internal/runnermodel.cpp internal/runnerproxymodel.cpp internal/runnerwindow.cpp - internal/selectionmanager.cpp + internal/overlaymanager.cpp internal/overlaytoggle.cpp internal/resultswidget.cpp diff --git a/internal/runnermodel.cpp b/internal/runnermodel.cpp index 9e5a8e6..965c2f3 100644 --- a/internal/runnermodel.cpp +++ b/internal/runnermodel.cpp @@ -88,12 +88,12 @@ RunnerModel::~RunnerModel() void RunnerModel::checkAll() { - if (m_rootItem) m_rootItem->internal()->check(); + if (m_rootItem) m_rootItem->internal()->setCheckState(Qt::Checked); } void RunnerModel::uncheckAll() { - if (m_rootItem) m_rootItem->internal()->unCheck(); + if (m_rootItem) m_rootItem->internal()->setCheckState(Qt::Unchecked); } QVariant RunnerModel::data(const QModelIndex& index, int role) const @@ -106,10 +106,8 @@ QVariant RunnerModel::data(const QModelIndex& index, int role) const return int(Qt::AlignLeft | Qt::AlignTop); case Qt::DisplayRole : return testFromIndex(index)->name(); - case Qt::TextColorRole : - return testFromIndex(index)->internal()->isChecked() ? - Qt::black : - Qt::lightGray; + case Qt::CheckStateRole : + return testFromIndex(index)->internal()->checkState(); case Qt::DecorationRole : if (index.child(0, 0).isValid()) { // not a leaf test return computeIconFromChildState(testFromIndex(index)); @@ -173,9 +171,18 @@ QVariant RunnerModel::computeIconFromChildState(Veritas::Test* test) const bool RunnerModel::setData(const QModelIndex& index, const QVariant& value, int role) { - Q_UNUSED(index); - Q_UNUSED(value); - Q_UNUSED(role); + if ( role == Qt::CheckStateRole ) + { + testFromIndex(index)->internal()->setCheckState((Qt::CheckState)value.toInt()); + QModelIndex parent = index; + while (parent.isValid()) { + emit dataChanged(parent, parent); + parent = parent.parent(); + } + for (int i = 0; i < rowCount(index); ++i) { + setData(index.child(i,0), value, Qt::CheckStateRole); + } + } return false; } @@ -193,7 +200,7 @@ Qt::ItemFlags RunnerModel::flags(const QModelIndex& index) const if (!index.isValid()) { return 0; } - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable; } QModelIndex RunnerModel::index(int row, int column, const QModelIndex& parent) const @@ -270,7 +277,7 @@ void RunnerModel::countItems() } Test* item = testFromIndex(currentIndex); // Have an item. numTotal++; - if (item->internal()->isChecked() && !hasChildren(currentIndex)) { + if (item->internal()->checkState() == Qt::Checked && !hasChildren(currentIndex)) { m_numSelected++; } switch (item->state()) { diff --git a/internal/runnerwindow.cpp b/internal/runnerwindow.cpp index 5cffb1d..0fb44fc 100644 --- a/internal/runnerwindow.cpp +++ b/internal/runnerwindow.cpp @@ -30,8 +30,8 @@ #include "resultsproxymodel.h" #include "runnermodel.h" #include "runnerproxymodel.h" -#include "selectionmanager.h" #include "overlaytoggle.h" +#include "overlaymanager.h" #include "testexecutor.h" #include @@ -137,10 +137,6 @@ RunnerWindow::RunnerWindow(ResultsModel* rmodel, ProjectSelection::IProjectFilte resultsView()->setModel(rproxy); m_results->setResizeMode(); - m_selection = new SelectionManager(runnerView()); - SelectionToggle* selectionToggle = new SelectionToggle(runnerView()->viewport()); - m_selection->setButton(selectionToggle); - m_verbose = new OverlayManager(runnerView()); m_verboseToggle = new VerboseToggle(runnerView()->viewport()); connect(m_verboseToggle, SIGNAL(clicked(bool)),SLOT(showVerboseTestOutput())); @@ -162,9 +158,6 @@ RunnerWindow::RunnerWindow(ResultsModel* rmodel, ProjectSelection::IProjectFilte QPixmap deselect = KIconLoader::global()->loadIcon("list-remove", KIconLoader::Small); m_ui->actionUnselectAll->setIcon(deselect); - connect(runnerView(), SIGNAL(clicked(QModelIndex)), - SLOT(expandOrCollapse(QModelIndex))); - const char* whatsthis = "xTest runner. First select a project from the rightmost dropdown box. Next, load the test tree by clicking on the green circular arrow icon. Run your tests with a click on the leftmost green arrow icon."; setWhatsThis( i18n(whatsthis) ); resultsView()->setWhatsThis( i18n(whatsthis) ); @@ -230,7 +223,7 @@ class SelectedLeafCount public: SelectedLeafCount() : result(0) {} void operator()(Test* t) { - if ((t->childCount() == 0) && t->internal()->isChecked()) { + if ((t->childCount() == 0) && t->internal()->checkState() == Qt::Checked) { result++; } } @@ -314,7 +307,6 @@ void RunnerWindow::selectAll() RunnerWindow::~RunnerWindow() { // Deleting the model is left to the owner of the model instance. - if (m_selection) delete m_selection; if (m_verbose) delete m_verbose; if (m_executor) { m_executor->stop(); @@ -390,7 +382,6 @@ void RunnerWindow::connectProgressIndicators(RunnerModel* model) void RunnerWindow::setModel(RunnerModel* model) { m_verbose->reset(); - m_selection->reset(); stopPreviousModel(); if (!model) { // No user interaction without a model or an empty one @@ -408,15 +399,11 @@ void RunnerWindow::setModel(RunnerModel* model) enableItemActions(true); m_ui->actionStop->setDisabled(true); - connect(m_selection, SIGNAL(selectionChanged()), - runnerModel(), SLOT(countItems())); - // set top row higlighted runnerView()->setCurrentIndex(runnerProxyModel()->index(0, 0)); enableToSource(); enableTestSync(true); m_verbose->makeConnections(); - m_selection->makeConnections(); m_toSource->makeConnections(); runnerView()->resizeColumnToContents(0); } diff --git a/internal/runnerwindow.h b/internal/runnerwindow.h index fe4a17f..6a24daa 100644 --- a/internal/runnerwindow.h +++ b/internal/runnerwindow.h @@ -221,7 +221,6 @@ private: // Operations private: Ui::RunnerWindow *m_ui; // QtDesigner main object ResultsWidget* m_results; - SelectionManager* m_selection; // is responsable for the fade-in out selection thingy OverlayManager* m_verbose; ProjectSelection* m_projectSelection; // a dropdown box to select the 'current' project QMap m_project2action; diff --git a/internal/selectionmanager.cpp b/internal/selectionmanager.cpp deleted file mode 100644 index 55ba046..0000000 --- a/internal/selectionmanager.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Peter Penz * - * modified by Manuel Breugelmans * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#include "selectionmanager.h" - -#include "../test.h" -#include "test_p.h" -#include "overlaytoggle.h" - -#include -#include - -using Veritas::SelectionManager; -using Veritas::Test; -using Veritas::OverlayManager; -using Veritas::OverlayButton; - -SelectionManager::SelectionManager(QAbstractItemView* parent) : - OverlayManager(parent) -{} - -void SelectionManager::setButton(OverlayButton* button) -{ - connect(button, SIGNAL(clicked(bool)), SLOT(setItemSelected(bool))); - OverlayManager::setButton(button); -} - -SelectionManager::~SelectionManager() -{} - - -void SelectionManager::slotEntered(const QModelIndex& index) -{ - if (index.isValid()) { - Test* t = index2Test(index); - Q_ASSERT(t); - button()->setChecked(t->internal()->isChecked()); - } - OverlayManager::slotEntered(index); -} - - -void SelectionManager::setItemSelected(bool selected) -{ - const QModelIndex index = button()->index(); - if (index.isValid()) { - selected ? index2Test(index)->internal()->check() : index2Test(index)->internal()->unCheck(); - view()->viewport()->update(); - } - emit selectionChanged(); -} - -#include "selectionmanager.moc" diff --git a/internal/selectionmanager.h b/internal/selectionmanager.h deleted file mode 100644 index f674bc3..0000000 --- a/internal/selectionmanager.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Peter Penz * - * modified by Manuel Breugelmans * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#ifndef VERITAS_SELECTIONMANAGER_H -#define VERITAS_SELECTIONMANAGER_H - -#include -#include "overlaymanager.h" - -class QAbstractItemView; -class QModelIndex; - -namespace Veritas -{ - -/*! Whenever a test-item is hovered by the mouse in the runner tree, - * a toggle button is shown. This allows the user to select/deselect that - * specific test and it's children. A deselected test is excluded from the - * test run. Individual Veritas::Test's must set the needSelectionToggle property - * if they want such a button. */ -class SelectionManager : public OverlayManager -{ - Q_OBJECT - -public: - SelectionManager(QAbstractItemView* parent); - virtual ~SelectionManager(); - virtual void setButton(OverlayButton*); - -protected slots: - void slotEntered(const QModelIndex&); - -private slots: - void setItemSelected(bool); - -signals: - /** Is emitted if the selection has been changed by the toggle button. */ - void selectionChanged(); -}; - -} // namespace Veritas - -#endif // VERITAS_SELECTION_MANAGER_H - diff --git a/internal/selectionstore.cpp b/internal/selectionstore.cpp index b78c8cf..fd321f4 100644 --- a/internal/selectionstore.cpp +++ b/internal/selectionstore.cpp @@ -47,7 +47,7 @@ public: void operator()(Test* t) { Q_ASSERT(m_store); if (m_store->wasDeselected(t)) { - t->internal()->unCheckNonRecursive(); + t->internal()->setCheckState(Qt::Unchecked); } } SelectionStore* m_store; @@ -58,7 +58,12 @@ public: void SelectionStore::saveState(Test* test) { Q_ASSERT(test); - if (!test->internal()->isChecked()) { + if (test->childCount() > 0) + { + // We only have to store the state for the leafs + return; + } + if (!test->internal()->checkState() == Qt::Unchecked) { m_deselected << serialize(test); } } diff --git a/internal/test_p.cpp b/internal/test_p.cpp index 2301030..e85f439 100644 --- a/internal/test_p.cpp +++ b/internal/test_p.cpp @@ -19,6 +19,7 @@ */ #include "test_p.h" +#include using Veritas::Test; @@ -68,30 +69,52 @@ void Test::Internal::clear() m_isRunning = false; } -bool Test::Internal::isChecked() const +void Test::Internal::setCheckState(Qt::CheckState state) { - return isChecked_; -} - -void Test::Internal::check() -{ - isChecked_ = true; - foreach (Test* child, children) { - child->internal()->check(); + if (checkState_ != state) { + checkState_ = state; + if (state != Qt::PartiallyChecked) { + foreach (Test* child, children) { + child->internal()->setCheckState(state); + } + } + if (self && self->parent()) { + self->parent()->internal()->updateCheckState(); + } } } -void Test::Internal::unCheckNonRecursive() +Qt::CheckState Test::Internal::checkState() const { - isChecked_ = false; + return checkState_; } -void Test::Internal::unCheck() +void Test::Internal::updateCheckState() { - isChecked_ = false; - foreach (Test* child, children) { - child->internal()->unCheck(); + Qt::CheckState newState = checkState_; + if (checkState_ == Qt::PartiallyChecked && children.isEmpty()) { + newState = Qt::Checked; + } + else if (!children.isEmpty()) { + bool checkedChildren = false; + bool unCheckedChildren = false; + foreach (Test* child, children) { + child->internal()->updateCheckState(); + checkedChildren |= child->internal()->checkState() != Qt::Unchecked; + unCheckedChildren |= child->internal()->checkState() != Qt::Checked; + if (checkedChildren && unCheckedChildren) { + newState = Qt::PartiallyChecked; + break; + } + } + if (checkedChildren && !unCheckedChildren) { + newState = Qt::Checked; + } + else if (unCheckedChildren && !checkedChildren) { + newState = Qt::Unchecked; + } } + setCheckState(newState); } bool Test::Internal::isRunning() const diff --git a/internal/test_p.h b/internal/test_p.h index 1cbc3f2..490d1d0 100644 --- a/internal/test_p.h +++ b/internal/test_p.h @@ -46,15 +46,10 @@ public: QVariant data(int column) const; void setData(int column, const QVariant& value); - - /*! Is this item checked by the user in the tree-runnerview? */ - bool isChecked() const; - /*! Check this test and all its children */ - void check(); - /*! Recursively lift check state */ - void unCheck(); - /*! Uncheck only this test, not it's children */ - void unCheckNonRecursive(); + + void setCheckState(Qt::CheckState state); + Qt::CheckState checkState() const; + void updateCheckState(); bool isRunning() const; void setIsRunning(bool); @@ -66,7 +61,7 @@ private: QString name; QModelIndex index_; TestResult* result; - bool isChecked_; + Qt::CheckState checkState_; QMap childMap; QList children; QList itemData; diff --git a/internal/testexecutor.cpp b/internal/testexecutor.cpp index 5911cd6..e6345cc 100644 --- a/internal/testexecutor.cpp +++ b/internal/testexecutor.cpp @@ -58,7 +58,7 @@ public: void SetupChain::operator()(Test* current) { - if (!(current->shouldRun() && current->internal()->isChecked())) { + if (!(current->shouldRun() && current->internal()->checkState() == Qt::Checked)) { return; // only run if is an exe and selected } if (!m_previous) { // first test in the chain. diff --git a/test.cpp b/test.cpp index 5b3843b..fd567fa 100644 --- a/test.cpp +++ b/test.cpp @@ -49,7 +49,7 @@ Test::Test(const QList& data, Test* parent) } else { d->name.clear(); } - d->check(); + d->setCheckState(Qt::Checked); d->needVerboseToggle = false; d->needSelectionToggle = false; } @@ -64,7 +64,7 @@ Test::Test(const QString& name, Test* parent) for (int i=0; i < Internal::columnCount; i++) { d->itemData << QString(); } - d->check(); + d->setCheckState(Qt::Checked); d->needVerboseToggle = false; d->needSelectionToggle = false; d->supportsToSource = false;