MenuItem - SelectActivity communication via Subject/Observer mechanism 37/152637/12
authorPawel Kurowski <p.kurowski2@samsung.com>
Tue, 26 Sep 2017 15:47:16 +0000 (17:47 +0200)
committerPawel Kurowski <p.kurowski2@samsung.com>
Tue, 3 Oct 2017 10:51:40 +0000 (12:51 +0200)
SelectActivity fixes:
+ AUTO_TAP_WAITING_PERIOD_KEY is a key of type "double", handle is kept in SelectActivity
+ small changes of UI can be done without refreshing whole Menu
+ problematic pointers to std::stack elements was removed

MenuItem:
+ subclass VconfIntTypeMenuItem and VconfBoolTypeMenuItem

Change-Id: Ie2e639e4d6a6811b0541f00e3eb25802b1294893

src/MenuBuilder.cpp
src/MenuBuilder.hpp
src/SelectActivity.cpp
src/Subject.hpp
tests/ui-scenarios/MenuBuilderTests.cpp
utils/setVconfKeys.sh

index d3eff02..c6633ee 100644 (file)
@@ -7,6 +7,48 @@
 #include "Window.hpp"
 #include "Quickpanel.hpp"
 
+#include <stack>
+
+class VconfTypeMenuItem : public MenuItem
+{
+public:
+       VconfTypeMenuItem(std::vector<std::string> names, std::string iconPath, std::string activityType,
+                                         std::string subMenuLabel, std::string showingStateVconfKey);
+
+       std::string getName() const override;
+
+       void vconfChangeCb();
+       virtual size_t getIndex() const = 0;
+
+       std::stack<VConfInterface::CallbackHandle, std::vector<VConfInterface::CallbackHandle>> callbackHandle;
+       size_t index;
+};
+
+class VconfIntTypeMenuItem : public VconfTypeMenuItem
+{
+public:
+       VconfIntTypeMenuItem(std::vector<std::string> names, std::string iconPath, std::string activityType,
+                                                std::string vconfStateKey,
+                                                std::string subMenuLabel = {}, std::string showingStateVconfKey = {});
+
+       size_t getIndex() const override;
+
+       std::string vconfStateKey;
+};
+
+class VconfBoolTypeMenuItem : public VconfTypeMenuItem
+{
+public:
+       VconfBoolTypeMenuItem(std::vector<std::string> names, std::string iconPath, std::string activityType,
+                                                 std::vector<std::string> vconfStateKeys,
+                                                 std::string subMenuLabel = {}, std::string showingStateVconfKey = {});
+
+       size_t getIndex() const override;
+
+       std::vector<std::string> vconfStateKeys;
+};
+
+
 MenuItem::MenuItem(std::vector<std::string> names, std::string iconPath, std::string activityType, std::string subMenuLabel, std::string showingStateVconfKey)
        : names(std::move(names)), iconPath(std::move(iconPath)), activityType(std::move(activityType)),
          subMenuLabel(std::move(subMenuLabel)), showingStateVconfKey(std::move(showingStateVconfKey)) {}
@@ -26,16 +68,6 @@ std::string MenuItem::getActivityType() const
        return activityType;
 }
 
-VconfKeyType MenuItem::getVconfStateKeysType() const
-{
-       return VconfKeyType::NONE;
-}
-
-std::vector<std::string> MenuItem::getVconfStateKeys() const
-{
-       return {};
-}
-
 std::string MenuItem::getSubMenuLabel() const
 {
        return subMenuLabel;
@@ -46,78 +78,81 @@ std::string MenuItem::getShowingStateVconfKey() const
        return showingStateVconfKey;
 }
 
-class VconfTypeMenuItem : public MenuItem
+VconfTypeMenuItem::VconfTypeMenuItem(std::vector<std::string> names, std::string iconPath, std::string activityType,
+                                                                        std::string subMenuLabel, std::string showingStateVconfKey)
+       : MenuItem(std::move(names), std::move(iconPath), std::move(activityType), std::move(subMenuLabel), std::move(showingStateVconfKey)), index(0)
 {
-public:
-       VconfTypeMenuItem(std::vector<std::string> names, std::string iconPath, std::string activityType,
-                                         VconfKeyType vconfStateKeysType, std::vector<std::string> vconfStateKeys,
-                                         std::string subMenuLabel = {}, std::string showingStateVconfKey = {});
-
-       std::string getName() const override;
-       VconfKeyType getVconfStateKeysType() const override;
-       std::vector<std::string> getVconfStateKeys() const override;
-
-private:
-       VconfKeyType vconfStateKeysType;
-       std::vector<std::string> vconfStateKeys;
-};
+       ASSERT(!this->names.empty(), "Forbidden VconfTypeMenuItem");
+}
 
-class QuickpanelTypeMenuItem : public MenuItem
+std::string VconfTypeMenuItem::getName() const
 {
-public:
-       QuickpanelTypeMenuItem(std::vector<std::string> names, std::string iconPath, std::string activityType);
+       return gettext(names[index].c_str());
+}
 
-       std::string getName() const override;
-};
+void VconfTypeMenuItem::vconfChangeCb()
+{
+       index = getIndex();
+       notify(shared_from_this());
+}
 
-VconfTypeMenuItem::VconfTypeMenuItem(std::vector<std::string> names, std::string iconPath, std::string activityType,
-                                                                        VconfKeyType vconfStateKeysType, std::vector<std::string> vconfStateKeys,
-                                                                        std::string subMenuLabel, std::string showingStateVconfKey)
-       : MenuItem(std::move(names), std::move(iconPath), std::move(activityType), std::move(subMenuLabel), std::move(showingStateVconfKey)),
-         vconfStateKeysType(vconfStateKeysType), vconfStateKeys(std::move(vconfStateKeys))
+VconfIntTypeMenuItem::VconfIntTypeMenuItem(std::vector<std::string> names, std::string iconPath, std::string activityType,
+               std::string vconfStateKey,
+               std::string subMenuLabel, std::string showingStateVconfKey)
+       : VconfTypeMenuItem(std::move(names), std::move(iconPath), std::move(activityType), std::move(subMenuLabel), std::move(showingStateVconfKey)),
+         vconfStateKey(std::move(vconfStateKey))
 {
-       ASSERT(!VconfTypeMenuItem::names.empty() && !VconfTypeMenuItem::vconfStateKeys.empty(), "Forbidden VconfTypeMenuItem");
+       index = getIndex();
+       callbackHandle.push(Singleton<VConfInterface>::instance()
+                                               .registerKeyChangedCb<int>(this->vconfStateKey, std::bind(&VconfIntTypeMenuItem::vconfChangeCb, this)));
 }
 
-std::string VconfTypeMenuItem::getName() const
+size_t VconfIntTypeMenuItem::getIndex() const
 {
-       switch (vconfStateKeysType) {
-       case VconfKeyType::BOOL: {
-               auto idx = 0;
-               for (auto i = 0u; i < vconfStateKeys.size(); ++i) {
-                       auto val = Singleton<VConfInterface>::instance().get(vconfStateKeys[i], false) ? 1 : 0;
-                       idx += val * (1 << i);
-               }
-               return gettext(names[idx].c_str());
-       }
-       case VconfKeyType::INT: {
-               // Int type vconf key. Correct values starts from 1, 0 means error
-               auto idx = Singleton<VConfInterface>::instance().get(vconfStateKeys[0], 0) - 1;
-               if (idx < 0 || idx >= static_cast<int>(names.size())) {
-                       ASSERT(0, "key = %s value = %d out of bound", vconfStateKeys[0].c_str(), idx);
-                       return {};
-               }
-               return gettext(names[idx].c_str());
-       }
-       case VconfKeyType::NONE:
-       case VconfKeyType::DOUBLE:
-       case VconfKeyType::STRING:
-               ASSERT(0, "Forbidden key type");
+       // Int type vconf key. Correct values starts from 1, 0 means error
+       auto idx = Singleton<VConfInterface>::instance().get(vconfStateKey, 0) - 1;
+       if (idx < 0 || idx >= static_cast<int>(names.size())) {
+               ERROR("Key = %s value = %d out of bound", vconfStateKey.c_str(), idx);
+               return 0;
        }
-
-       return {};
+       return static_cast<size_t>(idx);
 }
 
-VconfKeyType VconfTypeMenuItem::getVconfStateKeysType() const
+VconfBoolTypeMenuItem::VconfBoolTypeMenuItem(std::vector<std::string> names, std::string iconPath, std::string activityType,
+               std::vector<std::string> vconfStateKeys,
+               std::string subMenuLabel, std::string showingStateVconfKey)
+       : VconfTypeMenuItem(std::move(names), std::move(iconPath), std::move(activityType), std::move(subMenuLabel), std::move(showingStateVconfKey)),
+         vconfStateKeys(std::move(vconfStateKeys))
 {
-       return vconfStateKeysType;
+       index = getIndex();
+       for (auto &key : this->vconfStateKeys)
+               callbackHandle.push(Singleton<VConfInterface>::instance()
+                                                       .registerKeyChangedCb<bool>(key, std::bind(&VconfIntTypeMenuItem::vconfChangeCb, this)));
 }
 
-std::vector<std::string> VconfTypeMenuItem::getVconfStateKeys() const
+
+size_t VconfBoolTypeMenuItem::getIndex() const
 {
-       return vconfStateKeys;
+       auto idx = 0;
+       for (auto i = 0u; i < vconfStateKeys.size(); ++i) {
+               auto val = Singleton<VConfInterface>::instance().get(vconfStateKeys[i], false) ? 1 : 0;
+               idx += val * (1 << i);
+       }
+       if (idx < 0 || idx >= static_cast<int>(names.size())) {
+               ERROR("Index value = %d out of bound", idx);
+               return 0;
+       }
+       return static_cast<size_t>(idx);
 }
 
+class QuickpanelTypeMenuItem : public MenuItem
+{
+public:
+       QuickpanelTypeMenuItem(std::vector<std::string> names, std::string iconPath, std::string activityType);
+
+       std::string getName() const override;
+};
+
 QuickpanelTypeMenuItem::QuickpanelTypeMenuItem(std::vector<std::string> names, std::string iconPath, std::string activityType)
        : MenuItem(std::move(names), std::move(iconPath), std::move(activityType))
 {}
@@ -191,18 +226,16 @@ MenuMap::MenuMap()
        auto selectAll                          =       std::make_shared<MenuItem>(
                                                                                std::vector<std::string> {"IDS_SELECT_ALL"},
                                                                                defaultImg);
-       auto previous                           =       std::make_shared<VconfTypeMenuItem>(
+       auto previous                           =       std::make_shared<VconfIntTypeMenuItem>(
                                                                                std::vector<std::string> { "IDS_PREVIOUS_CHARACTER", "IDS_PREVIOUS_WORD", "IDS_PREVIOUS_LINE", "IDS_PREVIOUS_PARAGRAPH"},
                                                                                defaultImg,
                                                                                std::string {},/*TODO add activity*/
-                                                                               VconfKeyType::INT,
-                                                                               std::vector<std::string> {VCONF_KEY_GRANULARITY_UNIT});
-       auto next                                       =       std::make_shared<VconfTypeMenuItem>(
+                                                                               std::string {VCONF_KEY_GRANULARITY_UNIT});
+       auto next                                       =       std::make_shared<VconfIntTypeMenuItem>(
                                                                                std::vector<std::string> { "IDS_NEXT_CHARACTER", "IDS_NEXT_WORD", "IDS_NEXT_LINE", "IDS_NEXT_PARAGRAPH"},
                                                                                defaultImg,
                                                                                std::string {},/*TODO add activity*/
-                                                                               VconfKeyType::INT,
-                                                                               std::vector<std::string> {VCONF_KEY_GRANULARITY_UNIT});
+                                                                               std::string {VCONF_KEY_GRANULARITY_UNIT});
        auto copy                                       =       std::make_shared<MenuItem>(
                                                                                std::vector<std::string> {"IDS_COPY"},
                                                                                defaultImg);
@@ -234,11 +267,10 @@ MenuMap::MenuMap()
                                                                                std::vector<std::string> {"IDS_SWIPE_RIGHT"},
                                                                                defaultImg,
                                                                                "SWIPE_RIGHT");
-       auto turnOnOffAutoScroll        =       std::make_shared<VconfTypeMenuItem>(
+       auto turnOnOffAutoScroll        =       std::make_shared<VconfBoolTypeMenuItem>(
                                                                                std::vector<std::string> {"IDS_TURN_ON_AUTO_SCROLL", "IDS_TURN_OFF_AUTO_SCROLL"},
                                                                                defaultImg,
                                                                                std::string {},/*TODO add activity*/
-                                                                               VconfKeyType::BOOL,
                                                                                std::vector<std::string> {VCONF_KEY_AUTO_SCROLL_ENABLED});
        auto speedUpAutoScroll          =       std::make_shared<MenuItem>(
                                                                                std::vector<std::string> {"IDS_SPEED_UP_AUTO_SCROLL"},
@@ -272,11 +304,10 @@ MenuMap::MenuMap()
                                                                                std::vector<std::string> {"IDS_ZOOM_OUT"},
                                                                                defaultImg,
                                                                                "ZOOM_OUT");
-       auto soundVibrationMute         =       std::make_shared<VconfTypeMenuItem>(
+       auto soundVibrationMute         =       std::make_shared<VconfBoolTypeMenuItem>(
                                                                                std::vector<std::string> {"IDS_SOUND", "IDS_VIBRATION", "IDS_MUTE"},
                                                                                defaultImg,
                                                                                "CHANGE_SOUND_PROFILE_ACTIVITY",
-                                                                               VconfKeyType::BOOL,
                                                                                std::vector<std::string> {VCONF_KEY_SOUND_ENABLED, VCONF_KEY_VIBRATION_ENABLED});
        auto lock                                       =       std::make_shared<MenuItem>(
                                                                                std::vector<std::string> {"IDS_LOCK"},
@@ -302,29 +333,25 @@ MenuMap::MenuMap()
                                                                                std::vector<std::string> {"IDS_SLOW_DOWN_SCANING"},
                                                                                defaultImg,
                                                                                std::string{"SLOW_DOWN_AUTO_SCAN_ACTIVITY"});
-       auto scanMethod                         =       std::make_shared<VconfTypeMenuItem>(
+       auto scanMethod                         =       std::make_shared<VconfIntTypeMenuItem>(
                                                                                std::vector<std::string> {"IDS_ROW_SCAN", "IDS_POINT_SCAN"},
                                                                                defaultImg,
                                                                                std::string {"CHANGE_SCANNING_METHOD"},
-                                                                               VconfKeyType::INT,
-                                                                               std::vector<std::string> {VCONF_KEY_SCAN_METHOD});
-       auto scanVerticalDirection      =       std::make_shared<VconfTypeMenuItem>(
+                                                                               std::string {VCONF_KEY_SCAN_METHOD});
+       auto scanVerticalDirection      =       std::make_shared<VconfIntTypeMenuItem>(
                                                                                std::vector<std::string> {"IDS_BOTTOM_TO_TOP", "IDS_TOP_TO_BOTTOM"},
                                                                                defaultImg,
                                                                                std::string {}/*TODO add activity*/,
-                                                                               VconfKeyType::INT,
-                                                                               std::vector<std::string> {VCONF_KEY_SCAN_DIRECTION_VERTICAL});
-       auto turnOnOffVoice                     =       std::make_shared<VconfTypeMenuItem>(
+                                                                               std::string {VCONF_KEY_SCAN_DIRECTION_VERTICAL});
+       auto turnOnOffVoice                     =       std::make_shared<VconfBoolTypeMenuItem>(
                                                                                std::vector<std::string> {"IDS_TURN_ON_VOICE", "IDS_TURN_OFF_VOICE"},
                                                                                defaultImg,
                                                                                std::string {"TOGGLE_VOICE_FEEDBACK_ENABLED_ACTIVITY"},
-                                                                               VconfKeyType::BOOL,
                                                                                std::vector<std::string> {VCONF_KEY_FEEDBACK_VOICE_ENABLED});
-       auto turnOnOffSound                     =       std::make_shared<VconfTypeMenuItem>(
+       auto turnOnOffSound                     =       std::make_shared<VconfBoolTypeMenuItem>(
                                                                                std::vector<std::string> {"IDS_TURN_ON_SOUND", "IDS_TURN_OFF_SOUND"},
                                                                                defaultImg,
                                                                                std::string {"TOGGLE_SOUND_FEEDBACK_ENABLED_ACTIVITY"},
-                                                                               VconfKeyType::BOOL,
                                                                                std::vector<std::string> {VCONF_KEY_FEEDBACK_SOUND_ENABLED});
        auto moreSettings                       =       std::make_shared<MenuItem>(
                                                                                std::vector<std::string> {"IDS_MORE_SETTINGS"},
index 95decb8..b84652b 100644 (file)
@@ -1,16 +1,14 @@
 #ifndef MENU_BUILDER_HPP
 #define MENU_BUILDER_HPP
 
-#include <vector>
-#include <string>
+#include "Subject.hpp"
+
 #include <map>
 #include <memory>
+#include <string>
+#include <vector>
 
-enum class VconfKeyType {
-       NONE, BOOL, INT, DOUBLE, STRING
-};
-
-class MenuItem
+class MenuItem : public std::enable_shared_from_this<MenuItem>, public Subject<MenuItem>
 {
 public:
        MenuItem(std::vector<std::string> names = {}, std::string iconPath = {}, std::string activityType = {},
@@ -19,8 +17,6 @@ public:
        virtual std::string getName() const;
        std::string getIconPath() const;
        std::string getActivityType() const;
-       virtual VconfKeyType getVconfStateKeysType() const;
-       virtual std::vector<std::string> getVconfStateKeys() const;
        std::string getSubMenuLabel() const;
        std::string getShowingStateVconfKey() const;
 
index e45714a..3867658 100644 (file)
@@ -9,6 +9,7 @@
 #include "Optional.hpp"
 #include "UniversalSwitch.hpp"
 #include "ecore.hpp"
+#include "ConditionAll.hpp"
 
 #include <Elementary.h>
 #include <ui/efl_util.h>
@@ -16,7 +17,6 @@
 #include <telephony.h>
 #include <memory>
 #include <vector>
-#include <stack>
 #include <string>
 
 static const double    GENGRID_ITEM_HEIGHT_WIDTH_PROPORTION = 1.2;
@@ -30,18 +30,20 @@ static const std::string AUTO_TAP_KEY                       = VCONF_KEY_AUTO_TAP
 static const std::string AUTO_TAP_WAITING_PERIOD_KEY        = VCONF_KEY_AUTO_TAP_WAITING_TIME;
 
 
-class SelectActivity : public UIActivity, RegisterBindableActivity<SelectActivity>
+class SelectActivity : public UIActivity, public Observer<MenuItem>, RegisterBindableActivity<SelectActivity>
 {
 public:
        static constexpr const char *activityType = "SELECT";
        SelectActivity();
        ~SelectActivity();
+       SelectActivity(SelectActivity &&) = delete;
 
        bool process() override;
        void update(const std::shared_ptr<UIElement> &elem) override;
+       void update(const std::shared_ptr<MenuItem> &menuitem) override;
 
 private:
-       typedef std::pair<SelectActivity *, std::shared_ptr<MenuItem>> GengridItemSelectedCbData;
+       typedef std::pair<std::shared_ptr<MenuItem>, Elm_Widget_Item *> GengridItemData;
 
        void createMenu();
        void removeMenu();
@@ -60,6 +62,7 @@ private:
        bool hasRealUIElementEditableTextIface();
        std::string getCompleteLabelOfButtonsKeysMenu();
        int addItemsToMenu(Evas_Object *, const std::string &);
+       void gengridItemSelected(Elm_Gengrid_Item *);
 
        static void popupDismissedCb(void *, Evas_Object *, void *);
        static void popupBackCb(void *, Evas_Object *, void *);
@@ -69,8 +72,8 @@ private:
        static int divideAndRoundOut(int, int);
 
        std::vector<std::string> nestedMenusLabels;
-       std::stack<VConfInterface::CallbackHandle> callbackHandle;
-       std::stack<GengridItemSelectedCbData> gengridItemsSelectedCbData;
+       VConfInterface::CallbackHandle callbackHandle;
+       std::vector<GengridItemData> gengridItemsData;
        std::shared_ptr<UIElement> realUiElement;
        Optional<bool> realUiElementIsSlider;
        Optional<bool> realUiElementHasEditableText;
@@ -119,7 +122,7 @@ void SelectActivity::update(const std::shared_ptr<UIElement> &elem)
 
        realUiElement = elem;
        if (Singleton<VConfInterface>::instance().get(AUTO_TAP_KEY, false)) {
-               Singleton<VConfInterface>::instance().registerAndGet<bool>(AUTO_TAP_WAITING_PERIOD_KEY, AUTO_TAP_WAITING_PERIOD_DEFAULT_TIME,
+               autoTapWaitingPeriodCallbackHandle = Singleton<VConfInterface>::instance().registerAndGet<double>(AUTO_TAP_WAITING_PERIOD_KEY, AUTO_TAP_WAITING_PERIOD_DEFAULT_TIME,
                [this](auto x) {
                        this->setAutoTapWaitingPeriodCb(x);
                });
@@ -135,6 +138,16 @@ void SelectActivity::update(const std::shared_ptr<UIElement> &elem)
        createMenu();
 }
 
+void SelectActivity::update(const std::shared_ptr<MenuItem> &menuitem)
+{
+       DEBUG("Select - one of MenuItems changed, refreshing");
+       for (auto &e : gengridItemsData)
+               if (menuitem == e.first) {
+                       elm_gengrid_item_fields_update(e.second, "elm.text", ELM_GENGRID_ITEM_FIELD_TEXT);
+                       elm_gengrid_item_fields_update(e.second, "elm.swallow.icon", ELM_GENGRID_ITEM_FIELD_CONTENT);
+               }
+}
+
 void SelectActivity::createMenu()
 {
        ASSERT(realUiElement, "realUiElement is NULL");
@@ -154,11 +167,12 @@ void SelectActivity::createMenu()
 
 void SelectActivity::removeMenu()
 {
-       while (!callbackHandle.empty())
-               callbackHandle.pop();
+       callbackHandle.reset();
+
+       for (auto &e : gengridItemsData)
+               e.first->detach(this, nullptr);
 
-       while (!gengridItemsSelectedCbData.empty())
-               gengridItemsSelectedCbData.pop();
+       gengridItemsData.clear();
 
        if (virtualBackButton) {
                evas_object_smart_callback_del(virtualBackButton.get(), "clicked", popupBackCb);
@@ -273,8 +287,8 @@ std::string SelectActivity::getCompleteLabelOfMenu()
                return getCompleteLabelOfMainMenu();
 
        if (nestedMenusLabels.back() == "IDS_MENU_SETTINGS") {
-               callbackHandle.push(Singleton<VConfInterface>::instance()
-                                                       .registerKeyChangedCb<bool>(AUTO_SCAN_KEY, std::bind(&SelectActivity::refreshMenu, this)));
+               callbackHandle = Singleton<VConfInterface>::instance()
+                                                .registerKeyChangedCb<bool>(AUTO_SCAN_KEY, std::bind(&SelectActivity::refreshMenu, this));
                auto completeLabelOfSettingsMenu = Singleton<VConfInterface>::instance()
                                                                                   .get(AUTO_SCAN_KEY, false) ? "IDS_MENU_SETTINGS_AUTO_SCAN_ON" : "IDS_MENU_SETTINGS_AUTO_SCAN_OFF";
                return completeLabelOfSettingsMenu;
@@ -393,30 +407,12 @@ int SelectActivity::addItemsToMenu(Evas_Object *gengrid, const std::string &comp
        auto menuItems = Singleton<MenuMap>::instance().find(completeLabelOfMenu);
        auto numberOfItems = menuItems.size();
        while (!menuItems.empty()) {
-               gengridItemsSelectedCbData.push(std::make_pair(this, menuItems.back()));
-               auto object = elm_gengrid_item_append(gengrid, gic, menuItems.back().get(), gengridItemSelectedCb, &(gengridItemsSelectedCbData.top()));
+               menuItems.back()->attach(std::dynamic_pointer_cast<SelectActivity>(shared_from_this()), std::make_shared<ConditionAll<MenuItem>>());
+               auto object = elm_gengrid_item_append(gengrid, gic, menuItems.back().get(), gengridItemSelectedCb, this);
+               gengridItemsData.push_back(std::make_pair(menuItems.back(), object));
                if (object && menuItems.back()->getName().empty())
                        elm_atspi_accessible_can_highlight_set(object, EINA_FALSE);
 
-               auto keys = menuItems.back()->getVconfStateKeys();
-               if (!keys.empty())
-                       switch (menuItems.back()->getVconfStateKeysType()) {
-                       case VconfKeyType::BOOL:
-                               for (auto &key : keys)
-                                       callbackHandle.push(Singleton<VConfInterface>::instance()
-                                                                               .registerKeyChangedCb<bool>(key, std::bind(&SelectActivity::refreshMenu, this)));
-                               break;
-                       case VconfKeyType::INT:
-                               ASSERT(menuItems.back()->getVconfStateKeys().size() <= 1, "menuItem can not has more than one vconf int key");
-                               callbackHandle.push(Singleton<VConfInterface>::instance()
-                                                                       .registerKeyChangedCb<int>(keys[0], std::bind(&SelectActivity::refreshMenu, this)));
-                               break;
-                       case VconfKeyType::NONE:
-                       case VconfKeyType::DOUBLE:
-                       case VconfKeyType::STRING:
-                               ASSERT(0, "Forbidden key type");
-                       }
-
                menuItems.pop_back();
        }
 
@@ -425,6 +421,16 @@ int SelectActivity::addItemsToMenu(Evas_Object *gengrid, const std::string &comp
        return numberOfItems;
 }
 
+void SelectActivity::gengridItemSelected(Elm_Gengrid_Item *item)
+{
+       elm_gengrid_item_selected_set(item, EINA_FALSE);
+       for (auto &e : gengridItemsData)
+               if (e.second == item) {
+                       navigateThroughSubMenuOrCreateActivityChangeRequest(e.first.get());
+                       break;
+               }
+}
+
 void SelectActivity::popupDismissedCb(void *data, Evas_Object *obj, void *event_info)
 {
        static_cast<SelectActivity *>(data)->removeMenu();
@@ -457,9 +463,8 @@ Evas_Object *SelectActivity::gengridItemContentGetCb(void *data, Evas_Object *ob
 
 void SelectActivity::gengridItemSelectedCb(void *data, Evas_Object *obj, void *event_info)
 {
-       elm_gengrid_item_selected_set(static_cast<Elm_Gengrid_Item *>(event_info), EINA_FALSE);
-       auto pair = static_cast<GengridItemSelectedCbData *>(data);
-       pair->first->navigateThroughSubMenuOrCreateActivityChangeRequest(pair->second.get());
+       auto item = static_cast<Elm_Gengrid_Item *>(event_info);
+       static_cast<SelectActivity *>(data)->gengridItemSelected(item);
 }
 
 
index 5676d47..e659194 100644 (file)
@@ -29,7 +29,7 @@ public:
        }
 
 protected:
-       void notify(std::shared_ptr<T> item)
+       void notify(const std::shared_ptr<T> &item)
        {
                ASSERT(item, "Notification of NULL item requested");
                auto observersCopy = observers;
index ab4cad5..5b2b112 100644 (file)
 #include <string>
 #include <chrono>
 #include <thread>
+#include <glib.h>
+#include <stack>
 
 #define VCONF_TESTS_PREFIX             "accessibilityTests/"
 
 
+namespace eventLoop
+{
+       std::function<void()> mainFunction;
+       GMainLoop *event_loop;
+       gboolean mainLoopQuittimer(gpointer data)
+       {
+               g_main_loop_quit(event_loop);
+               return 0;
+       }
+
+       gboolean mainLoopIdle(gpointer data)
+       {
+               mainFunction();
+               g_timeout_add(1, mainLoopQuittimer, NULL);
+               return 0;
+       }
+
+       void run(std::function<void()> f)
+       {
+               event_loop = g_main_loop_new(NULL, FALSE);
+               mainFunction = f;
+               g_idle_add(mainLoopIdle, NULL);
+               g_main_loop_run(event_loop);
+               g_main_loop_unref(event_loop);
+       }
+}
+
 class MenuBuilderTest : public ::testing::Test
 {
 public:
@@ -24,21 +53,25 @@ public:
 
        void setMenuKeys(bool val)
        {
-               Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_ACTIONS_MENU_ITEM, val);
-               Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_BACK_MENU_ITEM, val);
-               Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_BUTTONS_AND_KEYS_MENU_ITEM, val);
-               Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_CONTEXTUAL_MENU, val);
-               Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_GESTURES_MENU_ITEM, val);
-               Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_HOME_SCREEN_MENU_ITEM, val);
-               Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_SETTINGS_MENU_ITEM, val);
-               Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_RECENT_APPS_MENU_ITEM, val);
+               eventLoop::run([&]() {
+                       Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_ACTIONS_MENU_ITEM, val);
+                       Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_BACK_MENU_ITEM, val);
+                       Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_BUTTONS_AND_KEYS_MENU_ITEM, val);
+                       Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_CONTEXTUAL_MENU, val);
+                       Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_GESTURES_MENU_ITEM, val);
+                       Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_HOME_SCREEN_MENU_ITEM, val);
+                       Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_SETTINGS_MENU_ITEM, val);
+                       Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_RECENT_APPS_MENU_ITEM, val);
+               });
        }
 
        void setSoundProfileKeys(std::string profile)
        {
                auto changeProfile = [](bool sound, bool vibration) {
-                       Singleton<VConfInterface>::instance().set(VCONF_KEY_SOUND_ENABLED, sound);
-                       Singleton<VConfInterface>::instance().set(VCONF_KEY_VIBRATION_ENABLED, vibration);
+                       eventLoop::run([&]() {
+                               Singleton<VConfInterface>::instance().set(VCONF_KEY_SOUND_ENABLED, sound);
+                               Singleton<VConfInterface>::instance().set(VCONF_KEY_VIBRATION_ENABLED, vibration);
+                       });
                };
 
                if (profile == "IDS_SOUND")
@@ -51,26 +84,16 @@ public:
                        ASSERT(0, "Wrong function arguemnt");
        }
 
-       void testMenuContent(const std::string &menuName,
-                                                std::vector<std::string> expectedMenuItemsNames,
-                                                std::vector<std::vector<std::string>> expectedMenuItemsKeys = {})
+       void testMenuContent(const std::string &menuName, std::vector<std::string> expectedMenuItemsNames)
        {
+               //This test will check content of menu, with each item in default state.
                auto actualMenuItems = Singleton<MenuMap>::instance().find(menuName);
 
                ASSERT_EQ(actualMenuItems.size(), expectedMenuItemsNames.size());
-               if (!expectedMenuItemsKeys.empty())
-                       ASSERT_EQ(actualMenuItems.size(), expectedMenuItemsKeys.size());
 
                for (auto ii = 0u; ii < actualMenuItems.size(); ++ii) {
                        auto idxForExpectedMenuItems = actualMenuItems.size() - 1 - ii;
                        EXPECT_EQ(actualMenuItems[ii]->getName(), expectedMenuItemsNames[idxForExpectedMenuItems]);
-
-                       if (expectedMenuItemsKeys.empty())
-                               continue;
-                       auto actualMenuItemsKeys = actualMenuItems[ii]->getVconfStateKeys();
-                       ASSERT_EQ(actualMenuItemsKeys.size(), expectedMenuItemsKeys[idxForExpectedMenuItems].size());
-                       for (auto jj = 0u; jj < actualMenuItemsKeys.size(); ++jj)
-                               EXPECT_EQ(actualMenuItemsKeys[jj], expectedMenuItemsKeys[idxForExpectedMenuItems][jj]);
                }
        }
 
@@ -87,8 +110,6 @@ public:
                testMenuContent("IDS_MENU_ACTIONS", {
                        "IDS_ZOOM_IN", "IDS_ZOOM_OUT", "IDS_SCREEN_ROTATION", soundProfile,
                        "IDS_LOCK", "IDS_OPEN_NOTI_PANEL", "IDS_CAPTURE_SCREENSHOT"
-               }, {
-                       {}, {}, {}, {VCONF_KEY_SOUND_ENABLED, VCONF_KEY_VIBRATION_ENABLED}, {}, {}, {}
                });
        }
 
@@ -98,10 +119,31 @@ public:
                testMenuContent("IDS_MENU_ACTIONS", {
                        "IDS_ZOOM_IN", "IDS_ZOOM_OUT", "IDS_SCREEN_ROTATION", "IDS_SOUND",
                        "IDS_LOCK", quickpanelState, "IDS_CAPTURE_SCREENSHOT"
-               }, {
-                       {}, {}, {}, {VCONF_KEY_SOUND_ENABLED, VCONF_KEY_VIBRATION_ENABLED}, {}, {}, {}
                });
        }
+
+       void testVconfTypeMenuItemStates(MenuItem *item, const std::string &key, const std::vector<std::string> &requiredStates, int typeShift)
+       {
+               for (auto ii = 0u; ii < requiredStates.size(); ++ii) {
+                       eventLoop::run([&]() {
+                               if (typeShift)
+                                       Singleton<VConfInterface>::instance().set(key, int(ii + typeShift));
+                               else
+                                       Singleton<VConfInterface>::instance().set(key, bool(ii));
+                       });
+                       EXPECT_EQ(item->getName(), requiredStates[ii]);
+               }
+       }
+
+       void testVconfIntTypeMenuItemStates(MenuItem *item, const std::string &key, const std::vector<std::string> &requiredStates)
+       {
+               testVconfTypeMenuItemStates(item, key, requiredStates, 1);
+       }
+
+       void testVconfBoolTypeMenuItemStates(MenuItem *item, const std::string &key, const std::vector<std::string> &requiredStates)
+       {
+               testVconfTypeMenuItemStates(item, key, requiredStates, 0);
+       }
 };
 
 TEST_F(MenuBuilderTest, testContentOfMenuMainNormal)
@@ -113,7 +155,9 @@ TEST_F(MenuBuilderTest, testContentOfMenuMainNormal)
 TEST_F(MenuBuilderTest, testImpactOfContextualMenuVconfValueOnMenuMain)
 {
        setMenuKeys(true);
-       Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_CONTEXTUAL_MENU, false);
+       eventLoop::run([]() {
+               Singleton<VConfInterface>::instance().set(VCONF_KEY_SHOW_CONTEXTUAL_MENU, false);
+       });
        testIfMenuMainIsEqualToNormal("IDS_MENU_MAIN_HOME_APPS");
        testIfMenuMainIsEqualToNormal("IDS_MENU_MAIN_SLIDER");
        testIfMenuMainIsEqualToNormal("IDS_MENU_MAIN_EDITABLE_TEXT");
@@ -215,35 +259,25 @@ TEST_F(MenuBuilderTest, testContentOfMenuRotateScreen)
 
 TEST_F(MenuBuilderTest, testContentOfMenuSettings)
 {
-       Singleton<VConfInterface>::instance().set(VCONF_KEY_SCAN_METHOD, 2);
-       Singleton<VConfInterface>::instance().set(VCONF_KEY_SCAN_DIRECTION_VERTICAL, 2);
-       Singleton<VConfInterface>::instance().set(VCONF_KEY_FEEDBACK_VOICE_ENABLED, false);
-       Singleton<VConfInterface>::instance().set(VCONF_KEY_FEEDBACK_SOUND_ENABLED, false);
+       eventLoop::run([]() {
+               Singleton<VConfInterface>::instance().set(VCONF_KEY_SCAN_METHOD, 2);
+               Singleton<VConfInterface>::instance().set(VCONF_KEY_SCAN_DIRECTION_VERTICAL, 2);
+               Singleton<VConfInterface>::instance().set(VCONF_KEY_FEEDBACK_VOICE_ENABLED, false);
+               Singleton<VConfInterface>::instance().set(VCONF_KEY_FEEDBACK_SOUND_ENABLED, false);
+       });
        testMenuContent("IDS_MENU_SETTINGS_AUTO_SCAN_ON", {
                "IDS_SPEED_UP_SCANING", "IDS_SLOW_DOWN_SCANING", "IDS_POINT_SCAN", "IDS_TOP_TO_BOTTOM",
                "IDS_TURN_ON_VOICE", "IDS_TURN_ON_SOUND", "IDS_MORE_SETTINGS"
-       }, {
-               std::vector<std::string> {},
-               std::vector<std::string> {},
-               std::vector<std::string> {VCONF_KEY_SCAN_METHOD},
-               std::vector<std::string> {VCONF_KEY_SCAN_DIRECTION_VERTICAL},
-               std::vector<std::string> {VCONF_KEY_FEEDBACK_VOICE_ENABLED},
-               std::vector<std::string> {VCONF_KEY_FEEDBACK_SOUND_ENABLED},
-               std::vector<std::string> {}
        });
 
-       Singleton<VConfInterface>::instance().set(VCONF_KEY_SCAN_METHOD, 1);
-       Singleton<VConfInterface>::instance().set(VCONF_KEY_SCAN_DIRECTION_VERTICAL, 1);
-       Singleton<VConfInterface>::instance().set(VCONF_KEY_FEEDBACK_VOICE_ENABLED, true);
-       Singleton<VConfInterface>::instance().set(VCONF_KEY_FEEDBACK_SOUND_ENABLED, true);
+       eventLoop::run([]() {
+               Singleton<VConfInterface>::instance().set(VCONF_KEY_SCAN_METHOD, 1);
+               Singleton<VConfInterface>::instance().set(VCONF_KEY_SCAN_DIRECTION_VERTICAL, 1);
+               Singleton<VConfInterface>::instance().set(VCONF_KEY_FEEDBACK_VOICE_ENABLED, true);
+               Singleton<VConfInterface>::instance().set(VCONF_KEY_FEEDBACK_SOUND_ENABLED, true);
+       });
        testMenuContent("IDS_MENU_SETTINGS_AUTO_SCAN_OFF", {
                "IDS_ROW_SCAN", "IDS_BOTTOM_TO_TOP", "IDS_TURN_OFF_VOICE", "IDS_TURN_OFF_SOUND", "IDS_MORE_SETTINGS"
-       }, {
-               std::vector<std::string> {VCONF_KEY_SCAN_METHOD},
-               std::vector<std::string> {VCONF_KEY_SCAN_DIRECTION_VERTICAL},
-               std::vector<std::string> {VCONF_KEY_FEEDBACK_VOICE_ENABLED},
-               std::vector<std::string> {VCONF_KEY_FEEDBACK_SOUND_ENABLED},
-               std::vector<std::string> {}
        });
 }
 
@@ -261,41 +295,29 @@ TEST_F(MenuBuilderTest, testContentOfMenuButtonsKeys)
 
 TEST_F(MenuBuilderTest, testContentOfMenuEditText)
 {
-       Singleton<VConfInterface>::instance().set(VCONF_KEY_GRANULARITY_UNIT, 1);
+       eventLoop::run([]() {
+               Singleton<VConfInterface>::instance().set(VCONF_KEY_GRANULARITY_UNIT, 1);
+       });
        testMenuContent("IDS_MENU_EDIT_TEXT", {
                "IDS_SELECTION_MODE", "IDS_SELECT_ALL", "IDS_PREVIOUS_CHARACTER", "IDS_NEXT_CHARACTER",
                "IDS_COPY", "IDS_PASTE", "IDS_CUT", "IDS_GRANULARITY_SETTINGS"
-       }, {
-               std::vector<std::string> {},
-               std::vector<std::string> {},
-               std::vector<std::string> {VCONF_KEY_GRANULARITY_UNIT},
-               std::vector<std::string> {VCONF_KEY_GRANULARITY_UNIT},
-               std::vector<std::string> {},
-               std::vector<std::string> {},
-               std::vector<std::string> {},
-               std::vector<std::string> {}
        });
 }
 
 TEST_F(MenuBuilderTest, testContentOfMenuAutoScroll)
 {
-       Singleton<VConfInterface>::instance().set(VCONF_KEY_AUTO_SCROLL_ENABLED, false);
+       eventLoop::run([]() {
+               Singleton<VConfInterface>::instance().set(VCONF_KEY_AUTO_SCROLL_ENABLED, false);
+       });
        testMenuContent("IDS_MENU_AUTO_SCROLL_OFF", {
                "IDS_TURN_ON_AUTO_SCROLL", "IDS_SCROLL_UP", "IDS_SCROLL_DOWN", "IDS_SCROLL_TOP"
-       }, {
-               std::vector<std::string> {VCONF_KEY_AUTO_SCROLL_ENABLED},
-               std::vector<std::string> {},
-               std::vector<std::string> {},
-               std::vector<std::string> {}
        });
 
-       Singleton<VConfInterface>::instance().set(VCONF_KEY_AUTO_SCROLL_ENABLED, true);
+       eventLoop::run([]() {
+               Singleton<VConfInterface>::instance().set(VCONF_KEY_AUTO_SCROLL_ENABLED, true);
+       });
        testMenuContent("IDS_MENU_AUTO_SCROLL_ON", {
                "IDS_TURN_OFF_AUTO_SCROLL", "IDS_SPEED_UP_AUTO_SCROLL", "IDS_SLOW_DOWN_AUTO_SCROLL"
-       }, {
-               std::vector<std::string> {VCONF_KEY_AUTO_SCROLL_ENABLED},
-               std::vector<std::string> {},
-               std::vector<std::string> {}
        });
 }
 
@@ -306,15 +328,39 @@ TEST_F(MenuBuilderTest, testContentOfMenuGranularity)
        });
 }
 
-TEST_F(MenuBuilderTest, testAllGranularityOptions)
+TEST_F(MenuBuilderTest, testMenuItemsStates)
 {
        auto actualMenuItems = Singleton<MenuMap>::instance().find("IDS_MENU_EDIT_TEXT");
-       auto next = actualMenuItems[4];
+
+       auto next = actualMenuItems[4]; //Named variables are created here to increase test readability
+       testVconfIntTypeMenuItemStates(next.get(), VCONF_KEY_GRANULARITY_UNIT,
+       {"IDS_NEXT_CHARACTER", "IDS_NEXT_WORD", "IDS_NEXT_LINE", "IDS_NEXT_PARAGRAPH"});
+
        auto prev = actualMenuItems[5];
-       auto requiredStates = std::vector<std::string> {"CHARACTER", "WORD", "LINE", "PARAGRAPH"};
-       for (auto ii = 0u; ii < requiredStates.size(); ++ii) {
-               Singleton<VConfInterface>::instance().set(VCONF_KEY_GRANULARITY_UNIT, int(ii + 1));
-               EXPECT_EQ(prev->getName(), "IDS_PREVIOUS_" + requiredStates[ii]);
-               EXPECT_EQ(next->getName(), "IDS_NEXT_" + requiredStates[ii]);
-       }
+       testVconfIntTypeMenuItemStates(prev.get(), VCONF_KEY_GRANULARITY_UNIT,
+       {"IDS_PREVIOUS_CHARACTER", "IDS_PREVIOUS_WORD", "IDS_PREVIOUS_LINE", "IDS_PREVIOUS_PARAGRAPH"});
+
+       actualMenuItems = Singleton<MenuMap>::instance().find("IDS_MENU_AUTO_SCROLL_ON");
+
+       auto turnOnOffAutoScroll = actualMenuItems[2];
+       testVconfBoolTypeMenuItemStates(turnOnOffAutoScroll.get(), VCONF_KEY_AUTO_SCROLL_ENABLED,
+       {"IDS_TURN_ON_AUTO_SCROLL", "IDS_TURN_OFF_AUTO_SCROLL"});
+
+       actualMenuItems = Singleton<MenuMap>::instance().find("IDS_MENU_SETTINGS_AUTO_SCAN_ON");
+
+       auto turnOnOffSound = actualMenuItems[1];
+       testVconfBoolTypeMenuItemStates(turnOnOffSound.get(), VCONF_KEY_FEEDBACK_SOUND_ENABLED,
+       {"IDS_TURN_ON_SOUND", "IDS_TURN_OFF_SOUND"});
+
+       auto turnOnOffVoice = actualMenuItems[2];
+       testVconfBoolTypeMenuItemStates(turnOnOffVoice.get(), VCONF_KEY_FEEDBACK_VOICE_ENABLED,
+       {"IDS_TURN_ON_VOICE", "IDS_TURN_OFF_VOICE"});
+
+       auto scanVerticalDirection = actualMenuItems[3];
+       testVconfIntTypeMenuItemStates(scanVerticalDirection.get(), VCONF_KEY_SCAN_DIRECTION_VERTICAL,
+       {"IDS_BOTTOM_TO_TOP", "IDS_TOP_TO_BOTTOM"});
+
+       auto scanMethod = actualMenuItems[4];
+       testVconfIntTypeMenuItemStates(scanMethod.get(), VCONF_KEY_SCAN_METHOD,
+       {"IDS_ROW_SCAN", "IDS_POINT_SCAN"});
 }
\ No newline at end of file
index 5224326..072f558 100755 (executable)
@@ -39,7 +39,7 @@ $VCONFTOOL bool   "${VCONF_PROJECT_PREFIX}FEEDBACK_VOICE_ENABLED"  0
 $VCONFTOOL int "${VCONF_PROJECT_PREFIX}FEEDBACK_VOICE_SPEECH_RATE" 8           # value beetwen 1 and 15, 0 = TTS_SPEED_AUTO
 $VCONFTOOL double "${VCONF_PROJECT_PREFIX}FEEDBACK_VOICE_SPEECH_VOLUME" 1.0
 
-$VCONFTOOL int "${VCONF_PROJECT_PREFIX}GRANULARITY_UNIT" 0                                     # 0 = CHARACTER, 1 = WORD, 2 = LINE, 3 = PARAGRAPH
+$VCONFTOOL int "${VCONF_PROJECT_PREFIX}GRANULARITY_UNIT" 1                                     # 1 = CHARACTER, 2 = WORD, 3 = LINE, 4 = PARAGRAPH
 
 $VCONFTOOL int "${VCONF_PROJECT_PREFIX}LOOP_LIMIT_TO_INACTION" 5                               # how many runs before scanning abort