--- /dev/null
+/*
+ * Copyright (c) 2015 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 LOGS_DETAILS_ACTION_ITEM_H
+#define LOGS_DETAILS_ACTION_ITEM_H
+
+#include "Logs/Model/LogGroup.h"
+#include "App/AppControl.h"
+#include "Ui/GenlistItem.h"
+
+namespace Logs
+{
+ namespace Model
+ {
+ class Log;
+ }
+
+ namespace Details
+ {
+ /**
+ * @brief Genlist item representing a item which value can be used to
+ * initiate some external action.
+ */
+ class ActionItem : public Ui::GenlistItem
+ {
+ public:
+ /**
+ * @brief Create action item.
+ * @param[in] group Log group for display
+ */
+ ActionItem(Model::LogGroup *group);
+ virtual ~ActionItem();
+
+ protected:
+ /**
+ * @see GenlistItem::getItemClass()
+ */
+ virtual Elm_Genlist_Item_Class *getItemClass() const override;
+
+ /**
+ * @see GenlistItem::getText()
+ */
+ virtual char *getText(Evas_Object *parent, const char *part) override;
+
+ /**
+ * @see GenlistItem::getContent()
+ */
+ virtual Evas_Object *getContent(Evas_Object *parent, const char *part) override;
+
+ /**
+ * @see GenlistItem::onSelected()
+ */
+ virtual void onSelected() override;
+
+ private:
+ enum ActionId
+ {
+ ActionCall, /**< Make a telephony call using value as a number */
+ ActionMessage, /**< Compose an SMS using value as recipient */
+ };
+
+ bool isSavedLog();
+ char *getStrNumberType();
+ Evas_Object *createEntryNumber(Evas_Object *parent);
+ Evas_Object *createActionButton(Evas_Object *parent, ActionId actionId);
+ void executeAction(ActionId actionId);
+ void onButtonPressed(Evas_Object *button, void *eventInfo);
+ void onGroupChanged(int type);
+
+ Model::LogGroup *m_Group;
+ Model::Log *m_Log;
+ App::AppControl m_AppControl;
+ Model::LogGroup::ChangeCbHandle m_GroupChangeCbHandle;
+ };
+ }
+}
+
+#endif /* LOGS_DETAILS_ACTION_ITEM_H */
namespace Details
{
class BasicInfoItem;
+ class ActionItem;
class LogDetailItem;
/**
void fillGenList();
void insertBasicInfoItem();
+ void insertActionItem();
void insertLogGroupItem();
void insertLogDetailItem(Model::Log *log);
void insertLogDetailItems();
Model::LogGroup *m_Group;
Ui::Genlist *m_Genlist;
BasicInfoItem *m_BasicInfoItem;
+ ActionItem *m_ActionItem;
List::LogGroupItem *m_GroupItem;
Model::LogGroup::ChangeCbHandle m_GroupChangeCbHandle;
};
#include <contacts.h>
#include <time.h>
#include <functional>
+#include <string>
namespace Logs
{
const char *getImagePath() const;
/**
+ * @return type of number
+ */
+ int getNumberType() const;
+
+ /**
+ * @return label of number, when the number type is CONTACTS_NUMBER_TYPE_CUSTOM
+ */
+ std::string getNumberLabel() const;
+
+ /**
* @return log type
*/
int getType() const;
#include "LogsDetailsPath.h"
#include "../../../../lib-common/res/details/edje/DetailsItemLayout.h"
-#define LOGS_DETAILS_ITEM_STYLE "logs_details_item"
+#define LOGS_DETAILS_ITEM_STYLE "logs_details_item"
+#define LOGS_DETAILS_ACTION_ITEM_STYLE "logs_details_action_item"
-#define STATE_SAVED "state_saved"
-#define PART_UNSAVED_BTNS "swallow.unsaved_btns"
+#define STATE_SAVED "state_saved"
+#define PART_UNSAVED_BTNS "swallow.unsaved_btns"
-#define COLOR_UNSAVED_BUTTON_NORMAL 0, 0, 0, 40
-#define COLOR_UNSAVED_BUTTON_PRESSED 0, 0, 0, 67
+#define COLOR_UNSAVED_BUTTON_NORMAL 0, 0, 0, 40
+#define COLOR_UNSAVED_BUTTON_PRESSED 0, 0, 0, 67
-#define GROUP_ICON_CALL "icon_call"
-#define GROUP_ICON_MESSAGE "icon_message"
+#define PART_NUMBER_TYPE "text.number_type"
+#define PART_NUMBER "swallow.number"
+#define PART_ICON_CALL "swallow.icon_call"
+#define PART_ICON_MESSAGE "swallow.icon_message"
+
+#define GROUP_ICON_CALL "icon_call"
+#define GROUP_ICON_MESSAGE "icon_message"
#endif /* LOGS_DETAILS_ITEM_LAYOUT_H */
#define UNSAVED_BTN_H 78
+#define ACTION_ITEM_PAD_L 32
+#define ACTION_ITEM_PAD_R 17
+#define ACTION_ITEM_PAD_TB 24
+#define ACTION_ITEM_PAD_BETWEEN 12
+
+#define ACTION_ITEM_NUMBER_TYPE_H 54
+#define ACTION_ITEM_NUMBER_H 43
+
+#define NUMBER_TYPE_TEXT_SIZE 32
+
+#define ACTION_ITEM_H 144
+
#endif /* LOGS_DETAILS_ITEM_LAYOUT_METRICS_H */
#include "../../../../lib-apps-common/res/apps-common/edje/apps-common-utils.edc"
#include "../../../../lib-common/res/details/edje/details-item-layout.edc"
+styles {
+ style {
+ name: "number_type_style";
+ base: "font=Tizen:style=Regular font_size="NUMBER_TYPE_TEXT_SIZE" align=left wrap=mixed color=#808080 ellipsis=1.0";
+ }
+}
+
collections
{
base_scale: 2.6;
}
}
}
+
+ group {
+ name: "elm/genlist/item/"LOGS_DETAILS_ACTION_ITEM_STYLE"/default";
+ alias: "elm/genlist/item_compress/"LOGS_DETAILS_ACTION_ITEM_STYLE"/default";
+ alias: "elm/genlist/tree/"LOGS_DETAILS_ACTION_ITEM_STYLE"/default";
+ alias: "elm/genlist/tree_compress/"LOGS_DETAILS_ACTION_ITEM_STYLE"/default";
+
+ data.item: "banded_bg_area" "swallow.bg";
+ data.item: "texts" PART_NUMBER_TYPE;
+ data.item: "contents" PART_NUMBER" "PART_ICON_CALL" "PART_ICON_MESSAGE;
+
+ parts {
+ swallow { "swallow.bg"; }
+ spacer { "spacer.base"; scale;
+ desc { "default";
+ min: 0 ACTION_ITEM_H;
+ }
+ }
+ spacer { "spacer.top"; scale;
+ desc { "default";
+ min: 0 ACTION_ITEM_PAD_TB;
+ align: 0.5 0.0;
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 0.0;
+ }
+ }
+ spacer { "spacer.bottom"; scale;
+ desc { "default";
+ min: 0 ACTION_ITEM_PAD_TB;
+ align: 0.5 0.0;
+ rel1.relative: 0.0 1.0;
+ rel2.relative: 1.0 1.0;
+ }
+ }
+ spacer { "spacer.left"; scale;
+ desc { "default";
+ min: ACTION_ITEM_PAD_L 0;
+ align: 0.0 0.5;
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 0.0 1.0;
+ }
+ }
+ spacer { "spacer.right"; scale;
+ desc { "default";
+ min: ACTION_ITEM_PAD_R 0;
+ align: 1.0 0.5;
+ rel1.relative: 1.0 0.0;
+ rel2.relative: 1.0 1.0;
+ }
+ }
+ textblock { PART_NUMBER_TYPE; scale;
+ desc { "default";
+ min: 0 ACTION_ITEM_NUMBER_TYPE_H;
+ max: -1 ACTION_ITEM_NUMBER_TYPE_H;
+ align: 0.0 0.0;
+ rel1 { relative: 1.0 1.0; to_x: "spacer.left"; to_y: "spacer.top"; }
+ rel2 { relative: 0.0 1.0; to_x: "spacer.icon_call_left"; }
+ text {
+ align: 0.5 0.5;
+ style: "number_type_style";
+ }
+ }
+ }
+ swallow { PART_NUMBER; scale;
+ desc { "default";
+ min: 0 ACTION_ITEM_NUMBER_H;
+ align: 0.5 0.0;
+ rel1 { relative: 1.0 1.0; to_x: "spacer.left"; to_y: PART_NUMBER_TYPE; }
+ rel2 { relative: 0.0 0.0; to_x: "spacer.icon_call_left"; to_y: "spacer.bottom"; }
+ }
+ }
+ spacer { "spacer.icon_call_left"; scale;
+ desc { "default";
+ min: ACTION_ITEM_PAD_BETWEEN 0;
+ align: 1.0 0.5;
+ rel1 { relative: 1.0 0.0; }
+ rel1 { relative: 0.0 0.0; to_x: PART_ICON_CALL; }
+ }
+ }
+ swallow { PART_ICON_CALL; scale;
+ desc { "default";
+ min: BTN_SIZE;
+ max: BTN_SIZE;
+ align: 1.0 0.5;
+ rel1 { relative: 1.0 0.0; to_x: "spacer.icon_call_left";}
+ rel2 { relative: 0.0 1.0; to_x: "spacer.icon_message_left";}
+ }
+ }
+ spacer { "spacer.icon_message_left"; scale;
+ desc { "default";
+ min: ACTION_ITEM_PAD_BETWEEN 0;
+ align: 1.0 0.5;
+ rel1 { relative: 0.0 0.0; to_x: PART_ICON_MESSAGE; }
+ }
+ }
+ swallow { PART_ICON_MESSAGE; scale;
+ desc { "default";
+ min: BTN_SIZE;
+ max: BTN_SIZE;
+ align: 1.0 0.5;
+ rel1 { relative: 1.0 0.0; to_x: "spacer.icon_message_left";}
+ rel2 { relative: 0.0 1.0; to_x: "spacer.right";}
+ }
+ }
+ }
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 "Logs/Details/ActionItem.h"
+#include "Logs/Model/Log.h"
+
+#include "LogsDetailsItemLayout.h"
+#include "LogsDetailsItemLayoutMetrics.h"
+#include "DetailsItemLayoutMetrics.h"
+
+#include "App/Path.h"
+#include "Ui/Scale.h"
+#include "Utils/Callback.h"
+
+#include <app_i18n.h>
+
+using namespace Logs::Details;
+using namespace Logs::Model;
+using namespace std::placeholders;
+
+namespace
+{
+ struct {
+ const char *icon;
+ const char *operation;
+ const char *scheme;
+ } actions[] = {
+ /* ActionCall = */ { GROUP_ICON_CALL, APP_CONTROL_OPERATION_CALL, "tel:" },
+ /* ActionMessage = */ { GROUP_ICON_MESSAGE, APP_CONTROL_OPERATION_COMPOSE, "sms:" },
+ };
+
+ struct {
+ const char *name;
+ int type;
+ } numberTypes[] = {
+ { "IDS_PB_OPT_MOBILE", CONTACTS_NUMBER_TYPE_CELL},
+ { "IDS_PB_OPT_HOME_ABB", CONTACTS_NUMBER_TYPE_VOICE | CONTACTS_NUMBER_TYPE_HOME },
+ { "IDS_PB_OPT_WORK", CONTACTS_NUMBER_TYPE_VOICE | CONTACTS_NUMBER_TYPE_WORK},
+ { "IDS_PB_OPT_MAIN", CONTACTS_NUMBER_TYPE_MAIN},
+ { "IDS_PB_OPT_FAX_HWORK_ABB", CONTACTS_NUMBER_TYPE_FAX | CONTACTS_NUMBER_TYPE_WORK},
+ { "IDS_PB_OPT_FAX_HHOME_ABB", CONTACTS_NUMBER_TYPE_FAX | CONTACTS_NUMBER_TYPE_HOME},
+ { "IDS_PB_OPT_PAGER", CONTACTS_NUMBER_TYPE_PAGER},
+ { "IDS_PB_OPT_OTHER", CONTACTS_NUMBER_TYPE_OTHER},
+ { "IDS_PB_OPT_CUSTOM", CONTACTS_NUMBER_TYPE_CUSTOM},
+ };
+
+ const std::string layoutPath = App::getResourcePath(LOGS_DETAILS_ITEM_LAYOUT_EDJ);
+}
+
+ActionItem::ActionItem(LogGroup *group)
+ : m_Group(group)
+{
+ m_Log = m_Group->getLogList().back();
+ m_GroupChangeCbHandle = m_Group->addChangeCallback(std::bind(&ActionItem::onGroupChanged, this, _1));
+}
+
+ActionItem::~ActionItem()
+{
+ if (m_Group) {
+ m_Group->removeChangeCallback(m_GroupChangeCbHandle);
+ }
+}
+
+Elm_Genlist_Item_Class *ActionItem::getItemClass() const
+{
+ static Elm_Genlist_Item_Class itc = createItemClass(LOGS_DETAILS_ACTION_ITEM_STYLE);
+ return &itc;
+}
+
+char *ActionItem::getText(Evas_Object *parent, const char *part)
+{
+ if (strcmp(part, PART_NUMBER_TYPE) == 0) {
+ if (isSavedLog()) {
+ return getStrNumberType();
+ } else {
+ return strdup(_("IDS_LOGS_SBODY_UNSAVED_M_STATUS"));
+ }
+ }
+
+ return nullptr;
+}
+
+Evas_Object *ActionItem::getContent(Evas_Object *parent, const char *part)
+{
+ if (strcmp(part, PART_ICON_CALL) == 0) {
+ return createActionButton(parent, ActionCall);
+ } else if (strcmp(part, PART_ICON_MESSAGE) == 0) {
+ return createActionButton(parent, ActionMessage);
+ } else if (strcmp(part, PART_NUMBER) == 0) {
+ return createEntryNumber(parent);
+ }
+ return nullptr;
+}
+
+void ActionItem::onSelected()
+{
+ executeAction(ActionCall);
+}
+
+bool ActionItem::isSavedLog()
+{
+ return m_Log->getPersonId() > 0;
+}
+
+char *ActionItem::getStrNumberType()
+{
+ int type = m_Log->getNumberType();
+ if (type == CONTACTS_NUMBER_TYPE_CUSTOM) {
+ return strdup(m_Log->getNumberLabel().c_str());
+ }
+ for (auto &numberType : numberTypes) {
+ if (numberType.type == type) {
+ return strdup(_(numberType.name));
+ }
+ }
+ return nullptr;
+}
+
+Evas_Object *ActionItem::createEntryNumber(Evas_Object *parent)
+{
+ Evas_Object *entry = elm_entry_add(parent);
+ elm_entry_scrollable_set(entry, EINA_TRUE);
+ elm_entry_single_line_set(entry, EINA_TRUE);
+ elm_entry_editable_set(entry, EINA_FALSE);
+
+ char *text = elm_entry_utf8_to_markup(m_Log->getNumber());
+ elm_entry_entry_set(entry, text);
+ free(text);
+
+ return entry;
+}
+
+Evas_Object *ActionItem::createActionButton(Evas_Object *parent, ActionId actionId)
+{
+ static const int imageSize = Ui::getScaledValue(BTN_WH);
+
+ Evas_Object *image = elm_image_add(parent);
+ elm_image_file_set(image, layoutPath.c_str(), actions[actionId].icon);
+ evas_object_size_hint_min_set(image, imageSize, imageSize);
+ evas_object_propagate_events_set(image, EINA_FALSE);
+ evas_object_smart_data_set(image, (void *) actionId);
+ evas_object_smart_callback_add(image, "clicked",
+ makeCallback(&ActionItem::onButtonPressed), this);
+
+ return image;
+}
+
+void ActionItem::executeAction(ActionId actionId)
+{
+ auto action = actions[actionId];
+
+ std::string uri = action.scheme;
+ const char *number = m_Log->getNumber();
+ if (number) {
+ uri.append(number);
+ }
+
+ m_AppControl = App::AppControl(action.operation, nullptr, uri.c_str());
+ m_AppControl.launch();
+}
+
+void ActionItem::onButtonPressed(Evas_Object *button, void *eventInfo)
+{
+ executeAction((ActionId) (long) evas_object_smart_data_get(button));
+}
+
+void ActionItem::onGroupChanged(int type)
+{
+ if (type & LogGroup::ChangeRemoved) {
+ m_Group = nullptr;
+ } else {
+ m_Log = m_Group->getLogList().back();
+ elm_genlist_item_fields_update(getObjectItem(), PART_NUMBER_TYPE, ELM_GENLIST_ITEM_FIELD_TEXT);
+ }
+}
#include "Logs/Details/DetailsView.h"
#include "Logs/Details/BasicInfoItem.h"
+#include "Logs/Details/ActionItem.h"
#include "Logs/Details/LogDetailItem.h"
#include "Logs/List/LogGroupItem.h"
#include "Logs/Model/Log.h"
using namespace std::placeholders;
DetailsView::DetailsView(LogGroup *group)
- : m_Group(group), m_Genlist(nullptr), m_BasicInfoItem(nullptr), m_GroupItem(nullptr)
+ : m_Group(group), m_Genlist(nullptr), m_BasicInfoItem(nullptr), m_ActionItem(nullptr),
+ m_GroupItem(nullptr)
{
setSelectCallback(std::bind(&DetailsView::onSelected, this, _1));
setCancelCallback(std::bind(&DetailsView::onCanceled, this));
{
if (getSelectMode() == SelectNone) {
insertBasicInfoItem();
- } else if (m_BasicInfoItem) {
- delete m_BasicInfoItem;
- m_BasicInfoItem = nullptr;
+ insertActionItem();
+ } else {
+ if (m_BasicInfoItem) {
+ delete m_BasicInfoItem;
+ m_BasicInfoItem = nullptr;
+ }
+ if (m_ActionItem) {
+ delete m_ActionItem;
+ m_ActionItem = nullptr;
+ }
}
}
{
if (getSelectMode() == SelectNone) {
insertBasicInfoItem();
+ insertActionItem();
}
insertLogGroupItem();
insertLogDetailItems();
m_Genlist->insert(m_BasicInfoItem, nullptr, nullptr, Ui::Genlist::After);
}
+void DetailsView::insertActionItem()
+{
+ m_ActionItem = new ActionItem(m_Group);
+ m_Genlist->insert(m_ActionItem, nullptr, m_BasicInfoItem, Ui::Genlist::After);
+ elm_genlist_item_select_mode_set(m_ActionItem->getObjectItem(), ELM_OBJECT_SELECT_MODE_NONE);
+}
+
void DetailsView::insertLogGroupItem()
{
Log *log = m_Group->getLogList().back();
return path;
}
+int Log::getNumberType() const
+{
+ int type = CONTACTS_NUMBER_TYPE_OTHER;
+
+ contacts_filter_h filter = nullptr;
+ contacts_filter_create(_contacts_person_phone_log._uri, &filter);
+ contacts_filter_add_int(filter, _contacts_person_phone_log.log_id, CONTACTS_MATCH_EQUAL, getId());
+
+ contacts_query_h query = nullptr;
+ contacts_query_create(_contacts_person_phone_log._uri, &query);
+ contacts_query_set_filter(query, filter);
+
+ contacts_list_h list = nullptr;
+ int err = contacts_db_get_records_with_query(query, 0, 1, &list);
+ WARN_IF_ERR(err, "contacts_db_get_records_with_query() failed.");
+
+ contacts_record_h record = nullptr;
+ contacts_list_get_current_record_p(list, &record);
+ contacts_record_get_int(record, _contacts_person_phone_log.address_type, &type);
+
+ contacts_list_destroy(list, true);
+ contacts_query_destroy(query);
+ contacts_filter_destroy(filter);
+
+ return type;
+}
+
+std::string Log::getNumberLabel() const
+{
+ std::string label;
+ contacts_filter_h filter = nullptr;
+ contacts_filter_create(_contacts_person_number._uri, &filter);
+ contacts_filter_add_int(filter, _contacts_person_number.person_id, CONTACTS_MATCH_EQUAL, getPersonId());
+ contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
+ contacts_filter_add_str(filter, _contacts_person_number.number, CONTACTS_MATCH_EXACTLY, getNumber());
+
+ contacts_query_h query = nullptr;
+ contacts_query_create(_contacts_person_number._uri, &query);
+ contacts_query_set_filter(query, filter);
+
+ contacts_list_h list = nullptr;
+ int err = contacts_db_get_records_with_query(query, 0, 0, &list);
+ WARN_IF_ERR(err, "contacts_db_get_records_with_query() failed.");
+
+ contacts_record_h record = nullptr;
+ char *tmp = nullptr;
+ contacts_list_get_current_record_p(list, &record);
+ contacts_record_get_str_p(record, _contacts_person_number.label, &tmp);
+ if (tmp) {
+ label = tmp;
+ }
+
+ contacts_list_destroy(list, true);
+ contacts_query_destroy(query);
+ contacts_filter_destroy(filter);
+
+ return label;
+}
+
int Log::getType() const
{
int type = CONTACTS_PLOG_TYPE_NONE;