File indexing completed on 2024-04-21 14:43:47
0001 /* GCompris - ActivityInfo.cpp 0002 * 0003 * SPDX-FileCopyrightText: 2014 Bruno Coudoin <bruno.coudoin@gcompris.net> 0004 * 0005 * Authors: 0006 * Bruno Coudoin <bruno.coudoin@gcompris.net> 0007 * 0008 * SPDX-License-Identifier: GPL-3.0-or-later 0009 */ 0010 #include "ActivityInfo.h" 0011 0012 #include <QFile> 0013 #include <QtDebug> 0014 #include <QQmlProperty> 0015 #include <QQmlEngine> 0016 #include <QQmlComponent> 0017 0018 #include "ApplicationSettings.h" 0019 0020 ActivityInfo::ActivityInfo(QObject *parent) : 0021 QObject(parent), 0022 m_difficulty(0), 0023 m_minimalDifficulty(0), 0024 m_maximalDifficulty(0), 0025 m_favorite(false), 0026 m_enabled(true), 0027 m_createdInVersion(0) 0028 { 0029 } 0030 0031 QString ActivityInfo::name() const 0032 { 0033 return m_name; 0034 } 0035 0036 void ActivityInfo::setName(const QString &name) 0037 { 0038 m_name = name; 0039 // Once we are given a name, we can get the favorite property 0040 // from the persistant configuration 0041 m_favorite = ApplicationSettings::getInstance()->isFavorite(m_name); 0042 0043 setCurrentLevels(); 0044 0045 Q_EMIT nameChanged(); 0046 } 0047 0048 QString ActivityInfo::section() const 0049 { 0050 return m_section; 0051 } 0052 void ActivityInfo::setSection(const QString §ion) 0053 { 0054 m_section = section; 0055 Q_EMIT sectionChanged(); 0056 } 0057 0058 quint32 ActivityInfo::difficulty() const 0059 { 0060 return m_difficulty; 0061 } 0062 void ActivityInfo::setDifficulty(const quint32 &difficulty) 0063 { 0064 m_difficulty = difficulty; 0065 Q_EMIT difficultyChanged(); 0066 } 0067 0068 quint32 ActivityInfo::minimalDifficulty() const 0069 { 0070 return m_minimalDifficulty; 0071 } 0072 void ActivityInfo::setMinimalDifficulty(const quint32 &minimalDifficulty) 0073 { 0074 m_minimalDifficulty = minimalDifficulty; 0075 Q_EMIT minimalDifficultyChanged(); 0076 } 0077 0078 quint32 ActivityInfo::maximalDifficulty() const 0079 { 0080 return m_maximalDifficulty; 0081 } 0082 void ActivityInfo::setMaximalDifficulty(const quint32 &maximalDifficulty) 0083 { 0084 m_maximalDifficulty = maximalDifficulty; 0085 Q_EMIT maximalDifficultyChanged(); 0086 } 0087 0088 QString ActivityInfo::icon() const 0089 { 0090 return m_icon; 0091 } 0092 void ActivityInfo::setIcon(const QString &icon) 0093 { 0094 m_icon = icon; 0095 Q_EMIT iconChanged(); 0096 } 0097 0098 QString ActivityInfo::author() const 0099 { 0100 return m_author; 0101 } 0102 void ActivityInfo::setAuthor(const QString &author) 0103 { 0104 m_author = author; 0105 Q_EMIT authorChanged(); 0106 } 0107 0108 QString ActivityInfo::title() const 0109 { 0110 return m_title; 0111 } 0112 void ActivityInfo::setTitle(const QString &title) 0113 { 0114 m_title = title; 0115 Q_EMIT titleChanged(); 0116 } 0117 0118 QString ActivityInfo::description() const 0119 { 0120 return m_description; 0121 } 0122 void ActivityInfo::setDescription(const QString &description) 0123 { 0124 m_description = description; 0125 Q_EMIT descriptionChanged(); 0126 } 0127 0128 QString ActivityInfo::goal() const 0129 { 0130 return m_goal; 0131 } 0132 void ActivityInfo::setGoal(const QString &goal) 0133 { 0134 m_goal = goal; 0135 Q_EMIT goalChanged(); 0136 } 0137 0138 QString ActivityInfo::prerequisite() const 0139 { 0140 return m_prerequisite; 0141 } 0142 void ActivityInfo::setPrerequisite(const QString &prerequisite) 0143 { 0144 m_prerequisite = prerequisite; 0145 Q_EMIT prerequisiteChanged(); 0146 } 0147 0148 QString ActivityInfo::manual() const 0149 { 0150 return m_manual; 0151 } 0152 void ActivityInfo::setManual(const QString &manual) 0153 { 0154 m_manual = manual; 0155 Q_EMIT manualChanged(); 0156 } 0157 0158 QString ActivityInfo::credit() const 0159 { 0160 return m_credit; 0161 } 0162 void ActivityInfo::setCredit(const QString &credit) 0163 { 0164 m_credit = credit; 0165 Q_EMIT creditChanged(); 0166 } 0167 0168 bool ActivityInfo::favorite() const 0169 { 0170 return m_favorite; 0171 } 0172 void ActivityInfo::setFavorite(const bool favorite) 0173 { 0174 m_favorite = favorite; 0175 ApplicationSettings::getInstance()->setFavorite(m_name, m_favorite); 0176 Q_EMIT favoriteChanged(); 0177 } 0178 0179 bool ActivityInfo::enabled() const 0180 { 0181 return m_enabled; 0182 } 0183 void ActivityInfo::setEnabled(const bool enabled) 0184 { 0185 m_enabled = enabled; 0186 Q_EMIT enabledChanged(); 0187 } 0188 0189 int ActivityInfo::createdInVersion() const 0190 { 0191 return m_createdInVersion; 0192 } 0193 void ActivityInfo::setCreatedInVersion(const int created) 0194 { 0195 m_createdInVersion = created; 0196 Q_EMIT createdInVersionChanged(); 0197 } 0198 0199 QStringList ActivityInfo::levels() const 0200 { 0201 return m_levels; 0202 } 0203 0204 void ActivityInfo::setLevels(const QStringList &levels) 0205 { 0206 // levels only contains one element containing all the difficulties 0207 m_levels = levels.front().split(','); 0208 0209 setCurrentLevels(); 0210 0211 Q_EMIT levelsChanged(); 0212 } 0213 0214 void ActivityInfo::fillDatasets(QQmlEngine *engine) 0215 { 0216 quint32 levelMin = ApplicationSettings::getInstance()->filterLevelMin(); 0217 quint32 levelMax = ApplicationSettings::getInstance()->filterLevelMax(); 0218 for (const QString &level: qAsConst(m_levels)) { 0219 QString url = QString("qrc:/gcompris/src/activities/%1/resource/%2/Data.qml").arg(m_name.split('/')[0], level); 0220 QQmlComponent componentRoot(engine, QUrl(url)); 0221 QObject *objectRoot = componentRoot.create(); 0222 if (objectRoot != nullptr) { 0223 Dataset *dataset = qobject_cast<Dataset *>(objectRoot); 0224 if (levelMin > dataset->difficulty() || levelMax < dataset->difficulty()) { 0225 dataset->setEnabled(false); 0226 } 0227 0228 addDataset(level, dataset); 0229 } 0230 else { 0231 qDebug() << "ERROR: failed to load " << m_name << " " << componentRoot.errors(); 0232 } 0233 } 0234 if (m_levels.empty()) { 0235 setMinimalDifficulty(m_difficulty); 0236 setMaximalDifficulty(m_difficulty); 0237 } 0238 else { 0239 computeMinMaxDifficulty(); 0240 } 0241 } 0242 0243 QStringList ActivityInfo::currentLevels() const 0244 { 0245 return m_currentLevels; 0246 } 0247 0248 void ActivityInfo::computeMinMaxDifficulty() 0249 { 0250 if (m_currentLevels.empty() || m_datasets.empty()) { 0251 return; 0252 } 0253 quint32 minimalDifficultyFound = 100; 0254 quint32 maximalDifficultyFound = 0; 0255 for (const QString &datasetName: qAsConst(m_currentLevels)) { 0256 Dataset *data = getDataset(datasetName); 0257 if (minimalDifficultyFound > data->difficulty()) { 0258 minimalDifficultyFound = data->difficulty(); 0259 } 0260 if (maximalDifficultyFound < data->difficulty()) { 0261 maximalDifficultyFound = data->difficulty(); 0262 } 0263 } 0264 setMinimalDifficulty(minimalDifficultyFound); 0265 setMaximalDifficulty(maximalDifficultyFound); 0266 } 0267 0268 void ActivityInfo::setCurrentLevels(const QStringList ¤tLevels) 0269 { 0270 m_currentLevels = currentLevels; 0271 computeMinMaxDifficulty(); 0272 Q_EMIT currentLevelsChanged(); 0273 } 0274 0275 void ActivityInfo::setCurrentLevels() 0276 { 0277 if (!m_name.isEmpty()) { 0278 // by default, activate all existing levels 0279 if (!m_levels.empty() && ApplicationSettings::getInstance()->currentLevels(m_name).empty()) { 0280 ApplicationSettings::getInstance()->setCurrentLevels(m_name, m_levels); 0281 } 0282 m_currentLevels = ApplicationSettings::getInstance()->currentLevels(m_name); 0283 } 0284 // Remove levels that could have been added in the configuration but are not existing 0285 // Either we rename a dataset, or after working in another branch to add dataset and switching to a branch without it 0286 QStringList levelsToRemove; 0287 for (const QString &level: qAsConst(m_currentLevels)) { 0288 if (!m_levels.contains(level)) { 0289 qDebug() << QString("Invalid level %1 for activity %2, removing it").arg(level, m_name); 0290 levelsToRemove << level; 0291 } 0292 } 0293 for (const QString &level: qAsConst(levelsToRemove)) { 0294 m_currentLevels.removeOne(level); 0295 } 0296 computeMinMaxDifficulty(); 0297 } 0298 0299 void ActivityInfo::enableDatasetsBetweenDifficulties(quint32 levelMin, quint32 levelMax) 0300 { 0301 QStringList newLevels; 0302 for (auto it = m_datasets.begin(); it != m_datasets.end(); ++it) { 0303 Dataset *dataset = it.value(); 0304 if (levelMin <= dataset->difficulty() && dataset->difficulty() <= levelMax) { 0305 newLevels << it.key(); 0306 dataset->setEnabled(true); 0307 } 0308 else { 0309 dataset->setEnabled(false); 0310 } 0311 } 0312 setCurrentLevels(newLevels); 0313 ApplicationSettings::getInstance()->setCurrentLevels(m_name, m_currentLevels, false); 0314 } 0315 0316 void ActivityInfo::addDataset(const QString &name, Dataset *dataset) 0317 { 0318 m_datasets[name] = dataset; 0319 } 0320 0321 Dataset *ActivityInfo::getDataset(const QString &name) const 0322 { 0323 return m_datasets[name]; 0324 } 0325 0326 bool ActivityInfo::hasConfig() const 0327 { 0328 return QFile::exists(":/gcompris/src/activities/" + m_name.split('/')[0] + "/ActivityConfig.qml"); 0329 } 0330 0331 bool ActivityInfo::hasDataset() const 0332 { 0333 return !m_levels.empty(); 0334 } 0335 0336 void ActivityInfo::resetLevels() 0337 { 0338 enableDatasetsBetweenDifficulties(1, 6); 0339 } 0340 0341 #include "moc_ActivityInfo.cpp"