namespace model {
- /*
+ /**
* @brief Structure for time zone details
*/
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
*
*/
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
*/
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
*
*/
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_;
void OnCustomListItemClicked();
void OnMapViewUpdateRequest();
+ void OnItemAdded();
+
};
}
#include <vector>
+#include <app_control.h>
#include "Model/WorldClock.h"
#include "View/PageView.h"
BUTTON_RIGHT_ARROW_CLICKED,
CUSTOM_LIST_ITEM_CLICKED,
+ CUSTOM_LIST_ITEM_ADD,
+
UPDATE_MAP_VIEW,
MAX
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);
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);
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);
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);
* limitations under the License.
*/
+#include <app_preference.h>
+#include <algorithm>
+
#include "Model/WorldClock.h"
#include "Model/Location.h"
#include "log.h"
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", ¤t_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
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;
+}
*/
#include "Presenter/WorldClockPresenter.h"
+#include "log.h"
namespace presenter {
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());
}
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 */
#include <sstream>
#include <efl_extension.h>
+#include <eina_str.h>
#include "View/WorldClockView.h"
#include "View/MainView.h"
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);
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,
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++) {
return item_last_clicked_;
}
+const model::Location *WorldClockView::GetLocationToAdd()
+{
+ return item_to_add_;
+}
+
void WorldClockView::SetItemLastClicked(const model::Location *location)
{
item_last_clicked_ = location;
<?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>