on xenial help sign in
Cleanups, added test for ratings filter bindings.
commit31a0aceedb68be85529fd4a7b2008b85191bc106 authorPawel Stolowski <pawel.stolowski@canonical.com> dateWed 10 Jul 2013, 18:33 (13 years ago) parent1448d73
8 files changed+131−68
plugins/Unity/combinedfilteroptions.cpp+8−28 plugins/Unity/combinedfilteroptions.h+2−9 plugins/Unity/genericlistmodel.cpp+10 plugins/Unity/genericlistmodel.h+5−8 plugins/Unity/ratingsfilter.cpp+19−13 plugins/Unity/ratingsfilter.h+2−10 tests/plugins/Unity/filtersbindingstest.cpp+83 tests/plugins/Unity/filtersbindingstest.h+2
plugins/Unity/combinedfilteroptions.cpp+8−28
@@ -18,29 +18,14 @@
1818 */
1919
2020#include "combinedfilteroptions.h"
21+#include "combinedfilteroption.h"
2122
2223CombinedFilterOptions::CombinedFilterOptions(const std::vector<unity::dash::FilterOption::Ptr>& list, QObject *parent)
23− : QAbstractListModel(parent)
24+ : GenericListModel(parent)
2425{
2526 initList(list);
2627}
2728
28−
29−QVariant CombinedFilterOptions::data(const QModelIndex& index, int /* role */) const
30−{
31− if (!index.isValid()) {
32− return QVariant();
33− }
34−
35− CombinedFilterOption* item = m_list.at(index.row());
36− return QVariant::fromValue(item);
37−}
38−
39−int CombinedFilterOptions::rowCount(const QModelIndex& /* parent */) const
40−{
41− return m_list.count();
42−}
43−
4429void CombinedFilterOptions::initList(const std::vector<unity::dash::FilterOption::Ptr>& list)
4530{
4631 // combine options, e.g. A, B, C becomes A-B, B-C, C
@@ -59,14 +44,6 @@ void CombinedFilterOptions::initList(const std::vector<unity::dash::FilterOption
5944 }
6045}
6146
62−void CombinedFilterOptions::addOption(CombinedFilterOption *option)
63−{
64− int index = m_list.count();
65− beginInsertRows(QModelIndex(), index, index);
66− m_list.insert(index, option);
67− endInsertRows();
68−}
69−
7047void CombinedFilterOptions::onActiveChanged(bool state)
7148{
7249 // if option became active, need to disable all other options
@@ -75,9 +52,12 @@ void CombinedFilterOptions::onActiveChanged(bool state)
7552 if (option) {
7653 Q_FOREACH (auto fo, m_list) {
7754 if (option != fo) {
78− // note that changing state will result in onActiveChanged signal for that option, but
79− // since it will be 'false', we won't end up in an infinite loop
80− fo->setInactive(*option);
55+ CombinedFilterOption *other = dynamic_cast<CombinedFilterOption*>(fo);
56+ if (fo) {
57+ // note that changing state will result in onActiveChanged signal for that option, but
58+ // since it will be 'false', we won't end up in an infinite loop
59+ other->setInactive(*option);
60+ }
8161 }
8262 }
8363 }
plugins/Unity/combinedfilteroptions.h+2−9
@@ -22,32 +22,25 @@
2222
2323// Qt
2424#include <QObject>
25−#include <QAbstractListModel>
2625
2726// libunity-core
2827#include <UnityCore/Filter.h>
2928
3029// local
31−#include "combinedfilteroption.h"
30+#include "genericlistmodel.h"
3231
33−class CombinedFilterOptions : public QAbstractListModel
32+class CombinedFilterOptions : public GenericListModel
3433{
3534 Q_OBJECT
3635
3736public:
3837 CombinedFilterOptions(const std::vector<unity::dash::FilterOption::Ptr>& list, QObject *parent = 0);
3938
40− QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
41− int rowCount(const QModelIndex& parent = QModelIndex()) const override;
42−
4339private Q_SLOTS:
4440 void onActiveChanged(bool state);
4541
4642private:
4743 void initList(const std::vector<unity::dash::FilterOption::Ptr>& list);
48− void addOption(CombinedFilterOption *option);
49−
50− QList<CombinedFilterOption*> m_list;
5144};
5245
5346Q_DECLARE_METATYPE(CombinedFilterOptions*)
plugins/Unity/genericlistmodel.cpp+10
@@ -46,3 +46,13 @@ void GenericListModel::addOption(QObject *option)
4646 m_list.insert(index, option);
4747 endInsertRows();
4848}
49+
50+QList<QObject *>::Iterator GenericListModel::optionsBegin()
51+{
52+ return m_list.begin();
53+}
54+
55+QList<QObject *>::Iterator GenericListModel::optionsEnd()
56+{
57+ return m_list.end();
58+}
plugins/Unity/genericlistmodel.h+5−8
@@ -24,13 +24,7 @@
2424#include <QObject>
2525#include <QAbstractListModel>
2626
27−// libunity-core
28−#include <UnityCore/Filter.h>
29−
30−// local
31−#include "combinedfilteroption.h"
32−
33−class GenericListModel : public QAbstractListModel
27+class Q_DECL_EXPORT GenericListModel : public QAbstractListModel
3428{
3529 Q_OBJECT
3630
@@ -39,9 +33,12 @@ public:
3933
4034 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
4135 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
42−
4336 void addOption(QObject* option);
4437
38+ QList<QObject *>::Iterator optionsBegin();
39+ QList<QObject *>::Iterator optionsEnd();
40+
41+protected:
4542 QList<QObject *> m_list;
4643};
4744
plugins/Unity/ratingsfilter.cpp+19−13
@@ -22,27 +22,21 @@
2222
2323// local
2424#include "genericlistmodel.h"
25+#include "ratingfilteroption.h"
26+
27+// Qt
28+#include <QDebug>
2529
2630RatingsFilter::RatingsFilter(QObject *parent) :
2731 Filter(parent), m_unityRatingsFilter(NULL), m_options(nullptr)
2832{
2933}
3034
31−float RatingsFilter::rating() const
32−{
33− return m_unityRatingsFilter->rating();
34−}
35−
3635GenericListModel* RatingsFilter::options() const
3736{
3837 return m_options;
3938}
4039
41−void RatingsFilter::setRating(float rating)
42−{
43− m_unityRatingsFilter->rating = rating;
44−}
45−
4640void RatingsFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
4741{
4842 if (m_unityFilter != NULL) {
@@ -63,15 +57,27 @@ void RatingsFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
6357 m_options->addOption(opt);
6458 }
6559
66− /* Property change signals */
67− m_signals << m_unityRatingsFilter->rating.changed.connect(sigc::mem_fun(this, &RatingsFilter::ratingChanged));
60+ Q_EMIT ratingsChanged();
6861}
6962
7063void RatingsFilter::onActiveChanged()
7164{
7265 RatingFilterOption *option = dynamic_cast<RatingFilterOption*>(QObject::sender());
7366 if (option != nullptr) {
74− setRating(option->value());
67+ if (option->active()) {
68+ // disable all other options
69+ for (auto it = m_options->optionsBegin(); it != m_options->optionsEnd(); it++) {
70+ RatingFilterOption *opt = dynamic_cast<RatingFilterOption *>(*it);
71+ if (opt && opt != option && opt->active()) {
72+ opt->setActive(false);
73+ }
74+ }
75+ m_unityRatingsFilter->rating = option->value();
76+ }
77+
78+ Q_EMIT ratingsChanged();
79+ } else {
80+ qWarning() << "Invalid option";
7581 }
7682}
7783
plugins/Unity/ratingsfilter.h+2−10
@@ -30,8 +30,6 @@
3030// Local
3131#include "filter.h"
3232#include "signalslist.h"
33−#include "ratingfilteroption.h"
34−#include "ratingfilteroption.h"
3533
3634class GenericListModel;
3735
@@ -39,22 +37,16 @@ class Q_DECL_EXPORT RatingsFilter : public Filter
3937{
4038 Q_OBJECT
4139
42− Q_PROPERTY(float rating READ rating WRITE setRating NOTIFY ratingChanged)
40+ Q_PROPERTY(GenericListModel* options READ options NOTIFY ratingsChanged)
4341
4442public:
4543 explicit RatingsFilter(QObject *parent = 0);
4644
47− /* getters */
48− float rating() const;
49−
5045 /* getters */
5146 GenericListModel* options() const;
5247
53− /* setters */
54− void setRating(float rating);
55−
5648Q_SIGNALS:
57− void ratingChanged(float);
49+ void ratingsChanged();
5850
5951protected:
6052 virtual void setUnityFilter(unity::dash::Filter::Ptr filter);
tests/plugins/Unity/filtersbindingstest.cpp+83
@@ -33,6 +33,8 @@
3333#include "combinedfilteroption.h"
3434#include "checkoptionfilter.h"
3535#include "radiooptionfilter.h"
36+#include "ratingsfilter.h"
37+#include "ratingfilteroption.h"
3638
3739void FiltersBindingsTest::initTestCase()
3840{
@@ -73,6 +75,30 @@ void FiltersBindingsTest::createCheckOptionFilter(DeeModel *model, const std::st
7375 createFilter(model, "filter-checkoption", id, name, optionCount);
7476}
7577
78+void FiltersBindingsTest::createRatingsFilter(DeeModel *model, const std::string &id, const std::string &name)
79+{
80+ GVariant* row[8];
81+
82+ row[0] = g_variant_new_string(id.c_str());
83+ row[1] = g_variant_new_string(name.c_str());
84+ row[2] = g_variant_new_string(""); // icon hint
85+ row[3] = g_variant_new_string("filter-ratings");
86+
87+ GVariant *children[2];
88+ GVariant *key1 = g_variant_new_string("show-all-button");
89+ GVariant *key2 = g_variant_new_string("rating");
90+ children[0] = g_variant_new_dict_entry(key1, g_variant_new_variant(g_variant_new_boolean(false)));
91+ children[1] = g_variant_new_dict_entry(key2, g_variant_new_variant(g_variant_new_double(0.0f)));
92+ auto fhints = g_variant_new_array(G_VARIANT_TYPE("{sv}"), children, 2);
93+
94+ row[4] = fhints;
95+ row[5] = g_variant_new_boolean(true); // visible
96+ row[6] = g_variant_new_boolean(false); // collapsed
97+ row[7] = g_variant_new_boolean(false); // filtering
98+
99+ dee_model_append_row(model, row);
100+}
101+
76102void FiltersBindingsTest::createFilter(DeeModel *model, const std::string &renderer, const std::string &id, const std::string &name, int optionCount)
77103{
78104 GVariant* row[8];
@@ -350,4 +376,61 @@ void FiltersBindingsTest::testRadioOptionFilter()
350376 }
351377}
352378
379+void FiltersBindingsTest::testRatingsFilter()
380+{
381+ auto model = createFilterModel();
382+
383+ createRatingsFilter(model, "f1", "Filter1");
384+
385+ // create filter out of 1st row
386+ auto iter = dee_model_get_first_iter(DEE_MODEL(model));
387+ {
388+ auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
389+ QVERIFY(core_filter != nullptr);
390+ auto bind_filter = Filter::newFromUnityFilter(core_filter);
391+ auto rating_filter = dynamic_cast<RatingsFilter*>(bind_filter);
392+ QVERIFY(rating_filter != nullptr);
393+ auto options = rating_filter->options();
394+ QCOMPARE(options->rowCount(), 5);
395+
396+ RatingFilterOption* opt[5];
397+ for (int i = 0; i<5; i++) {
398+ opt[i] = options->data(options->index(i)).value<RatingFilterOption*>();
399+ }
400+
401+ QSignalSpy opt0spy(opt[0], SIGNAL(activeChanged(bool)));
402+ QSignalSpy opt4spy(opt[4], SIGNAL(activeChanged(bool)));
403+
404+ QVERIFY(qAbs(opt[0]->value() - 0.2f) <= 0.0001f);
405+ QVERIFY(qAbs(opt[1]->value() - 0.4f) <= 0.0001f);
406+ QVERIFY(qAbs(opt[2]->value() - 0.6f) <= 0.0001f);
407+ QVERIFY(qAbs(opt[3]->value() - 0.8f) <= 0.0001f);
408+ QVERIFY(qAbs(opt[4]->value() - 1.0f) <= 0.0001f);
409+
410+ // all options initially inactive
411+ for (int i=0; i<5; i++) {
412+ QCOMPARE(opt[i]->active(), false);
413+ }
414+
415+ // verify activation for all options
416+ for (int i=0; i<5; i++) {
417+ opt[i]->setActive(true);
418+ QCOMPARE(opt[i]->active(), true);
419+
420+ // verify that all other options are inactive
421+ for (int j=0; j<5; j++) {
422+ if (i != j) {
423+ QCOMPARE(opt[j]->active(), false);
424+ }
425+ }
426+ }
427+
428+ QCOMPARE(opt0spy.count(), 2);
429+ QCOMPARE(opt4spy.count(), 1);
430+
431+ opt[4]->setActive(false);
432+ QCOMPARE(opt4spy.count(), 2);
433+ }
434+}
435+
353436QTEST_MAIN(FiltersBindingsTest)
tests/plugins/Unity/filtersbindingstest.h+2
@@ -29,6 +29,7 @@ class FiltersBindingsTest : public QObject
2929 void testMultiRangeFilter();
3030 void testCheckOptionFilter();
3131 void testRadioOptionFilter();
32+ void testRatingsFilter();
3233
3334 private:
3435 DeeModel* createFilterModel();
@@ -36,6 +37,7 @@ class FiltersBindingsTest : public QObject
3637 void createMultiRangeFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount);
3738 void createCheckOptionFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount);
3839 void createRadioOptionFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount);
40+ void createRatingsFilter(DeeModel *model, const std::string &id, const std::string &name);
3941 void createFilter(DeeModel *model, const std::string &renderer, const std::string &id, const std::string &name, int optionCount);
4042};
4143