* @return Whether the component that provided the selection should be destroyed.
*/
typedef std::function<bool(SelectResults)> SelectCallback;
+
+ /**
+ * @brief Callback to be called when cancel is pressed.
+ * @return Whether the component that provided the selection should be destroyed.
+ */
+ typedef std::function<bool()> CancelCallback;
}
#endif /* CONTACTS_SELECT_TYPES_H */
void setSelectCallback(SelectCallback callback);
/**
+ * @brief Set cancel callback.
+ * @param[in] callback Cancel callback
+ */
+ void setCancelCallback(CancelCallback callback);
+
+ /**
* @brief Set item check callback.
* @param[in] callback Check callback
*/
SelectMode m_SelectMode;
SelectCallback m_OnSelected;
CheckCallback m_OnChecked;
+ CancelCallback m_OnCanceled;
};
}
m_OnSelected = std::move(callback);
}
+void SelectView::setCancelCallback(CancelCallback callback)
+{
+ m_OnCanceled = std::move(callback);
+}
+
void SelectView::setCheckCallback(CheckCallback callback)
{
m_OnChecked = std::move(callback);
void SelectView::onCancelPressed(Evas_Object *button, void *eventInfo)
{
- getPage()->close();
+ if (!m_OnCanceled || m_OnCanceled()) {
+ getPage()->close();
+ }
}
#include "Ui/GenlistItem.h"
#include "App/AppControl.h"
+#include "Logs/Model/LogGroup.h"
namespace Logs
{
BasicInfoItem(Model::LogGroup *group);
/**
+ * @brief Destroy basic info item.
+ */
+ virtual ~BasicInfoItem() override;
+
+ /**
* @brief Set "back" button callback.
* @param[in] callback "back" button callback
*/
void onBackPressed(Evas_Object *button, void *eventInfo);
void onCreatePressed();
void onUpdatePressed();
+ void onGroupChanged(int type);
Model::LogGroup *m_Group;
Model::Log *m_Log;
App::AppControl m_AppControl;
BackCallback m_OnBackPressed;
+ Model::LogGroup::ChangeCbHandle m_GroupChangeCbHandle;
};
}
}
#define LOGS_DETAILS_DETAILS_VIEW_H
#include "Contacts/SelectView.h"
+#include "Logs/Model/LogGroup.h"
namespace Ui
{
{
namespace Model
{
- class LogGroup;
+ class Log;
+ }
+ namespace List
+ {
+ class LogGroupItem;
}
namespace Details
{
class BasicInfoItem;
+ class LogDetailItem;
/**
* @brief Log details view.
DetailsView(Model::LogGroup *group);
private:
+ virtual ~DetailsView() override;
virtual Evas_Object *onCreate(Evas_Object *parent) override;
virtual void onCreated() override;
+ virtual bool onBackPressed() override;
+ virtual void onMenuPressed() override;
+
virtual void onSelectModeChanged(Contacts::SelectMode selectMode) override;
virtual void onSelectAllInsert(Ui::GenlistItem *item) override;
- virtual void onMenuPressed() override;
void fillGenList();
void insertBasicInfoItem();
void insertLogGroupItem();
+ void insertLogDetailItem(Model::Log *log);
void insertLogDetailItems();
+ bool onSelected(Contacts::SelectResults results);
+ bool onCanceled();
+ void onGroupChanged(int type);
+ void onLogAdded(Model::Log *log);
+ void onLogRemoved(LogDetailItem *logItem);
+
Model::LogGroup *m_Group;
Ui::Genlist *m_Genlist;
BasicInfoItem *m_BasicInfoItem;
+ List::LogGroupItem *m_GroupItem;
+ Model::LogGroup::ChangeCbHandle m_GroupChangeCbHandle;
};
}
}
#include <contacts.h>
#include <time.h>
+#include <functional>
namespace Logs
{
{
public:
/**
+ * @brief Callback to be called when log was removed to group.
+ * @param[in] log Removed log
+ */
+ typedef std::function<void()> RemoveCallback;
+
+ /**
* @brief Create log record
* @param[in] record Log record (_contact_person_phone_log)
*/
Log &operator=(const Log &log) = delete;
/**
+ * @brief Set log remove callback.
+ * @param[in] callback log remove callback
+ */
+ void setRemoveCallback(RemoveCallback callback);
+
+ /**
+ * @brief Unset log remove callback.
+ */
+ void unsetRemoveCallback();
+
+ /**
* @return log name
*/
const char *getName() const;
contacts_record_h m_ContactRecord;
LogGroup *m_Group;
+ RemoveCallback m_OnRemoved;
};
}
}
typedef std::function<void(int)> ChangeCallback;
/**
+ * @brief Callback to be called when log was added to group.
+ * @param[in] log Added log
+ */
+ typedef std::function<void(Log *log)> LogAddCallback;
+
+ private:
+ typedef std::list<ChangeCallback> ChangeCbs;
+
+ public:
+ /**
* @brief List of logs.
*/
typedef std::list<Log *> LogList;
/**
+ * @brief Callback handle
+ * @remark Used to remove callback
+ */
+ typedef ChangeCbs::const_iterator ChangeCbHandle;
+
+ /**
* @brief Constructor
* @param[in] log Log to add
*/
void remove();
/**
- * @brief Set log changed callback
+ * @brief Add log changed callback
* @remark Callback called when log is changed.
- * @param[in] callback Changed log callback
+ * @param[in] callback Changed log callback
+ * @return handle of change callback
*/
- void setChangeCallback(ChangeCallback callback);
+ ChangeCbHandle addChangeCallback(ChangeCallback callback);
/**
- * @brief Unset log change callback
+ * @brief Remove log change callback
+ * @param[in] handle Handle of change callback
*/
- void unsetChangeCallback();
+ void removeChangeCallback(ChangeCbHandle handle);
/**
* @brief Call log change callback
*/
void setChangedType(int type);
+ /**
+ * @brief Set log add callback.
+ * @param[in] callback log add callback
+ */
+ void setLogAddCallback(LogAddCallback callback);
+
+ /**
+ * @brief Unset log add callback.
+ */
+ void unsetLogAddCallback();
+
private:
LogList m_LogList;
-
- ChangeCallback m_ChangeCallback;
int m_ChangedType;
+ ChangeCbs m_ChangeCbs;
+ LogAddCallback m_OnLogAdded;
};
}
}
using namespace Logs::Details;
using namespace Logs::Model;
+using namespace std::placeholders;
BasicInfoItem::BasicInfoItem(LogGroup *group)
: m_Group(group)
{
m_Log = m_Group->getLogList().back();
+ m_GroupChangeCbHandle = m_Group->addChangeCallback(std::bind(&BasicInfoItem::onGroupChanged, this, _1));
+}
+
+BasicInfoItem::~BasicInfoItem()
+{
+ if (m_Group) {
+ m_Group->removeChangeCallback(m_GroupChangeCbHandle);
+ }
}
void BasicInfoItem::setBackCallback(BackCallback callback)
char *BasicInfoItem::getText(Evas_Object *parent, const char *part)
{
- const char *name = m_Log->getName();
if (isSavedLog() && strcmp(part, PART_NAME) == 0) {
- return strdup(name);
+ return strdup(m_Log->getName());
}
return nullptr;
{
Evas_Object *button = elm_button_add(parent);
elm_object_style_set(button, "naviframe/back_btn/default");
+ evas_object_propagate_events_set(button, EINA_FALSE);
evas_object_smart_callback_add(button, "clicked",
makeCallback(&BasicInfoItem::onBackPressed), this);
return button;
m_AppControl = App::requestContactEdit(0, m_Log->getNumber());
m_AppControl.launch();
}
+
+void BasicInfoItem::onGroupChanged(int type)
+{
+ if (type & LogGroup::ChangeRemoved) {
+ m_Group = nullptr;
+ } else {
+ m_Log = m_Group->getLogList().back();
+ if (type & LogGroup::ChangeName) {
+ elm_genlist_item_fields_update(getObjectItem(), STATE_SAVED, ELM_GENLIST_ITEM_FIELD_STATE);
+ elm_genlist_item_fields_update(getObjectItem(), PART_NAME, ELM_GENLIST_ITEM_FIELD_TEXT);
+ elm_genlist_item_fields_update(getObjectItem(), PART_UNSAVED_BTNS, ELM_GENLIST_ITEM_FIELD_CONTENT);
+ }
+ if (type & LogGroup::ChangeImage) {
+ elm_genlist_item_fields_update(getObjectItem(), PART_THUMBNAIL, ELM_GENLIST_ITEM_FIELD_CONTENT);
+ }
+ }
+}
#include "Logs/Details/BasicInfoItem.h"
#include "Logs/Details/LogDetailItem.h"
#include "Logs/List/LogGroupItem.h"
-#include "Logs/Model/LogGroup.h"
#include "Logs/Model/Log.h"
#include "LogsDetailsItemLayout.h"
#include "App/Path.h"
#include "Ui/Genlist.h"
#include "Ui/Menu.h"
-#include "Ui/Navigator.h"
+
+#include <algorithm>
using namespace Logs::Model;
using namespace Logs::Details;
using namespace Logs::List;
using namespace Contacts;
+using namespace std::placeholders;
DetailsView::DetailsView(LogGroup *group)
- : m_Group(group), m_Genlist(nullptr), m_BasicInfoItem(nullptr)
+ : m_Group(group), m_Genlist(nullptr), m_BasicInfoItem(nullptr), m_GroupItem(nullptr)
{
+ setSelectCallback(std::bind(&DetailsView::onSelected, this, _1));
+ setCancelCallback(std::bind(&DetailsView::onCanceled, this));
+ m_Group->setLogAddCallback(std::bind(&DetailsView::onLogAdded, this, _1));
+ m_GroupChangeCbHandle = m_Group->addChangeCallback(std::bind(&DetailsView::onGroupChanged, this, _1));
+}
+
+DetailsView::~DetailsView()
+{
+ if (m_Group) {
+ for (auto &log : m_Group->getLogList()) {
+ log->unsetRemoveCallback();
+ }
+ m_Group->unsetLogAddCallback();
+ m_Group->removeChangeCallback(m_GroupChangeCbHandle);
+ }
}
Evas_Object *DetailsView::onCreate(Evas_Object *parent)
fillGenList();
}
-void DetailsView::onSelectModeChanged(SelectMode selectMode)
+bool DetailsView::onBackPressed()
{
- if (getSelectMode() == SelectNone) {
- insertBasicInfoItem();
- } else if (m_BasicInfoItem) {
- delete m_BasicInfoItem;
- m_BasicInfoItem = nullptr;
+ if (getSelectMode() != SelectNone) {
+ setSelectMode(SelectNone);
+ return false;
}
-}
-
-void DetailsView::onSelectAllInsert(Ui::GenlistItem *item)
-{
- m_Genlist->insert(item, nullptr, nullptr, Ui::Genlist::After);
+ return true;
}
void DetailsView::onMenuPressed()
Ui::Menu *menu = new Ui::Menu();
menu->create(getEvasObject());
-
menu->addItem("IDS_LOGS_OPT_DELETE", [this] {
- DetailsView *view = new DetailsView(m_Group);
- view->setSelectMode(SelectMulti);
- view->setSelectCallback([](SelectResults results) {
- for (auto &&result : results) {
- Log *log = (Log *)result.value.data;
- log->remove();
- }
- return true;
- });
- getNavigator()->navigateTo(view);
+ setSelectMode(SelectMulti);
});
menu->show();
}
+void DetailsView::onSelectModeChanged(SelectMode selectMode)
+{
+ if (getSelectMode() == SelectNone) {
+ insertBasicInfoItem();
+ } else if (m_BasicInfoItem) {
+ delete m_BasicInfoItem;
+ m_BasicInfoItem = nullptr;
+ }
+}
+
+void DetailsView::onSelectAllInsert(Ui::GenlistItem *item)
+{
+ m_Genlist->insert(item, nullptr, nullptr, Ui::Genlist::After);
+}
+
void DetailsView::fillGenList()
{
if (getSelectMode() == SelectNone) {
void DetailsView::insertLogGroupItem()
{
Log *log = m_Group->getLogList().back();
- LogGroupItem *groupItem = new LogGroupItem(log->getTime());
- m_Genlist->insert(groupItem);
- elm_genlist_item_select_mode_set(groupItem->getObjectItem(), ELM_OBJECT_SELECT_MODE_NONE);
+ m_GroupItem = new LogGroupItem(log->getTime());
+ m_Genlist->insert(m_GroupItem);
+ elm_genlist_item_select_mode_set(m_GroupItem->getObjectItem(), ELM_OBJECT_SELECT_MODE_NONE);
+}
+
+void DetailsView::insertLogDetailItem(Log *log)
+{
+ LogDetailItem *logItem = new LogDetailItem(log);
+ m_Genlist->insert(logItem, m_GroupItem, m_GroupItem, Ui::Genlist::After);
+ log->setRemoveCallback(std::bind(&DetailsView::onLogRemoved, this, logItem));
+ onItemInserted(logItem);
}
void DetailsView::insertLogDetailItems()
{
- for (auto &log:m_Group->getLogList()) {
- LogDetailItem *logItem = new LogDetailItem(log);
- m_Genlist->insert(logItem);
- onItemInserted(logItem);
+ for (auto &log : m_Group->getLogList()) {
+ insertLogDetailItem(log);
}
}
+
+bool DetailsView::onSelected(SelectResults results)
+{
+ for (auto &&result : results) {
+ Log *log = (Log *)result.value.data;
+ log->remove();
+ }
+ setSelectMode(SelectNone);
+ return false;
+}
+
+bool DetailsView::onCanceled()
+{
+ setSelectMode(SelectNone);
+ return false;
+}
+
+void DetailsView::onGroupChanged(int type)
+{
+ if (type & LogGroup::ChangeRemoved) {
+ getPage()->close();
+ m_Group = nullptr;
+ }
+}
+
+void DetailsView::onLogAdded(Log *log)
+{
+ insertLogDetailItem(log);
+}
+
+void DetailsView::onLogRemoved(LogDetailItem *logItem)
+{
+ onItemRemove(logItem);
+ delete logItem;
+}
void LogItem::setUpdateCallback()
{
- m_Group->setChangeCallback([this](int type){
+ m_Group->addChangeCallback([this](int type){
if (type & LogGroup::ChangeRemoved) {
if (m_OnDelete) {
m_OnDelete(this);
if (m_Group) {
m_Group->removeLog(this);
}
+ if (m_OnRemoved) {
+ m_OnRemoved();
+ }
contacts_record_destroy(m_LogRecord, true);
if (m_ContactRecord) {
contacts_record_destroy(m_ContactRecord, true);
}
}
+void Log::setRemoveCallback(RemoveCallback callback)
+{
+ m_OnRemoved = std::move(callback);
+}
+
+void Log::unsetRemoveCallback()
+{
+ m_OnRemoved = nullptr;
+}
+
const char *Log::getName() const
{
char *name = nullptr;
setChangedType(ChangeCount);
m_LogList.push_back(log);
log->setLogGroup(this);
+ if (m_OnLogAdded) {
+ m_OnLogAdded(log);
+ }
}
void LogGroup::removeLog(Log *log)
}
}
-void LogGroup::setChangeCallback(ChangeCallback callback)
+LogGroup::ChangeCbHandle LogGroup::addChangeCallback(ChangeCallback callback)
{
- m_ChangeCallback = std::move(callback);
+ m_ChangeCbs.push_back(std::move(callback));
+ return --m_ChangeCbs.cend();
}
-void LogGroup::unsetChangeCallback()
+void LogGroup::removeChangeCallback(ChangeCbHandle handle)
{
- m_ChangeCallback = nullptr;
+ m_ChangeCbs.erase(handle);
}
void LogGroup::onChange()
{
- if (m_ChangeCallback) {
+ if (!m_ChangeCbs.empty()) {
if (m_ChangedType != ChangeNone) {
if (m_LogList.empty()) {
m_ChangedType = ChangeRemoved;
}
-
- m_ChangeCallback(m_ChangedType);
+ for (auto &changeCb : m_ChangeCbs) {
+ changeCb(m_ChangedType);
+ }
m_ChangedType = ChangeNone;
}
}
void LogGroup::setChangedType(int type)
{
- if (m_ChangeCallback) {
+ if (!m_ChangeCbs.empty()) {
m_ChangedType |= type;
}
}
+
+void LogGroup::setLogAddCallback(LogAddCallback callback)
+{
+ m_OnLogAdded = std::move(callback);
+}
+
+void LogGroup::unsetLogAddCallback()
+{
+ m_OnLogAdded = nullptr;
+}