1 /*
2     SPDX-FileCopyrightText: 2013 Andreas Cord-Landwehr <cordlandwehr@kde.org>
3 
4     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5 */
6 
7 #include "languageresourcemodel.h"
8 #include "application.h"
9 #include "core/iresourcerepository.h"
10 #include "core/language.h"
11 
12 #include "artikulate_debug.h"
13 #include <KLocalizedString>
14 #include <QSignalMapper>
15 
LanguageResourceModel(QObject * parent)16 LanguageResourceModel::LanguageResourceModel(QObject *parent)
17     : QAbstractListModel(parent)
18     , m_repository(nullptr)
19     , m_view(LanguageModel::NonEmptyGhnsOnlyLanguages)
20     , m_signalMapper(new QSignalMapper(this))
21 {
22     connect(m_signalMapper, SIGNAL(mapped(int)), SLOT(emitLanguageChanged(int)));
23     setResourceRepository(artikulateApp->resourceRepository());
24 }
25 
roleNames() const26 QHash<int, QByteArray> LanguageResourceModel::roleNames() const
27 {
28     QHash<int, QByteArray> roles;
29     roles[TitleRole] = "title";
30     roles[I18nTitleRole] = "i18nTitle";
31     roles[IdRole] = "id";
32     roles[DataRole] = "dataRole";
33     roles[CourseNumberRole] = "courseNumberRole";
34 
35     return roles;
36 }
37 
setResourceRepository(IResourceRepository * repository)38 void LanguageResourceModel::setResourceRepository(IResourceRepository *repository)
39 {
40     if (m_repository == repository) {
41         return;
42     }
43 
44     if (m_repository) {
45         m_repository->disconnect(this);
46     }
47     m_repository = repository;
48     updateDisplayedLanguages();
49 
50     emit resourceRepositoryChanged();
51 }
52 
resourceRepository() const53 IResourceRepository *LanguageResourceModel::resourceRepository() const
54 {
55     return m_repository;
56 }
57 
data(const QModelIndex & index,int role) const58 QVariant LanguageResourceModel::data(const QModelIndex &index, int role) const
59 {
60     if (!index.isValid()) {
61         return QVariant();
62     }
63 
64     if (index.row() >= m_languages.count()) {
65         return QVariant();
66     }
67 
68     ILanguage *const language = m_languages.at(index.row());
69     switch (role) {
70         case Qt::DisplayRole:
71             return !language->title().isEmpty() ? QVariant(language->title()) : QVariant(i18nc("@item:inlistbox:", "unknown"));
72         case Qt::ToolTipRole:
73             return QVariant(language->title());
74         case TitleRole:
75             return language->title();
76         case I18nTitleRole:
77             return language->i18nTitle();
78         case IdRole:
79             return language->id();
80         case DataRole:
81             return QVariant::fromValue<QObject *>(language);
82         case CourseNumberRole:
83             return m_languages.count();
84         default:
85             return QVariant();
86     }
87 }
88 
rowCount(const QModelIndex & parent) const89 int LanguageResourceModel::rowCount(const QModelIndex &parent) const
90 {
91     if (parent.isValid()) {
92         return 0;
93     }
94     return m_languages.count();
95 }
96 
onLanguageAboutToBeAdded(Language * language,int index)97 void LanguageResourceModel::onLanguageAboutToBeAdded(Language *language, int index)
98 {
99     beginInsertRows(QModelIndex(), index, index);
100     m_languages.append(language);
101 
102     connect(language, SIGNAL(titleChanged()), m_signalMapper, SLOT(map()));
103     connect(language, SIGNAL(phonemesChanged()), m_signalMapper, SLOT(map()));
104     connect(language, SIGNAL(phonemeGroupsChanged()), m_signalMapper, SLOT(map()));
105 }
106 
onLanguageAdded()107 void LanguageResourceModel::onLanguageAdded()
108 {
109     updateMappings();
110     endInsertRows();
111 }
112 
onLanguageAboutToBeRemoved(int index)113 void LanguageResourceModel::onLanguageAboutToBeRemoved(int index)
114 {
115     if (!m_repository) {
116         return;
117     }
118 
119     ILanguage *originalLanguage = m_repository->languages().at(index).get();
120     int modelIndex = m_languages.indexOf(originalLanguage);
121 
122     if (modelIndex == -1) {
123         qCWarning(ARTIKULATE_LOG()) << "Cannot remove language from model, not registered";
124         return;
125     }
126     beginRemoveRows(QModelIndex(), modelIndex, modelIndex);
127     originalLanguage->disconnect(m_signalMapper);
128     m_languages.removeAt(modelIndex);
129 }
130 
onLanguageRemoved()131 void LanguageResourceModel::onLanguageRemoved()
132 {
133     endRemoveRows();
134 }
135 
emitLanguageChanged(int row)136 void LanguageResourceModel::emitLanguageChanged(int row)
137 {
138     emit languageChanged(row);
139     emit dataChanged(index(row, 0), index(row, 0));
140 }
141 
headerData(int section,Qt::Orientation orientation,int role) const142 QVariant LanguageResourceModel::headerData(int section, Qt::Orientation orientation, int role) const
143 {
144     if (role != Qt::DisplayRole) {
145         return QVariant();
146     }
147     if (orientation == Qt::Vertical) {
148         return QVariant(section + 1);
149     }
150     return QVariant(i18nc("@title:column", "Language"));
151 }
152 
setView(LanguageModel::LanguageResourceView view)153 void LanguageResourceModel::setView(LanguageModel::LanguageResourceView view)
154 {
155     if (m_view == view) {
156         return;
157     }
158     m_view = view;
159     updateDisplayedLanguages();
160 }
161 
updateDisplayedLanguages()162 void LanguageResourceModel::updateDisplayedLanguages()
163 {
164     beginResetModel();
165     m_languages.clear();
166     if (m_repository) {
167         m_languages.clear();
168         for (auto language : m_repository->languages()) {
169             m_languages.append(language.get());
170         }
171     }
172     updateMappings();
173     endResetModel();
174 }
175 
view() const176 LanguageModel::LanguageResourceView LanguageResourceModel::view() const
177 {
178     return m_view;
179 }
180 
updateMappings()181 void LanguageResourceModel::updateMappings()
182 {
183     int languages = m_languages.count();
184     for (int i = 0; i < languages; i++) {
185         m_signalMapper->setMapping(m_languages.at(i), i);
186     }
187 }
188