on 0ee222d help sign in
unity8/tests/mocks/Unity/fake_categories.cpp
181 lines 5.7 kB history raw
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Nick Dedekind <nick.dedekind@canonical.com>
17 */
19// self
20#include "fake_categories.h"
22// local
23#include "categoryresults.h"
25#define CATEGORY_COLUMN 2
27Categories::Categories(QObject* parent)
28 : DeeListModel(parent)
30 // FIXME: need to clean up unused filters on countChanged
31 m_roles[Categories::RoleId] = "id";
32 m_roles[Categories::RoleName] = "name";
33 m_roles[Categories::RoleIcon] = "icon";
34 m_roles[Categories::RoleRenderer] = "renderer";
35 m_roles[Categories::RoleContentType] = "contentType";
36 m_roles[Categories::RoleHints] = "hints";
37 m_roles[Categories::RoleResults] = "results";
38 m_roles[Categories::RoleCount] = "count";
39 m_roles[Categories::RoleCategoryIndex] = "categoryIndex";
41 // TODO This should not be needed but accumulatting the count changes
42 // makes the visualization more stable and also makes crashes on fast
43 // change of the search term harder to reproduce
44 m_timer.setSingleShot(true);
45 m_timer.setInterval(50);
46 connect(&m_timer, SIGNAL(timeout()), this, SLOT(onEmitCountChanged()));
49DeeListModel*
50Categories::getFilter(int index) const
52 if (!m_filters.contains(index)) {
53 auto results = new CategoryResults ();
54 results->setCategoryIndex(index);
55 connect(results, SIGNAL(countChanged()), this, SLOT(onCountChanged()));
57 unsigned cat_index = static_cast<unsigned>(index);
58 auto model = getResultsForCategory(cat_index);
59 results->setModel(model);
61 m_filters.insert(index, results);
62 }
64 return m_filters[index];
67void
68Categories::onCountChanged()
70 DeeListModel* filter = qobject_cast<DeeListModel*>(sender());
71 if (filter) {
72 m_timerFilters << filter;
73 m_timer.start();
74 }
77void
78Categories::onEmitCountChanged()
80 QVector<int> roles;
81 roles.append(Categories::RoleCount);
82 Q_FOREACH(DeeListModel* results, m_timerFilters) {
83 auto cat_results = qobject_cast<CategoryResults*>(results);
84 QModelIndex changedIndex = index(cat_results->categoryIndex());
85 Q_EMIT dataChanged(changedIndex, changedIndex, roles);
86 }
87 m_timerFilters.clear();
90QHash<int, QByteArray>
91Categories::roleNames() const
93 return m_roles;
96void Categories::setResultModel(DeeModel* model)
98 // FIXME: should ref it
99 m_dee_results = model;
103static void category_filter_map_func (DeeModel* orig_model,
104 DeeFilterModel* filter_model,
105 gpointer user_data)
107 DeeModelIter* iter;
108 DeeModelIter* end;
109 unsigned index = GPOINTER_TO_UINT(user_data);
111 iter = dee_model_get_first_iter(orig_model);
112 end = dee_model_get_last_iter(orig_model);
113 while (iter != end) {
114 unsigned category_index = dee_model_get_uint32(orig_model, iter, CATEGORY_COLUMN);
115 if (index == category_index) {
116 dee_filter_model_append_iter(filter_model, iter);
117 }
118 iter = dee_model_next(orig_model, iter);
119 }
122static gboolean category_filter_notify_func (DeeModel* orig_model,
123 DeeModelIter* orig_iter,
124 DeeFilterModel* filter_model,
125 gpointer user_data)
127 unsigned index = GPOINTER_TO_UINT(user_data);
128 unsigned category_index = dee_model_get_uint32(orig_model, orig_iter, CATEGORY_COLUMN);
130 if (index != category_index)
131 return FALSE;
133 dee_filter_model_insert_iter_with_original_order(filter_model, orig_iter);
134 return TRUE;
137DeeModel* Categories::getResultsForCategory(unsigned cat_index) const
139 DeeFilter filter;
140 filter.map_func = category_filter_map_func;
141 filter.map_notify = category_filter_notify_func;
142 filter.destroy = nullptr;
143 filter.userdata = GUINT_TO_POINTER(cat_index);
145 DeeModel* filtered_model = dee_filter_model_new(m_dee_results, &filter);
146 return filtered_model;
149QVariant
150Categories::data(const QModelIndex& index, int role) const
152 if (!index.isValid()) {
153 return QVariant();
154 }
156 switch (role) {
157 case RoleId:
158 return DeeListModel::data(index, 0); //ID
159 case RoleName:
160 return DeeListModel::data(index, 1); //DISPLAY_NAME
161 case RoleIcon:
162 return DeeListModel::data(index, 2); //ICON_HINT
163 case RoleRenderer:
164 return DeeListModel::data(index, 3); //RENDERER_NAME
165 case RoleContentType:
166 {
167 auto hints = DeeListModel::data(index, 4).toHash();
168 return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
169 }
170 case RoleHints:
171 return DeeListModel::data(index, 4); //HINTS
172 case RoleResults:
173 return QVariant::fromValue(getFilter(index.row()));
174 case RoleCount:
175 return QVariant::fromValue(getFilter(index.row())->rowCount());
176 case RoleCategoryIndex:
177 return QVariant::fromValue(index.row());
178 default:
179 return QVariant();
180 }