on 77121cf help sign in
unity8/tests/mocks/Unity/fake_categories.cpp
178 lines 5.6 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] = "content_type";
36 m_roles[Categories::RoleHints] = "hints";
37 m_roles[Categories::RoleResults] = "results";
38 m_roles[Categories::RoleCount] = "count";
40 // TODO This should not be needed but accumulatting the count changes
41 // makes the visualization more stable and also makes crashes on fast
42 // change of the search term harder to reproduce
43 m_timer.setSingleShot(true);
44 m_timer.setInterval(50);
45 connect(&m_timer, SIGNAL(timeout()), this, SLOT(onEmitCountChanged()));
48DeeListModel*
49Categories::getFilter(int index) const
51 if (!m_filters.contains(index)) {
52 auto results = new CategoryResults ();
53 results->setCategoryIndex(index);
54 connect(results, SIGNAL(countChanged()), this, SLOT(onCountChanged()));
56 unsigned cat_index = static_cast<unsigned>(index);
57 auto model = getResultsForCategory(cat_index);
58 results->setModel(model);
60 m_filters.insert(index, results);
61 }
63 return m_filters[index];
66void
67Categories::onCountChanged()
69 DeeListModel* filter = qobject_cast<DeeListModel*>(sender());
70 if (filter) {
71 m_timerFilters << filter;
72 m_timer.start();
73 }
76void
77Categories::onEmitCountChanged()
79 QVector<int> roles;
80 roles.append(Categories::RoleCount);
81 Q_FOREACH(DeeListModel* results, m_timerFilters) {
82 auto cat_results = qobject_cast<CategoryResults*>(results);
83 QModelIndex changedIndex = index(cat_results->categoryIndex());
84 Q_EMIT dataChanged(changedIndex, changedIndex, roles);
85 }
86 m_timerFilters.clear();
89QHash<int, QByteArray>
90Categories::roleNames() const
92 return m_roles;
95void Categories::setResultModel(DeeModel* model)
97 // FIXME: should ref it
98 m_dee_results = model;
102static void category_filter_map_func (DeeModel* orig_model,
103 DeeFilterModel* filter_model,
104 gpointer user_data)
106 DeeModelIter* iter;
107 DeeModelIter* end;
108 unsigned index = GPOINTER_TO_UINT(user_data);
110 iter = dee_model_get_first_iter(orig_model);
111 end = dee_model_get_last_iter(orig_model);
112 while (iter != end) {
113 unsigned category_index = dee_model_get_uint32(orig_model, iter, CATEGORY_COLUMN);
114 if (index == category_index) {
115 dee_filter_model_append_iter(filter_model, iter);
116 }
117 iter = dee_model_next(orig_model, iter);
118 }
121static gboolean category_filter_notify_func (DeeModel* orig_model,
122 DeeModelIter* orig_iter,
123 DeeFilterModel* filter_model,
124 gpointer user_data)
126 unsigned index = GPOINTER_TO_UINT(user_data);
127 unsigned category_index = dee_model_get_uint32(orig_model, orig_iter, CATEGORY_COLUMN);
129 if (index != category_index)
130 return FALSE;
132 dee_filter_model_insert_iter_with_original_order(filter_model, orig_iter);
133 return TRUE;
136DeeModel* Categories::getResultsForCategory(unsigned cat_index) const
138 DeeFilter filter;
139 filter.map_func = category_filter_map_func;
140 filter.map_notify = category_filter_notify_func;
141 filter.destroy = nullptr;
142 filter.userdata = GUINT_TO_POINTER(cat_index);
144 DeeModel* filtered_model = dee_filter_model_new(m_dee_results, &filter);
145 return filtered_model;
148QVariant
149Categories::data(const QModelIndex& index, int role) const
151 if (!index.isValid()) {
152 return QVariant();
153 }
155 switch (role) {
156 case RoleId:
157 return QVariant::fromValue(index.row());
158 case RoleName:
159 return DeeListModel::data(index, 1); //DISPLAY_NAME
160 case RoleIcon:
161 return DeeListModel::data(index, 2); //ICON_HINT
162 case RoleRenderer:
163 return DeeListModel::data(index, 3); //RENDERER_NAME
164 case RoleContentType:
165 {
166 auto hints = DeeListModel::data(index, 4).toHash();
167 return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
168 }
169 case RoleHints:
170 return DeeListModel::data(index, 4); //HINTS
171 case RoleResults:
172 return QVariant::fromValue(getFilter(index.row()));
173 case RoleCount:
174 return QVariant::fromValue(getFilter(index.row())->rowCount());
175 default:
176 return QVariant();
177 }