[education/gcompris] /: core, add command-line option to set the difficulty.
Johnny Jazeix
null at kde.org
Wed Mar 15 21:45:26 GMT 2023
Git commit b14ec28be263528256b90c242db36f83675ead01 by Johnny Jazeix.
Committed on 15/03/2023 at 20:51.
Pushed by jjazeix into branch 'master'.
core, add command-line option to set the difficulty.
gcompris-qt --difficulty x to set to x difficulty (x between 1 and 6) or
gcompris-qt --difficulty x-y to set difficulty between x and y (x and between 1 and 6, x < y).
If there is any error parsing the difficulty, an error is displayed and GCompris leaves.
M +4 -0 docs/docbook/index.docbook
M +2 -0 src/activities/menu/ConfigurationItem.qml
M +6 -3 src/core/ActivityInfoTree.cpp
M +14 -2 src/core/ActivityInfoTree.h
M +13 -5 src/core/ApplicationSettings.cpp
M +22 -0 src/core/ApplicationSettings.h
M +2 -2 src/core/GComprisPlugin.cpp
M +32 -0 src/core/main.cpp
https://invent.kde.org/education/gcompris/commit/b14ec28be263528256b90c242db36f83675ead01
diff --git a/docs/docbook/index.docbook b/docs/docbook/index.docbook
index 3203a9fab..dadb6e5ba 100644
--- a/docs/docbook/index.docbook
+++ b/docs/docbook/index.docbook
@@ -306,6 +306,10 @@ or make it show real car images instead of filled rectangles (traffic).</para>
<entry>Specify the activity when starting GCompris.</entry>
</row>
<row>
+<entry>--difficulty {value|min-max}</entry>
+<entry>For the session, force the GCompris activities difficulties to be at either value or between min and max values. The values must be between 1 and 6, and if the format is min-max, the min value must be lower than the max value. If it is not the case GCompris will not start.</entry>
+</row>
+<row>
<entry>--export-activities-as-sql</entry>
<entry>Export activities as SQL.</entry>
</row>
diff --git a/src/activities/menu/ConfigurationItem.qml b/src/activities/menu/ConfigurationItem.qml
index a0bf13535..b96a6809c 100644
--- a/src/activities/menu/ConfigurationItem.qml
+++ b/src/activities/menu/ConfigurationItem.qml
@@ -371,6 +371,7 @@ Item {
GCText {
text: qsTr("Difficulty filter:")
fontSize: mediumSize
+ visible: !ApplicationSettings.filterLevelOverridedByCommandLineOption
width: dialogConfig.contentWidth
height: 50 * ApplicationInfo.ratio
}
@@ -379,6 +380,7 @@ Item {
id: difficultyFlow
width: dialogConfig.contentWidth
spacing: 5 * ApplicationInfo.ratio
+ visible: !ApplicationSettings.filterLevelOverridedByCommandLineOption
property int starsSize: Math.floor(dialogConfig.contentWidth * 0.11)
Image {
diff --git a/src/core/ActivityInfoTree.cpp b/src/core/ActivityInfoTree.cpp
index a6b68ba32..aeb8f94fa 100644
--- a/src/core/ActivityInfoTree.cpp
+++ b/src/core/ActivityInfoTree.cpp
@@ -19,6 +19,7 @@
#include <QTextStream>
QString ActivityInfoTree::m_startingActivity = "";
+ActivityInfoTree *ActivityInfoTree::m_instance = nullptr;
ActivityInfoTree::ActivityInfoTree(QObject *parent) :
QObject(parent),
@@ -256,7 +257,7 @@ QObject *ActivityInfoTree::menuTreeProvider(QQmlEngine *engine, QJSEngine *scrip
{
Q_UNUSED(scriptEngine)
- ActivityInfoTree *menuTree = new ActivityInfoTree(nullptr);
+ ActivityInfoTree *menuTree = getInstance();
QQmlComponent componentRoot(engine,
QUrl("qrc:/gcompris/src/activities/menu/ActivityInfo.qml"));
QObject *objectRoot = componentRoot.create();
@@ -351,12 +352,14 @@ void ActivityInfoTree::filterBySearch(const QString &text)
Q_EMIT menuTreeChanged();
}
-void ActivityInfoTree::minMaxFiltersChanged(quint32 levelMin, quint32 levelMax, bool emitChanged)
+void ActivityInfoTree::minMaxFiltersChanged(quint32 levelMin, quint32 levelMax, bool doSynchronize)
{
for (ActivityInfo *activity: qAsConst(m_menuTreeFull)) {
activity->enableDatasetsBetweenDifficulties(levelMin, levelMax);
}
- ApplicationSettings::getInstance()->sync();
+ if (doSynchronize) {
+ ApplicationSettings::getInstance()->sync();
+ }
}
QVariantList ActivityInfoTree::allCharacters()
diff --git a/src/core/ActivityInfoTree.h b/src/core/ActivityInfoTree.h
index 25ffe64a5..fe9a9b1fe 100644
--- a/src/core/ActivityInfoTree.h
+++ b/src/core/ActivityInfoTree.h
@@ -28,6 +28,13 @@ class ActivityInfoTree : public QObject
Q_PROPERTY(QString startingActivity MEMBER m_startingActivity NOTIFY startingActivityChanged)
public:
+ static ActivityInfoTree *getInstance()
+ {
+ if (!m_instance) {
+ m_instance = new ActivityInfoTree();
+ }
+ return m_instance;
+ }
QQmlListProperty<ActivityInfo> menuTree();
ActivityInfo *getRootMenu() const;
void setRootMenu(ActivityInfo *rootMenu);
@@ -42,15 +49,20 @@ public:
static void setStartingActivity(const QString &startingActivity) { m_startingActivity = startingActivity; }
-protected Q_SLOTS:
+protected:
+ static ActivityInfoTree *m_instance;
+
+public Q_SLOTS:
+ Q_INVOKABLE void minMaxFiltersChanged(quint32 levelMin, quint32 levelMax, bool doSynchronize = true);
Q_INVOKABLE void filterByTag(const QString &tag, const QString &category = "", bool emitChanged = true);
+
+protected Q_SLOTS:
Q_INVOKABLE void filterEnabledActivities(bool emitChanged = true);
// create a tree from the whole list of activities with the activities created between the two versions
Q_INVOKABLE void filterCreatedWithinVersions(int firstVersion, int lastVersion,
bool emitChanged = true);
Q_INVOKABLE void filterBySearch(const QString &text);
Q_INVOKABLE void filterByDifficulty(quint32 levelMin, quint32 levelMax);
- Q_INVOKABLE void minMaxFiltersChanged(quint32 levelMin, quint32 levelMax, bool emitChanged = true);
Q_INVOKABLE void setCurrentActivityFromName(const QString &name);
Q_SIGNALS:
diff --git a/src/core/ApplicationSettings.cpp b/src/core/ApplicationSettings.cpp
index 8f023292f..5f79e82fe 100644
--- a/src/core/ApplicationSettings.cpp
+++ b/src/core/ApplicationSettings.cpp
@@ -206,8 +206,10 @@ ApplicationSettings::~ApplicationSettings()
m_config.setValue(PREVIOUS_WIDTH_KEY, m_previousWidth);
m_config.setValue(VIRTUALKEYBOARD_KEY, m_isVirtualKeyboard);
m_config.setValue(ENABLE_AUTOMATIC_DOWNLOADS, m_isAutomaticDownloadsEnabled);
- m_config.setValue(FILTER_LEVEL_MIN, m_filterLevelMin);
- m_config.setValue(FILTER_LEVEL_MAX, m_filterLevelMax);
+ if (!m_filterLevelOverridedByCommandLineOption) {
+ m_config.setValue(FILTER_LEVEL_MIN, m_filterLevelMin);
+ m_config.setValue(FILTER_LEVEL_MAX, m_filterLevelMax);
+ }
m_config.setValue(KIOSK_KEY, m_isKioskMode);
m_config.setValue(SECTION_VISIBLE, m_sectionVisible);
m_config.setValue(EXIT_CONFIRMATION, m_exitConfirmation);
@@ -348,14 +350,18 @@ void ApplicationSettings::notifyAutomaticDownloadsEnabledChanged()
void ApplicationSettings::notifyFilterLevelMinChanged()
{
- updateValueInConfig(GENERAL_GROUP_KEY, FILTER_LEVEL_MIN, m_filterLevelMin);
qDebug() << "filterLevelMin set to: " << m_filterLevelMin;
+ if (!m_filterLevelOverridedByCommandLineOption) {
+ updateValueInConfig(GENERAL_GROUP_KEY, FILTER_LEVEL_MIN, m_filterLevelMin);
+ }
}
void ApplicationSettings::notifyFilterLevelMaxChanged()
{
- updateValueInConfig(GENERAL_GROUP_KEY, FILTER_LEVEL_MAX, m_filterLevelMax);
qDebug() << "filterLevelMax set to: " << m_filterLevelMax;
+ if (!m_filterLevelOverridedByCommandLineOption) {
+ updateValueInConfig(GENERAL_GROUP_KEY, FILTER_LEVEL_MAX, m_filterLevelMax);
+ }
}
void ApplicationSettings::notifyKioskModeChanged()
@@ -478,7 +484,9 @@ bool ApplicationSettings::isFavorite(const QString &activity)
void ApplicationSettings::setCurrentLevels(const QString &activity, const QStringList &level, bool sync)
{
- updateValueInConfig(LEVELS_GROUP_KEY, activity, level, sync);
+ if (!m_filterLevelOverridedByCommandLineOption) {
+ updateValueInConfig(LEVELS_GROUP_KEY, activity, level, sync);
+ }
}
QStringList ApplicationSettings::currentLevels(const QString &activity)
diff --git a/src/core/ApplicationSettings.h b/src/core/ApplicationSettings.h
index 3e7558d1b..b9233b7a1 100644
--- a/src/core/ApplicationSettings.h
+++ b/src/core/ApplicationSettings.h
@@ -161,6 +161,12 @@ class ApplicationSettings : public QObject
*/
Q_PROPERTY(quint32 filterLevelMax READ filterLevelMax WRITE setFilterLevelMax NOTIFY filterLevelMaxChanged)
+ /**
+ * Boolean to know if the difficulty level filter has been set via command-line option.
+ * In this case, we hide the possibility to change the level in the configuration and we never override the levels in the GCompris config file.
+ */
+ Q_PROPERTY(bool filterLevelOverridedByCommandLineOption READ filterLevelOverridedByCommandLineOption WRITE setFilterLevelOverridedByCommandLineOption NOTIFY filterLevelOverridedByCommandLineOptionChanged)
+
/**
* Whether kiosk mode is currently active.
*/
@@ -405,6 +411,13 @@ public:
Q_EMIT filterLevelMaxChanged();
}
+ bool filterLevelOverridedByCommandLineOption() const { return m_filterLevelOverridedByCommandLineOption; }
+ void setFilterLevelOverridedByCommandLineOption(const bool newValue)
+ {
+ m_filterLevelOverridedByCommandLineOption = newValue;
+ Q_EMIT filterLevelOverridedByCommandLineOptionChanged();
+ }
+
bool isKioskMode() const { return m_isKioskMode; }
void setKioskMode(const bool newMode)
{
@@ -527,6 +540,13 @@ public:
*/
Q_INVOKABLE bool useExternalWordset();
+ void setDifficultyFromCommandLine(quint32 newFilterLevelMin, quint32 newFilterLevelMax)
+ {
+ m_filterLevelOverridedByCommandLineOption = true;
+ setFilterLevelMin(newFilterLevelMin);
+ setFilterLevelMax(newFilterLevelMax);
+ }
+
protected Q_SLOTS:
Q_INVOKABLE void notifyAudioVoicesEnabledChanged();
@@ -624,6 +644,7 @@ Q_SIGNALS:
void automaticDownloadsEnabledChanged();
void filterLevelMinChanged();
void filterLevelMaxChanged();
+ void filterLevelOverridedByCommandLineOptionChanged();
void kioskModeChanged();
void sectionVisibleChanged();
void exitConfirmationChanged();
@@ -666,6 +687,7 @@ private:
qreal m_fontLetterSpacing;
quint32 m_filterLevelMin;
quint32 m_filterLevelMax;
+ bool m_filterLevelOverridedByCommandLineOption = false;
bool m_defaultCursor;
bool m_noCursor;
QString m_locale;
diff --git a/src/core/GComprisPlugin.cpp b/src/core/GComprisPlugin.cpp
index 250835793..064648776 100644
--- a/src/core/GComprisPlugin.cpp
+++ b/src/core/GComprisPlugin.cpp
@@ -35,8 +35,8 @@ void GComprisPlugin::registerTypes(const char *uri)
qmlRegisterSingletonType<ApplicationInfo>(uri, versionMajor, versionMinor,
"ApplicationInfo", ApplicationInfo::applicationInfoProvider);
- qmlRegisterSingletonType<QObject>(uri, versionMajor, versionMinor,
- "ActivityInfoTree", ActivityInfoTree::menuTreeProvider);
+ qmlRegisterSingletonType<ActivityInfoTree>(uri, versionMajor, versionMinor,
+ "ActivityInfoTree", ActivityInfoTree::menuTreeProvider);
qmlRegisterType<Dataset>(uri, versionMajor, versionMinor, "Data");
qmlRegisterType<ActivityInfo>(uri, versionMajor, versionMinor, "ActivityInfo");
qmlRegisterSingletonType<ApplicationSettings>(uri, versionMajor, versionMinor,
diff --git a/src/core/main.cpp b/src/core/main.cpp
index bb9cc10f8..65cc4ab27 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -208,6 +208,10 @@ int main(int argc, char *argv[])
QObject::tr("Outputs all the available activities on the standard output."));
parser.addOption(clListActivities);
+ QCommandLineOption clDifficultyRange("difficulty",
+ QObject::tr("Specify the range of the activity difficulties to display for the session. Either a single value (2), or a range (3-6). Values must be between 1 and 6."), "difficulty");
+ parser.addOption(clDifficultyRange);
+
parser.process(app);
GComprisPlugin plugin;
@@ -331,6 +335,34 @@ int main(int argc, char *argv[])
menuTree->listActivities();
return 0;
}
+ // Start on specific difficulties
+ if (parser.isSet(clDifficultyRange)) {
+ QString difficultyRange = parser.value(clDifficultyRange);
+ QStringList levels = difficultyRange.split(QStringLiteral("-"));
+ quint32 minDifficulty = levels[0].toUInt();
+ quint32 maxDifficulty = minDifficulty;
+ // If we have a range, take the second value as max difficulty
+ if (levels.size() > 1) {
+ maxDifficulty = levels[1].toUInt();
+ }
+ if (minDifficulty > maxDifficulty) {
+ qWarning() << "Minimal level must be lower than maximum level";
+ return -1;
+ }
+ if (minDifficulty < 1 || minDifficulty > 6) {
+ qWarning() << "Minimal level must between 1 and 6";
+ return -1;
+ }
+ if (maxDifficulty < 1 || maxDifficulty > 6) {
+ qWarning() << "Maximal level must between 1 and 6";
+ return -1;
+ }
+
+ qDebug() << QStringLiteral("Setting difficulty between %1 and %2").arg(minDifficulty).arg(maxDifficulty);
+ ApplicationSettings::getInstance()->setDifficultyFromCommandLine(minDifficulty, maxDifficulty);
+ ActivityInfoTree::getInstance()->minMaxFiltersChanged(minDifficulty, maxDifficulty, false);
+ ActivityInfoTree::getInstance()->filterByTag("favorite");
+ }
QObject *topLevel = engine.rootObjects().value(0);
More information about the kde-doc-english
mailing list