[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [gcompris/multiple_dataset] /: multiple dataset, proof of concept
From:       Johnny Jazeix <null () kde ! org>
Date:       2018-09-19 17:36:45
Message-ID: E1g2gP7-0000pP-Bf () code ! kde ! org
[Download RAW message or body]

Git commit aad6aa567c3ce79e553ca8a259a4876c3e8985d6 by Johnny Jazeix.
Committed on 19/09/2018 at 17:36.
Pushed by jjazeix into branch 'multiple_dataset'.

multiple dataset, proof of concept

M  +1    -0    src/activities/algebra_by/ActivityInfo.qml
A  +49   -0    src/activities/algebra_by/resource/1/Data.qml     [License: GPL (v3+)]
A  +49   -0    src/activities/algebra_by/resource/2/Data.qml     [License: GPL (v3+)]
A  +49   -0    src/activities/algebra_by/resource/3/Data.qml     [License: GPL (v3+)]
A  +49   -0    src/activities/algebra_by/resource/4/Data.qml     [License: GPL (v3+)]
A  +231  -0    src/activities/menu/DialogChooseLevel.qml     [License: GPL (v3+)]
M  +39   -4    src/activities/menu/Menu.qml
M  +2    -1    src/activities/reversecount/ActivityInfo.qml
M  +5    -5    src/activities/reversecount/Reversecount.qml
M  +1    -1    src/activities/reversecount/Tux.qml
A  +49   -0    src/activities/reversecount/resource/1/Data.qml     [License: GPL \
(v3+)] A  +54   -0    src/activities/reversecount/resource/2/Data.qml     [License: \
GPL (v3+)] M  +12   -75   src/activities/reversecount/reversecount.js
M  +19   -0    src/core/ActivityBase.qml
M  +40   -0    src/core/ActivityInfo.cpp
M  +44   -22   src/core/ActivityInfo.h
M  +0    -14   src/core/ActivityInfoTree.cpp
M  +0    -1    src/core/ActivityInfoTree.h
M  +14   -0    src/core/ApplicationSettings.cpp
M  +11   -5    src/core/ApplicationSettings.h
A  +38   -0    src/core/Dataset.qml     [License: GPL (v3+)]
M  +5    -0    tests/core/ApplicationSettingsTest.cpp

https://commits.kde.org/gcompris/aad6aa567c3ce79e553ca8a259a4876c3e8985d6

diff --git a/src/activities/algebra_by/ActivityInfo.qml \
b/src/activities/algebra_by/ActivityInfo.qml index 4eb99374..7f14046f 100644
--- a/src/activities/algebra_by/ActivityInfo.qml
+++ b/src/activities/algebra_by/ActivityInfo.qml
@@ -37,4 +37,5 @@ ActivityInfo {
   credit: ""
   section: "math multiplication"
   createdInVersion: 0
+  levels: "1,2,3,4"
 }
diff --git a/src/activities/algebra_by/resource/1/Data.qml \
b/src/activities/algebra_by/resource/1/Data.qml new file mode 100644
index 00000000..3fcca88b
--- /dev/null
+++ b/src/activities/algebra_by/resource/1/Data.qml
@@ -0,0 +1,49 @@
+/* GCompris - Data.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ *   Johnny Jazeix <jazeix@gmail.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+import "../../../../core"
+
+Dataset {
+    objective: qsTr("This is a long long long long objective. We want to see it it \
can display long long texts. But it is not long long long enough. Or maybe it is...") \
+    data: [ +    {
+        "maxNumber": 1, /* Max number on each domino side */
+        "minNumber": 1,
+        "numberOfFish": 3
+    },
+    {
+        "maxNumber": 2,
+        "minNumber": 1,
+        "numberOfFish": 4
+    },
+    {
+        "maxNumber": 3,
+        "minNumber": 1,
+        "numberOfFish": 5
+    },
+    {
+        "maxNumber": 4,
+        "minNumber": 1,
+        "numberOfFish": 5
+    }
+    ]
+}
diff --git a/src/activities/algebra_by/resource/2/Data.qml \
b/src/activities/algebra_by/resource/2/Data.qml new file mode 100644
index 00000000..e919f42d
--- /dev/null
+++ b/src/activities/algebra_by/resource/2/Data.qml
@@ -0,0 +1,49 @@
+/* GCompris - Data.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ *   Johnny Jazeix <jazeix@gmail.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+import "../../../../core"
+
+Dataset {
+    objective: qsTr("obj 2")
+    data: [
+    {
+        "maxNumber": 1, /* Max number on each domino side */
+        "minNumber": 1,
+        "numberOfFish": 3
+    },
+    {
+        "maxNumber": 2,
+        "minNumber": 1,
+        "numberOfFish": 4
+    },
+    {
+        "maxNumber": 3,
+        "minNumber": 1,
+        "numberOfFish": 5
+    },
+    {
+        "maxNumber": 4,
+        "minNumber": 1,
+        "numberOfFish": 5
+    }
+    ]
+}
diff --git a/src/activities/algebra_by/resource/3/Data.qml \
b/src/activities/algebra_by/resource/3/Data.qml new file mode 100644
index 00000000..45d6b690
--- /dev/null
+++ b/src/activities/algebra_by/resource/3/Data.qml
@@ -0,0 +1,49 @@
+/* GCompris - Data.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ *   Johnny Jazeix <jazeix@gmail.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+import "../../../../core"
+
+Dataset {
+    objective: qsTr("obj 3")
+    data: [
+    {
+        "maxNumber": 1, /* Max number on each domino side */
+        "minNumber": 1,
+        "numberOfFish": 3
+    },
+    {
+        "maxNumber": 2,
+        "minNumber": 1,
+        "numberOfFish": 4
+    },
+    {
+        "maxNumber": 3,
+        "minNumber": 1,
+        "numberOfFish": 5
+    },
+    {
+        "maxNumber": 4,
+        "minNumber": 1,
+        "numberOfFish": 5
+    }
+    ]
+}
diff --git a/src/activities/algebra_by/resource/4/Data.qml \
b/src/activities/algebra_by/resource/4/Data.qml new file mode 100644
index 00000000..a0f87426
--- /dev/null
+++ b/src/activities/algebra_by/resource/4/Data.qml
@@ -0,0 +1,49 @@
+/* GCompris - Data.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ *   Johnny Jazeix <jazeix@gmail.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+import "../../../../core"
+
+Dataset {
+    objective: qsTr("obj 4")
+    data: [
+    {
+        "maxNumber": 1, /* Max number on each domino side */
+        "minNumber": 1,
+        "numberOfFish": 3
+    },
+    {
+        "maxNumber": 2,
+        "minNumber": 1,
+        "numberOfFish": 4
+    },
+    {
+        "maxNumber": 3,
+        "minNumber": 1,
+        "numberOfFish": 5
+    },
+    {
+        "maxNumber": 4,
+        "minNumber": 1,
+        "numberOfFish": 5
+    }
+    ]
+}
diff --git a/src/activities/menu/DialogChooseLevel.qml \
b/src/activities/menu/DialogChooseLevel.qml new file mode 100644
index 00000000..c48820b1
--- /dev/null
+++ b/src/activities/menu/DialogChooseLevel.qml
@@ -0,0 +1,231 @@
+/* GCompris - DialogChooseLevel.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ *   Johnny Jazeix <jazeix@gmail.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import QtQuick.Controls 1.5
+import GCompris 1.0
+import "../../core"
+
+/**
+ * A QML component for a full screen configuration dialog.
+ * @ingroup components
+ *
+ * All user editable settings are presented to the user in a
+ * DialogActivityConfig dialog. The global configuration can be accessed
+ * through the Bar in the main menu, activity specific configuration from the
+ * respective activity.
+ *
+ * All config items that are shown in this dialog are persisted
+ * using ApplicationSettings.
+ *
+ * For an example have a look at Menu.qml.
+ *
+ * For more details on how to add configuration to an activity cf.
+ * [the wiki](http://gcompris.net/wiki/Qt_Quick_development_process#Adding_a_configuration_for_a_specific_activity)
 + *
+ * @sa ApplicationSettings
+ * @inherit QtQuick.Item
+ */
+Rectangle {
+    id: dialogChooseLevel
+    visible: false
+
+    /* Public interface: */
+
+    /**
+     * type:string
+     * The name of the activity in case of per-activity config.
+     *
+     * Will be autogenerated unless set by the caller.
+     */
+    property string activityName
+
+    /// @cond INTERNAL_DOCS
+
+    property bool isDialog: true
+
+    /**
+     * type:string
+     * Title of the configuration dialog.
+    */
+    readonly property string title: currentActivity ? qsTr("%1 \
levels").arg(currentActivity.title) : "" +
+    property var difficultiesModel: []
+    property QtObject currentActivity
+
+    property string chosenLevel
+
+    /// @endcond
+
+    /**
+     * Emitted when the config dialog has been closed.
+     */
+    signal close
+
+    /**
+     * Emitted when the config dialog has been started.
+     */
+    signal start
+
+    signal stop
+
+    color: "#696da3"
+    border.color: "black"
+    border.width: 1
+
+    onCurrentActivityChanged: initialize()
+
+    function initialize() {
+        activityName = currentActivity.name.split('/')[0]
+        difficultiesModel = []
+        for(var level in currentActivity.levels) {
+            objectiveLoader.dataFiles.push({"level": currentActivity.levels[level], \
"file": "qrc:/gcompris/src/activities/"+activityName+"/resource/"+currentActivity.levels[level]+"/Data.qml"})
 +        }
+        objectiveLoader.start()
+    }
+
+    Loader {
+        id: objectiveLoader
+        property var dataFiles: []
+        property var currentFile
+        signal start
+        signal stop
+
+        onStart: {
+            var file = dataFiles.shift()
+            currentFile = file
+            source = file.file.toString()
+        }
+        onLoaded: {
+            difficultiesModel.push({"level": currentFile.level, "objective": \
item.objective}) +            if(dataFiles.length != 0) {
+                start()
+            }
+            else {
+                stop()
+            }
+        }
+        onStop: {
+            difficultiesRepeater.model = difficultiesModel
+        }
+    }
+
+    Row {
+        visible: true
+        spacing: 2
+        Item { width: 10; height: 1 }
+
+        Column {
+            spacing: 10
+            anchors.top: parent.top
+            Item { width: 1; height: 10 }
+            Rectangle {
+                color: "#e6e6e6"
+                radius: 6.0
+                width: dialogChooseLevel.width - 30
+                height: title.height * 1.2
+                border.color: "black"
+                border.width: 2
+
+                Row {
+                    spacing: 2
+                    padding: 8
+                    Image {
+                        id: titleIcon
+                        anchors {
+                            left: parent.left
+                            top: parent.top
+                            margins: 4 * ApplicationInfo.ratio
+                        }
+                    }
+
+                    GCText {
+                        id: title
+                        text: dialogChooseLevel.title
+                        width: dialogChooseLevel.width - (30 + cancel.width)
+                        horizontalAlignment: Text.AlignHCenter
+                        verticalAlignment: Text.AlignVCenter
+                        color: "black"
+                        fontSize: 20
+                        font.weight: Font.DemiBold
+                        wrapMode: Text.WordWrap
+                    }
+                }
+            }
+
+            Rectangle {
+                color: "#e6e6e6"
+                radius: 6.0
+                width: dialogChooseLevel.width - 30
+                height: dialogChooseLevel.height - (30 + title.height * 1.2)
+                border.color: "black"
+                border.width: 2
+                anchors.margins: 100
+
+                Flickable {
+                    id: flick
+                    anchors.margins: 8
+                    anchors.fill: parent
+                    flickableDirection: Flickable.VerticalFlick
+                    clip: true
+                    contentHeight: contentItem.childrenRect.height + 40 * \
ApplicationInfo.ratio +                    ExclusiveGroup {
+                        id: levelsGroup
+                    }
+                    Column {
+                        Repeater {
+                            id: difficultiesRepeater
+                            delegate: GCDialogCheckBox {
+                                id: objective
+                                width: dialogChooseLevel.width
+                                text: modelData.objective
+                                exclusiveGroup: levelsGroup
+                                checked: chosenLevel == modelData.level
+                                onClicked: chosenLevel = modelData.level
+                            }
+                        }
+                    }
+                }
+
+                // The scroll buttons
+                GCButtonScroll {
+                    anchors.right: parent.right
+                    anchors.rightMargin: 5 * ApplicationInfo.ratio
+                    anchors.bottom: flick.bottom
+                    anchors.bottomMargin: 5 * ApplicationInfo.ratio
+                    onUp: flick.flick(0, 1400)
+                    onDown: flick.flick(0, -1400)
+                    upVisible: flick.visibleArea.yPosition <= 0 ? false : true
+                    downVisible: flick.visibleArea.yPosition + \
flick.visibleArea.heightRatio >= 1 ? false : true +                }
+            }
+
+            Item { width: 1; height: 10 }
+        }
+    }
+
+    // The cancel button
+    GCButtonCancel {
+        id: cancel
+        onClose: {
+            parent.close()
+        }
+    }
+}
diff --git a/src/activities/menu/Menu.qml b/src/activities/menu/Menu.qml
index 36fdc430..0c9be144 100644
--- a/src/activities/menu/Menu.qml
+++ b/src/activities/menu/Menu.qml
@@ -381,13 +381,13 @@ ActivityBase {
                     anchors.horizontalCenter: parent.horizontalCenter
                     sourceSize.height: iconHeight
                     anchors.margins: 5
-                    Image {
+                    /*Image {
                         source: "qrc:/gcompris/src/core/resource/difficulty" +
                                 ActivityInfoTree.menuTree[index].difficulty + \
".svg";  anchors.top: parent.top
                         sourceSize.width: iconWidth * 0.15
                         x: 5
-                    }
+                    }*/
                     Image {
                         anchors {
                             horizontalCenter: parent.horizontalCenter
@@ -447,6 +447,29 @@ ActivityBase {
                     anchors.fill: activityBackground
                     onClicked: selectCurrentItem()
                 }
+
+                Rectangle {
+                    id: rect
+                    width: currentLevelField.width
+                    height: currentLevelField.height
+                    radius: 8
+                    color: "lightgrey"
+                    GCText {
+                        id: currentLevelField
+                        anchors.top: parent.top
+                        width: iconWidth * 0.15
+                        text: currentLevel
+                    }
+                    MouseArea {
+                        anchors.fill: parent
+                        onClicked: {
+                            if(currentLevel == "") return;
+                            dialogChooseLevel.currentActivity = \
ActivityInfoTree.menuTree[index] +                            \
dialogChooseLevel.chosenLevel = currentLevel; +                            \
displayDialog(dialogChooseLevel); +                        }
+                    }
+                }
                 Image {
                     source: activity.url + (favorite ? "all.svg" : \
"all_disabled.svg");  anchors {
@@ -467,13 +490,25 @@ ActivityBase {
                         return
                     particles.burst(50)
                     ActivityInfoTree.currentActivity = \
                ActivityInfoTree.menuTree[index]
-                    activityLoader.setSource("qrc:/gcompris/src/activities/" + \
ActivityInfoTree.menuTree[index].name, +
+                    activityLoader.setSource("qrc:/gcompris/src/activities/" + \
ActivityInfoTree.currentActivity.name,  {
                                                  'menu': activity,
-                                                 'activityInfo': \
ActivityInfoTree.currentActivity +                                                 \
'activityInfo': ActivityInfoTree.currentActivity, +                                   \
'levelFolder': currentLevel  })
                     if (activityLoader.status == Loader.Ready) loadActivity()
                 }
+
+                DialogChooseLevel {
+                    id: dialogChooseLevel
+                    onClose: home()
+                    onStop: {
+                        currentLevel = dialogChooseLevel.chosenLevel
+                        ApplicationSettings.setCurrentLevel(name, currentLevel)
+                    }
+                }
+
             }
             highlight: Rectangle {
                 width: activityCellWidth - activitiesGrid.spacing
diff --git a/src/activities/reversecount/ActivityInfo.qml \
b/src/activities/reversecount/ActivityInfo.qml index 3e175a28..a238db0a 100644
--- a/src/activities/reversecount/ActivityInfo.qml
+++ b/src/activities/reversecount/ActivityInfo.qml
@@ -21,7 +21,7 @@ ActivityInfo {
   name: "reversecount/Reversecount.qml"
   difficulty: 2
   icon: "reversecount/reversecount.svg"
-  author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
+  author: "Emmanuel Charruau &lt;echarruau@gmail.com&gt;"
   demo: false
   //: Activity title
   title: qsTr("Practice subtraction with a fun game")
@@ -37,4 +37,5 @@ ActivityInfo {
   credit: ""
   section: "math numeration"
   createdInVersion: 0
+  levels: "1,2"
 }
diff --git a/src/activities/reversecount/Reversecount.qml \
b/src/activities/reversecount/Reversecount.qml index 57259ecb..e686f1a8 100644
--- a/src/activities/reversecount/Reversecount.qml
+++ b/src/activities/reversecount/Reversecount.qml
@@ -51,6 +51,8 @@ ActivityBase {
             id: items
             property Item main: activity.main
             property GCSfx audioEffects: activity.audioEffects
+            readonly property string resourceUrl: activity.resourceUrl
+            property var levels: activity.datasetLoader.item.data
             property alias background: background
             property alias backgroundImg: backgroundImg
             property alias bar: bar
@@ -97,7 +99,7 @@ ActivityBase {
 
         Image {
             id: backgroundImg
-            source: Activity.url + Activity.backgrounds[0]
+            source: activity.resourceUrl + Activity.backgrounds[0]
             sourceSize.height: parent.height * 0.5
             anchors.horizontalCenter: parent.horizontalCenter
             anchors.verticalCenter: parent.verticalCenter
@@ -112,7 +114,7 @@ ActivityBase {
                 y: modelData[1] * (background.height- background.height/5) / 5
                 width: background.width / 5
                 height: background.height / 5
-                source: Activity.url + "iceblock.svg"
+                source: activity.resourceUrl + "iceblock.svg"
             }
         }
 
@@ -197,8 +199,7 @@ ActivityBase {
                 }
                 PropertyAction {
                     target: clock; property: 'source';
-                    value: "qrc:/gcompris/src/activities/reversecount/resource/" +
-                           "flower" + items.clockPosition + ".svg"
+                    value: activity.resourceUrl + "flower" + items.clockPosition + \
".svg"  }
                 ParallelAnimation {
                     NumberAnimation {
@@ -228,5 +229,4 @@ ActivityBase {
             onLoose: Activity.initLevel()
         }
     }
-
 }
diff --git a/src/activities/reversecount/Tux.qml \
b/src/activities/reversecount/Tux.qml index b42d7081..a5ad55f7 100644
--- a/src/activities/reversecount/Tux.qml
+++ b/src/activities/reversecount/Tux.qml
@@ -27,7 +27,7 @@ import GCompris 1.0
 Image {
     id: tux
 
-    source: Activity.url + "tux_top_south.svg"
+    source: activity.resourceUrl + "tux_top_south.svg"
     fillMode: Image.PreserveAspectFit
     z: 10
 
diff --git a/src/activities/reversecount/resource/1/Data.qml \
b/src/activities/reversecount/resource/1/Data.qml new file mode 100644
index 00000000..49633813
--- /dev/null
+++ b/src/activities/reversecount/resource/1/Data.qml
@@ -0,0 +1,49 @@
+/* GCompris - Data.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ *   Johnny Jazeix <jazeix@gmail.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+import "../../../../core"
+
+Dataset {
+    objective: qsTr("Numbers between 1 and 8")
+    data: [
+    {
+        "maxNumber": 1, /* Max number on each domino side */
+        "minNumber": 1,
+        "numberOfFish": 3
+    },
+    {
+        "maxNumber": 2,
+        "minNumber": 1,
+        "numberOfFish": 4
+    },
+    {
+        "maxNumber": 3,
+        "minNumber": 1,
+        "numberOfFish": 5
+    },
+    {
+        "maxNumber": 4,
+        "minNumber": 1,
+        "numberOfFish": 5
+    }
+    ]
+}
diff --git a/src/activities/reversecount/resource/2/Data.qml \
b/src/activities/reversecount/resource/2/Data.qml new file mode 100644
index 00000000..a790cd10
--- /dev/null
+++ b/src/activities/reversecount/resource/2/Data.qml
@@ -0,0 +1,54 @@
+/* GCompris - Data.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ *   Johnny Jazeix <jazeix@gmail.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+import "../../../../core"
+
+Dataset {
+    objective: qsTr("Numbers between 2 and 18")
+    data: [
+    {
+        "maxNumber": 5,
+        "minNumber": 2,
+        "numberOfFish": 5
+    },
+    {
+        "maxNumber": 6,
+        "minNumber": 3,
+        "numberOfFish": 5
+    },
+    {
+        "maxNumber": 7,
+        "minNumber": 4,
+        "numberOfFish": 5
+    },
+    {
+        "maxNumber": 8,
+        "minNumber": 4,
+        "numberOfFish": 5
+    },
+    {
+        "maxNumber": 9,
+        "minNumber": 5,
+        "numberOfFish": 5
+    }
+    ]
+}
diff --git a/src/activities/reversecount/reversecount.js \
b/src/activities/reversecount/reversecount.js index bb290df2..79622083 100644
--- a/src/activities/reversecount/reversecount.js
+++ b/src/activities/reversecount/reversecount.js
@@ -42,7 +42,6 @@ var backgrounds = [
 var tuxIceBlockNumber = 0
 var tuxIceBlockNumberGoal = 0
 var tuxIsMoving = false;
-var debuginttmp = 0
 var placeFishToReachBool = false
 
 var level = null;
@@ -62,73 +61,20 @@ var fishes = [
             "Fish02.svg"
         ]
 
-
-var levels = [
-            {
-                "maxNumber": 1, /* Max number on each domino side */
-                "minNumber": 1,
-                "numberOfFish": 3
-            },
-            {
-                "maxNumber": 2,
-                "minNumber": 1,
-                "numberOfFish": 4
-            },
-            {
-                "maxNumber": 3,
-                "minNumber": 1,
-                "numberOfFish": 5
-            },
-            {
-                "maxNumber": 4,
-                "minNumber": 1,
-                "numberOfFish": 5
-            },
-            {
-                "maxNumber": 5,
-                "minNumber": 2,
-                "numberOfFish": 5
-            },
-            {
-                "maxNumber": 6,
-                "minNumber": 3,
-                "numberOfFish": 5
-            },
-            {
-                "maxNumber": 7,
-                "minNumber": 4,
-                "numberOfFish": 5
-            },
-            {
-                "maxNumber": 8,
-                "minNumber": 4,
-                "numberOfFish": 5
-            },
-            {
-                "maxNumber": 9,
-                "minNumber": 5,
-                "numberOfFish": 5
-            },
-
-        ]
-
 var numberOfFish
 var fishIndex = -1
 
 var currentLevel = 0
-var numberOfLevel = levels.length
+var numberOfLevel = 0
 var items
 
-var url = "qrc:/gcompris/src/activities/reversecount/resource/"
-
-
 function start(items_) {
     items = items_
     currentLevel = 0
+    numberOfLevel = items.levels.length
     initLevel()
 }
 
-
 function stop() {
     fishIndex = -1
 }
@@ -138,8 +84,8 @@ function initLevel() {
 
     items.chooseDiceBar.value1 = 0
     items.chooseDiceBar.value2 = 0
-    items.chooseDiceBar.valueMax = levels[currentLevel].maxNumber
-    numberOfFish = levels[currentLevel].numberOfFish
+    items.chooseDiceBar.valueMax = items.levels[currentLevel].maxNumber
+    numberOfFish = items.levels[currentLevel].numberOfFish
 
     fishIndex = 0
     tuxIceBlockNumber = 0
@@ -148,11 +94,10 @@ function initLevel() {
     calculateNextPlaceFishToReach()
     placeFishToReach()
     moveTuxToIceBlock()
-    items.backgroundImg.source = url + backgrounds[currentLevel % \
backgrounds.length] +    items.backgroundImg.source = items.resourceUrl + \
backgrounds[currentLevel % backgrounds.length]  items.clockPosition = 4
 }
 
-
 function moveTux() {
     calculateTuxIceBlockNextPos()
 
@@ -169,13 +114,12 @@ function moveTux() {
     }
 }
 
-
 function moveTuxToNextIceBlock() {
-    tuxIsMoving = false;
+    tuxIsMoving = false
     tuxIceBlockNumber++
     tuxIceBlockNumber = tuxIceBlockNumber % iceBlocksLayout.length
 
-    if (tuxIceBlockNumber >= 0 && tuxIceBlockNumber <= 4)
+    if (tuxIceBlockNumber > 0 && tuxIceBlockNumber <= 4)
         items.tux.rotation = -90
     else if (tuxIceBlockNumber >= 5 && tuxIceBlockNumber <= 8)
         items.tux.rotation = 0
@@ -205,7 +149,7 @@ function moveTuxToNextIceBlock() {
         return
     }
 
-    items.audioEffects.play(url + 'icy_walk.wav')
+    items.audioEffects.play(items.resourceUrl + 'icy_walk.wav')
     //if tux reaches its position + dice number before reaching the fish, \
calculation was wrong  if (tuxIceBlockNumber == tuxIceBlockNumberGoal) {
         items.clockPosition--
@@ -219,7 +163,6 @@ function moveTuxToNextIceBlock() {
     tuxIsMoving = true
 }
 
-
 function moveTuxToIceBlock() {
     items.tux.x = iceBlocksLayout[tuxIceBlockNumber % iceBlocksLayout.length][0] *
             items.background.width / 5 +
@@ -229,10 +172,7 @@ function moveTuxToIceBlock() {
             (items.background.height / 5 - items.tux.height) / 2
 }
 
-
-
 function tuxRunningChanged() {
-
     if (tuxIsMoving) {
         moveTuxToNextIceBlock()
     } else {
@@ -243,7 +183,6 @@ function tuxRunningChanged() {
     }
 }
 
-
 function calculateTuxIceBlockNextPos() {
     tuxIceBlockNumberGoal = tuxIceBlockNumber +
             items.chooseDiceBar.value1 + items.chooseDiceBar.value2
@@ -257,9 +196,9 @@ function calculateNextPlaceFishToReach() {
     var newFishIndex
     do {
         newFishIndex = Math.floor(Math.random() *
-                                  (levels[currentLevel].maxNumber * 2 -
-                                   levels[currentLevel].minNumber + 1)) +
-                levels[currentLevel].minNumber
+                                  (items.levels[currentLevel].maxNumber * 2 -
+                                   items.levels[currentLevel].minNumber + 1)) +
+                items.levels[currentLevel].minNumber
     } while((previousFishIndex === newFishIndex) || (newFishIndex >= \
iceBlocksLayout.length))  previousFishIndex = newFishIndex
 
@@ -274,7 +213,7 @@ function placeFishToReach() {
     else
         items.fishToReach.opacity = 0
 
-    items.fishToReach.nextSource = url + fishes[fishIndex % fishes.length]
+    items.fishToReach.nextSource = items.resourceUrl + fishes[fishIndex % \
                fishes.length]
     items.fishToReach.nextX = iceBlocksLayout[fishIndex % iceBlocksLayout.length][0] \
*  items.background.width / 5 +
             (items.background.width / 5 - items.tux.width) / 2
@@ -283,7 +222,6 @@ function placeFishToReach() {
             (items.background.height / 5 - items.tux.height) / 2
 }
 
-
 function nextLevel() {
     if(numberOfLevel <= ++currentLevel) {
         currentLevel = 0
@@ -305,4 +243,3 @@ function lost() {
 function won() {
     items.bonus.good("flower")
 }
-
diff --git a/src/core/ActivityBase.qml b/src/core/ActivityBase.qml
index 21b1b3a4..8ce64ce8 100644
--- a/src/core/ActivityBase.qml
+++ b/src/core/ActivityBase.qml
@@ -122,6 +122,15 @@ Item {
      */
     property Loading loading
 
+    /**
+     * type:string
+     * The resource folder for the current activity. The resources
+     * of each activity needs to be stored with the same pattern.
+     * "qrc:/gcompris/src/activities/" + activity name + "/resource/"
+     *
+     */
+    property string resourceUrl: (activityInfo && activityInfo.name) ? \
"qrc:/gcompris/src/activities/" + activityInfo.name.split('/')[0] + "/resource/": "" \
+  /**
      * type: bool
      * This variable stores if the activity is a musical activity.
@@ -130,6 +139,9 @@ Item {
      */
     property bool isMusicalActivity: false
 
+    property alias datasetLoader: datasetLoader
+    property string levelFolder
+
     /**
      * Emitted when the user wants to return to the Home/Menu screen.
      */
@@ -232,4 +244,11 @@ Item {
         anchors.fill: parent
         active: !activityInfo.demo && ApplicationSettings.isDemoMode
     }
+
+    Loader {
+        id: datasetLoader
+        asynchronous: false
+        source: resourceUrl + levelFolder + "/Data.qml"
+        active: levelFolder != ""
+    }
 }
diff --git a/src/core/ActivityInfo.cpp b/src/core/ActivityInfo.cpp
index 4ced6da1..767a40b1 100644
--- a/src/core/ActivityInfo.cpp
+++ b/src/core/ActivityInfo.cpp
@@ -40,6 +40,7 @@ QString ActivityInfo::name() const
 {
     return m_name;
 }
+
 void ActivityInfo::setName(const QString &name)
 {
     m_name = name;
@@ -47,6 +48,9 @@ void ActivityInfo::setName(const QString &name)
     // from the persistant configuration
     if(!ApplicationSettings::getInstance()->isKioskMode())
         m_favorite = ApplicationSettings::getInstance()->isFavorite(m_name);
+
+    setCurrentLevel();
+
     emit nameChanged();
 }
 
@@ -191,6 +195,42 @@ void ActivityInfo::setCreatedInVersion(const int created)
     emit createdInVersionChanged();
 }
 
+QStringList ActivityInfo::levels() const
+{
+    return m_levels;
+}
+
+void ActivityInfo::setLevels(const QStringList &levels)
+{
+    // levels only contains one element containing all the difficulties
+    m_levels = levels.front().split(',');
+
+    setCurrentLevel();
+
+    emit levelsChanged();
+}
+
+QString ActivityInfo::currentLevel() const
+{
+    return m_currentLevel;
+}
+
+void ActivityInfo::setCurrentLevel(const QString &currentLevel)
+{
+    m_currentLevel = currentLevel;
+    emit currentLevelChanged();
+}
+
+void ActivityInfo::setCurrentLevel()
+{
+    if(!m_name.isEmpty()) {
+        if(!m_levels.empty() && \
ApplicationSettings::getInstance()->currentLevel(m_name) == "") { +            \
ApplicationSettings::getInstance()->setCurrentLevel(m_name, m_levels[0]); +        }
+        m_currentLevel = ApplicationSettings::getInstance()->currentLevel(m_name);
+    }
+}
+
 QStringList ActivityInfo::getSectionPath()
 {
     QStringList path;
diff --git a/src/core/ActivityInfo.h b/src/core/ActivityInfo.h
index ea4fe094..b50a48be 100644
--- a/src/core/ActivityInfo.h
+++ b/src/core/ActivityInfo.h
@@ -39,14 +39,14 @@
  */
 class ActivityInfo : public QObject
 {
-	Q_OBJECT
+    Q_OBJECT
 
-	/**
-	 * Name of the main activity QML file.
-	 *
-	 * Example: "activity/Activity.qml"
-	 */
-	Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+    /**
+     * Name of the main activity QML file.
+     *
+     * Example: "activity/Activity.qml"
+     */
+    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
 
     /**
      * Section(s) this activity belongs to.
@@ -56,63 +56,63 @@ class ActivityInfo : public QObject
      * computer, discovery, experiment, fun, math, puzzle,
      * reading, strategy.
      */
-	Q_PROPERTY(QString section READ section WRITE setSection NOTIFY sectionChanged)
+    Q_PROPERTY(QString section READ section WRITE setSection NOTIFY sectionChanged)
 
     /**
      * Difficulty of the activity.
      *
      * A difficulty level from 1 (easiest) to 6 (most difficult).
      */
-	Q_PROPERTY(quint32 difficulty READ difficulty WRITE setDifficulty NOTIFY \
difficultyChanged) +    Q_PROPERTY(quint32 difficulty READ difficulty WRITE \
setDifficulty NOTIFY difficultyChanged)  
     /**
      * Relative path to the icon of the activity.
      *
      * Example: "activity/activity.svg"
      */
-	Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged)
+    Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged)
 
     /**
      * Author of the activity.
      */
-	Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
+    Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
 
     /**
      * Whether the activity is part of the demo version of GCompris.
      */
-	Q_PROPERTY(bool demo READ demo WRITE setDemo NOTIFY demoChanged)
+    Q_PROPERTY(bool demo READ demo WRITE setDemo NOTIFY demoChanged)
 
     /**
      * Title of the activity.
      */
-	Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
+    Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
 
     /**
      * Description of the activity.
      */
-	Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY \
descriptionChanged) +    Q_PROPERTY(QString description READ description WRITE \
setDescription NOTIFY descriptionChanged)  
     /**
      * Goal that this activity wants to achieve.
      */
-	Q_PROPERTY(QString goal READ goal WRITE setGoal NOTIFY goalChanged)
+    Q_PROPERTY(QString goal READ goal WRITE setGoal NOTIFY goalChanged)
 
-	/**
+    /**
      * Prerequisite for using this activity.
      */
-	Q_PROPERTY(QString prerequisite READ prerequisite WRITE setPrerequisite NOTIFY \
prerequisiteChanged) +    Q_PROPERTY(QString prerequisite READ prerequisite WRITE \
setPrerequisite NOTIFY prerequisiteChanged)  
     /**
      * Manual describing the activity's usage.
      */
-	Q_PROPERTY(QString manual READ manual WRITE setManual NOTIFY manualChanged)
+    Q_PROPERTY(QString manual READ manual WRITE setManual NOTIFY manualChanged)
 
     /**
      * Credits to third parties.
      */
-	Q_PROPERTY(QString credit READ credit WRITE setCredit NOTIFY creditChanged)
+    Q_PROPERTY(QString credit READ credit WRITE setCredit NOTIFY creditChanged)
 
-	Q_PROPERTY(bool favorite READ favorite WRITE setFavorite NOTIFY favoriteChanged)
+    Q_PROPERTY(bool favorite READ favorite WRITE setFavorite NOTIFY favoriteChanged)
 
     /**
      * This activity is enabled.
@@ -122,7 +122,17 @@ class ActivityInfo : public QObject
     /**
      * Version in which this activity has been created
      */
-	Q_PROPERTY(int createdInVersion READ createdInVersion WRITE setCreatedInVersion \
NOTIFY createdInVersionChanged) +    Q_PROPERTY(int createdInVersion READ \
createdInVersion WRITE setCreatedInVersion NOTIFY createdInVersionChanged) +
+    /**
+     * Contains a list of string defining the folder names for the different \
datasets. +     */
+    Q_PROPERTY(QStringList levels READ levels WRITE setLevels NOTIFY levelsChanged)
+
+    /**
+     * Current dataset used for the activity (it is among the 'levels' list)
+     */
+    Q_PROPERTY(QString currentLevel READ currentLevel WRITE setCurrentLevel NOTIFY \
currentLevelChanged)  
 public:
 	/// @cond INTERNAL_DOCS
@@ -158,6 +168,10 @@ public:
         void setEnabled(const bool);
         int createdInVersion() const;
         void setCreatedInVersion(const int);
+        QStringList levels() const;
+        void setLevels(const QStringList&);
+        QString currentLevel() const;
+        void setCurrentLevel(const QString&);
 
 	QStringList getSectionPath();
 
@@ -177,7 +191,8 @@ signals:
         void favoriteChanged();
         void enabledChanged();
 	void createdInVersionChanged();
-
+	void levelsChanged();
+	void currentLevelChanged();
 	/// @endcond
 private:
 	QString m_name;
@@ -195,6 +210,13 @@ private:
         bool m_favorite;
         bool m_enabled;
 	int m_createdInVersion;
+	QStringList m_levels;
+	QString m_currentLevel;
+
+	/*
+         * Set current level once we have the name and the levels
+         */
+	void setCurrentLevel();
 };
 
 #endif // ACTIVITYINFO_H
diff --git a/src/core/ActivityInfoTree.cpp b/src/core/ActivityInfoTree.cpp
index 70e53dda..477cc7f8 100644
--- a/src/core/ActivityInfoTree.cpp
+++ b/src/core/ActivityInfoTree.cpp
@@ -83,20 +83,6 @@ ActivityInfo *ActivityInfoTree::getCurrentActivity() const
     return m_currentActivity;
 }
 
-ActivityInfo *ActivityInfoTree::getParentActivity(ActivityInfo *root, ActivityInfo \
                *menu)
-{
-    qDebug() << "Parent Path= " << menu->getSectionPath();
-
-    Q_FOREACH( QObject *object, root->children() )
-	{
-            ActivityInfo *activityInfo = qobject_cast<ActivityInfo*>(object);
-            if(activityInfo->section() == menu->section()) {
-                return activityInfo;
-            }
-	}
-    return m_menuTree.at(0);
-}
-
 void ActivityInfoTree::menuTreeAppend(ActivityInfo *menu)
 {
     m_menuTreeFull.append(menu);
diff --git a/src/core/ActivityInfoTree.h b/src/core/ActivityInfoTree.h
index 733d1976..e8396be9 100644
--- a/src/core/ActivityInfoTree.h
+++ b/src/core/ActivityInfoTree.h
@@ -41,7 +41,6 @@ public:
     ActivityInfo *menuTree(int) const;
     void setCurrentActivity(ActivityInfo *currentActivity);
     ActivityInfo *getCurrentActivity() const;
-    ActivityInfo *getParentActivity(ActivityInfo *root, ActivityInfo *menu);
     void menuTreeAppend(ActivityInfo *menu);
     void menuTreeAppend(QQmlEngine *engine,
                         const QDir &menuDir, const QString &menuFile);
diff --git a/src/core/ApplicationSettings.cpp b/src/core/ApplicationSettings.cpp
index 8ae2296e..75b23011 100644
--- a/src/core/ApplicationSettings.cpp
+++ b/src/core/ApplicationSettings.cpp
@@ -44,6 +44,7 @@ static const QString GENERAL_GROUP_KEY = "General";
 static const QString ADMIN_GROUP_KEY = "Admin";
 static const QString INTERNAL_GROUP_KEY = "Internal";
 static const QString FAVORITE_GROUP_KEY = "Favorite";
+static const QString LEVELS_GROUP_KEY = "Levels";
 
 static const QString FULLSCREEN_KEY = "fullscreen";
 static const QString PREVIOUS_HEIGHT_KEY = "previousHeight";
@@ -442,6 +443,19 @@ bool ApplicationSettings::isFavorite(const QString &activity)
 	return favorite;
 }
 
+void ApplicationSettings::setCurrentLevel(const QString &activity, const QString \
&level) +{
+	updateValueInConfig(LEVELS_GROUP_KEY, activity, level);
+}
+
+QString ApplicationSettings::currentLevel(const QString &activity)
+{
+	m_config.beginGroup(LEVELS_GROUP_KEY);
+	QString level = m_config.value(activity, "").toString();
+	m_config.endGroup();
+	return level;
+}
+
 template<class T> void ApplicationSettings::updateValueInConfig(const QString& \
                group,
                                               const QString& key, const T& value)
 {
diff --git a/src/core/ApplicationSettings.h b/src/core/ApplicationSettings.h
index 6efff404..5cc7cbc7 100644
--- a/src/core/ApplicationSettings.h
+++ b/src/core/ApplicationSettings.h
@@ -54,6 +54,9 @@
  * The <em>[Favorite]</em> group is auto-generated from the favorite activities
  * selected by a user.
  *
+ * The <em>[Levels]</em> group is auto-generated from the levels chosen by
+ * a user (if the activity provides multiple datasets).
+ *
  * Besides these global settings there is one group for each activity that
  * stores persistent settings.
  *
@@ -409,14 +412,14 @@ public:
             m_isDemoMode = !isBought;
             emit demoModeChanged();
         }
-	}
+    }
 
     bool sectionVisible() const { return m_sectionVisible; }
     void setSectionVisible(const bool newMode) {
-		qDebug() << "c++ setSectionVisible=" << newMode;
-		m_sectionVisible = newMode;
-		emit sectionVisibleChanged();
-	}
+        qDebug() << "c++ setSectionVisible=" << newMode;
+        m_sectionVisible = newMode;
+        emit sectionVisibleChanged();
+    }
 
     QString wordset() const { return m_wordset; }
     void setWordset(const QString &newWordset) {
@@ -505,6 +508,9 @@ protected slots:
 public slots:
     Q_INVOKABLE bool isFavorite(const QString &activity);
     Q_INVOKABLE void setFavorite(const QString &activity, bool favorite);
+    Q_INVOKABLE void setCurrentLevel(const QString &activity, const QString &level);
+    Q_INVOKABLE QString currentLevel(const QString &activity);
+
     Q_INVOKABLE void saveBaseFontSize();
     /// @endcond
 
diff --git a/src/core/Dataset.qml b/src/core/Dataset.qml
new file mode 100644
index 00000000..c2803e55
--- /dev/null
+++ b/src/core/Dataset.qml
@@ -0,0 +1,38 @@
+/* GCompris - Dataset.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ *   Johnny Jazeix <jazeix@gmail.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+/**
+ * Contains objective and data variable to instanciate new dataset.
+ * Each activity defines its own data format.
+ * @ingroup components
+ *
+ * Used by each activities wanting to provide multiple dataset along with
+ * their objectives.
+ *
+ */
+Item {
+    id: dataset
+
+    property string objective
+    property var data
+}
diff --git a/tests/core/ApplicationSettingsTest.cpp \
b/tests/core/ApplicationSettingsTest.cpp index bc5b5433..3a09759c 100644
--- a/tests/core/ApplicationSettingsTest.cpp
+++ b/tests/core/ApplicationSettingsTest.cpp
@@ -151,6 +151,11 @@ void CoreApplicationSettingsTest::ActivitySettingsTest()
     applicationSettingsMock.saveActivityProgress(dummyActivity, 0);
     QCOMPARE(applicationSettingsMock.loadActivityProgress(dummyActivity), 0);
 
+    // Test current level getter/setter
+    QCOMPARE(applicationSettingsMock.currentLevel(dummyActivity), "");
+    applicationSettingsMock.setCurrentLevel(dummyActivity, "3");
+    QCOMPARE(applicationSettingsMock.currentLevel(dummyActivity), "3");
+
     // By Default the activity
     QVariantMap configuration;
     configuration.insert(QStringLiteral("DummyKey1"), \
QStringLiteral("DummyValue1"));


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic