worldclock: adding new Location to custom list implemented. 75/90275/5
authorRadoslaw Czerski <r.czerski@samsung.com>
Fri, 30 Sep 2016 13:25:25 +0000 (15:25 +0200)
committerLukasz Stanislawski <l.stanislaws@samsung.com>
Mon, 3 Oct 2016 10:32:48 +0000 (03:32 -0700)
Change-Id: Icf1997a5770c846b94da0bcb17121c96cf4dc797
Signed-off-by: Radoslaw Czerski <r.czerski@samsung.com>
clock/inc/Model/WorldClock.h
clock/inc/Presenter/WorldClockPresenter.h
clock/inc/View/WorldClockView.h
clock/src/Model/WorldClock.cpp
clock/src/Presenter/WorldClockPresenter.cpp
clock/src/View/WorldClockView.cpp
clock/tizen-manifest.xml

index d60e2b5..69149d1 100644 (file)
@@ -23,7 +23,7 @@
 
 namespace model {
 
-       /*
+       /**
         * @brief Structure for time zone details
         */
 
@@ -36,19 +36,31 @@ namespace model {
 
        class WorldClock {
                public:
-                       enum Direction {
-                               LEFT,
-                               RIGHT
+
+                       /**
+                        * @brief Enumeration for direction of time zone shift.
+                        */
+                       enum Direction{
+                               LEFT,//!< LEFT
+                               RIGHT//!< RIGHT
                        };
 
-                       /*
+                       /**
                         * @brief Constructs the WorldClock object. It will also load UserLocation list from preferences.
                         */
                        WorldClock();
-                       ~WorldClock(){};
-                       std::vector<model::Location> UserLocations;
 
-                       /*
+                       /**
+                        * @brief Frees all resources that will not be fried automatically. It will also save UserLocation list to preferences.
+                        */
+                       ~WorldClock();
+
+                       /**
+                        *@brief List of locations added by user
+                        */
+                       std::vector<const model::Location *> user_locations_;
+
+                       /**
                         * @brief Adds location to UserLocations list.
                         * @remarks The location is retrieved from called Worldclock-efl app
                         *
@@ -56,35 +68,35 @@ namespace model {
                         */
                        void AddUserLocation(model::Location l);
 
-                       /*
+                       /**
                         * @brief Deletes location from UserLocations list
                         *
                         * @param[in] l location to remove from UserLocation list
                         */
                        void RemoveUserLocation(model::Location l);
 
-                       /*
+                       /**
                         * @brief Gets current time zone set to display
                         *
                         * @return time zone number [from 0 to (time_zones_.size() - 1)]
                         */
                        int GetCurrentTimezoneNo() const;
 
-                       /*
+                       /**
                         * @brief Gets time zone marked ad current
                         *
                         * @return pointer to time zone
                         */
                        const Timezone *GetCurrentTimezone() const;
 
-                       /*
+                       /**
                         * @brief Sets specified time zone as current
                         *
                         * @param[in] timezone time zone to set as current
                         */
                        void SetCurrentTimezone(const Timezone *timezone);
 
-                       /*
+                       /**
                         * @brief Gets timezone position in time_zone_ list
                         *
                         * @param[in] timezone time zone
@@ -93,21 +105,21 @@ namespace model {
                         */
                        int GetTimezoneNo(const Timezone *timezone) const;
 
-                       /*
+                       /**
                         * @brief Gets total number of time zones stored in time_zone_ list
                         *
                         * @return number of time zones
                         */
                        int GetTimezonesCount() const;
 
-                       /*
+                       /**
                         * @brief Gets total number of locations stored in locations_ list
                         *
                         * @return number of locations
                         */
                        int GetLocationsCount() const;
 
-                       /*
+                       /**
                         * @brief Retrieve time zone for specified offset
                         * @param[in] offset offset in minutes between GMT 0 and returned time zone
                         *
@@ -125,31 +137,38 @@ namespace model {
                         */
                        const model::Location *GetLocation(int no) const;
 
-                       /*
+                       /**
                         * @brief Sets next on the left to current time zone as current
                         * param[in] direction direction to change current time zone to
                         */
                        void MoveCurrentTimezone(Direction direction);
 
+                       /*
+                        * @brief Adds item to custom list
+                        *
+                        * param[in] l location to add
+                        */
+                       bool AddItemToCustomList(const model::Location *l);
+
                private:
 
-                       /*
+                       /**
                         * @brief Gets time zone by its no in time_zone_ list
                         */
                        const Timezone *GetTimezone(int no) const;
 
-                       /*
+                       /**
                         * @brief Currently set time zone.
                         * It means the time zone to be displayed on world map and its details will be displayed below the map
                         */
                        const Timezone *current_tz_;
 
-                       /*
+                       /**
                         * @brief List of locations that may be shown on the map with corresponding time zone
                         */
                        static std::vector<model::Location> locations_;
 
-                       /*
+                       /**
                         * @brief List of time zones that may be shown on the map
                         */
                        static std::vector<Timezone> time_zones_;
index bae22e5..5263361 100644 (file)
@@ -36,6 +36,8 @@ namespace presenter {
                        void OnCustomListItemClicked();
 
                        void OnMapViewUpdateRequest();
+                       void OnItemAdded();
+
        };
 }
 
index 836195a..f7d96f7 100644 (file)
@@ -19,6 +19,7 @@
 
 
 #include <vector>
+#include <app_control.h>
 
 #include "Model/WorldClock.h"
 #include "View/PageView.h"
@@ -31,6 +32,8 @@ namespace view {
                BUTTON_RIGHT_ARROW_CLICKED,
 
                CUSTOM_LIST_ITEM_CLICKED,
+               CUSTOM_LIST_ITEM_ADD,
+
                UPDATE_MAP_VIEW,
 
                MAX
@@ -41,7 +44,7 @@ namespace view {
                public:
                        WorldClockView();
 
-                       Evas_Object *GetEvasObject(){return world_clock_;};
+                       Evas_Object *GetEvasObject(){return world_clock_main_;};
 
                        void RegisterSignal(std::function<void(void)>func, view::WorldClockSignals signal);
 
@@ -50,11 +53,13 @@ namespace view {
                        void AppendItemToCustomList(const model::Location *location);
 
                        const model::Location *GetLastClickedItem();
+                       const model::Location *GetLocationToAdd();
 
                private:
                        void CreateTimezoneDetails();
                        void CreateCustomLocationsList();
                        void CreateTimezoneCitiesList();
+                       Evas_Object *CreateFloatingButton();
 
                        void UpdateTimezoneLocationsDots(const model::Timezone *timezone);
                        void UpdateGmtOffset(const model::Timezone *timezone);
@@ -77,8 +82,11 @@ namespace view {
                        static char *TextGet(void *data, Evas_Object *obj, const char *part);
                        static void Del(void *data, Evas_Object *obj);
 
-                       void SetItemLastClicked(const model::Location *location);
+                       static void AddButtonClicked(void *data, Evas_Object *obj, void *event_info);
+                       static void AddLocationReplayCb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data);
 
+                       void SetItemLastClicked(const model::Location *location);
+                       void SetItemToAdd(model::Location *l);
                        void EmitSignal(view::WorldClockSignals signal);
 
                        const char *OffsetToString(int offset);
@@ -86,11 +94,13 @@ namespace view {
                        static Elm_Genlist_Item_Class world_clock_itc_;
 
                        Evas_Object *world_clock_;
+                       Evas_Object *world_clock_main_;
                        Evas_Object *timezone_details_;
                        Evas_Object *timezone_cities_;
                        Evas_Object *custom_locations_list_;
 
                        const model::Location *item_last_clicked_;
+                       const model::Location *item_to_add_;
 
                        std::vector<std::function<void(void)>> signals
                                                = std::vector<std::function<void(void)>>((int)WorldClockSignals::MAX, nullptr);
index f339f94..74e215a 100644 (file)
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#include <app_preference.h>
+#include <algorithm>
+
 #include "Model/WorldClock.h"
 #include "Model/Location.h"
 #include "log.h"
@@ -132,11 +135,21 @@ std::vector<Timezone> WorldClock::time_zones_ = {
 
 WorldClock::WorldClock()
 {
-       SetCurrentTimezone(&time_zones_.at(12));
-       /* Need to load and store currently set tz to file or any app_data if possible
-        *
-        * Also All User Locations (from Custom list) need to be stored and loaded from file/app preferences/other
-        */
+       int current_tz = 1;
+       int ret = preference_get_int("WORLD_CLOCK_MAP_CURRENT_TIMEZONE", &current_tz);
+       if (ret != PREFERENCE_ERROR_NONE) {
+               preference_set_int("WORLD_CLOCK_MAP_CURRENT_TIMEZONE", 12); // This timezone 'no' need to be retrieved using current position
+       }
+
+       SetCurrentTimezone(&time_zones_.at(current_tz));
+}
+
+WorldClock::~WorldClock()
+{
+       int ret = preference_set_int("WORLD_CLOCK_MAP_CURRENT_TIMEZONE", GetCurrentTimezoneNo());
+       if (ret != PREFERENCE_ERROR_NONE) {
+               DBG("preference_set_int failed[%d]: %s", ret, get_error_message(ret));
+       }
 }
 
 int WorldClock::GetCurrentTimezoneNo() const
@@ -215,3 +228,16 @@ void model::WorldClock::MoveCurrentTimezone(Direction direction)
                        ERR("Invalid direction");
        }
 }
+
+bool WorldClock::AddItemToCustomList(const model::Location *l)
+{
+       if (!user_locations_.empty()) {
+               auto it = std::find(user_locations_.begin(), user_locations_.end(), l);
+               if (it != user_locations_.end()) {
+                       DBG("Location already exists in custom list");
+                       return false;
+               }
+       }
+       user_locations_.push_back(l);
+       return true;
+}
index 9d6ce21..6479874 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "Presenter/WorldClockPresenter.h"
+#include "log.h"
 
 namespace presenter {
 
@@ -27,13 +28,8 @@ WorldClockPresenter::WorldClockPresenter(view::WorldClockView *view, model::Worl
                                view::WorldClockSignals::BUTTON_RIGHT_ARROW_CLICKED);
        view_->RegisterSignal(std::bind(&WorldClockPresenter::OnCustomListItemClicked, this),
                                view::WorldClockSignals::CUSTOM_LIST_ITEM_CLICKED);
-
-       /* Temporary added custom list items */
-       view_->AppendItemToCustomList(model_->GetLocation(0));
-       view_->AppendItemToCustomList(model_->GetLocation(12));
-       view_->AppendItemToCustomList(model_->GetLocation(32));
-       view_->AppendItemToCustomList(model_->GetLocation(54));
-       view_->AppendItemToCustomList(model_->GetLocation(70));
+       view_->RegisterSignal(std::bind(&WorldClockPresenter::OnItemAdded, this),
+                               view::WorldClockSignals::CUSTOM_LIST_ITEM_ADD);
 
        view_->UpdateMapAndTimezoneDetails(model_->GetCurrentTimezone());
 }
@@ -68,4 +64,19 @@ void WorldClockPresenter::OnMapViewUpdateRequest()
        view_->UpdateMapAndTimezoneDetails(model_->GetCurrentTimezone());
 }
 
+void WorldClockPresenter::OnItemAdded()
+{
+       const model::Location *l = view_->GetLocationToAdd();
+       if (!l) {
+               ERR("Invalid Location object");
+               return;
+       }
+       bool attached = model_->AddItemToCustomList(l);
+       if (attached) {
+               model_->SetCurrentTimezone(model_->GetTimezoneByOffset(l->gmt_offset_));
+               view_->UpdateMapAndTimezoneDetails(model_->GetCurrentTimezone());
+               view_->AppendItemToCustomList(l);
+       }
+}
+
 } /* presenter */
index 4bdb9db..6e00bcd 100644 (file)
@@ -18,6 +18,7 @@
 #include <sstream>
 
 #include <efl_extension.h>
+#include <eina_str.h>
 
 #include "View/WorldClockView.h"
 #include "View/MainView.h"
@@ -202,13 +203,20 @@ void message_cb(void *data, Evas_Object *obj, Edje_Message_Type type, int id, vo
 
 WorldClockView::WorldClockView()
 {
-       world_clock_ = elm_layout_add(MainView::GetInstance().GetEvasObject());
+       world_clock_main_ = elm_layout_add(MainView::GetInstance().GetEvasObject());
+       evas_object_size_hint_align_set(world_clock_main_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+       evas_object_size_hint_weight_set(world_clock_main_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_layout_theme_set(world_clock_main_, "layout", "application", "default");
+
+       world_clock_ = elm_layout_add(world_clock_main_);
 
        if(!elm_layout_file_set(world_clock_,
                Utils::GetAppResourcePath(Utils::APP_DIR_RESOURCE, "edje/WorldClock.edj"),
                "main")) {
                FAT("Failed to load layout file");
        }
+       elm_theme_extension_add(NULL,
+                       Utils::GetAppResourcePath(Utils::APP_DIR_RESOURCE, "edje/CitiesListItem.edj"));
 
        evas_object_size_hint_align_set(world_clock_, EVAS_HINT_FILL, EVAS_HINT_FILL);
        evas_object_size_hint_weight_set(world_clock_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@@ -218,8 +226,10 @@ WorldClockView::WorldClockView()
        CreateTimezoneDetails();
        CreateCustomLocationsList();
 
-       elm_theme_extension_add(NULL,
-                       Utils::GetAppResourcePath(Utils::APP_DIR_RESOURCE, "edje/CitiesListItem.edj"));
+       Evas_Object *fb = CreateFloatingButton();
+       elm_object_part_content_set(world_clock_main_, "elm.swallow.floatingbutton", fb);
+       elm_object_part_content_set(world_clock_main_, "elm.swallow.content", world_clock_);
+
 
        elm_layout_signal_callback_add(world_clock_, "timezone,go,left",
                "main.world.map:arrow.left", WorldClockView::ChangeTimezoneCb,
@@ -229,6 +239,122 @@ WorldClockView::WorldClockView()
                static_cast<void *>(this));
 }
 
+
+
+void WorldClockView::SetItemToAdd(model::Location *l)
+{
+       item_to_add_ = l;
+}
+
+
+void WorldClockView::AddLocationReplayCb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data)
+{
+       char *city_name;
+       char *country_name;
+       char *timezone;
+       char **timezone_splited;
+
+       int h = 0;
+       int min = 0;
+       int ret;
+       unsigned int elements;
+
+       ret = app_control_get_extra_data(reply, "city_name", &city_name);
+       if (ret != APP_CONTROL_ERROR_NONE) {
+               ERR("app_control_get_extra_data failed[%d]: %s", ret, get_error_message(ret));
+               return;
+       }
+       ret = app_control_get_extra_data(reply, "country_name", &country_name);
+       if (ret != APP_CONTROL_ERROR_NONE) {
+               ERR("app_control_get_extra_data failed[%d]: %s", ret, get_error_message(ret));
+               return;
+       }
+       ret = app_control_get_extra_data(reply, "timezone", &timezone);
+       if (ret != APP_CONTROL_ERROR_NONE) {
+               ERR("app_control_get_extra_data failed[%d]: %s", ret, get_error_message(ret));
+               return;
+       }
+
+       timezone_splited = eina_str_split_full(&timezone[1], ":", 2, &elements);
+
+       if (elements == 1)
+               h = atoi(timezone_splited[0]);
+       else if (elements == 2) {
+               h = atoi(timezone_splited[0]);
+               min = atoi(timezone_splited[1]);
+       }
+
+       int gmt_offset = (60*h + min) * ((timezone[0] == '-') ? (-1) : (1));
+       model::Location *l = new model::Location{
+               std::string(city_name),
+               std::string(country_name),
+               gmt_offset,};
+
+       WorldClockView *view = static_cast<WorldClockView *>(user_data);
+       view->SetItemToAdd(l);
+       view->EmitSignal(view::WorldClockSignals::CUSTOM_LIST_ITEM_ADD);
+
+       free(city_name);
+       free(country_name);
+       free(timezone);
+}
+
+void WorldClockView::AddButtonClicked(void *data, Evas_Object *obj, void *event_info)
+{
+       WorldClockView *view = static_cast<WorldClockView *>(data);
+       app_control_h control;
+
+       int ret = app_control_create(&control);
+       if (ret != APP_CONTROL_ERROR_NONE) {
+               ERR("app_control_create failed[%d]: %s", ret, get_error_message(ret));
+               return;
+       }
+
+       ret = app_control_set_operation(control, APP_CONTROL_OPERATION_PICK);
+       if (ret != APP_CONTROL_ERROR_NONE) {
+               ERR("app_control_set_operation failed[%d]: %s", ret, get_error_message(ret));
+               app_control_destroy(control);
+               return;
+       }
+
+       ret = app_control_set_app_id(control, "org.tizen.worldclock-efl");
+       if (ret != APP_CONTROL_ERROR_NONE) {
+               ERR("app_control_set_app_id failed[%d]: %s", ret, get_error_message(ret));
+               app_control_destroy(control);
+               return;
+       }
+
+       ret = app_control_set_launch_mode(control, APP_CONTROL_LAUNCH_MODE_GROUP);
+       if (ret != APP_CONTROL_ERROR_NONE) {
+               ERR("app_control_set_launch_mode failed[%d]: %s", ret, get_error_message(ret));
+               app_control_destroy(control);
+               return;
+       }
+
+       ret = app_control_send_launch_request(control, WorldClockView::AddLocationReplayCb, view);
+       if (ret != APP_CONTROL_ERROR_NONE) {
+               ERR("app_control_send_launch_request failed[%d]: %s", ret, get_error_message(ret));
+       }
+       app_control_destroy(control);
+}
+
+Evas_Object *WorldClockView::CreateFloatingButton()
+{
+       /* Floating Button */
+       Evas_Object *fb = eext_floatingbutton_add(world_clock_main_);
+
+       Evas_Object *btn = elm_button_add(fb);
+       evas_object_smart_callback_add(btn, "clicked", WorldClockView::AddButtonClicked, this);
+       Evas_Object *image = elm_image_add(fb);
+       elm_image_file_set(image, Utils::GetAppResourcePath(
+                       Utils::APP_DIR_RESOURCE, "images/core_floating_icon_01.png"), NULL);
+       elm_object_part_content_set(btn, "icon", image);
+
+       elm_object_part_content_set(fb, "button1", btn);
+
+       return fb;
+}
+
 void WorldClockView::UpdateTimezoneLocationsDots(const model::Timezone *timezone)
 {
        for (int i = 0; i < 8; i++) {
@@ -429,6 +555,11 @@ const model::Location *WorldClockView::GetLastClickedItem()
        return item_last_clicked_;
 }
 
+const model::Location *WorldClockView::GetLocationToAdd()
+{
+       return item_to_add_;
+}
+
 void WorldClockView::SetItemLastClicked(const model::Location *location)
 {
        item_last_clicked_ = location;
index 5ac90e3..9a1f202 100644 (file)
@@ -1,13 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns="http://tizen.org/ns/packages" api-version="3.0" package="org.tizen.clock" version="1.0.0">
-       <profile name="mobile" />
-       <ui-application appid="org.tizen.clock" exec="clock" type="capp" multiple="false" taskmanage="true" nodisplay="false" launch_mode="single">
-               <icon>clock.png</icon>
-               <label>Clock</label>
-       </ui-application>
+    <profile name="mobile"/>
+    <ui-application appid="org.tizen.clock" exec="clock" type="capp" multiple="false" taskmanage="true" nodisplay="false" launch_mode="single">
+        <label>Clock</label>
+        <icon>clock.png</icon>
+    </ui-application>
     <privileges>
         <privilege>http://tizen.org/privilege/alarm</privilege>
         <privilege>http://tizen.org/privilege/alarm.set</privilege>
         <privilege>http://tizen.org/privilege/window.priority.set</privilege>
+        <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
     </privileges>
 </manifest>