World Clock: Delete Items view implemented. 79/92979/6
authorRadoslaw Czerski <r.czerski@samsung.com>
Wed, 26 Oct 2016 15:56:47 +0000 (17:56 +0200)
committerRadoslaw Czerski <r.czerski@samsung.com>
Wed, 26 Oct 2016 15:56:47 +0000 (17:56 +0200)
Change-Id: I5104ca3d1e5e400f708ecda2e18a038c3849bf8f
Signed-off-by: Radoslaw Czerski <r.czerski@samsung.com>
18 files changed:
clock/inc/Controller/MainController.h
clock/inc/Model/WorldClock.h
clock/inc/Model/WorldClockEvents.h [new file with mode: 0644]
clock/inc/Presenter/WorldClockDeletePresenter.h [new file with mode: 0644]
clock/inc/Presenter/WorldClockPresenter.h
clock/inc/Utils/Log.h
clock/inc/Utils/WorldClock.h [new file with mode: 0644]
clock/inc/View/WorldClockDeleteItemsView.h [new file with mode: 0644]
clock/inc/View/WorldClockView.h
clock/res/edje/CitiesListItem.edc
clock/res/edje/WorldClockDeleteList.edc [new file with mode: 0644]
clock/src/Controller/MainController.cpp
clock/src/Model/WorldClock.cpp
clock/src/Presenter/WorldClockDeletePresenter.cpp [new file with mode: 0644]
clock/src/Presenter/WorldClockPresenter.cpp
clock/src/Utils/WorldClock.cpp [new file with mode: 0644]
clock/src/View/WorldClockDeleteItemsView.cpp [new file with mode: 0644]
clock/src/View/WorldClockView.cpp

index a0a83f2..7d5c4d5 100644 (file)
@@ -40,6 +40,7 @@
 #include "Presenter/StopWatchPresenter.h"
 #include "Presenter/TimerPresenter.h"
 #include "Presenter/WorldClockPresenter.h"
+#include "Presenter/WorldClockDeletePresenter.h"
 
 
 /**
@@ -121,6 +122,12 @@ namespace controller {
                         */
                        void CreateNewDeleteAlarmsPage(utils::Event &e);
 
+                       /**
+                        * @brief Creates new "Delete" page in world clock;
+                        * @param e event data
+                        */
+                       void CreateNewWorldClockDeletePage(utils::Event &e);
+
                        model::WorldClock *world_clock_model_;
                        model::StopWatch *stop_watch_model_;
                        model::Timer *timer_model_;
@@ -131,11 +138,13 @@ namespace controller {
                        presenter::TimerPresenter *timer_presenter_;
                        presenter::EditAlarmPresenter *edit_presenter_;
                        presenter::DeleteAlarmPresenter *delete_presenter_;
+                       presenter::WorldClockDeletePresenter *world_clock_delete_presenter_;
 
                        view::MainView main_view_;
 
                        view::EditAlarmView edit_page_;
                        view::DeleteAlarmView delete_page_;
+                       view::WorldClockDeleteItemsView world_clock_delete_page_;
 
                        /**
                         * @brief Creates new "Edit" alarm page.
index d951c21..d11b575 100644 (file)
@@ -18,6 +18,7 @@
 #define _CLOCK_WORLDCLOCK_H_
 
 #include <vector>
+#include <functional>
 
 #include "Model/Location.h"
 
@@ -37,6 +38,11 @@ namespace model {
        class WorldClock {
                public:
 
+                       enum class SignalType {
+                               USER_LOCATION_REMOVED,
+                               MAX
+                       };
+
                        /**
                         * @brief Enumeration for direction of time zone shift.
                         */
@@ -65,15 +71,17 @@ namespace model {
                         * @remarks The location is retrieved from called Worldclock-efl app
                         *
                         * @param[in] l location to add
+                        *
+                        * @return true if l not exists yet in user_locations_ list, false otherwise
                         */
-                       void AddUserLocation(model::Location l);
+                       bool AddUserLocation(const model::Location *l);
 
                        /**
-                        * @brief Deletes location from UserLocations list
+                        * @brief Deletes locations from UserLocations list
                         *
-                        * @param[in] l location to remove from UserLocation list
+                        * @param[in] deleted locations list to remove from UserLocation list
                         */
-                       void RemoveUserLocation(model::Location l);
+                       void RemoveUserLocations(const std::vector<const model::Location *> &deleted);
 
                        /**
                         * @brief Gets current time zone set to display
@@ -127,7 +135,7 @@ namespace model {
                         */
                        const Timezone *GetTimezoneByOffset(int offset) const;
 
-                       /*
+                       /**
                         * @brief Gets location using its no in locations_ list
                         * @remarks This function is for temporary usage and will be removed before final version
                         *
@@ -143,13 +151,13 @@ namespace model {
                         */
                        void MoveCurrentTimezone(Direction direction);
 
-                       /*
-                        * @brief Adds item to custom list
+                       /**
+                        * @brief Registers signal handler
                         *
-                        * param[in] l location to add
+                        * @param signal signal type
+                        * @param func function to be called when registered signal is emitted.
                         */
-                       bool AddItemToCustomList(const model::Location *l);
-
+                       void RegisterSignalHandler(SignalType signal, std::function<void(const model::Location &)> func);
                private:
 
                        enum ItemKeyType {
@@ -159,11 +167,6 @@ namespace model {
                        };
 
                        /**
-                        * @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
                         */
@@ -179,6 +182,8 @@ namespace model {
                         */
                        static std::vector<Timezone> time_zones_;
 
+                       std::vector<std::function<void(const model::Location &)>> signals_;;
+
                        /**
                         * @brief Saves items list state using app_preferences API
                         * @details It saves every particular item(location)
@@ -214,6 +219,17 @@ namespace model {
                         */
                        const model::Location *LoadItem(int i);
 
+                       /**
+                        * @brief Gets time zone by its no in time_zone_ list
+                        */
+                       const Timezone *GetTimezone(int no) const;
+
+                       /**
+                        * @brief Emits signal s
+                        * @param s signal
+                        * @param location location to pass to function registered for given signal
+                        */
+                       void EmitSignal(SignalType s, const model::Location &location);
        };
 } /* model */
 
diff --git a/clock/inc/Model/WorldClockEvents.h b/clock/inc/Model/WorldClockEvents.h
new file mode 100644 (file)
index 0000000..3685393
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CLOCK_MODEL_WORLDCLOCKEVENT_H_
+#define _CLOCK_MODEL_WORLDCLOCKEVENT_H_
+
+#include "Utils/EventBus.h"
+#include "Model/Location.h"
+
+namespace model {
+
+       class WorldClockDeleteRequestEvent : public utils::Event {
+       };
+}
+
+#endif /* _CLOCK_MODEL_WORLDCLOCKEVENT_H_ */
diff --git a/clock/inc/Presenter/WorldClockDeletePresenter.h b/clock/inc/Presenter/WorldClockDeletePresenter.h
new file mode 100644 (file)
index 0000000..bb1bc6f
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CLOCK_PRESENTER_WORLDCLOCKDELETE_H_
+#define _CLOCK_PRESENTER_WORLDCLOCKDELETE_H_
+
+#include "View/WorldClockDeleteItemsView.h"
+#include "Model/WorldClock.h"
+
+namespace presenter {
+
+       class WorldClockDeletePresenter {
+               public:
+
+                       /**
+                        * @brief Creates presenter for Delete view
+                        *
+                        * @param view the view
+                        * @param model world clock data model
+                        */
+                       WorldClockDeletePresenter(view::WorldClockDeleteItemsView *view, model::WorldClock *model);
+
+                       /**
+                        * @brief Destructor
+                        */
+                       ~WorldClockDeletePresenter();
+               private:
+
+                       /**
+                        * @brief Data model
+                        */
+                       model::WorldClock *model_;
+
+                       /**
+                        * @brief Delete view genlist Item data
+                        */
+                       view::WorldClockDeleteItemsView *delete_view_;
+
+                       /**
+                        * @brief Invoked when "Cancel" button is clicked.
+                        * @details Pops page.
+                        */
+                       void OnCancelClicked();
+
+                       /**
+                        * @brief Invoked when "Delete" button is clicked.
+                        * @details Deletes selected items. Pops page.
+                        */
+                       void OnDeleteClicked();
+
+                       /**
+                        * @brief Applies proper state to checkbox of all items and updates page label
+                        */
+                       void OnSelectAllClicked();
+                       /**
+                        * @brief Updates page title and "Select All" item state.
+                        */
+                       void OnListItemClicked();
+       };
+}
+
+
+#endif /* _CLOCK_PRESENTER_WORLDCLOCKDELETE_H_ */
index 3253efe..a817359 100644 (file)
@@ -18,6 +18,8 @@
 #define _CLOCK_PRESENTER_WORLDCLOCK_H_
 
 #include "View/WorldClockView.h"
+#include "View/WorldClockDeleteItemsView.h"
+#include "Utils/EventBus.h"
 #include "Model/WorldClock.h"
 
 namespace presenter {
@@ -39,15 +41,34 @@ namespace presenter {
                        view::WorldClockView *view_;
                        model::WorldClock *model_;
 
+                       std::vector<utils::Listener> listeners_;
+
                        void UpdateEmptyListBackground();
 
                        void OnLeftArrowButtonClicked();
                        void OnRightArrowButtonClicked();
                        void OnCustomListItemClicked();
 
+                       /**
+                        * @brief Invoked when more button is clicked. Shows popup
+                        */
+                       void OnMoreButtonClicked();
+
+                       /**
+                        * @brief Invoked when Delete option is chosen on "more" popup.
+                        * @details Created Delete View
+                        */
+                       void OnMoreDeleteButtonClicked();
+
                        void OnMapViewUpdateRequest();
                        void OnItemAdded();
 
+                       /**
+                        * @brief Deletes location from user locations list.
+                        * @param location location to delete
+                        */
+                       void OnItemDeleted(const model::Location &location);
+
        };
 }
 
index 06ed9a7..a5c2925 100644 (file)
@@ -53,9 +53,6 @@
 #define FAT(fmt, arg...) dlog_print(DLOG_FATAL, LOG_TAG, "%s: %s[%d]\t " #fmt "\n", __FILENAME__, __func__, __LINE__, ##arg);
 #endif
 
-#undef _
-#define _(str) i18n_get_text(str)
-
 /**
  * @}
  */
diff --git a/clock/inc/Utils/WorldClock.h b/clock/inc/Utils/WorldClock.h
new file mode 100644 (file)
index 0000000..0280d0d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CLOCK_UTILS_WORLDCLOCK_H_
+#define _CLOCK_UTILS_WORLDCLOCK_H_
+
+#include <vector>
+#include <string>
+#include <sstream>
+
+namespace utils {
+
+/**
+ * @brief Creates description regarding offset between offsets (e.g "5 h behind")
+ * @param local_timezeone_offset offset in minutes between GMT+0 and local timezone
+ * @param timezone_offset offset in minutes between GMT+0 and a timezone
+ *
+ * @return description regarding offset between offsets (e.g "5 h behind")
+ */
+std::string GetTimezoneDiffDescription(int local_timezone_offset, int timezone_offset);
+
+}
+#endif /* _CLOCK_UTILS_WORLDCLOCK_H_ */
+
+
diff --git a/clock/inc/View/WorldClockDeleteItemsView.h b/clock/inc/View/WorldClockDeleteItemsView.h
new file mode 100644 (file)
index 0000000..767b0c5
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CLOCK_VIEW_WORLDCLOCKDELETEITEMS_H_
+#define _CLOCK_VIEW_WORLDCLOCKDELETEITEMS_H_
+
+#include "View/PageView.h"
+#include "Model/Location.h"
+#include "Utils/Time.h"
+
+namespace view {
+
+       class WorldClockDeleteItemsView: public PageView {
+
+               public:
+
+                       /**
+                        * @brief Enumeration for callbacks signals
+                        */
+                       enum class SignalType {
+                               BUTTON_CANCEL_CLICKED,      //!< BUTTON_CANCEL_CLICKED
+                               BUTTON_DELETE_CLICKED,      //!< BUTTON_DELETE_CLICKED
+                               BUTTON_BACK_CLICKED,        //!< BUTTON_BACK_CLICKED
+                               CHECKBOX_SELECT_ALL_CLICKED,//!< CHECKBOX_SELECT_ALL_CLICKED
+                               LIST_ITEM_CLICKED,          //!< LIST_ITEM_CLICKED
+                               MAX                         //!< MAX
+                       };
+
+                       /**
+                        * @brief Creates Class object, push new page and invokes CreateContent().
+                        */
+                       WorldClockDeleteItemsView(ui::IView &main);
+
+                       /**
+                        * @brief Destroy all resources that can not be deleted automatically
+                        */
+                       ~WorldClockDeleteItemsView();
+
+                       /**
+                        * @brief Gets evas object of the page content -> genlist
+                        * @return the object
+                        */
+                       Evas_Object *GetEvasObject() override;
+
+                       /**
+                        * @brief Registers signals
+                        * @param s signal enumerator
+                        * @param func function invoked when the signal will be emitted
+                        */
+                       void RegisterSignal(SignalType s, std::function<void(void)>func);
+
+                       /**
+                        * @brief Appends items(Locations) from given list to delete View genlist
+                        * @details The list is identical with user_locations_ list
+                        * @param locations list of locations
+                        */
+                       void AppendItems(std::vector<const model::Location *> locations);
+
+                       /**
+                        * @brief Updates title of the page(# Selected)
+                        */
+                       void UpdateTitle();
+
+                       /**
+                        * @brief Sets items checkbox state
+                        * @param state state to set
+                        */
+                       void SetAllItems(bool state);
+
+                       /**
+                        * @brief Sets state of "Select All" checkbox
+                        * @details It is useful when all items are selected manually
+                        * @param state state to set
+                        */
+                       void SetSelectAllCheckbox(bool state);
+
+                       /**
+                        * @brief Gets list of items selected to be deleted from user_locations_ list
+                        * @return
+                        */
+                       std::vector<const model::Location *> GetSelectedItems();
+
+                       /**
+                        * @brief Gets state of "Select All" item checkbox
+                        * @return state of "Select All" item checkbox
+                        */
+                       bool GetSelectAllState();
+
+               protected:
+                       /**
+                        * @brief Creates main content of the Destroy View page
+                        */
+                       void CreateContent(Evas_Object *parent) override;
+
+                       /**
+                        * @brief Destroys main content of the Destroy View page
+                        */
+                       void DestroyContent() override;
+               private:
+
+                       /**
+                        * @brief Main content - genlist
+                        */
+                       Evas_Object *content_;
+
+                       /**
+                        * @brief Evas object of "Cancel" button
+                        */
+                       Evas_Object *left_button_;
+
+                       /**
+                        * @brief Evas object of "Delete" button
+                        */
+                       Evas_Object *right_button_;
+
+                       /**
+                        * @brief Evas object of "select All" checkbox
+                        */
+                       Evas_Object *select_all_checkbox_;
+
+                       /**
+                        * @brief Item class for the main content genlist
+                        */
+                       static Elm_Genlist_Item_Class world_clock_delete_view_itc_;
+
+                       /**
+                        * @brief Flag for state of "select All" checkbox state
+                        */
+                       bool all_selected_;
+
+                       /**
+                        * @brief list of signals
+                        */
+                       std::vector<std::function<void(void)>> signals_
+                                       = std::vector<std::function<void(void)>>((int)SignalType::MAX, nullptr);
+
+                       /**
+                        * @brief Callback invoked when any item of list is clicked
+                        * @param data user data
+                        * @param obj obj
+                        * @param event_info event_info
+                        */
+                       static void ItemClicked(void *data, Evas_Object *obj, void *event_info);
+
+                       /**
+                        * @brief Gets content for genlist item part
+                        * @param data user data
+                        * @param obj item object
+                        * @param part part related to content to get
+                        * @return Object of content that will be swallowed to the part
+                        */
+                       static Evas_Object *ContentGet(void *data, Evas_Object *obj, const char *part);
+
+                       /**
+                        * @brief Gets text for genlist item part
+                        * @param data user data
+                        * @param obj item object
+                        * @param part part related to text to get
+                        * @return text to set to the textblock part
+                        */
+                       static char *TextGet(void *data, Evas_Object *obj, const char *part);
+
+                       /**
+                        * @brief Deletes all resources of the item that cannot be deleted automatically
+                        * @param data user data
+                        * @param obj item object
+                        */
+                       static void Del(void *data, Evas_Object *obj);
+
+                       /**
+                        * @brief Creates evas object for time
+                        * @param parent parent
+                        * @return the object
+                        */
+                       static Evas_Object *CreateTimeObject(Evas_Object *parent, utils::Time t);
+
+                       /**
+                        * @brief Creates evas object for meridiem
+                        * @param parent parent
+                        * @return the object
+                        */
+                       static Evas_Object *CreateXMeridiemObject(Evas_Object *parent, utils::Time t);
+
+                       /**
+                        * @brief Creates evas object for padding
+                        * @param parent parent
+                        * @return the object
+                        */
+                       static Evas_Object *CreatePaddingObject(Evas_Object *parent, int width);
+
+                       /**
+                        * @brief Creates genlist item of "Select all"
+                        */
+                       void CreateSelectAll();
+
+                       /**
+                        * @brief emits signal
+                        * @details it cause invocation of registered function
+                        * @param s signal enumerator
+                        */
+                       void EmitSignal(SignalType s);
+
+                       /**
+                        * @brief Emits BUTTON_CANCEL_CLICKED signal.
+                        * @details Invoked when "Cancel" button is clicked
+                        */
+                       static void OnCancelButtonClicked(void *data, Evas_Object *obj, void *event_info);
+
+                       /**
+                        * @brief Emits BUTTON_DELETE_CLICKED signal.
+                        * @details Invoked when "Delete" button is clicked
+                        */
+                       static void OnDeleteButtonClicked(void *data, Evas_Object *obj, void *event_info);
+
+                       /**
+                        * @brief Emits CHECKBOX_SELECT_ALL_CLICKED signal and toggle "Select all" checkbox state.
+                        * @details Invoked when "Select all" item or checkbox is clicked
+                        */
+                       static void OnSelectAllClicked(void *data, Evas_Object *obj, void *event_info);
+
+                       /**
+                        * @brief Emits LIST_ITEM_CLICKED signal and toggle checkbox state.
+                        */
+                       static void ItemSelectToggle(void *data, Evas_Object *obj, void *event_info);
+       };
+
+} /* view */
+
+
+#endif /* _CLOCK_VIEW_WORLDCLOCKDELETEITEMS_H_ */
index b06a6a3..91dfea2 100644 (file)
@@ -30,12 +30,12 @@ namespace view {
        enum class WorldClockSignals {
                BUTTON_LEFT_ARROW_CLICKED,
                BUTTON_RIGHT_ARROW_CLICKED,
+               BUTTON_MORE_CLICKED,
+               BUTTON_MORE_DELETE_CLICKED,
 
                CUSTOM_LIST_ITEM_CLICKED,
                CUSTOM_LIST_ITEM_ADD,
 
-               UPDATE_MAP_VIEW,
-
                MAX
        };
 
@@ -51,14 +51,21 @@ namespace view {
                        void UpdateMapAndTimezoneDetails(const model::Timezone *timezone);
 
                        void AppendItemToCustomList(const model::Location *location);
-
+                       void RemoveItem(const model::Location &location);
                        const model::Location *GetLastClickedItem();
                        const model::Location *GetLocationToAdd();
 
                        void ShowEmptyListLabel();
                        void HideEmptyListLabel();
-
                        void PostItemExistMessage();
+                       void ShowMorePopup();
+
+                       /**
+                        * @brief Checks if user locations list is empty or not
+                        *
+                        * @return true if empty, false otherwise
+                        */
+                       bool IsListEmpty();
 
                private:
                        void CreateTimezoneDetails();
@@ -94,8 +101,6 @@ namespace view {
                        static void MorePopupDeleteItemCallback(void *data, Evas_Object *obj, void *event_info);
                        static void MorePopupReorderItemCallback(void *data, Evas_Object *obj, void *event_info);
 
-                       void ShowMorePopup();
-
                        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);
index 7a52d50..f294415 100644 (file)
@@ -35,16 +35,6 @@ collections {
                                        rel2.to: "base";
                                }
                        }
-                       rect { "bg";
-                               desc { "default"
-                                       rel1.to: "base";
-                                       rel2.to: "base";
-                                       color: 0 0 0 0;
-                               }
-                               desc { "pressed"; inherit: "default";
-                                       color: 0 0 0 20;
-                               }
-                       }
                        spacer { "padding.top.left"; scale;
                                desc { "default";
                                        min: 205 17;
diff --git a/clock/res/edje/WorldClockDeleteList.edc b/clock/res/edje/WorldClockDeleteList.edc
new file mode 100644 (file)
index 0000000..0dff8ea
--- /dev/null
@@ -0,0 +1,172 @@
+
+collections {
+       base_scale: 2.6;
+
+       group { name: "elm/genlist/item/worldclock.delete.list/default";
+               styles {
+                       style { name: "date_ATO042";
+                               base: "font=Tizen:style=Regular color=#808080ff font_size=30 align=left";
+                       }
+                       style { name: "city_country_ATO043";
+                               base: "font=Tizen:style=Regular color=#000000ff font_size=40 align=left ellipsis=1.0";
+                       }
+                       style { name: "gmt_offset_desc_ATO044";
+                               base: "font=Tizen:style=Regular color=#808080ff font_size=40 align=left ellipsis=1.0";
+                       }
+               }
+               data.item: "banded_bg_area" "elm.swallow.bg";
+               data.item: "texts" "ampm date city.country gmt.offset.desc";
+               data.item: "contents" "time check";
+               parts {
+                       spacer { "base"; scale;
+                               desc { "default";
+                                       min: 0 22+53+43+26;
+                               }
+                       }
+                       swallow { "elm.swallow.bg";
+                               desc { "default";
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                               }
+                       }
+                       spacer { "padding.top.left"; scale;
+                               desc { "default";
+                                       min: 205 17;
+                                       max: 205 17;
+                                       fixed: 1 1;
+                                       align: 0.0 0.0;
+                                       rel1.to: "base";
+                               }
+                       }
+                       spacer { "padding.left"; scale;
+                               desc { "default";
+                                       min: 32 0;
+                                       max: 32 -1;
+                                       fixed: 1 0;
+                                       align: 0.0 0.0;
+                                       rel1.to: "base";
+                               }
+                       }
+                       swallow { "time"; scale;
+                               desc { "default";
+                                       min: 173 67;
+                                       max: 173 67;
+                                       fixed: 1 1;
+                                       align: 0.0 0.0;
+                                       rel1 {
+                                               relative: 1.0 1.0;
+                                               to_x: "padding.left";
+                                               to_y: "padding.top.left";
+                                       }
+                               }
+                       }
+                       spacer { "padding.middle"; scale;
+                               desc { "default";
+                                       min: 82 0;
+                                       max: 82 -1;
+                                       fixed: 1 0;
+                                       align: 0.0 0.0;
+                                       rel1 {
+                                               relative: 1.0 0.0;
+                                               to: "padding.top.left";
+                                       }
+                               }
+                       }
+                       spacer { "padding.top.right"; scale;
+                               desc { "default";
+                                       min: 405 22;
+                                       max: 405 22;
+                                       fixed: 1 1;
+                                       align: 0.0 0.0;
+                                       rel1 {
+                                               relative: 1.0 0.0;
+                                               to: "padding.middle";
+                                       }
+                               }
+                       }
+                       textblock { "date"; scale;
+                               desc { "default";
+                                       min: 173 40;
+                                       max: 173 40;
+                                       fixed: 1 1;
+                                       align: 0.0 0.0;
+                                       rel1 {
+                                               relative: 1.0 1.0;
+                                               to_x: "padding.left";
+                                               to_y: "time";
+                                       }
+                                       rel2 {
+                                               relative: 0.0 1.0;
+                                               to_x: "padding.middle";
+                                       }
+                                       text {
+                                               style: "date_ATO042";
+                                               min: 1 1;
+                                               ellipsis: -1;
+                                       }
+                               }
+                       }
+                       spacer { "padding.right"; scale;
+                               desc { "default";
+                                       fixed: 1 0;
+                                       min: 32 0;
+                                       max: 32 -1;
+                                       align: 1.0 0.5;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                               }
+                       }
+                       swallow { "check";
+                               desc { "default";
+                                       min: 80 80;
+                                       max: 80 80;
+                                       fixed: 1 1;
+                                       align: 1.0 0.5;
+                                       rel1.to: "base";
+                                       rel2 {
+                                               relative: 0.0 1.0;
+                                               to: "padding.right";
+                                       }
+                               }
+                       }
+                       textblock { "city.country"; scale;
+                               desc { "default";
+                                       min: 0 53;
+                                       max: -1 53;
+                                       fixed: 0 1;
+                                       align: 0.0 0.0;
+                                       rel1 {
+                                               relative: 1.0 1.0;
+                                               to_x: "padding.middle";
+                                               to_y: "padding.top.right";
+                                       }
+                                       rel2 {
+                                               relative: 0.0 1.0;
+                                               to_x: "check";
+                                       }
+                                       text.style: "city_country_ATO043";
+                               }
+                       }
+                       textblock { "gmt.offset.desc"; scale;
+                               desc { "default";
+                                       min: 0 43;
+                                       max: -1 43;
+                                       fixed: 0 1;
+                                       align: 0.0 0.0;
+                                       rel1 {
+                                               relative: 0.0 1.0;
+                                               to: "city.country";
+                                       }
+                                       rel2 {
+                                               relative: 0.0 1.0;
+                                               to_x: "check";
+                                       }
+                                       text {
+                                               style: "gmt_offset_desc_ATO044";
+                                               ellipsis: 1;
+                                       }
+                               }
+                       }
+               }
+       }
+}
index 3aeba55..ec382cb 100644 (file)
 #include "View/DeleteAlarmView.h"
 #include "Presenter/DeleteAlarmPresenter.h"
 
+#include "Model/WorldClockEvents.h"
+#include "View/WorldClockDeleteItemsView.h"
+#include "Presenter/WorldClockDeletePresenter.h"
+
 using namespace controller;
 using namespace view;
 using namespace utils;
@@ -38,9 +42,9 @@ MainController &MainController::GetInstance()
 }
 
 MainController::MainController() :
-       edit_page_(main_view_), delete_page_(main_view_),
+       edit_page_(main_view_), delete_page_(main_view_), world_clock_delete_page_(main_view_),
        delete_presenter_(nullptr), edit_presenter_(nullptr),
-       initialized_(false)
+       world_clock_delete_presenter_(nullptr), initialized_(false)
 {
 }
 
@@ -79,6 +83,9 @@ int MainController::Init()
        listeners_.push_back(utils::EventBus::AddListener<AlarmEditRequestEvent>(
                        std::bind(&MainController::CreateEditAlarmPage, this, _1)));
 
+       listeners_.push_back(utils::EventBus::AddListener<WorldClockDeleteRequestEvent>(
+                       std::bind(&MainController::CreateNewWorldClockDeletePage, this, _1)));
+
        initialized_ = true;
        return 0;
 }
@@ -124,3 +131,11 @@ void MainController::CreateNewDeleteAlarmsPage(Event &e)
 
        delete_presenter_ = new DeleteAlarmPresenter(&delete_page_, AlarmProvider::GetInstance());
 }
+
+void MainController::CreateNewWorldClockDeletePage(utils::Event &e)
+{
+       delete world_clock_delete_presenter_;
+
+       world_clock_delete_presenter_ = new WorldClockDeletePresenter(&world_clock_delete_page_, world_clock_model_);
+
+}
index 03e081d..7fb1b2d 100644 (file)
@@ -137,6 +137,7 @@ std::vector<Timezone> WorldClock::time_zones_ = {
 
 WorldClock::WorldClock()
 {
+       signals_.resize((int)SignalType::MAX);
        LoadItemsList();
 
        int current_tz = 1;
@@ -233,7 +234,7 @@ void model::WorldClock::MoveCurrentTimezone(Direction direction)
        }
 }
 
-bool WorldClock::AddItemToCustomList(const model::Location *l)
+bool WorldClock::AddUserLocation(const model::Location *l)
 {
        if (!user_locations_.empty()) {
                for (auto it = user_locations_.begin(); it != user_locations_.end(); it++) {
@@ -248,6 +249,21 @@ bool WorldClock::AddItemToCustomList(const model::Location *l)
        return true;
 }
 
+void WorldClock::RemoveUserLocations(const std::vector<const model::Location *> &deleted)
+{
+       for (auto d_it: deleted) {
+
+               for (auto it = user_locations_.begin(); it != user_locations_.end(); ++it) {
+
+                       if (!((*it)->name.compare(d_it->name)) && !((*it)->country.compare(d_it->country))) {
+                               EmitSignal(SignalType::USER_LOCATION_REMOVED, **it);
+                               user_locations_.erase(it);
+                               break;
+                       }
+               }
+       }
+}
+
 void WorldClock::SaveItemsList()
 {
        int ret = preference_remove_all();
@@ -382,3 +398,15 @@ const model::Location *WorldClock::LoadItem(int i)
 
        return location;
 }
+
+void WorldClock::RegisterSignalHandler(SignalType signal, std::function<void(const model::Location &)> func)
+{
+       signals_.at((int)signal) = func;
+}
+
+void WorldClock::EmitSignal(SignalType signal, const model::Location &location)
+{
+       if (signals_.at((int)signal) != nullptr) {
+               signals_.at((int)signal)(location);
+       }
+}
diff --git a/clock/src/Presenter/WorldClockDeletePresenter.cpp b/clock/src/Presenter/WorldClockDeletePresenter.cpp
new file mode 100644 (file)
index 0000000..5642dc5
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Presenter/WorldClockDeletePresenter.h"
+#include "Model/WorldClockEvents.h"
+#include "Utils/Log.h"
+
+using namespace presenter;
+using namespace view;
+using namespace model;
+
+
+WorldClockDeletePresenter::WorldClockDeletePresenter(
+        WorldClockDeleteItemsView *view, WorldClock *model) :
+               delete_view_(view), model_(model)
+{
+       DBG("");
+       delete_view_->RegisterSignal(view::WorldClockDeleteItemsView::SignalType::BUTTON_CANCEL_CLICKED,
+                       std::bind(&WorldClockDeletePresenter::OnCancelClicked, this));
+       delete_view_->RegisterSignal(view::WorldClockDeleteItemsView::SignalType::BUTTON_DELETE_CLICKED,
+                       std::bind(&WorldClockDeletePresenter::OnDeleteClicked, this));
+       delete_view_->RegisterSignal(view::WorldClockDeleteItemsView::SignalType::CHECKBOX_SELECT_ALL_CLICKED,
+                       std::bind(&WorldClockDeletePresenter::OnSelectAllClicked, this));
+       delete_view_->RegisterSignal(view::WorldClockDeleteItemsView::SignalType::LIST_ITEM_CLICKED,
+                       std::bind(&WorldClockDeletePresenter::OnListItemClicked, this));
+
+       delete_view_->PushPage();
+       delete_view_->AppendItems(model_->user_locations_);
+}
+
+WorldClockDeletePresenter::~WorldClockDeletePresenter()
+{
+}
+
+void WorldClockDeletePresenter::OnCancelClicked()
+{
+       delete_view_->PopPage();
+}
+
+void WorldClockDeletePresenter::OnDeleteClicked()
+{
+       model_->RemoveUserLocations(delete_view_->GetSelectedItems());
+
+       delete_view_->PopPage();
+}
+
+void WorldClockDeletePresenter::OnSelectAllClicked()
+{
+       delete_view_->SetAllItems(delete_view_->GetSelectAllState());
+       delete_view_->UpdateTitle();
+}
+
+void WorldClockDeletePresenter::OnListItemClicked()
+{
+       delete_view_->UpdateTitle();
+       if (model_->user_locations_.size() == delete_view_->GetSelectedItems().size()) {
+               delete_view_->SetSelectAllCheckbox(true);
+       }
+}
index 2c42390..7bf2255 100644 (file)
  */
 
 #include "Presenter/WorldClockPresenter.h"
+#include "Presenter/WorldClockDeletePresenter.h"
+#include "Model/WorldClockEvents.h"
+#include "Model/WorldClock.h"
+#include "Utils/EventBus.h"
 #include "Utils/Log.h"
 #include "Utils/PopupManager.h"
 
+using namespace utils;
+using namespace model;
+using namespace view;
+using std::placeholders::_1;
+
 namespace presenter {
 
-WorldClockPresenter::WorldClockPresenter(view::WorldClockView *view, model::WorldClock *model)
+WorldClockPresenter::WorldClockPresenter(WorldClockView *view, WorldClock *model)
                        : view_(view), model_(model)
 {
        view_->RegisterSignal(std::bind(&WorldClockPresenter::OnLeftArrowButtonClicked, this),
-                       view::WorldClockSignals::BUTTON_LEFT_ARROW_CLICKED);
+                       WorldClockSignals::BUTTON_LEFT_ARROW_CLICKED);
        view_->RegisterSignal(std::bind(&WorldClockPresenter::OnRightArrowButtonClicked, this),
-                               view::WorldClockSignals::BUTTON_RIGHT_ARROW_CLICKED);
+                       WorldClockSignals::BUTTON_RIGHT_ARROW_CLICKED);
        view_->RegisterSignal(std::bind(&WorldClockPresenter::OnCustomListItemClicked, this),
-                               view::WorldClockSignals::CUSTOM_LIST_ITEM_CLICKED);
+                       WorldClockSignals::CUSTOM_LIST_ITEM_CLICKED);
        view_->RegisterSignal(std::bind(&WorldClockPresenter::OnItemAdded, this),
-                               view::WorldClockSignals::CUSTOM_LIST_ITEM_ADD);
+                       WorldClockSignals::CUSTOM_LIST_ITEM_ADD);
+       view_->RegisterSignal(std::bind(&WorldClockPresenter::OnMoreButtonClicked, this),
+                       WorldClockSignals::BUTTON_MORE_CLICKED);
+       view_->RegisterSignal(std::bind(&WorldClockPresenter::OnMoreDeleteButtonClicked, this),
+                       WorldClockSignals::BUTTON_MORE_DELETE_CLICKED);
+
+       model_->RegisterSignalHandler(WorldClock::SignalType::USER_LOCATION_REMOVED,
+                       std::bind(&WorldClockPresenter::OnItemDeleted, this, _1));
 
        view_->UpdateMapAndTimezoneDetails(model_->GetCurrentTimezone());
 
@@ -46,7 +62,7 @@ WorldClockPresenter::~WorldClockPresenter()
 
 void WorldClockPresenter::UpdateEmptyListBackground()
 {
-       if (model_->user_locations_.size() == 0)
+       if (view_->IsListEmpty())
                view_->ShowEmptyListLabel();
        else
                view_->HideEmptyListLabel();
@@ -93,7 +109,7 @@ void WorldClockPresenter::OnItemAdded()
                ERR("Invalid Location object");
                return;
        }
-       bool attached = model_->AddItemToCustomList(l);
+       bool attached = model_->AddUserLocation(l);
        if (attached) {
                const model::Timezone *t = model_->GetTimezoneByOffset(l->gmt_offset_);
                if (!t) {
@@ -111,4 +127,22 @@ void WorldClockPresenter::OnItemAdded()
        UpdateEmptyListBackground();
 }
 
+void WorldClockPresenter::OnItemDeleted(const model::Location &location)
+{
+       view_->RemoveItem(location);
+
+       UpdateEmptyListBackground();
+}
+
+void WorldClockPresenter::OnMoreButtonClicked()
+{
+       view_->ShowMorePopup();
+}
+
+void WorldClockPresenter::OnMoreDeleteButtonClicked()
+{
+       WorldClockDeleteRequestEvent ev;
+       EventBus::FireEvent(ev);
+}
+
 } /* presenter */
diff --git a/clock/src/Utils/WorldClock.cpp b/clock/src/Utils/WorldClock.cpp
new file mode 100644 (file)
index 0000000..a72297d
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <app_i18n.h>
+
+#include "Utils/WorldClock.h"
+
+namespace utils {
+// local_timezone_offset and timezone_offset should be relative to GMT
+std::string GetTimezoneDiffDescription(int local_timezone_offset, int timezone_offset)
+{
+       char *pattern;
+       char relative[128] = { 0, };
+
+       int offset_integer = (abs(timezone_offset - local_timezone_offset)) / 60;
+       int offset_remainder = (abs(timezone_offset - local_timezone_offset)) % 60;
+
+       if (timezone_offset < local_timezone_offset) {
+               if (offset_remainder > 0) {
+                       pattern = _("IDS_CLOCK_BODY_PS1D_H_P2SD_M_BEHIND_ABB");
+                       snprintf(relative, sizeof(relative), pattern, offset_integer,
+                       offset_remainder);
+               } else {
+                       pattern = _("IDS_CLOCK_BODY_PD_H_BEHIND_ABB");
+                       snprintf(relative, sizeof(relative), pattern, offset_integer);
+               }
+       } else if (timezone_offset > local_timezone_offset) {
+               if (offset_remainder > 0) {
+                       pattern = _("IDS_CLOCK_BODY_PS1D_H_P2SD_M_AHEAD_ABB");
+                       snprintf(relative, sizeof(relative), pattern, offset_integer,
+                       offset_remainder);
+               } else {
+                       pattern = _("IDS_CLOCK_BODY_PD_H_AHEAD_ABB");
+                       snprintf(relative, sizeof(relative), pattern, offset_integer);
+               }
+       } else {
+               snprintf(relative, sizeof(relative), "Same as local time");
+       }
+       return relative;
+}
+
+} /* utils */
diff --git a/clock/src/View/WorldClockDeleteItemsView.cpp b/clock/src/View/WorldClockDeleteItemsView.cpp
new file mode 100644 (file)
index 0000000..fe7b7af
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <efl_extension.h>
+#include <vector>
+#include <sstream>
+#include "View/WorldClockDeleteItemsView.h"
+#include "Internal/WorldClockDefs.h"
+#include "Model/Location.h"
+#include "Utils/Utils.h"
+#include "Utils/Time.h"
+#include "Utils/Log.h"
+#include "Utils/WorldClock.h"
+
+using namespace view;
+using namespace utils;
+
+struct LocationDeleteItemData {
+
+               WorldClockDeleteItemsView *view;
+               Evas_Object *time;
+               Evas_Object *checkbox;
+
+               const model::Location *location;
+               char *ampm;
+               char *date;
+               char *city_country;
+               char *gmt_offset_relative;
+
+               int gmt_offset;
+               bool selected;
+               Elm_Object_Item *it;
+};
+
+
+/* Delete list View */
+
+Elm_Genlist_Item_Class WorldClockDeleteItemsView::world_clock_delete_view_itc_= {
+       .item_style = "worldclock.delete.list",
+       .func.content_get = WorldClockDeleteItemsView::ContentGet,
+       .func.text_get = WorldClockDeleteItemsView::TextGet,
+       .func.del = WorldClockDeleteItemsView::Del
+};
+
+void WorldClockDeleteItemsView::AppendItems(std::vector<const model::Location *> locations)
+{
+       std::stringstream ss;
+
+       for (auto l: locations) {
+               DBG();
+               LocationDeleteItemData *data = new LocationDeleteItemData;
+               Time t = Time::Now().InTimezone(Time::GetTimezoneNameByOffset(l->gmt_offset_).c_str());
+               int local_timezone_offset = Time::GetTimezoneOffset(Time::GetCurrentTimezone().c_str());
+               ss.str(std::string());
+               ss.clear();
+               ss << l->name << ", " << l->country;
+               data->city_country = strdup(ss.str().c_str());
+
+               data->location = l;
+               data->view = this;
+               data->ampm = strdup(t.Format("a").c_str());
+               data->gmt_offset_relative = strdup(GetTimezoneDiffDescription(local_timezone_offset,
+                               l->gmt_offset_).c_str());
+               data->gmt_offset = l->gmt_offset_;
+               data->date = strdup(t.Format("E d MMM").c_str());
+               data->selected = false;
+               data->it = elm_genlist_item_append(content_,
+                               &world_clock_delete_view_itc_,
+                               data,
+                               NULL,
+                               ELM_GENLIST_ITEM_NONE,
+                               WorldClockDeleteItemsView::ItemClicked,
+                               data);
+               if (!data->it)
+                       FAT("Item append failed");
+       }
+}
+
+void WorldClockDeleteItemsView::ItemClicked(void *data, Evas_Object *obj, void *event_info)
+{
+       LocationDeleteItemData *ldid = static_cast<LocationDeleteItemData *>(data);
+
+       ldid->selected = !ldid->selected;
+       if (!ldid->selected) {
+               ldid->view->all_selected_ = false;
+               elm_check_state_set(ldid->view->select_all_checkbox_, ldid->view->all_selected_);
+       }
+       ldid->view->UpdateTitle();
+
+       ldid->view->EmitSignal(SignalType::LIST_ITEM_CLICKED);
+
+       elm_genlist_item_selected_set(ldid->it, EINA_FALSE);
+       elm_check_state_set(ldid->checkbox, ldid->selected);
+}
+
+Evas_Object *WorldClockDeleteItemsView::ContentGet(void *data, Evas_Object *obj, const char *part)
+{
+       LocationDeleteItemData *ldid = static_cast<LocationDeleteItemData *>(data);
+
+       if (!strcmp(part, "time")) {
+               Time t = Time::Now().InTimezone(Time::GetTimezoneNameByOffset(ldid->gmt_offset).c_str());
+
+               ldid->time = elm_table_add(obj);
+               evas_object_size_hint_align_set(ldid->time, 0.0, 0.0);
+
+               Evas_Object *time = CreateTimeObject(ldid->time, t);
+               Evas_Object *padding = CreatePaddingObject(ldid->time, 8);
+               Evas_Object *ampm = CreateXMeridiemObject(ldid->time, t);
+
+               Evas_Object *dynamic_padding = elm_bg_add(ldid->time);
+               evas_object_color_set(dynamic_padding, 0, 0, 0, 0);
+               evas_object_size_hint_weight_set(dynamic_padding, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+               elm_table_pack(ldid->time, time, 0, 0, 1, 1);
+               elm_table_pack(ldid->time, padding, 1, 0, 1, 1);
+               elm_table_pack(ldid->time, ampm, 2, 0, 1, 1);
+               elm_table_pack(ldid->time, dynamic_padding, 3, 0, 1, 1);
+
+               return ldid->time;
+
+       } else if (!strcmp(part, "check")) {
+               ldid->checkbox = elm_check_add(obj);
+               evas_object_propagate_events_set(ldid->checkbox, EINA_FALSE);
+               elm_check_state_set(ldid->checkbox, ldid->selected ? EINA_TRUE : EINA_FALSE);
+               evas_object_smart_callback_add(ldid->checkbox, "changed",
+                               WorldClockDeleteItemsView::ItemSelectToggle, ldid);
+               evas_object_show(ldid->checkbox);
+               return ldid->checkbox;
+       }
+       return nullptr;
+}
+
+char *WorldClockDeleteItemsView::TextGet(void *data, Evas_Object *obj, const char *part)
+{
+       LocationDeleteItemData *ldid = static_cast<LocationDeleteItemData *>(data);
+       if (!strcmp(part, "ampm"))
+               return strdup(ldid->ampm);
+       if (!strcmp(part, "date"))
+               return strdup(ldid->date);
+       if (!strcmp(part, "city.country"))
+               return strdup(ldid->city_country);
+       if (!strcmp(part, "gmt.offset.desc"))
+               return strdup(ldid->gmt_offset_relative);
+
+       return nullptr;
+}
+
+void WorldClockDeleteItemsView::Del(void *data, Evas_Object *obj)
+{
+       LocationDeleteItemData *ldid = static_cast<LocationDeleteItemData *>(data);
+       free(ldid->ampm);
+       free(ldid->city_country);
+       free(ldid->date);
+       free(ldid->gmt_offset_relative);
+       evas_object_del(ldid->checkbox);
+       delete ldid;
+}
+
+Evas_Object *WorldClockDeleteItemsView::CreateTimeObject(Evas_Object *parent, Time t)
+{
+       Evas_Object *label = elm_label_add(parent);
+       evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+       std::string timezone_time = t.Format("HH:mm");
+       char time_formatted[MAX_STYLE_LEN] = { 0, };
+       snprintf(time_formatted, sizeof(time_formatted),
+                       CUSTOM_LIST_TIME_STYLE("%s"), timezone_time.c_str());
+       elm_object_text_set(label, time_formatted);
+
+       evas_object_show(label);
+
+
+       return label;
+}
+
+Evas_Object *WorldClockDeleteItemsView::CreateXMeridiemObject(Evas_Object *parent, Time t)
+{
+       Evas_Object *ampm = elm_label_add(parent);
+       evas_object_size_hint_align_set(ampm, EVAS_HINT_FILL, 0.75);
+
+
+       std::string meridiem = t.Format("a");
+       char ampm_formatted[MAX_STYLE_LEN] = { 0, };
+       snprintf(ampm_formatted, sizeof(ampm_formatted),
+                       CUSTOM_LIST_AMPM_STYLE("%s"), meridiem.c_str());
+       elm_object_text_set(ampm, ampm_formatted);
+
+       evas_object_show(ampm);
+
+       return ampm;
+}
+
+Evas_Object *WorldClockDeleteItemsView::CreatePaddingObject(Evas_Object *parent, int width)
+{
+       Evas_Object *padding = elm_bg_add(parent);
+       evas_object_size_hint_min_set(padding, width, 10);
+       evas_object_size_hint_max_set(padding, width, 10);
+       evas_object_color_set(padding, 0, 0, 0, 0);
+       evas_object_show(padding);
+
+       return padding;
+}
+
+/*[END] Delete list View */
+
+WorldClockDeleteItemsView::WorldClockDeleteItemsView(ui::IView &main):
+               PageView(main), all_selected_(false)
+{
+}
+
+WorldClockDeleteItemsView::~WorldClockDeleteItemsView()
+{
+}
+
+Evas_Object *WorldClockDeleteItemsView::GetEvasObject()
+{
+       return content_;
+}
+
+void WorldClockDeleteItemsView::CreateContent(Evas_Object *parent)
+{
+       elm_object_item_style_set(navi_item_, "basic");
+
+       static bool extension_init = false;
+
+       if (!extension_init) {
+               elm_theme_extension_add(NULL,
+                               Utils::GetAppResourcePath(Utils::APP_DIR_RESOURCE,
+                               "edje/WorldClockDeleteList.edj"));
+               extension_init = true;
+       }
+       left_button_ = elm_button_add(parent);
+       elm_object_text_set(left_button_, "CANCEL");
+       elm_object_style_set(left_button_, "naviframe/title_left");
+       evas_object_smart_callback_add(left_button_, "clicked",
+                       WorldClockDeleteItemsView::OnCancelButtonClicked, this);
+       evas_object_show(left_button_);
+
+       right_button_ = elm_button_add(parent);
+       elm_object_text_set(right_button_, "DELETE");
+       elm_object_style_set(right_button_, "naviframe/title_left");
+       evas_object_smart_callback_add(right_button_, "clicked",
+                       WorldClockDeleteItemsView::OnDeleteButtonClicked, this);
+       evas_object_show(right_button_);
+
+       content_ = elm_genlist_add(parent);
+       evas_object_size_hint_align_set(content_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+       evas_object_size_hint_weight_set(content_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_genlist_mode_set(content_, ELM_LIST_COMPRESS);
+       elm_genlist_homogeneous_set(content_, EINA_TRUE);
+       evas_object_show(content_);
+
+       elm_object_item_part_text_set(navi_item_, "elm.text.title", "Select cities");
+       elm_object_item_part_content_set(navi_item_, "title_left_btn", left_button_);
+       elm_object_item_part_content_set(navi_item_, "title_right_btn", right_button_);
+       elm_object_item_content_set(navi_item_, content_);
+
+       CreateSelectAll();
+}
+
+void WorldClockDeleteItemsView::CreateSelectAll()
+{
+       Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
+       Elm_Genlist_Item *item;
+
+       itc->item_style = "select_all";
+
+       itc->func.text_get = [](void *data, Evas_Object *obj, const char *part) -> char* {
+               if (!strcmp(part, "elm.text")) {
+                       return strdup("Select all");
+               }
+               return nullptr;
+       };
+       itc->func.content_get = [](void *data, Evas_Object *obj, const char *part) -> Evas_Object* {
+               WorldClockDeleteItemsView *view = static_cast<WorldClockDeleteItemsView *>(data);
+               if (!strcmp(part, "sw.check")) {
+                       view->select_all_checkbox_ = elm_check_add(obj);
+                       elm_check_state_set(view->select_all_checkbox_, view->all_selected_);
+                       evas_object_propagate_events_set(view->select_all_checkbox_, EINA_FALSE);
+                       evas_object_smart_callback_add(view->select_all_checkbox_, "changed",
+                                       WorldClockDeleteItemsView::OnSelectAllClicked, view);
+                       evas_object_show(view->select_all_checkbox_);
+                       return view->select_all_checkbox_;
+               }
+               return nullptr;
+       };
+       item = elm_genlist_item_append(content_, itc, this, NULL, ELM_GENLIST_ITEM_NONE,
+                       WorldClockDeleteItemsView::OnSelectAllClicked, this);
+       elm_genlist_item_select_mode_set(item, ELM_OBJECT_SELECT_MODE_ALWAYS);
+
+       elm_genlist_item_class_unref(itc);
+}
+
+void WorldClockDeleteItemsView::DestroyContent()
+{
+       evas_object_del(content_);
+       evas_object_del(left_button_);
+       evas_object_del(right_button_);
+}
+
+void WorldClockDeleteItemsView::RegisterSignal(SignalType s, std::function<void(void)>func)
+{
+       signals_.at((int)s) = func;
+}
+
+
+void WorldClockDeleteItemsView::EmitSignal(SignalType s)
+{
+       if (signals_.at((int)s) != nullptr)
+               signals_.at((int)s)();
+}
+
+void WorldClockDeleteItemsView::OnCancelButtonClicked(void *data, Evas_Object *obj, void *event_data)
+{
+       WorldClockDeleteItemsView * view = static_cast<WorldClockDeleteItemsView *>(data);
+       view->EmitSignal(SignalType::BUTTON_CANCEL_CLICKED);
+}
+
+void WorldClockDeleteItemsView::OnDeleteButtonClicked(void *data, Evas_Object *obj, void *event_data)
+{
+       WorldClockDeleteItemsView * view = static_cast<WorldClockDeleteItemsView *>(data);
+       view->EmitSignal(SignalType::BUTTON_DELETE_CLICKED);
+}
+
+void WorldClockDeleteItemsView::OnSelectAllClicked(void *data, Evas_Object *obj, void *event_info)
+{
+       Elm_Object_Item *it = static_cast<Elm_Object_Item*>(event_info);
+       WorldClockDeleteItemsView *view = static_cast<WorldClockDeleteItemsView *>(data);
+       elm_genlist_item_selected_set(it, EINA_FALSE);
+       view->all_selected_ = !view->all_selected_;
+       elm_check_state_set(view->select_all_checkbox_, view->all_selected_);
+
+       view->EmitSignal(SignalType::CHECKBOX_SELECT_ALL_CLICKED);
+}
+
+void WorldClockDeleteItemsView::ItemSelectToggle(void *data, Evas_Object *obj, void *event_info)
+{
+       LocationDeleteItemData *ldid = static_cast<LocationDeleteItemData *>(data);
+
+       ldid->selected = !ldid->selected;
+       if (!ldid->selected)
+               ldid->view->SetSelectAllCheckbox(false);
+
+       ldid->view->EmitSignal(SignalType::LIST_ITEM_CLICKED);
+}
+
+std::vector<const model::Location *> WorldClockDeleteItemsView::GetSelectedItems()
+{
+       static std::vector<const model::Location *> removed;
+       removed.clear();
+
+       Elm_Genlist_Item *it = elm_genlist_nth_item_get(content_, 1);
+       while (it) {
+               LocationDeleteItemData *ldid = static_cast<LocationDeleteItemData *> (elm_object_item_data_get(it));
+               if (ldid->selected)
+                       removed.push_back(ldid->location);
+
+               it = elm_genlist_item_next_get(it);
+       }
+       return removed;
+}
+
+void WorldClockDeleteItemsView::UpdateTitle()
+{
+       int cnt = 0;
+       std::stringstream ss;
+
+       cnt = GetSelectedItems().size();
+       ss << cnt << " selected";
+       elm_object_item_part_text_set(navi_item_, "elm.text.title", ss.str().c_str());
+}
+
+void WorldClockDeleteItemsView::SetAllItems(bool state)
+{
+       Elm_Genlist_Item *it = elm_genlist_nth_item_get(content_, 1);
+       while (it) {
+               LocationDeleteItemData *ldid = static_cast<LocationDeleteItemData *> (elm_object_item_data_get(it));
+               ldid->selected = state;
+               elm_check_state_set(ldid->checkbox, ldid->selected);
+               it = elm_genlist_item_next_get(it);
+       }
+}
+
+void WorldClockDeleteItemsView::SetSelectAllCheckbox(bool state)
+{
+       all_selected_ = state;
+       elm_check_state_set(select_all_checkbox_, all_selected_);
+}
+
+bool WorldClockDeleteItemsView::GetSelectAllState()
+{
+       return elm_check_state_get(select_all_checkbox_);
+}
index 6dd242b..cce5899 100644 (file)
@@ -28,6 +28,7 @@
 #include "Internal/WorldClockDefs.h"
 #include "Utils/Log.h"
 #include "Utils/Time.h"
+#include "Utils/WorldClock.h"
 #include "Utils/PopupManager.h"
 
 using namespace view;
@@ -67,44 +68,11 @@ void WorldClockView::CreateCustomLocationsList(Evas_Object *parent)
        elm_layout_content_set(world_clock_, TIMEZONE_CUSTOM_LOCATIONS_LIST_PART, custom_locations_list_);
 }
 
-// local_timezone_offset and timezone_offset should be relative to GMT
-std::string GetTimezoneDiffDescription(int local_timezone_offset, int timezone_offset)
-{
-       char *pattern;
-       char relative[128] = { 0, };
-
-       int offset_integer = (abs(timezone_offset - local_timezone_offset)) / 60;
-       int offset_remainder = (abs(timezone_offset - local_timezone_offset)) % 60;
-
-       if (timezone_offset < local_timezone_offset) {
-               if (offset_remainder > 0) {
-                               pattern = _("IDS_CLOCK_BODY_PS1D_H_P2SD_M_BEHIND_ABB");
-                               snprintf(relative, sizeof(relative), pattern, offset_integer,
-                               offset_remainder);
-               } else {
-                       pattern = _("IDS_CLOCK_BODY_PD_H_BEHIND_ABB");
-                       snprintf(relative, sizeof(relative), pattern, offset_integer);
-               }
-       } else if (timezone_offset > local_timezone_offset) {
-               if (offset_remainder > 0) {
-                       pattern = _("IDS_CLOCK_BODY_PS1D_H_P2SD_M_AHEAD_ABB");
-                       snprintf(relative, sizeof(relative), pattern, offset_integer,
-                       offset_remainder);
-               } else {
-                       pattern = _("IDS_CLOCK_BODY_PD_H_AHEAD_ABB");
-                       snprintf(relative, sizeof(relative), pattern, offset_integer);
-               }
-       } else {
-               snprintf(relative, sizeof(relative), "Same as local time");
-       }
-       return std::string(&relative[0]);
-}
-
 void WorldClockView::AppendItemToCustomList(const model::Location *location)
 {
        LocationItemData *data = new LocationItemData;
        Time t = Time::Now().InTimezone(
-                       Time::GetTimezoneNameByOffset(location->gmt_offset_).c_str());;
+                       Time::GetTimezoneNameByOffset(location->gmt_offset_).c_str());
        int local_timezone_offset = Time::GetTimezoneOffset(Time::GetCurrentTimezone().c_str());
        std::stringstream ss;
 
@@ -130,6 +98,21 @@ void WorldClockView::AppendItemToCustomList(const model::Location *location)
        return;
 }
 
+void WorldClockView::RemoveItem(const model::Location &location)
+{
+       Elm_Genlist_Item *it = elm_genlist_nth_item_get(custom_locations_list_, 0);
+
+       while (it) {
+               LocationItemData *lid = static_cast<LocationItemData *> (elm_object_item_data_get(it));
+
+               if (!(location.name.compare(lid->location->name)) && !(location.country.compare(lid->location->country))) {
+                       elm_object_item_del(it);
+                       break;
+               }
+               it = elm_genlist_item_next_get(it);
+       }
+}
+
 void WorldClockView::ItemClicked(void *data, Evas_Object *obj, void *event_info)
 {
        LocationItemData *lid = static_cast<LocationItemData *>(data);
@@ -282,7 +265,7 @@ WorldClockView::WorldClockView(ui::IView &main)
 void WorldClockView::MoreButtonClicked(void *data, Evas_Object *obj, void *info)
 {
        WorldClockView *view = static_cast<WorldClockView *>(data);
-       view->ShowMorePopup();
+       view->EmitSignal(view::WorldClockSignals::BUTTON_MORE_CLICKED);
 }
 
 void WorldClockView::ShowMorePopup()
@@ -309,6 +292,7 @@ void WorldClockView::MorePopupDeleteItemCallback(void *data, Evas_Object *obj, v
 {
        WorldClockView *view = static_cast<WorldClockView *>(data);
 
+       view->EmitSignal(view::WorldClockSignals::BUTTON_MORE_DELETE_CLICKED);
        evas_object_del(view->more_popup_);
        view->more_popup_ = nullptr;
 }
@@ -514,11 +498,6 @@ void WorldClockView::CreateTimezoneDetails()
                timezone_details_);
 
        CreateTimezoneCitiesList();
-
-       EmitSignal(view::WorldClockSignals::UPDATE_MAP_VIEW);
-
-       /* TODO load timezone to display on map from app preferences(it must be saved on app temination)*/
-
 }
 
 void WorldClockView::UpdateMapAndTimezoneDetails(const model::Timezone *timezone)
@@ -697,3 +676,11 @@ void WorldClockView::PostItemExistMessage()
        // TODO This text is temporary. Waiting for UX Designer response
        utils::PopupManager::CreatePopup(*this, "Location already exists in the list", 3);
 }
+
+bool WorldClockView::IsListEmpty()
+{
+       if (elm_genlist_items_count(custom_locations_list_) > 0)
+               return false;
+       else
+               return true;
+}