on xenial help sign in
Use proper models for filter options: created GenericOptionsModel and UnityOptionsModel + RatingOptionsModel. Removed CombinedFilterOption. Lots of other refactorings.
066af94Pawel Stolowski
plugins/Unity/CMakeLists.txt+4−4
@@ -18,8 +18,6 @@ include_directories(
18
18
19set(QMLPLUGIN_SRC
19set(QMLPLUGIN_SRC
20 abstractfilteroption.cpp
20 abstractfilteroption.cpp
21− combinedfilteroption.cpp
22− combinedfilteroptions.cpp
23 scope.cpp
21 scope.cpp
24 scopes.cpp
22 scopes.cpp
25 categories.cpp
23 categories.cpp
@@ -27,7 +25,9 @@ set(QMLPLUGIN_SRC
27 filter.cpp
25 filter.cpp
28 filteroption.cpp
26 filteroption.cpp
29 filters.cpp
27 filters.cpp
30− genericlistmodel.cpp
28+ genericoptionsmodel.cpp
29+ ratingoptionsmodel.cpp
30+ unityoptionsmodel.cpp
31 categoryresults.cpp
31 categoryresults.cpp
32 plugin.cpp
32 plugin.cpp
33 multirangefilter.cpp
33 multirangefilter.cpp
@@ -46,7 +46,7 @@ set(QMLPLUGIN_SRC
46 socialpreview.cpp
46 socialpreview.cpp
47 socialpreviewcomment.cpp
47 socialpreviewcomment.cpp
48 variantutils.cpp
48 variantutils.cpp
49− )
49+)
50
50
51add_library(Unity-qml MODULE
51add_library(Unity-qml MODULE
52 ${QMLPLUGIN_SRC}
52 ${QMLPLUGIN_SRC}
plugins/Unity/abstractfilteroption.h+1−1
@@ -24,7 +24,7 @@
24#include <QObject>
24#include <QObject>
25#include <QMetaType>
25#include <QMetaType>
26
26
27−class AbstractFilterOption : public QObject
27+class Q_DECL_EXPORT AbstractFilterOption : public QObject
28{
28{
29 Q_OBJECT
29 Q_OBJECT
30
30
plugins/Unity/checkoptionfilter.cpp+14−28
@@ -20,12 +20,17 @@
20// Self
20// Self
21#include "checkoptionfilter.h"
21#include "checkoptionfilter.h"
22
22
23+// local
24+#include "unityoptionsmodel.h"
25+
23CheckOptionFilter::CheckOptionFilter(QObject *parent) :
26CheckOptionFilter::CheckOptionFilter(QObject *parent) :
27+ Filter(parent),
24− Filter(parent), m_unityCheckOptionFilter(nullptr), m_options(nullptr)
28+ m_unityCheckOptionFilter(nullptr),
29+ m_options(nullptr)
25{
30{
26}
31}
27
32
28−FilterOptions* CheckOptionFilter::options() const
33+GenericOptionsModel* CheckOptionFilter::options() const
29{
34{
30 return m_options;
35 return m_options;
31}
36}
@@ -34,44 +39,25 @@ void CheckOptionFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
34{
39{
35 Filter::setUnityFilter(filter);
40 Filter::setUnityFilter(filter);
36 m_unityCheckOptionFilter = std::dynamic_pointer_cast<unity::dash::CheckOptionFilter>(m_unityFilter);
41 m_unityCheckOptionFilter = std::dynamic_pointer_cast<unity::dash::CheckOptionFilter>(m_unityFilter);
37−
38 onOptionsChanged(m_unityCheckOptionFilter->options);
42 onOptionsChanged(m_unityCheckOptionFilter->options);
39}
43}
40
44
41−void CheckOptionFilter::onOptionsChanged(unity::dash::CheckOptionFilter::CheckOptions /* options */)
45+void CheckOptionFilter::onOptionsChanged(unity::dash::CheckOptionFilter::CheckOptions options)
42{
46{
43 if (m_options != nullptr) {
47 if (m_options != nullptr) {
44 m_signals.disconnectAll();
48 m_signals.disconnectAll();
45 delete m_options;
49 delete m_options;
46 m_options = nullptr;
50 m_options = nullptr;
47 }
51 }
48− m_options = new FilterOptions(m_unityCheckOptionFilter->options,
49− m_unityCheckOptionFilter->option_added,
50− m_unityCheckOptionFilter->option_removed);
51
52
52− Q_FOREACH(FilterOption* option, m_options->rawList()) {
53+ m_options = new UnityOptionsModel(this, options,
53− connect(option, SIGNAL(activeChanged(bool)), this, SLOT(onActiveChanged(bool)));
54+ m_unityCheckOptionFilter->option_added,
54− }
55+ m_unityCheckOptionFilter->option_removed);
56+
57+ connect(m_options, SIGNAL(activeChanged(AbstractFilterOption *)), m_options, SLOT(ensureTheOnlyActive(AbstractFilterOption *)));
55
58
56 /* Property change signals */
59 /* Property change signals */
57− m_signals.append(m_unityCheckOptionFilter->options.changed.connect(sigc::mem_fun(this, &CheckOptionFilter::onOptionsChanged)));
60+ m_signals << m_unityCheckOptionFilter->options.changed.connect(sigc::mem_fun(this, &CheckOptionFilter::onOptionsChanged));
58
61
59 Q_EMIT optionsChanged();
62 Q_EMIT optionsChanged();
60}
63}
61−
62−void CheckOptionFilter::onActiveChanged(bool state)
63−{
64− if (state == false)
65− return;
66−
67− FilterOption *selected_option = dynamic_cast<FilterOption*>(QObject::sender());
68− if (selected_option) {
69− Q_FOREACH(FilterOption* option, m_options->rawList()) {
70− if (option != selected_option && option->active()) {
71− option->setActive(false);
72− // we know only one option can be selected, so break immediately
73− break;
74− }
75− }
76− }
77−}
plugins/Unity/checkoptionfilter.h+5−13
@@ -36,29 +36,21 @@ class Q_DECL_EXPORT CheckOptionFilter : public Filter
36{
36{
37 Q_OBJECT
37 Q_OBJECT
38
38
39− Q_PROPERTY(FilterOptions* options READ options NOTIFY optionsChanged)
40−
41public:
39public:
42 explicit CheckOptionFilter(QObject *parent = nullptr);
40 explicit CheckOptionFilter(QObject *parent = nullptr);
43
41
44 /* getters */
42 /* getters */
45− FilterOptions* options() const;
43+ GenericOptionsModel* options() const override;
46−
47−Q_SIGNALS:
48− void optionsChanged();
49−
50−private Q_SLOTS:
51− void onActiveChanged(bool state);
52
44
53protected:
45protected:
54− virtual void setUnityFilter(unity::dash::Filter::Ptr filter);
46+ void setUnityFilter(unity::dash::Filter::Ptr filter) override;
55
47
56private:
48private:
49+ void onOptionsChanged(unity::dash::CheckOptionFilter::CheckOptions filter);
50+
57 unity::dash::CheckOptionFilter::Ptr m_unityCheckOptionFilter;
51 unity::dash::CheckOptionFilter::Ptr m_unityCheckOptionFilter;
58− FilterOptions* m_options;
59 SignalsList m_signals;
52 SignalsList m_signals;
60−
53+ GenericOptionsModel* m_options;
61− void onOptionsChanged(unity::dash::CheckOptionFilter::CheckOptions);
62};
54};
63
55
64Q_DECLARE_METATYPE(CheckOptionFilter*)
56Q_DECLARE_METATYPE(CheckOptionFilter*)
plugins/Unity/combinedfilteroption.cppdeleted−139
@@ -1,139 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#include "combinedfilteroption.h"
21−
22−#include <libintl.h>
23−
24−CombinedFilterOption::CombinedFilterOption(unity::dash::FilterOption::Ptr unityFilterOption1, unity::dash::FilterOption::Ptr unityFilterOption2, QObject *parent)
25− : AbstractFilterOption(parent),
26− m_active(false),
27− m_requestedActive(false),
28− m_unityFilterOption {nullptr, nullptr}
29−{
30− setUnityFilterOption(unityFilterOption1, unityFilterOption2);
31−}
32−
33−QString CombinedFilterOption::getCombinedId() const
34−{
35− if (m_unityFilterOption[1] != nullptr)
36− return QString::fromStdString(m_unityFilterOption[0]->id() + "-" + m_unityFilterOption[1]->id());
37− return QString::fromStdString(m_unityFilterOption[0]->id());
38−}
39−
40−QString CombinedFilterOption::getCombinedName() const
41−{
42− if (m_unityFilterOption[1] != nullptr) {
43− // TRANSLATORS: this joins two names from a Range filter
44− return QString::fromStdString(gettext("%1 - %2"))
45− .arg(QString::fromStdString(m_unityFilterOption[0]->name()))
46− .arg(QString::fromStdString(m_unityFilterOption[1]->name()));
47− }
48− return QString::fromStdString(m_unityFilterOption[0]->name());
49−}
50−
51−QString CombinedFilterOption::id() const
52−{
53− return getCombinedId();
54−}
55−
56−QString CombinedFilterOption::name() const
57−{
58− return getCombinedName();
59−}
60−
61−QString CombinedFilterOption::iconHint() const
62−{
63− return QString::fromStdString(m_unityFilterOption[0]->icon_hint());
64−}
65−
66−bool CombinedFilterOption::active() const
67−{
68− if (m_unityFilterOption[1] != nullptr)
69− return m_unityFilterOption[0]->active && m_unityFilterOption[1]->active && m_requestedActive;
70− return m_unityFilterOption[0]->active && m_requestedActive;
71−}
72−
73−void CombinedFilterOption::setActive(bool active)
74−{
75− m_requestedActive = active;
76− m_unityFilterOption[0]->active = active;
77− if (m_unityFilterOption[1] != nullptr)
78− m_unityFilterOption[1]->active = active;
79−}
80−
81−void CombinedFilterOption::setInactive(const CombinedFilterOption &otherFilter)
82−{
83− // de-activate underlying unity filter options as long as they don't belong
84− // to otherFilter.
85− if (this != &otherFilter) {
86− m_requestedActive = false;
87− for (int i = 0; i<2; i++) {
88− if (m_unityFilterOption[i] != nullptr) {
89− if (m_unityFilterOption[i]->active &&
90− m_unityFilterOption[i] != otherFilter.m_unityFilterOption[0] &&
91− m_unityFilterOption[i] != otherFilter.m_unityFilterOption[1]) {
92− m_unityFilterOption[i]->active = false;
93− }
94− }
95− }
96− }
97−}
98−
99−void CombinedFilterOption::onIdChanged(const std::string &/* id */)
100−{
101− Q_EMIT idChanged(getCombinedId());
102−}
103−
104−void CombinedFilterOption::onNameChanged(const std::string &/* name */)
105−{
106− Q_EMIT nameChanged(getCombinedName());
107−}
108−
109−void CombinedFilterOption::onIconHintChanged(const std::string &/* iconHint */)
110−{
111− Q_EMIT iconHintChanged(iconHint());
112−}
113−
114−void CombinedFilterOption::onActiveChanged(bool /*active*/)
115−{
116− bool combinedState = CombinedFilterOption::active();
117− if (m_active != combinedState) {
118− m_active = combinedState;
119− Q_EMIT activeChanged(m_active);
120− }
121−}
122−
123−void CombinedFilterOption::setUnityFilterOption(unity::dash::FilterOption::Ptr unityFilterOption1, unity::dash::FilterOption::Ptr unityFilterOption2)
124−{
125− m_signals.disconnectAll();
126−
127− m_unityFilterOption[0] = unityFilterOption1;
128− m_unityFilterOption[1] = unityFilterOption2;
129−
130− /* Property change signals */
131− for (int i=0; i<2; i++) {
132− if (m_unityFilterOption[i] != nullptr) {
133− m_signals << m_unityFilterOption[i]->id.changed.connect(sigc::mem_fun(this, &CombinedFilterOption::onIdChanged))
134− << m_unityFilterOption[i]->name.changed.connect(sigc::mem_fun(this, &CombinedFilterOption::onNameChanged))
135− << m_unityFilterOption[i]->icon_hint.changed.connect(sigc::mem_fun(this,&CombinedFilterOption::onIconHintChanged))
136− << m_unityFilterOption[i]->active.changed.connect(sigc::mem_fun(this, &CombinedFilterOption::onActiveChanged));
137− }
138− }
139−}
plugins/Unity/combinedfilteroption.hdeleted−78
@@ -1,78 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef COMBINEDFILTEROPTION_H
21−#define COMBINEDFILTEROPTION_H
22−
23−// Local
24−#include "abstractfilteroption.h"
25−#include "signalslist.h"
26−
27−// libunity-core
28−#include <UnityCore/Filter.h>
29−
30−/**
31− * Combines one or two Unity's filter options into one.
32− * Becomes active if both of them are active.
33− */
34−class Q_DECL_EXPORT CombinedFilterOption : public AbstractFilterOption
35−{
36− Q_OBJECT
37−
38−public:
39− explicit CombinedFilterOption(unity::dash::FilterOption::Ptr unityFilterOption1,
40− unity::dash::FilterOption::Ptr unityFilterOption2 = nullptr,
41− QObject *parent = nullptr);
42−
43− /* getters */
44− QString id() const override;
45− QString name() const override;
46− QString iconHint() const override;
47− bool active() const override;
48−
49− /* setters */
50− void setActive(bool active) override;
51−
52−private:
53− void onIdChanged(const std::string &id);
54− void onNameChanged(const std::string &name);
55− void onIconHintChanged(const std::string &iconHint);
56− void onActiveChanged(bool active);
57−
58− QString getCombinedId() const;
59− QString getCombinedName() const;
60− void setUnityFilterOption(unity::dash::FilterOption::Ptr unityFilterOption1,
61− unity::dash::FilterOption::Ptr unityFilterOption2 = nullptr);
62−
63− /* De-activate the filter, and also de-activate one or both of the underlying unity's filter options, depending on whether
64− one of them is active in otherFilter. This is used internally by CombinedFilterOptions to ensure only one
65− CombinedFilterOption is active. */
66− void setInactive(const CombinedFilterOption &otherFilter);
67−
68− bool m_active;
69− bool m_requestedActive;
70− unity::dash::FilterOption::Ptr m_unityFilterOption[2];
71− SignalsList m_signals;
72−
73− friend class CombinedFilterOptions;
74−};
75−
76−Q_DECLARE_METATYPE(CombinedFilterOption*)
77−
78−#endif // COMBINEDFILTEROPTION_H
plugins/Unity/combinedfilteroptions.cppdeleted−65
@@ -1,65 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#include "combinedfilteroptions.h"
21−#include "combinedfilteroption.h"
22−
23−CombinedFilterOptions::CombinedFilterOptions(const std::vector<unity::dash::FilterOption::Ptr>& list, QObject *parent)
24− : GenericListModel(parent)
25−{
26− initList(list);
27−}
28−
29−void CombinedFilterOptions::initList(const std::vector<unity::dash::FilterOption::Ptr>& list)
30−{
31− // combine options, e.g. A, B, C becomes A-B, B-C, C
32− unsigned int i = 0;
33− while (i < list.size() - 1) {
34− unity::dash::FilterOption::Ptr option1 = list[i];
35− unity::dash::FilterOption::Ptr option2 = list[i+1];
36− auto co = new CombinedFilterOption(option1, option2, this);
37− connect(co, SIGNAL(activeChanged(bool)), this, SLOT(onActiveChanged(bool)));
38− addObject(co);
39− ++i;
40− }
41− if (list.size() > 0) {
42− auto co = new CombinedFilterOption(list[i], nullptr, this);
43− addObject(co);
44− }
45−}
46−
47−void CombinedFilterOptions::onActiveChanged(bool state)
48−{
49− // if option became active, need to disable all other options
50− if (state) {
51− CombinedFilterOption *option = dynamic_cast<CombinedFilterOption*>(QObject::sender());
52− if (option) {
53− Q_FOREACH (auto fo, m_list) {
54− if (option != fo) {
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− }
61− }
62− }
63− }
64− }
65−}
plugins/Unity/filter.cpp+1−1
@@ -115,7 +115,7 @@ Filter* Filter::newFromUnityFilter(unity::dash::Filter::Ptr unityFilter)
115 filter = new MultiRangeFilter;
115 filter = new MultiRangeFilter;
116 } else {
116 } else {
117 qWarning() << "Filter of unknown type: " << typeid(*unityFilter).name();
117 qWarning() << "Filter of unknown type: " << typeid(*unityFilter).name();
118− filter = new Filter;
118+ return nullptr;
119 }
119 }
120
120
121 filter->setUnityFilter(unityFilter);
121 filter->setUnityFilter(unityFilter);
plugins/Unity/filter.h+5
@@ -31,6 +31,8 @@
31// local
31// local
32#include "signalslist.h"
32#include "signalslist.h"
33
33
34+class GenericOptionsModel;
35+
34class Q_DECL_EXPORT Filter : public QObject
36class Q_DECL_EXPORT Filter : public QObject
35{
37{
36 Q_OBJECT
38 Q_OBJECT
@@ -42,6 +44,7 @@ class Q_DECL_EXPORT Filter : public QObject
42 Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
44 Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
43 Q_PROPERTY(bool collapsed READ collapsed NOTIFY collapsedChanged)
45 Q_PROPERTY(bool collapsed READ collapsed NOTIFY collapsedChanged)
44 Q_PROPERTY(bool filtering READ filtering NOTIFY filteringChanged)
46 Q_PROPERTY(bool filtering READ filtering NOTIFY filteringChanged)
47+ Q_PROPERTY(GenericOptionsModel* options READ options NOTIFY optionsChanged)
45
48
46public:
49public:
47 explicit Filter(QObject *parent = nullptr);
50 explicit Filter(QObject *parent = nullptr);
@@ -54,6 +57,7 @@ public:
54 bool visible() const;
57 bool visible() const;
55 bool collapsed() const;
58 bool collapsed() const;
56 bool filtering() const;
59 bool filtering() const;
60+ virtual GenericOptionsModel* options() const = 0;
57
61
58 Q_INVOKABLE void clear();
62 Q_INVOKABLE void clear();
59
63
@@ -68,6 +72,7 @@ Q_SIGNALS:
68 void visibleChanged(bool);
72 void visibleChanged(bool);
69 void collapsedChanged(bool);
73 void collapsedChanged(bool);
70 void filteringChanged(bool);
74 void filteringChanged(bool);
75+ void optionsChanged();
71
76
72protected:
77protected:
73 unity::dash::Filter::Ptr m_unityFilter;
78 unity::dash::Filter::Ptr m_unityFilter;
plugins/Unity/filteroption.h−4
@@ -23,7 +23,6 @@
23
23
24// Local
24// Local
25#include "abstractfilteroption.h"
25#include "abstractfilteroption.h"
26−#include "listmodelwrapper.h"
27#include "signalslist.h"
26#include "signalslist.h"
28
27
29// libunity-core
28// libunity-core
@@ -59,7 +58,4 @@ private:
59
58
60Q_DECLARE_METATYPE(FilterOption*)
59Q_DECLARE_METATYPE(FilterOption*)
61
60
62−typedef ListModelWrapper<FilterOption, unity::dash::FilterOption::Ptr> FilterOptions;
63−Q_DECLARE_METATYPE(FilterOptions*)
64−
65#endif // FILTEROPTION_H
61#endif // FILTEROPTION_H
plugins/Unity/filters.cpp+6−3
@@ -74,7 +74,7 @@ QVariant Filters::data(const QModelIndex& index, int role) const
74 Filter* filter = m_filters.at(index.row());
74 Filter* filter = m_filters.at(index.row());
75 switch (role)
75 switch (role)
76 {
76 {
77− case Filters::RoleId:
77+ case Filters::RoleId:
78 return filter->id();
78 return filter->id();
79 case Filters::RoleName:
79 case Filters::RoleName:
80 return filter->name();
80 return filter->name();
@@ -89,8 +89,9 @@ QVariant Filters::data(const QModelIndex& index, int role) const
89 case Filters::RoleFiltering:
89 case Filters::RoleFiltering:
90 return filter->filtering();
90 return filter->filtering();
91 default:
91 default:
92− return QVariant();
92+ break;
93 }
93 }
94+ return QVariant();
94}
95}
95
96
96QHash<int, QByteArray> Filters::roleNames() const
97QHash<int, QByteArray> Filters::roleNames() const
@@ -137,7 +138,9 @@ void Filters::addFilter(unity::dash::Filter::Ptr unityFilter, int index)
137{
138{
138 beginInsertRows(QModelIndex(), index, index);
139 beginInsertRows(QModelIndex(), index, index);
139 Filter* filter = Filter::newFromUnityFilter(unityFilter);
140 Filter* filter = Filter::newFromUnityFilter(unityFilter);
141+ if (filter != nullptr) {
140− m_filters.insert(index, filter);
142+ m_filters.insert(index, filter);
143+ }
141 endInsertRows();
144 endInsertRows();
142}
145}
143
146
plugins/Unity/genericlistmodel.cppdeleted−58
@@ -1,58 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#include "genericlistmodel.h"
21−
22−GenericListModel::GenericListModel(QObject *parent)
23− : QAbstractListModel(parent)
24−{
25−}
26−
27−QVariant GenericListModel::data(const QModelIndex& index, int /* role */) const
28−{
29− if (!index.isValid()) {
30− return QVariant();
31− }
32−
33− QObject* item = m_list.at(index.row());
34− return QVariant::fromValue(item);
35−}
36−
37−int GenericListModel::rowCount(const QModelIndex& /* parent */) const
38−{
39− return m_list.count();
40−}
41−
42−void GenericListModel::addObject(QObject *option)
43−{
44− int index = m_list.count();
45− beginInsertRows(QModelIndex(), index, index);
46− m_list.insert(index, option);
47− endInsertRows();
48−}
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.hdeleted−50
@@ -1,50 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef GENERICLISTMODEL_H
21−#define GENERICLISTMODEL_H
22−
23−// Qt
24−#include <QObject>
25−#include <QAbstractListModel>
26−
27−/*
28− * TODO: see if it'd be better to use QVariantListModel.
29− */
30−class Q_DECL_EXPORT GenericListModel : public QAbstractListModel
31−{
32− Q_OBJECT
33−
34−public:
35− GenericListModel(QObject *parent = nullptr);
36−
37− QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
38− int rowCount(const QModelIndex& parent = QModelIndex()) const override;
39− void addObject(QObject* option);
40−
41− QList<QObject *>::Iterator optionsBegin();
42− QList<QObject *>::Iterator optionsEnd();
43−
44−protected:
45− QList<QObject *> m_list;
46−};
47−
48−Q_DECLARE_METATYPE(GenericListModel*)
49−
50−#endif // GENERICLISTMODEL_H
plugins/Unity/genericoptionsmodel.cppnew file+155
@@ -0,0 +1,155 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// self
21+#include "genericoptionsmodel.h"
22+
23+// local
24+#include "abstractfilteroption.h"
25+
26+GenericOptionsModel::GenericOptionsModel(QObject *parent)
27+ : QAbstractListModel(parent)
28+{
29+ setupRoles();
30+}
31+
32+GenericOptionsModel::~GenericOptionsModel()
33+{
34+ Q_FOREACH(auto opt, m_options)
35+ {
36+ opt->deleteLater();
37+ }
38+}
39+
40+void GenericOptionsModel::setupRoles()
41+{
42+ m_roles[GenericOptionsModel::RoleId] = "id";
43+ m_roles[GenericOptionsModel::RoleName] = "name";
44+ m_roles[GenericOptionsModel::RoleIconHint] = "iconHint";
45+ m_roles[GenericOptionsModel::RoleActive] = "active";
46+}
47+
48+QHash<int, QByteArray> GenericOptionsModel::roleNames() const
49+{
50+ return m_roles;
51+}
52+
53+QVariant GenericOptionsModel::data(const QModelIndex& index, int role) const
54+{
55+ if (!index.isValid()) {
56+ return QVariant();
57+ }
58+
59+ auto filterOption = m_options[index.row()];
60+ switch (role)
61+ {
62+ case GenericOptionsModel::RoleId:
63+ return filterOption->id();
64+ case GenericOptionsModel::RoleName:
65+ return filterOption->name();
66+ case GenericOptionsModel::RoleIconHint:
67+ return filterOption->iconHint();
68+ case GenericOptionsModel::RoleActive:
69+ return filterOption->active();
70+ default:
71+ break;
72+ }
73+
74+ return QVariant();
75+}
76+
77+int GenericOptionsModel::rowCount(const QModelIndex& /* parent */) const
78+{
79+ return m_options.size ();
80+}
81+
82+AbstractFilterOption* GenericOptionsModel::getRawOption(QVector<AbstractFilterOption *>::size_type idx) const
83+{
84+ if (idx < m_options.size())
85+ {
86+ return m_options[idx];
87+ }
88+ return nullptr;
89+}
90+
91+void GenericOptionsModel::ensureTheOnlyActive(AbstractFilterOption *activeOption)
92+{
93+ if (activeOption->active()) {
94+ // disable all other options
95+ Q_FOREACH(auto opt, m_options) {
96+ if (opt != activeOption && opt->active()) {
97+ opt->setActive(false);
98+ }
99+ }
100+ }
101+}
102+
103+void GenericOptionsModel::addOption(AbstractFilterOption *option, int index)
104+{
105+ m_options.insert(index, option);
106+
107+ connect(option, SIGNAL(idChanged(const QString &)), this, SLOT(onOptionChanged()));
108+ connect(option, SIGNAL(nameChanged(const QString &)), this, SLOT(onOptionChanged()));
109+ connect(option, SIGNAL(iconHintChanged(const QString &)), this, SLOT(onOptionChanged()));
110+ connect(option, SIGNAL(activeChanged(bool)), this, SLOT(onOptionChanged()));
111+ connect(option, SIGNAL(activeChanged(bool)), this, SLOT(onActiveChanged()));
112+}
113+
114+void GenericOptionsModel::removeOption(int index)
115+{
116+ m_options[index]->deleteLater();
117+ m_options.remove(index);
118+}
119+
120+int GenericOptionsModel::indexOf(const QString &option_id)
121+{
122+ int row = 0;
123+ Q_FOREACH(auto opt, m_options)
124+ {
125+ if (opt->id() == option_id)
126+ {
127+ return row;
128+ }
129+ ++row;
130+ }
131+ return -1;
132+}
133+
134+void GenericOptionsModel::onOptionChanged()
135+{
136+ AbstractFilterOption *option = dynamic_cast<AbstractFilterOption*>(QObject::sender());
137+ if (option)
138+ {
139+ int idx = indexOf(option->id());
140+ if (idx >= 0)
141+ {
142+ QModelIndex optionIndex = index(idx, idx);
143+ Q_EMIT dataChanged(optionIndex, optionIndex);
144+ }
145+ }
146+}
147+
148+void GenericOptionsModel::onActiveChanged()
149+{
150+ AbstractFilterOption *option = dynamic_cast<AbstractFilterOption*>(QObject::sender());
151+ if (option)
152+ {
153+ Q_EMIT activeChanged(option);
154+ }
155+}
plugins/Unity/genericoptionsmodel.hnew file+77
@@ -0,0 +1,77 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef GENERICOPTIONSMODEL_H
21+#define GENERICOPTIONSMODEL_H
22+
23+// Qt
24+#include <QObject>
25+#include <QAbstractListModel>
26+#include <QHash>
27+#include <QVector>
28+
29+class AbstractFilterOption;
30+
31+class Q_DECL_EXPORT GenericOptionsModel : public QAbstractListModel
32+{
33+ Q_OBJECT
34+
35+ Q_ENUMS(Roles)
36+
37+Q_SIGNALS:
38+ void activeChanged(AbstractFilterOption *option);
39+
40+public:
41+ GenericOptionsModel(QObject *parent = nullptr);
42+ ~GenericOptionsModel();
43+
44+ enum Roles {
45+ RoleId,
46+ RoleName,
47+ RoleIconHint,
48+ RoleActive
49+ };
50+
51+ QHash<int, QByteArray> roleNames() const override;
52+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
53+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
54+
55+ AbstractFilterOption* getRawOption(QVector<AbstractFilterOption *>::size_type idx) const;
56+
57+public Q_SLOTS:
58+ virtual void ensureTheOnlyActive(AbstractFilterOption *activeOption);
59+
60+protected Q_SLOTS:
61+ void onOptionChanged();
62+ void onActiveChanged();
63+
64+protected:
65+ void addOption(AbstractFilterOption *option, int index);
66+ void removeOption(int index);
67+ int indexOf(const QString &option_id);
68+
69+ QVector<AbstractFilterOption *> m_options;
70+private:
71+ void setupRoles();
72+ QHash<int, QByteArray> m_roles;
73+};
74+
75+Q_DECLARE_METATYPE(GenericOptionsModel*)
76+
77+#endif // GENERICOPTIONSMODEL_H
plugins/Unity/listmodelwrapper.hdeleted−146
@@ -1,146 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef LISTMODELWRAPPER_H
21−#define LISTMODELWRAPPER_H
22−
23−// Qt
24−#include <QAbstractListModel>
25−#include <QList>
26−
27−#include <sigc++/signal.h>
28−#include <vector>
29−
30−template <class WrapperItem, class ItemClass>
31−class ListModelWrapper : public QAbstractListModel
32−{
33−public:
34− explicit ListModelWrapper(const std::vector<ItemClass>& list,
35− sigc::signal<void, ItemClass> itemAddedSignal,
36− sigc::signal<void, ItemClass> itemRemovedSignal,
37− QObject *parent = nullptr);
38− ~ListModelWrapper();
39−
40− QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
41− int rowCount(const QModelIndex& parent = QModelIndex()) const;
42−
43− const QList<WrapperItem*>& rawList() const;
44−
45−private:
46− void onItemAdded(ItemClass item);
47− void onItemRemoved(ItemClass item);
48− void onItemChanged(ItemClass item);
49−
50− QList<WrapperItem*> m_list;
51− QMap<ItemClass, int> m_indexes;
52−
53− void addItem(ItemClass item, int index);
54− void removeItem(ItemClass item, int index);
55−};
56−
57−
58−template <class WrapperItem, class ItemClass>
59−ListModelWrapper<WrapperItem, ItemClass>::ListModelWrapper(const std::vector<ItemClass>& list,
60− sigc::signal<void, ItemClass> itemAddedSignal,
61− sigc::signal<void, ItemClass> itemRemovedSignal,
62− QObject *parent) :
63− QAbstractListModel(parent)
64−{
65− for (unsigned int i=0; i<list.size(); i++) {
66− addItem(list[i], i);
67− }
68− itemAddedSignal.connect(sigc::mem_fun(this, &ListModelWrapper::onItemAdded));
69− itemRemovedSignal.connect(sigc::mem_fun(this, &ListModelWrapper::onItemRemoved));
70−}
71−
72−template <class WrapperItem, class ItemClass>
73−ListModelWrapper<WrapperItem, ItemClass>::~ListModelWrapper()
74−{
75− m_indexes.clear();
76− while (!m_list.isEmpty()) {
77− delete m_list.takeFirst();
78− }
79−}
80−
81−template <class WrapperItem, class ItemClass>
82−int ListModelWrapper<WrapperItem, ItemClass>::rowCount(const QModelIndex& parent) const
83−{
84− Q_UNUSED(parent)
85−
86− return m_list.count();
87−}
88−
89−template <class WrapperItem, class ItemClass>
90−const QList<WrapperItem*>& ListModelWrapper<WrapperItem, ItemClass>::rawList() const
91−{
92− return m_list;
93−}
94−
95−template <class WrapperItem, class ItemClass>
96−QVariant ListModelWrapper<WrapperItem, ItemClass>::data(const QModelIndex& index, int) const
97−{
98− if (!index.isValid()) {
99− return QVariant();
100− }
101−
102− WrapperItem* item = m_list.at(index.row());
103−
104− return QVariant::fromValue(item);
105−}
106−
107−template <class WrapperItem, class ItemClass>
108−void ListModelWrapper<WrapperItem, ItemClass>::onItemAdded(ItemClass item)
109−{
110− int index = m_list.count();
111− beginInsertRows(QModelIndex(), index, index);
112− addItem(item, index);
113− endInsertRows();
114−}
115−
116−template <class WrapperItem, class ItemClass>
117−void ListModelWrapper<WrapperItem, ItemClass>::onItemRemoved(ItemClass item)
118−{
119− int index = m_indexes[item];
120− beginInsertRows(QModelIndex(), index, index);
121− removeItem(item, index);
122− endInsertRows();
123−}
124−
125−template <class WrapperItem, class ItemClass>
126−void ListModelWrapper<WrapperItem, ItemClass>::onItemChanged(ItemClass item)
127−{
128− QModelIndex itemIndex = index(m_indexes[item]);
129− Q_EMIT dataChanged(itemIndex, itemIndex);
130−}
131−
132−template <class WrapperItem, class ItemClass>
133−void ListModelWrapper<WrapperItem, ItemClass>::addItem(ItemClass item, int index)
134−{
135− m_indexes.insert(item, index);
136− m_list.insert(index, new WrapperItem(item));
137−}
138−
139−template <class WrapperItem, class ItemClass>
140−void ListModelWrapper<WrapperItem, ItemClass>::removeItem(ItemClass item, int index)
141−{
142− m_indexes.remove(item);
143− delete m_list.takeAt(index);
144−}
145−
146−#endif // LISTMODELWRAPPER_H
plugins/Unity/multirangefilter.cpp+9−2
@@ -21,12 +21,15 @@
21// Self
21// Self
22#include "multirangefilter.h"
22#include "multirangefilter.h"
23
23
24+// local
25+#include "unityoptionsmodel.h"
26+
24MultiRangeFilter::MultiRangeFilter(QObject *parent) :
27MultiRangeFilter::MultiRangeFilter(QObject *parent) :
25 Filter(parent), m_unityMultiRangeFilter(nullptr), m_options(nullptr)
28 Filter(parent), m_unityMultiRangeFilter(nullptr), m_options(nullptr)
26{
29{
27}
30}
28
31
29−CombinedFilterOptions* MultiRangeFilter::options() const
32+GenericOptionsModel* MultiRangeFilter::options() const
30{
33{
31 return m_options;
34 return m_options;
32}
35}
@@ -47,7 +50,11 @@ void MultiRangeFilter::onOptionsChanged(unity::dash::MultiRangeFilter::Options /
47 m_options = nullptr;
50 m_options = nullptr;
48 }
51 }
49
52
50− m_options = new CombinedFilterOptions(m_unityMultiRangeFilter->options);
53+ m_options = new UnityOptionsModel(this, m_unityMultiRangeFilter->options,
54+ m_unityMultiRangeFilter->option_added,
55+ m_unityMultiRangeFilter->option_removed);
56+
57+ connect(m_options, SIGNAL(activeChanged(AbstractFilterOption *)), m_options, SLOT(ensureTheOnlyActive(AbstractFilterOption *)));
51
58
52 /* Property change signals */
59 /* Property change signals */
53 m_signals << m_unityMultiRangeFilter->options.changed.connect(sigc::mem_fun(this, &MultiRangeFilter::onOptionsChanged));
60 m_signals << m_unityMultiRangeFilter->options.changed.connect(sigc::mem_fun(this, &MultiRangeFilter::onOptionsChanged));
plugins/Unity/multirangefilter.h+5−9
@@ -31,31 +31,27 @@
31// Local
31// Local
32#include "filter.h"
32#include "filter.h"
33#include "filteroption.h"
33#include "filteroption.h"
34−#include "combinedfilteroptions.h"
35#include "signalslist.h"
34#include "signalslist.h"
36
35
36+class GenericOptionsModel;
37+
37class Q_DECL_EXPORT MultiRangeFilter : public Filter
38class Q_DECL_EXPORT MultiRangeFilter : public Filter
38{
39{
39 Q_OBJECT
40 Q_OBJECT
40
41
41− Q_PROPERTY(CombinedFilterOptions* options READ options NOTIFY optionsChanged)
42−
43public:
42public:
44 explicit MultiRangeFilter(QObject *parent = nullptr);
43 explicit MultiRangeFilter(QObject *parent = nullptr);
45
44
46 /* getters */
45 /* getters */
47− CombinedFilterOptions* options() const;
46+ GenericOptionsModel* options() const override;
48−
49−Q_SIGNALS:
50− void optionsChanged();
51
47
52protected:
48protected:
53− virtual void setUnityFilter(unity::dash::Filter::Ptr filter);
49+ void setUnityFilter(unity::dash::Filter::Ptr filter) override;
54
50
55private:
51private:
56 unity::dash::MultiRangeFilter::Ptr m_unityMultiRangeFilter;
52 unity::dash::MultiRangeFilter::Ptr m_unityMultiRangeFilter;
57− CombinedFilterOptions* m_options;
58 SignalsList m_signals;
53 SignalsList m_signals;
54+ GenericOptionsModel* m_options;
59
55
60 void onOptionsChanged(unity::dash::MultiRangeFilter::Options);
56 void onOptionsChanged(unity::dash::MultiRangeFilter::Options);
61};
57};
plugins/Unity/radiooptionfilter.cpp+9−15
@@ -3,6 +3,7 @@
3 *
3 *
4 * Authors:
4 * Authors:
5 * Florian Boucault <florian.boucault@canonical.com>
5 * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6 *
7 *
7 * This program is free software; you can redistribute it and/or modify
8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * it under the terms of the GNU General Public License as published by
@@ -20,26 +21,19 @@
20// Self
21// Self
21#include "radiooptionfilter.h"
22#include "radiooptionfilter.h"
22
23
24+// local
25+#include "unityoptionsmodel.h"
26+
23RadioOptionFilter::RadioOptionFilter(QObject *parent) :
27RadioOptionFilter::RadioOptionFilter(QObject *parent) :
24 Filter(parent), m_unityRadioOptionFilter(nullptr), m_options(nullptr)
28 Filter(parent), m_unityRadioOptionFilter(nullptr), m_options(nullptr)
25{
29{
26}
30}
27
31
28−FilterOptions* RadioOptionFilter::options() const
32+GenericOptionsModel* RadioOptionFilter::options() const
29{
33{
30 return m_options;
34 return m_options;
31}
35}
32
36
33−FilterOption* RadioOptionFilter::getOption(const QString& id) const
34−{
35− Q_FOREACH (FilterOption* option, m_options->rawList()) {
36− if (option->id() == id) {
37− return option;
38− }
39− }
40− return nullptr;
41−}
42−
43void RadioOptionFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
37void RadioOptionFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
44{
38{
45 Filter::setUnityFilter(filter);
39 Filter::setUnityFilter(filter);
@@ -55,10 +49,10 @@ void RadioOptionFilter::onOptionsChanged(unity::dash::RadioOptionFilter::RadioOp
55 delete m_options;
49 delete m_options;
56 m_options = nullptr;
50 m_options = nullptr;
57 }
51 }
58− m_options = new FilterOptions(m_unityRadioOptionFilter->options,
52+ m_options = new UnityOptionsModel(this, m_unityRadioOptionFilter->options,
59− m_unityRadioOptionFilter->option_added,
53+ m_unityRadioOptionFilter->option_added,
60− m_unityRadioOptionFilter->option_removed);
54+ m_unityRadioOptionFilter->option_removed);
61− /* Property change signals */
55+
62 m_signals << m_unityRadioOptionFilter->options.changed.connect(sigc::mem_fun(this, &RadioOptionFilter::onOptionsChanged));
56 m_signals << m_unityRadioOptionFilter->options.changed.connect(sigc::mem_fun(this, &RadioOptionFilter::onOptionsChanged));
63
57
64 Q_EMIT optionsChanged();
58 Q_EMIT optionsChanged();
plugins/Unity/radiooptionfilter.h+4−10
@@ -3,6 +3,7 @@
3 *
3 *
4 * Authors:
4 * Authors:
5 * Florian Boucault <florian.boucault@canonical.com>
5 * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6 *
7 *
7 * This program is free software; you can redistribute it and/or modify
8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * it under the terms of the GNU General Public License as published by
@@ -36,25 +37,18 @@ class Q_DECL_EXPORT RadioOptionFilter : public Filter
36{
37{
37 Q_OBJECT
38 Q_OBJECT
38
39
39− Q_PROPERTY(FilterOptions* options READ options NOTIFY optionsChanged)
40−
41public:
40public:
42 explicit RadioOptionFilter(QObject *parent = nullptr);
41 explicit RadioOptionFilter(QObject *parent = nullptr);
43
42
44 /* getters */
43 /* getters */
45− FilterOptions* options() const;
44+ GenericOptionsModel* options() const override;
46−
47− Q_INVOKABLE FilterOption* getOption(const QString& id) const;
48−
49−Q_SIGNALS:
50− void optionsChanged();
51
45
52protected:
46protected:
53− virtual void setUnityFilter(unity::dash::Filter::Ptr filter);
47+ void setUnityFilter(unity::dash::Filter::Ptr filter) override;
54
48
55private:
49private:
56 unity::dash::RadioOptionFilter::Ptr m_unityRadioOptionFilter;
50 unity::dash::RadioOptionFilter::Ptr m_unityRadioOptionFilter;
57− FilterOptions* m_options;
51+ GenericOptionsModel* m_options;
58 SignalsList m_signals;
52 SignalsList m_signals;
59
53
60 void onOptionsChanged(unity::dash::RadioOptionFilter::RadioOptions);
54 void onOptionsChanged(unity::dash::RadioOptionFilter::RadioOptions);
plugins/Unity/ratingfilteroption.cpp+12−1
@@ -20,7 +20,7 @@
20#include "ratingfilteroption.h"
20#include "ratingfilteroption.h"
21
21
22RatingFilterOption::RatingFilterOption(const QString &id, float value, QObject *parent) :
22RatingFilterOption::RatingFilterOption(const QString &id, float value, QObject *parent) :
23− QObject(parent),
23+ AbstractFilterOption(parent),
24 m_active(false),
24 m_active(false),
25 m_id(id),
25 m_id(id),
26 m_value(value)
26 m_value(value)
@@ -32,6 +32,17 @@ QString RatingFilterOption::id() const
32 return m_id;
32 return m_id;
33}
33}
34
34
35+
36+QString RatingFilterOption::name() const
37+{
38+ return QString::Null();
39+}
40+
41+QString RatingFilterOption::iconHint() const
42+{
43+ return QString::Null();
44+}
45+
35float RatingFilterOption::value() const
46float RatingFilterOption::value() const
36{
47{
37 return m_value;
48 return m_value;
plugins/Unity/ratingfilteroption.h+8−9
@@ -20,25 +20,24 @@
20#ifndef RATINGFILTEROPTION_H
20#ifndef RATINGFILTEROPTION_H
21#define RATINGFILTEROPTION_H
21#define RATINGFILTEROPTION_H
22
22
23−#include <QObject>
23+#include "abstractfilteroption.h"
24
24
25−class Q_DECL_EXPORT RatingFilterOption : public QObject
25+class Q_DECL_EXPORT RatingFilterOption : public AbstractFilterOption
26{
26{
27 Q_OBJECT
27 Q_OBJECT
28
28
29public:
29public:
30− explicit RatingFilterOption(const QString &id, float ratingValue, QObject *parent = 0);
30+ explicit RatingFilterOption(const QString &id, float ratingValue, QObject *parent = nullptr);
31
31
32 /* getters */
32 /* getters */
33− QString id() const;
33+ QString id() const override;
34+ QString name() const override;
35+ QString iconHint() const override;
34− bool active() const;
36+ bool active() const override;
35 float value() const;
37 float value() const;
36
38
37 /* setters */
39 /* setters */
38− Q_INVOKABLE void setActive(bool active);
40+ void setActive(bool active) override;
39−
40−Q_SIGNALS:
41− void activeChanged(bool);
42
41
43private:
42private:
44 bool m_active;
43 bool m_active;
plugins/Unity/ratingoptionsmodel.cppnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// self
21+#include "ratingoptionsmodel.h"
22+
23+// local
24+#include "ratingfilteroption.h"
25+
26+RatingOptionsModel::RatingOptionsModel(QObject *parent) :
27+ GenericOptionsModel(parent)
28+{
29+ for (int i=1; i<=5; i++) {
30+ auto opt = new RatingFilterOption(QString::number(i), i*0.2f, this);
31+ addOption(opt, i-1);
32+ }
33+}
plugins/Unity/combinedfilteroptions.h → plugins/Unity/ratingoptionsmodel.hrenamed+6−21
@@ -17,32 +17,17 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
18 */
19
19
20−#ifndef COMBINEDFILTEROPTIONS_H
20+#ifndef RATINGOPTIONSMODEL_H
21−#define COMBINEDFILTEROPTIONS_H
21+#define RATINGOPTIONSMODEL_H
22
22
23−// Qt
23+#include "genericoptionsmodel.h"
24−#include <QObject>
25
24
26−// libunity-core
25+class RatingOptionsModel : public GenericOptionsModel
27−#include <UnityCore/Filter.h>
28−
29−// local
30−#include "genericlistmodel.h"
31−
32−class CombinedFilterOptions : public GenericListModel
33{
26{
34 Q_OBJECT
27 Q_OBJECT
35
28
36public:
29public:
37− CombinedFilterOptions(const std::vector<unity::dash::FilterOption::Ptr>& list, QObject *parent = nullptr);
30+ RatingOptionsModel(QObject *parent);
38−
39−private Q_SLOTS:
40− void onActiveChanged(bool state);
41−
42−private:
43− void initList(const std::vector<unity::dash::FilterOption::Ptr>& list);
44};
31};
45
32
46−Q_DECLARE_METATYPE(CombinedFilterOptions*)
33+#endif // RATINGOPTIONSMODEL_H
47−
48−#endif // COMBINEDFILTEROPTIONS_H
plugins/Unity/ratingsfilter.cpp+24−36
@@ -3,6 +3,7 @@
3 *
3 *
4 * Authors:
4 * Authors:
5 * Florian Boucault <florian.boucault@canonical.com>
5 * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6 *
7 *
7 * This program is free software; you can redistribute it and/or modify
8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * it under the terms of the GNU General Public License as published by
@@ -21,62 +22,49 @@
21#include "ratingsfilter.h"
22#include "ratingsfilter.h"
22
23
23// local
24// local
24−#include "genericlistmodel.h"
25#include "ratingfilteroption.h"
25#include "ratingfilteroption.h"
26−
26+#include "ratingoptionsmodel.h"
27−// Qt
28−#include <QDebug>
29
27
30RatingsFilter::RatingsFilter(QObject *parent) :
28RatingsFilter::RatingsFilter(QObject *parent) :
29+ Filter(parent),
31− Filter(parent), m_unityRatingsFilter(nullptr), m_options(nullptr)
30+ m_unityRatingsFilter(nullptr),
31+ m_options(nullptr)
32{
32{
33}
33}
34
34
35−GenericListModel* RatingsFilter::options() const
35+GenericOptionsModel* RatingsFilter::options() const
36{
36{
37 return m_options;
37 return m_options;
38}
38}
39
39
40−void RatingsFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
40+float RatingsFilter::rating() const
41{
41{
42− if (m_unityFilter != nullptr) {
42+ if (m_unityRatingsFilter)
43− m_signals.disconnectAll();
43+ {
44+ return m_unityRatingsFilter->rating;
44 }
45 }
46+ return 0.0f;
47+}
45
48
49+void RatingsFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
50+{
46 Filter::setUnityFilter(filter);
51 Filter::setUnityFilter(filter);
47 m_unityRatingsFilter = std::dynamic_pointer_cast<unity::dash::RatingsFilter>(m_unityFilter);
52 m_unityRatingsFilter = std::dynamic_pointer_cast<unity::dash::RatingsFilter>(m_unityFilter);
48
53
49− if (m_options) {
50− delete m_options;
54+ delete m_options;
51− }
52
55
53− m_options = new GenericListModel(this);
56+ m_options = new RatingOptionsModel(this);
54− for (int i=1; i<=5; i++) {
57+ connect(m_options, SIGNAL(activeChanged(AbstractFilterOption *)), m_options, SLOT(ensureTheOnlyActive(AbstractFilterOption *)));
55− auto opt = new RatingFilterOption(QString::number(i), i*0.2f, this);
56− connect(opt, SIGNAL(activeChanged(bool)), this, SLOT(onActiveChanged()));
58+ connect(m_options, SIGNAL(activeChanged(AbstractFilterOption *)), this, SLOT(onActiveChanged(AbstractFilterOption *)));
57− m_options->addObject(opt);
58− }
59
59
60− Q_EMIT ratingsChanged();
60+ Q_EMIT optionsChanged();
61}
61}
62
62
63−void RatingsFilter::onActiveChanged()
63+void RatingsFilter::onActiveChanged(AbstractFilterOption *option)
64{
64{
65− RatingFilterOption *option = dynamic_cast<RatingFilterOption*>(QObject::sender());
65+ RatingFilterOption *ratingOption = dynamic_cast<RatingFilterOption*>(option);
66− if (option != nullptr) {
66+ if (ratingOption != nullptr)
67− if (option->active()) {
67+ {
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();
68+ m_unityRatingsFilter->rating = ratingOption->active() ? ratingOption->value() : 0.0f;
76− }
77−
78− Q_EMIT ratingsChanged();
79− } else {
80− qWarning() << "Invalid option";
81 }
69 }
82}
70}
plugins/Unity/ratingsfilter.h+10−9
@@ -3,6 +3,7 @@
3 *
3 *
4 * Authors:
4 * Authors:
5 * Florian Boucault <florian.boucault@canonical.com>
5 * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6 *
7 *
7 * This program is free software; you can redistribute it and/or modify
8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * it under the terms of the GNU General Public License as published by
@@ -29,35 +30,35 @@
29
30
30// Local
31// Local
31#include "filter.h"
32#include "filter.h"
32−#include "signalslist.h"
33
33
34−class GenericListModel;
34+class GenericOptionsModel;
35+class AbstractFilterOption;
35
36
36class Q_DECL_EXPORT RatingsFilter : public Filter
37class Q_DECL_EXPORT RatingsFilter : public Filter
37{
38{
38 Q_OBJECT
39 Q_OBJECT
39
40
40− Q_PROPERTY(GenericListModel* options READ options NOTIFY ratingsChanged)
41+ Q_PROPERTY(float rating READ rating NOTIFY ratingChanged)
41
42
42public:
43public:
43 explicit RatingsFilter(QObject *parent = nullptr);
44 explicit RatingsFilter(QObject *parent = nullptr);
44
45
45 /* getters */
46 /* getters */
46− GenericListModel* options() const;
47+ GenericOptionsModel* options() const override;
48+ float rating() const;
47
49
48Q_SIGNALS:
50Q_SIGNALS:
49− void ratingsChanged();
51+ void ratingChanged(float);
50
52
51protected:
53protected:
52− virtual void setUnityFilter(unity::dash::Filter::Ptr filter);
54+ void setUnityFilter(unity::dash::Filter::Ptr filter) override;
53
55
54protected Q_SLOTS:
56protected Q_SLOTS:
55− void onActiveChanged();
57+ void onActiveChanged(AbstractFilterOption *option);
56
58
57private:
59private:
58 unity::dash::RatingsFilter::Ptr m_unityRatingsFilter;
60 unity::dash::RatingsFilter::Ptr m_unityRatingsFilter;
59− GenericListModel *m_options;
61+ GenericOptionsModel *m_options;
60− SignalsList m_signals;
61};
62};
62
63
63Q_DECLARE_METATYPE(RatingsFilter*)
64Q_DECLARE_METATYPE(RatingsFilter*)
plugins/Unity/unityoptionsmodel.cppnew file+67
@@ -0,0 +1,67 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// self
21+#include "unityoptionsmodel.h"
22+
23+// local
24+#include "filteroption.h"
25+
26+UnityOptionsModel::UnityOptionsModel(QObject *parent,
27+ const std::vector<unity::dash::FilterOption::Ptr> options,
28+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionAdded,
29+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionRemoved) :
30+ GenericOptionsModel(parent)
31+{
32+ setOptions(options, optionAdded, optionRemoved);
33+}
34+
35+void UnityOptionsModel::setOptions(const std::vector<unity::dash::FilterOption::Ptr> options,
36+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionAdded,
37+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionRemoved)
38+{
39+ for (unsigned int i=0; i<options.size(); i++)
40+ {
41+ addOption(new FilterOption(options[i], this), i);
42+ }
43+ optionAdded.connect(sigc::mem_fun(this, &UnityOptionsModel::onOptionAdded));
44+ optionRemoved.connect(sigc::mem_fun(this, &UnityOptionsModel::onOptionRemoved));
45+}
46+
47+void UnityOptionsModel::onOptionAdded(unity::dash::FilterOption::Ptr option)
48+{
49+ int index = m_options.count();
50+ if (index >= 0)
51+ {
52+ beginInsertRows(QModelIndex(), index, index);
53+ addOption(new FilterOption(option, this), index);
54+ endInsertRows();
55+ }
56+}
57+
58+void UnityOptionsModel::onOptionRemoved(unity::dash::FilterOption::Ptr option)
59+{
60+ auto index = indexOf(QString::fromStdString(option->id));
61+ if (index >= 0)
62+ {
63+ beginRemoveRows(QModelIndex(), index, index);
64+ removeOption(index);
65+ endRemoveRows();
66+ }
67+}
plugins/Unity/unityoptionsmodel.hnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef UNITYOPTIONSMODEL_H
21+#define UNITYOPTIONSMODEL_H
22+
23+#include "genericoptionsmodel.h"
24+
25+// libunity-core
26+#include <UnityCore/Filter.h>
27+
28+#include <sigc++/signal.h>
29+
30+class UnityOptionsModel : public GenericOptionsModel
31+{
32+ Q_OBJECT
33+
34+public:
35+ UnityOptionsModel(QObject *parent,
36+ const std::vector<unity::dash::FilterOption::Ptr> options,
37+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionAdded,
38+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionRemoved);
39+
40+private:
41+ void setOptions(const std::vector<unity::dash::FilterOption::Ptr> options,
42+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionAdded,
43+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionRemoved);
44+
45+ void onOptionAdded(unity::dash::FilterOption::Ptr option);
46+ void onOptionRemoved(unity::dash::FilterOption::Ptr option);
47+};
48+
49+#endif // UNITYOPTIONSMODEL_H
tests/plugins/Unity/filtersbindingstest.cpp+86−50
@@ -33,11 +33,11 @@
33// local
33// local
34#include "filter.h"
34#include "filter.h"
35#include "multirangefilter.h"
35#include "multirangefilter.h"
36−#include "combinedfilteroption.h"
37#include "checkoptionfilter.h"
36#include "checkoptionfilter.h"
38#include "radiooptionfilter.h"
37#include "radiooptionfilter.h"
39#include "ratingsfilter.h"
38#include "ratingsfilter.h"
40#include "ratingfilteroption.h"
39#include "ratingfilteroption.h"
40+#include "genericoptionsmodel.h"
41
41
42void FiltersBindingsTest::initTestCase()
42void FiltersBindingsTest::initTestCase()
43{
43{
@@ -145,9 +145,16 @@ void FiltersBindingsTest::testMultiRangeFilter()
145 auto options = multi_filter->options();
145 auto options = multi_filter->options();
146 QCOMPARE(options->rowCount(), 1);
146 QCOMPARE(options->rowCount(), 1);
147
147
148− QVariant optvar = options->data(options->index(0));
148+ auto idx = options->index(0);
149− CombinedFilterOption* opt1 = optvar.value<CombinedFilterOption*>();
149+ QVariant id_var = options->data(idx, GenericOptionsModel::RoleId);
150+ QVariant name_var = options->data(idx, GenericOptionsModel::RoleName);
151+ QVariant icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
152+ QVariant active_var = options->data(idx, GenericOptionsModel::RoleActive);
153+
150− QCOMPARE(opt1->id(), QString("opt0"));
154+ QCOMPARE(id_var.toString(), QString("opt0"));
155+ QCOMPARE(name_var.toString(), QString("Option 0"));
156+ QCOMPARE(icon_var.toString(), QString(""));
157+ QCOMPARE(active_var.toBool(), false);
151
158
152 delete multi_filter;
159 delete multi_filter;
153 }
160 }
@@ -163,12 +170,21 @@ void FiltersBindingsTest::testMultiRangeFilter()
163 auto options = multi_filter->options();
170 auto options = multi_filter->options();
164 QCOMPARE(options->rowCount(), 2);
171 QCOMPARE(options->rowCount(), 2);
165
172
166− QVariant optvar = options->data(options->index(0));
173+ auto idx = options->index(0);
167− CombinedFilterOption* opt1 = optvar.value<CombinedFilterOption*>();
174+ QVariant id_var = options->data(idx, GenericOptionsModel::RoleId);
175+ QVariant name_var = options->data(idx, GenericOptionsModel::RoleName);
176+ QVariant icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
177+ QVariant active_var = options->data(idx, GenericOptionsModel::RoleActive);
178+
168− QCOMPARE(opt1->id(), QString("opt0-opt1"));
179+ QCOMPARE(id_var.toString(), QString("opt0"));
180+ QCOMPARE(name_var.toString(), QString("Option 0"));
181+ QCOMPARE(icon_var.toString(), QString(""));
182+ QCOMPARE(active_var.toBool(), false);
169
183
170− optvar = options->data(options->index(1));
184+ AbstractFilterOption* opt1 = options->getRawOption(0);
171− CombinedFilterOption* opt2 = optvar.value<CombinedFilterOption*>();
185+ QCOMPARE(opt1->id(), QString("opt0"));
186+
187+ AbstractFilterOption* opt2 = options->getRawOption(1);
172 QCOMPARE(opt2->id(), QString("opt1"));
188 QCOMPARE(opt2->id(), QString("opt1"));
173
189
174 delete multi_filter;
190 delete multi_filter;
@@ -185,16 +201,13 @@ void FiltersBindingsTest::testMultiRangeFilter()
185 auto options = multi_filter->options();
201 auto options = multi_filter->options();
186 QCOMPARE(options->rowCount(), 3);
202 QCOMPARE(options->rowCount(), 3);
187
203
188− QVariant optvar = options->data(options->index(0));
204+ AbstractFilterOption* opt0 = options->getRawOption(0);
189− CombinedFilterOption* opt0 = optvar.value<CombinedFilterOption*>();
190− QCOMPARE(opt0->id(), QString("opt0-opt1"));
205+ QCOMPARE(opt0->id(), QString("opt0"));
191
206
192− optvar = options->data(options->index(1));
207+ AbstractFilterOption* opt1 = options->getRawOption(1);
193− CombinedFilterOption* opt1 = optvar.value<CombinedFilterOption*>();
194− QCOMPARE(opt1->id(), QString("opt1-opt2"));
208+ QCOMPARE(opt1->id(), QString("opt1"));
195
209
196− optvar = options->data(options->index(2));
210+ AbstractFilterOption* opt2 = options->getRawOption(2);
197− CombinedFilterOption* opt2 = optvar.value<CombinedFilterOption*>();
198 QCOMPARE(opt2->id(), QString("opt2"));
211 QCOMPARE(opt2->id(), QString("opt2"));
199
212
200 // verify combined filter options are bound to correct underlying unity options
213 // verify combined filter options are bound to correct underlying unity options
@@ -210,25 +223,21 @@ void FiltersBindingsTest::testMultiRangeFilter()
210 // test active property changes
223 // test active property changes
211 QCOMPARE(opt0->active(), false);
224 QCOMPARE(opt0->active(), false);
212
225
213− opt0->setActive(true); // activate 1st combined option
226+ opt0->setActive(true); // activate 1st option
214 QCOMPARE(opt0spy.count(), 1);
227 QCOMPARE(opt0spy.count(), 1);
215 QCOMPARE(opt1spy.count(), 0);
228 QCOMPARE(opt1spy.count(), 0);
216 QCOMPARE(opt2spy.count(), 0);
229 QCOMPARE(opt2spy.count(), 0);
217 QCOMPARE(opt0->active(), true);
230 QCOMPARE(opt0->active(), true);
218 QCOMPARE(opt1->active(), false);
231 QCOMPARE(opt1->active(), false);
219− QCOMPARE(core_multi_filter->options()[0]->active(), true);
232+ QCOMPARE(opt2->active(), false);
220− QCOMPARE(core_multi_filter->options()[1]->active(), true);
221− QCOMPARE(core_multi_filter->options()[2]->active(), false);
222
233
223− opt1->setActive(true); // activate another combined option
234+ opt1->setActive(true);
224 QCOMPARE(opt0spy.count(), 2);
235 QCOMPARE(opt0spy.count(), 2);
225 QCOMPARE(opt1spy.count(), 1);
236 QCOMPARE(opt1spy.count(), 1);
226 QCOMPARE(opt2spy.count(), 0);
237 QCOMPARE(opt2spy.count(), 0);
227 QCOMPARE(opt0->active(), false); //1st combined option gets deactivated
238 QCOMPARE(opt0->active(), false); //1st combined option gets deactivated
228 QCOMPARE(opt1->active(), true);
239 QCOMPARE(opt1->active(), true);
229− QCOMPARE(core_multi_filter->options()[0]->active(), false);
240+ QCOMPARE(opt2->active(), false);
230− QCOMPARE(core_multi_filter->options()[1]->active(), true); // shared option, stays active
231− QCOMPARE(core_multi_filter->options()[2]->active(), true);
232
241
233 opt1->setActive(false); // and de-activate it
242 opt1->setActive(false); // and de-activate it
234 QCOMPARE(opt0spy.count(), 2);
243 QCOMPARE(opt0spy.count(), 2);
@@ -236,9 +245,7 @@ void FiltersBindingsTest::testMultiRangeFilter()
236 QCOMPARE(opt2spy.count(), 0);
245 QCOMPARE(opt2spy.count(), 0);
237 QCOMPARE(opt0->active(), false);
246 QCOMPARE(opt0->active(), false);
238 QCOMPARE(opt1->active(), false);
247 QCOMPARE(opt1->active(), false);
239− QCOMPARE(core_multi_filter->options()[0]->active(), false);
248+ QCOMPARE(opt2->active(), false);
240− QCOMPARE(core_multi_filter->options()[1]->active(), false);
241− QCOMPARE(core_multi_filter->options()[2]->active(), false);
242
249
243 opt2->setActive(true); // activate another combined option
250 opt2->setActive(true); // activate another combined option
244 QCOMPARE(opt0spy.count(), 2);
251 QCOMPARE(opt0spy.count(), 2);
@@ -247,9 +254,6 @@ void FiltersBindingsTest::testMultiRangeFilter()
247 QCOMPARE(opt0->active(), false);
254 QCOMPARE(opt0->active(), false);
248 QCOMPARE(opt1->active(), false);
255 QCOMPARE(opt1->active(), false);
249 QCOMPARE(opt2->active(), true);
256 QCOMPARE(opt2->active(), true);
250− QCOMPARE(core_multi_filter->options()[0]->active(), false);
251− QCOMPARE(core_multi_filter->options()[1]->active(), false);
252− QCOMPARE(core_multi_filter->options()[2]->active(), true);
253
257
254 delete multi_filter;
258 delete multi_filter;
255 }
259 }
@@ -280,17 +284,31 @@ void FiltersBindingsTest::testCheckOptionFilter()
280 QCOMPARE(check_filter->collapsed(), false);
284 QCOMPARE(check_filter->collapsed(), false);
281 QCOMPARE(check_filter->filtering(), false);
285 QCOMPARE(check_filter->filtering(), false);
282
286
283− QVariant optvar = options->data(options->index(0));
287+ auto idx = options->index(0);
284− FilterOption* opt0 = optvar.value<FilterOption*>();
288+ QVariant id_var = options->data(idx, GenericOptionsModel::RoleId);
285− QCOMPARE(opt0->id(), QString("opt0"));
289+ QVariant name_var = options->data(idx, GenericOptionsModel::RoleName);
290+ QVariant icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
291+ QVariant active_var = options->data(idx, GenericOptionsModel::RoleActive);
286
292
287− optvar = options->data(options->index(1));
293+ QCOMPARE(id_var.toString(), QString("opt0"));
288− FilterOption* opt1 = optvar.value<FilterOption*>();
294+ QCOMPARE(name_var.toString(), QString("Option 0"));
289− QCOMPARE(opt1->id(), QString("opt1"));
295+ QCOMPARE(icon_var.toString(), QString(""));
296+ QCOMPARE(active_var.toBool(), false);
290
297
291− optvar = options->data(options->index(2));
298+ idx = options->index(1);
292− FilterOption* opt2 = optvar.value<FilterOption*>();
299+ id_var = options->data(idx, GenericOptionsModel::RoleId);
293− QCOMPARE(opt2->id(), QString("opt2"));
300+ name_var = options->data(idx, GenericOptionsModel::RoleName);
301+ icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
302+ active_var = options->data(idx, GenericOptionsModel::RoleActive);
303+
304+ QCOMPARE(id_var.toString(), QString("opt1"));
305+ QCOMPARE(name_var.toString(), QString("Option 1"));
306+ QCOMPARE(icon_var.toString(), QString(""));
307+ QCOMPARE(active_var.toBool(), false);
308+
309+ AbstractFilterOption* opt0 = options->getRawOption(0);
310+ AbstractFilterOption* opt1 = options->getRawOption(1);
311+ AbstractFilterOption* opt2 = options->getRawOption(2);
294
312
295 QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
313 QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
296 QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
314 QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
@@ -338,17 +356,31 @@ void FiltersBindingsTest::testRadioOptionFilter()
338 auto options = radio_filter->options();
356 auto options = radio_filter->options();
339 QCOMPARE(options->rowCount(), 3);
357 QCOMPARE(options->rowCount(), 3);
340
358
341− QVariant optvar = options->data(options->index(0));
359+ auto idx = options->index(0);
342− FilterOption* opt0 = optvar.value<FilterOption*>();
360+ QVariant id_var = options->data(idx, GenericOptionsModel::RoleId);
343− QCOMPARE(opt0->id(), QString("opt0"));
361+ QVariant name_var = options->data(idx, GenericOptionsModel::RoleName);
362+ QVariant icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
363+ QVariant active_var = options->data(idx, GenericOptionsModel::RoleActive);
344
364
345− optvar = options->data(options->index(1));
365+ QCOMPARE(id_var.toString(), QString("opt0"));
346− FilterOption* opt1 = optvar.value<FilterOption*>();
366+ QCOMPARE(name_var.toString(), QString("Option 0"));
347− QCOMPARE(opt1->id(), QString("opt1"));
367+ QCOMPARE(icon_var.toString(), QString(""));
368+ QCOMPARE(active_var.toBool(), false);
348
369
349− optvar = options->data(options->index(2));
370+ idx = options->index(1);
350− FilterOption* opt2 = optvar.value<FilterOption*>();
371+ id_var = options->data(idx, GenericOptionsModel::RoleId);
351− QCOMPARE(opt2->id(), QString("opt2"));
372+ name_var = options->data(idx, GenericOptionsModel::RoleName);
373+ icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
374+ active_var = options->data(idx, GenericOptionsModel::RoleActive);
375+
376+ QCOMPARE(id_var.toString(), QString("opt1"));
377+ QCOMPARE(name_var.toString(), QString("Option 1"));
378+ QCOMPARE(icon_var.toString(), QString(""));
379+ QCOMPARE(active_var.toBool(), false);
380+
381+ AbstractFilterOption* opt0 = options->getRawOption(0);
382+ AbstractFilterOption* opt1 = options->getRawOption(1);
383+ AbstractFilterOption* opt2 = options->getRawOption(2);
352
384
353 QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
385 QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
354 QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
386 QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
@@ -398,7 +430,7 @@ void FiltersBindingsTest::testRatingsFilter()
398
430
399 RatingFilterOption* opt[5];
431 RatingFilterOption* opt[5];
400 for (int i = 0; i<5; i++) {
432 for (int i = 0; i<5; i++) {
401− opt[i] = options->data(options->index(i)).value<RatingFilterOption*>();
433+ opt[i] = dynamic_cast<RatingFilterOption *>(options->getRawOption(i));
402 }
434 }
403
435
404 QSignalSpy opt0spy(opt[0], SIGNAL(activeChanged(bool)));
436 QSignalSpy opt0spy(opt[0], SIGNAL(activeChanged(bool)));
@@ -410,6 +442,8 @@ void FiltersBindingsTest::testRatingsFilter()
410 QVERIFY(qAbs(opt[3]->value() - 0.8f) <= 0.0001f);
442 QVERIFY(qAbs(opt[3]->value() - 0.8f) <= 0.0001f);
411 QVERIFY(qAbs(opt[4]->value() - 1.0f) <= 0.0001f);
443 QVERIFY(qAbs(opt[4]->value() - 1.0f) <= 0.0001f);
412
444
445+ QVERIFY(rating_filter->rating() <= 0.0001f); // rating equals zero
446+
413 // all options initially inactive
447 // all options initially inactive
414 for (int i=0; i<5; i++) {
448 for (int i=0; i<5; i++) {
415 QCOMPARE(opt[i]->active(), false);
449 QCOMPARE(opt[i]->active(), false);
@@ -419,6 +453,7 @@ void FiltersBindingsTest::testRatingsFilter()
419 for (int i=0; i<5; i++) {
453 for (int i=0; i<5; i++) {
420 opt[i]->setActive(true);
454 opt[i]->setActive(true);
421 QCOMPARE(opt[i]->active(), true);
455 QCOMPARE(opt[i]->active(), true);
456+ QVERIFY(rating_filter->rating() - ((i+1)*0.2f) <= 0.0001f);
422
457
423 // verify that all other options are inactive
458 // verify that all other options are inactive
424 for (int j=0; j<5; j++) {
459 for (int j=0; j<5; j++) {
@@ -432,6 +467,7 @@ void FiltersBindingsTest::testRatingsFilter()
432 QCOMPARE(opt4spy.count(), 1);
467 QCOMPARE(opt4spy.count(), 1);
433
468
434 opt[4]->setActive(false);
469 opt[4]->setActive(false);
470+ QVERIFY(rating_filter->rating() <= 0.0001f); // rating equals zero
435 QCOMPARE(opt4spy.count(), 2);
471 QCOMPARE(opt4spy.count(), 2);
436 }
472 }
437}
473}