@@ -24,11 +24,20 @@
2424
2525#define CATEGORY_COLUMN 2
2626
27+// TODO: use something from libunity once it's public
28+enum CategoryColumn {
29+ ID,
30+ DISPLAY_NAME,
31+ ICON_HINT,
32+ RENDERER_NAME,
33+ HINTS
34+};
35+
2736Categories::Categories(QObject* parent)
2837 : DeeListModel(parent)
2938{
3039 // FIXME: need to clean up unused filters on countChanged
31− m_roles[Categories::RoleId] = "id";
40+ m_roles[Categories::RoleCategoryId] = "categoryId";
3241 m_roles[Categories::RoleName] = "name";
3342 m_roles[Categories::RoleIcon] = "icon";
3443 m_roles[Categories::RoleRenderer] = "renderer";
@@ -74,6 +83,25 @@ Categories::onCountChanged()
7483 }
7584}
7685
86+void Categories::onRowCountChanged()
87+{
88+ QAbstractItemModel* model = qobject_cast<QAbstractItemModel*>(sender());
89+ // find the corresponding category index
90+ for (auto iter = m_overriddenCategories.begin(); iter != m_overriddenCategories.end(); ++iter) {
91+ if (iter.value() == model) {
92+ for (int i = 0; i < rowCount(); i++) {
93+ auto id = data(index(i), RoleCategoryId).toString();
94+ if (id != iter.key()) continue;
95+ QVector<int> roles;
96+ roles.append(RoleCount);
97+ QModelIndex changedIndex = index(i);
98+ Q_EMIT dataChanged(changedIndex, changedIndex, roles);
99+ break;
100+ }
101+ }
102+ }
103+}
104+
77105void
78106Categories::onEmitCountChanged()
79107{
@@ -93,6 +121,41 @@ Categories::roleNames() const
93121 return m_roles;
94122}
95123
124+void Categories::onOverrideModelDestroyed()
125+{
126+ QObject* model = sender();
127+ auto iter = m_overriddenCategories.begin();
128+ while (iter != m_overriddenCategories.end()) {
129+ if (iter.value() == model) {
130+ iter = m_overriddenCategories.erase(iter);
131+ continue;
132+ }
133+ ++iter;
134+ }
135+}
136+
137+void Categories::overrideResults(const QString& categoryId, QAbstractItemModel* model)
138+{
139+ m_overriddenCategories[categoryId] = model;
140+ // watch the model
141+ connect(model, &QObject::destroyed, this, &Categories::onOverrideModelDestroyed);
142+ connect(model, &QAbstractItemModel::rowsInserted, this, &Categories::onRowCountChanged);
143+ connect(model, &QAbstractItemModel::rowsRemoved, this, &Categories::onRowCountChanged);
144+ connect(model, &QAbstractItemModel::modelReset, this, &Categories::onRowCountChanged);
145+
146+ // emit the dataChanged signal if the category is already in the model
147+ for (int i = 0; i < rowCount(); i++) {
148+ auto id = data(index(i), RoleCategoryId).toString();
149+ if (id != categoryId) continue;
150+ QVector<int> roles;
151+ roles.append(RoleCount);
152+ roles.append(RoleResults);
153+ QModelIndex changedIndex = index(i);
154+ Q_EMIT dataChanged(changedIndex, changedIndex, roles);
155+ break;
156+ }
157+}
158+
96159void Categories::setResultModel(DeeModel* model)
97160{
98161 // FIXME: should ref it
@@ -154,24 +217,36 @@ Categories::data(const QModelIndex& index, int role) const
154217 }
155218
156219 switch (role) {
157− case RoleId:
158− return DeeListModel::data(index, 0); //ID
220+ case RoleCategoryId:
221+ return DeeListModel::data(index, CategoryColumn::ID);
159222 case RoleName:
160− return DeeListModel::data(index, 1); //DISPLAY_NAME
223+ return DeeListModel::data(index, CategoryColumn::DISPLAY_NAME);
161224 case RoleIcon:
162− return DeeListModel::data(index, 2); //ICON_HINT
225+ return DeeListModel::data(index, CategoryColumn::ICON_HINT);
163226 case RoleRenderer:
164− return DeeListModel::data(index, 3); //RENDERER_NAME
227+ return DeeListModel::data(index, CategoryColumn::RENDERER_NAME);
165228 case RoleContentType:
166229 {
167− auto hints = DeeListModel::data(index, 4).toHash();
168− return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
230+ auto hints = DeeListModel::data(index, CategoryColumn::HINTS).toHash();
231+ return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
169232 }
170233 case RoleHints:
171− return DeeListModel::data(index, 4); //HINTS
234+ return DeeListModel::data(index, CategoryColumn::HINTS);
172235 case RoleResults:
236+ if (m_overriddenCategories.size() > 0)
237+ {
238+ auto id = DeeListModel::data(index, CategoryColumn::ID).toString();
239+ if (m_overriddenCategories.find(id) != m_overriddenCategories.end())
240+ return QVariant::fromValue(m_overriddenCategories[id]);
241+ }
173242 return QVariant::fromValue(getFilter(index.row()));
174243 case RoleCount:
244+ if (m_overriddenCategories.size() > 0)
245+ {
246+ auto id = DeeListModel::data(index, CategoryColumn::ID).toString();
247+ if (m_overriddenCategories.find(id) != m_overriddenCategories.end())
248+ return QVariant::fromValue(m_overriddenCategories[id]->rowCount());
249+ }
175250 return QVariant::fromValue(getFilter(index.row())->rowCount());
176251 case RoleCategoryIndex:
177252 return QVariant::fromValue(index.row());