Lomiri
Loading...
Searching...
No Matches
appdrawerproxymodel.cpp
1/*
2 * Copyright (C) 2016 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
17#include "appdrawerproxymodel.h"
18
19#include <lomiri/shell/launcher/LauncherItemInterface.h>
20
21#include <QDebug>
22
23AppDrawerProxyModel::AppDrawerProxyModel(QObject *parent):
24 QSortFilterProxyModel(parent)
25{
26 setSortRole(AppDrawerModelInterface::RoleName);
27 setSortLocaleAware(true);
28 sort(0);
29
30 connect(this, &QAbstractListModel::rowsInserted, this, &AppDrawerProxyModel::countChanged);
31 connect(this, &QAbstractListModel::rowsRemoved, this, &AppDrawerProxyModel::countChanged);
32 connect(this, &QAbstractListModel::layoutChanged, this, &AppDrawerProxyModel::countChanged);
33}
34
35QAbstractItemModel *AppDrawerProxyModel::source() const
36{
37 return m_source;
38}
39
40void AppDrawerProxyModel::setSource(QAbstractItemModel *source)
41{
42 if (m_source != source) {
43 m_source = source;
44 setSourceModel(m_source);
45 setSortRole(m_sortBy == SortByAToZ ? AppDrawerModelInterface::RoleName : AppDrawerModelInterface::RoleUsage);
46 connect(m_source, &QAbstractItemModel::rowsRemoved, this, &AppDrawerProxyModel::invalidate);
47 connect(m_source, &QAbstractItemModel::rowsInserted, this, &AppDrawerProxyModel::invalidate);
48 Q_EMIT sourceChanged();
49 }
50}
51
52AppDrawerProxyModel::GroupBy AppDrawerProxyModel::group() const
53{
54 return m_group;
55}
56
57void AppDrawerProxyModel::setGroup(AppDrawerProxyModel::GroupBy group)
58{
59 if (m_group != group) {
60 m_group = group;
61 Q_EMIT groupChanged();
62 invalidateFilter();
63 }
64}
65
66QString AppDrawerProxyModel::filterLetter() const
67{
68 return m_filterLetter;
69}
70
71void AppDrawerProxyModel::setFilterLetter(const QString &filterLetter)
72{
73 if (m_filterLetter != filterLetter) {
74 m_filterLetter = filterLetter;
75 Q_EMIT filterLetterChanged();
76 invalidateFilter();
77 }
78}
79
80QString AppDrawerProxyModel::filterString() const
81{
82 return m_filterString;
83}
84
85void AppDrawerProxyModel::setFilterString(const QString &filterString)
86{
87 const QString filterStringOptimised = removeDiacritics(filterString);
88 if (m_filterString != filterStringOptimised) {
89 m_filterString = filterStringOptimised;
90 Q_EMIT filterStringChanged();
91 invalidateFilter();
92 }
93}
94
95AppDrawerProxyModel::SortBy AppDrawerProxyModel::sortBy() const
96{
97 return m_sortBy;
98}
99
100void AppDrawerProxyModel::setSortBy(AppDrawerProxyModel::SortBy sortBy)
101{
102 if (m_sortBy != sortBy) {
103 m_sortBy = sortBy;
104 Q_EMIT sortByChanged();
105 setSortRole(m_sortBy == SortByAToZ ? AppDrawerModelInterface::RoleName : AppDrawerModelInterface::RoleUsage);
106 sort(0);
107 }
108}
109
110int AppDrawerProxyModel::count() const
111{
112 return rowCount();
113}
114
115QVariant AppDrawerProxyModel::data(const QModelIndex &index, int role) const
116{
117 QModelIndex idx = mapToSource(index);
118 if (role == Qt::UserRole) {
119 QString name = m_source->data(idx, AppDrawerModelInterface::RoleName).toString();
120 return name.length() > 0 ? QString(name.at(0)).toUpper() : QChar();
121 }
122 return m_source->data(idx, role);
123}
124
125QHash<int, QByteArray> AppDrawerProxyModel::roleNames() const
126{
127 if (m_source) {
128 QHash<int, QByteArray> roles = m_source->roleNames();
129 roles.insert(Qt::UserRole, "letter");
130 return roles;
131 }
132 return QHash<int, QByteArray>();
133}
134
135bool AppDrawerProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
136{
137 Q_UNUSED(source_parent)
138
139 if (m_group == GroupByAToZ && source_row > 0) {
140 QString currentName = m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleName).toString();
141 QChar currentLetter = currentName.length() > 0 ? currentName.at(0) : QChar();
142 QString previousName = m_source->data(m_source->index(source_row - 1,0 ), AppDrawerModelInterface::RoleName).toString();
143 QChar previousLetter = previousName.length() > 0 ? previousName.at(0) : QChar();
144 if (currentLetter.toLower() == previousLetter.toLower()) {
145 return false;
146 }
147 } else if(m_group == GroupByAll && source_row > 0) {
148 return false;
149 }
150 if (!m_filterLetter.isEmpty()) {
151 QString currentName = m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleName).toString();
152 QString currentLetter = currentName.length() > 0 ? QString(currentName.at(0)) : QString();
153 if (currentLetter.toLower() != m_filterLetter.toLower()) {
154 return false;
155 }
156 }
157 if (!m_filterString.isEmpty()) {
158 QStringList allWords = m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleKeywords).toStringList();
159 allWords.prepend(m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleName).toString());
160 bool found = false;
161 Q_FOREACH (const QString &currentWord, allWords) {
162 if (removeDiacritics(currentWord).contains(m_filterString, Qt::CaseInsensitive)) {
163 found = true;
164 break;
165 }
166 }
167 if (!found) {
168 return false;
169 }
170 }
171 return true;
172}
173
174QString AppDrawerProxyModel::removeDiacritics(const QString &input) const
175{
176 QString normalized = input.normalized(QString::NormalizationForm_D);
177
178 QString result = normalized;
179 result.remove(QRegularExpression("[\\p{M}]"));
180
181 return result;
182}
183
184QString AppDrawerProxyModel::appId(int index) const
185{
186 if (index >= 0 && index < rowCount()) {
187 QModelIndex sourceIndex = mapToSource(this->index(index, 0));
188
189 AppDrawerModelInterface* adm = dynamic_cast<AppDrawerModelInterface*>(m_source);
190 if (adm) {
191 return adm->data(sourceIndex, AppDrawerModelInterface::RoleAppId).toString();
192 }
193
194 AppDrawerProxyModel* adpm = qobject_cast<AppDrawerProxyModel*>(m_source);
195 if (adpm) {
196 return adpm->appId(sourceIndex.row());
197 }
198 }
199 return QString();
200}