void App::exit()
{
+ // TODO: Temporary solution
+ terminate();
+/*
if (m_NeedToCloseApp)
terminate(); // Close app completely
else if (m_pWindow)
m_pWindow->lower(); // Minimize window
+*/
}
void App::updateCharacterOrientation()
Window &App::getWindow()
{
- if (!m_pWindow)
- {
+ if (!m_pWindow) {
m_pWindow = new StandardWindow;
m_pWindow->show();
}
/**
* @brief A constructor of ListView object based on outside parent object.
* @param[in] parent an object responsible for automatic removing of ListView instance.
+ * @param[in] parent circle surface
*/
- ListView(Evas_Object *parent);
+ ListView(Evas_Object *parent, Eext_Circle_Surface *parentCircleSurface = nullptr);
virtual ~ListView();
/**
static void notifyListener(void *data, Evas_Object *obj, void *event_info, ListenerMethod method);
private:
- void createListView(Evas_Object *parent);
+ void createListView(Evas_Object *parent, Eext_Circle_Surface *parentCircleSurface);
static void on_item_selected_cb(void *data, Evas_Object *obj, void *event_info);
static void on_realized_cb(void *data, Evas_Object *obj, void *event_info);
IListViewListener *m_pListener;
bool m_CheckMode;
CmpFunc m_CmpFunc;
+ Evas_Object *m_pCircleGenlist;
};
/**
Evas_Object *getWinEvasObject() const override;
Evas_Object *getConformEvasObject() const override;
Evas_Object *getHostEvasObject() const override;
+ Eext_Circle_Surface *getCircleSurface() const override;
void setContent(Evas_Object *content) override;
void getScreenSize(int *x, int *y, int *w, int *h) const override;
int getRotation() const override;
private:
Evas_Object *m_pConform;
Evas_Object *m_pBg;
+ Eext_Circle_Surface *m_pCircleSurface;
};
}
virtual Evas_Object *getWinEvasObject() const = 0;
virtual Evas_Object *getConformEvasObject() const = 0;
virtual Evas_Object *getHostEvasObject() const = 0;
+ virtual Eext_Circle_Surface *getCircleSurface() const = 0;
virtual void setContent(Evas_Object *content) = 0;
virtual void getScreenSize(int *x, int *y, int *w, int *h) const = 0;
virtual int getRotation() const = 0;
* limitations under the License.
*/
-#include <GroupListViewItem.h>
+#include "GroupListViewItem.h"
using namespace Msg;
std::string GroupListViewItem::getText(ListItem &item, const char *part)
{
if (!strcmp(part, "elm.text"))
- return m_TitleText;
+ return msg(m_TitleText);
return "";
}
#include <assert.h>
#include <string.h>
+#include <efl_extension.h>
+
using namespace Msg;
namespace
}
// ListView:
-ListView::ListView(Evas_Object *parent)
+ListView::ListView(Evas_Object *parent, Eext_Circle_Surface *parentCircleSurface)
: View()
, m_pListener(nullptr)
, m_CheckMode(false)
, m_CmpFunc()
+ , m_pCircleGenlist(nullptr)
{
- createListView(parent);
+ createListView(parent, parentCircleSurface);
}
ListView::~ListView()
m_pListener = listener;
}
-void ListView::createListView(Evas_Object *parent)
+void ListView::createListView(Evas_Object *parent, Eext_Circle_Surface *parentCircleSurface)
{
setEo(elm_genlist_add(parent));
evas_object_smart_callback_add(getEo(), "realized", ListView::on_realized_cb, this);
evas_object_smart_callback_add(getEo(), "unrealized", ListView::on_unrealized_cb, this);
evas_object_smart_callback_add(getEo(), "longpressed", ListView::on_longpressed_cb, this);
+
+ if (parentCircleSurface) {
+ // Default settings:
+ m_pCircleGenlist = eext_circle_object_genlist_add(getEo(), parentCircleSurface);
+ if (m_pCircleGenlist) {
+ eext_circle_object_genlist_scroller_policy_set(m_pCircleGenlist, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
+ eext_rotary_object_event_activated_set(m_pCircleGenlist, true);
+ }
+ }
}
bool ListView::appendItem(ListItem &listItem, ListItem *parent)
{
for (ListItem *item: getItems())
{
- item->setCheckedState(check, false);
+ if (item->isCheckable())
+ item->setCheckedState(check, false);
}
if (updateFullItem)
else
for (ListItem *item: getRealizedItems())
{
- item->updateFields(item->getCheckPart(*item), ELM_GENLIST_ITEM_FIELD_ALL);
+ if (item->isCheckable())
+ item->updateFields(item->getCheckPart(*item), ELM_GENLIST_ITEM_FIELD_ALL);
}
}
}
NaviFrameView::NaviFrameView(View &parent)
- : View()
- , m_TransitionStatus(false)
+ : NaviFrameView(parent.getEo())
{
- create(parent.getEo());
}
NaviFrameView::~NaviFrameView()
// TODO: Move functionality for gets TransitionStatus to EFL (elm_naviframe) side.
return m_TransitionStatus;
}
+
: Window()
, m_pConform(nullptr)
, m_pBg(nullptr)
+ , m_pCircleSurface(nullptr)
{
// Window:
setEo(elm_win_add(nullptr, PACKAGE_NAME, ELM_WIN_BASIC));
elm_win_resize_object_add(getEo(), m_pConform);
evas_object_show(m_pConform);
+ m_pCircleSurface = eext_circle_surface_conformant_add(m_pConform);
+
// Bg:
m_pBg = elm_bg_add(m_pConform);
evas_object_size_hint_weight_set(m_pBg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
return m_pConform;
}
+Eext_Circle_Surface *StandardWindow::getCircleSurface() const
+{
+ return m_pCircleSurface;
+}
+
void StandardWindow::setContent(Evas_Object *content)
{
elm_object_content_set(m_pConform, content);
#include "SelectButton.h"
#include "MoreOption.h"
#include "CtxPopup.h"
+#include "ThreadList.h"
namespace Msg {
class MsgThreadFrame
- : public FrameController {
+ : public FrameController
+ , private IThreadListListener {
public:
MsgThreadFrame(NaviFrameController &parent);
void onNewMessageClicked(MoreOption &obj);
void onDeleteClicked(MoreOption &obj);
+ // IThreadListListener:
+ void onListItemSelected(ThreadId id) override;
+ void onThreadListChanged() override;
+ void onThreadListItemChecked() override;
+ void onComposeButtonClicked() override;
+ void onContactsButtonClicked() override;
+
private:
DefaultLayout *m_pLayout;
MoreOption *m_pMoreOption;
BottomButton *m_pDeleteButton;
SelectButton *m_pSelectButton;
+ ThreadList *m_pThreadList;
Mode m_Mode;
};
}
--- /dev/null
+/*
+ * Copyright 2016 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 ThreadList_h_
+#define ThreadList_h_
+
+#include "ListView.h"
+#include "MsgStorage.h"
+#include "ContactManager.h"
+#include "SystemSettingsManager.h"
+#include "ThreadComposeListViewItem.h"
+#include "MsgTypes.h"
+#include <set>
+
+namespace Msg {
+ class IThreadListListener;
+ class ThreadListItem;
+ class App;
+
+ class ThreadList
+ : public ListView
+ , private IMsgStorageListener
+ , private IListViewListener
+ , private IContactManagerListener
+ , private ISystemSettingsManager
+ , private IThreadComposeListViewItemListener {
+
+ public:
+ ThreadList(Evas_Object *parent);
+ virtual ~ThreadList();
+
+ void setListener(IThreadListListener *l);
+ void setDeleteMode(bool value);
+ bool isDeleteModeEnabled() const;
+ void deleteSelectedItems();
+ int getThreadsCheckedCount() const;
+
+ private:
+ // IMsgStorageListener:
+ void onMsgStorageThreadUpdate(const ThreadId &threadId) override;
+ void onMsgStorageThreadInsert(const ThreadId &threadId) override;
+ void onMsgStorageThreadDelete(const ThreadId &threadId) override;
+
+ // IContactManagerListener:
+ void onContactChanged() override;
+
+ // IListViewListener:
+ void onListItemSelected(ListItem &listItem) override;
+ void onListItemChecked(ListItem &listItem) override;
+
+ // ISystemSettingsManager:
+ void onTimeFormatChanged() override;
+ void onLanguageChanged() override;
+
+ // IThreadComposeListViewItemListener:
+ void onComposeButtonClicked() override;
+ void onContactsButtonClicked() override;
+
+ private:
+ void checkHandler(ThreadListItem &item);
+ void fillList();
+ void deleteItems();
+ void updateItems(const MsgIdList &idList);
+ void updateItems();
+ void updateItem(ThreadListItem &item);
+ void insertItem(ThreadId id);
+ void navigateTo(ThreadListItem &item);
+ ThreadListItem *getItem(ThreadId id) const;
+ bool isAllThreadListItemChecked() const;
+ void updateSelectAllItem();
+ std::set<ThreadId> getThreadIdSet(const MsgIdList &idList);
+ static int cmpFunc(const ListItem &item1, const ListItem &item2);
+
+ private:
+ IThreadListListener *m_pListener;
+ App &m_App;
+ bool m_DeleteMode;
+ ThreadComposeListViewItem *m_ComposeItem;
+ };
+
+ class IThreadListListener {
+ public:
+ virtual ~IThreadListListener() {}
+ virtual void onListItemSelected(ThreadId id) {};
+ virtual void onThreadListChanged() {}
+ virtual void onThreadListItemChecked() {}
+ virtual void onComposeButtonClicked() {};
+ virtual void onContactsButtonClicked() {};
+ };
+}
+
+#endif // ThreadList_h_
--- /dev/null
+/*
+ * Copyright 2016 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 ThreadListItem_h_
+#define ThreadListItem_h_
+
+#include "MsgThreadItem.h"
+#include "ContactPersonNumber.h"
+#include "ThreadListViewItem.h"
+
+namespace Msg {
+ class ThreadListItem
+ : public ThreadListViewItem {
+ public:
+ ThreadListItem(const MsgThreadItem &threadItem);
+ virtual ~ThreadListItem();
+
+ ThreadId getThreadId() const;
+ void update(const MsgThreadItem &threadItem, bool updateUi);
+ void updateName(const MsgAddressList &addressList);
+ void updateName(const MsgThreadItem &threadItem);
+ void updateName(const MsgAddress &address, int addressesCount);
+ void updateName(const ContactAddress &address, int addressesCount);
+ void updateName(const std::string &address, int addressesCount);
+ void updateTime(time_t time);
+ void updateTime();
+ void updateMessage(const MsgThreadItem &threadItem);
+ void updateMessage(const std::string &msg);
+ time_t getRawTime() const;
+
+ private:
+ // ThreadListViewItem:
+ std::string getName() override;
+ std::string getMessage() override;
+ std::string getTime() override;
+ std::string getUnreadCount() override;
+
+ private:
+ ThreadId m_ThreadId;
+ std::string m_UnreadCount;
+ std::string m_Name;
+ std::string m_Message;
+ std::string m_Time;
+ time_t m_RawTime;
+ };
+}
+
+#endif // ThreadListItem_h_
, m_pMoreOption(nullptr)
, m_pDeleteButton(nullptr)
, m_pSelectButton(nullptr)
+ , m_pThreadList(nullptr)
, m_Mode(InitMode)
{
MSG_LOG("");
prepareMainLayout();
prepareMoreOption();
prepareDeleteViews();
+ prepareThreadList();
setMode(NormalMode);
}
m_pLayout->showMoreOption(true);
m_pLayout->showBottomButton(false);
m_pSelectButton->showButton(false);
+ m_pThreadList->setDeleteMode(false);
}
void MsgThreadFrame::setDeleteMode(bool value)
MSG_LOG("");
m_Mode = DeleteMode;
m_pLayout->showBottomButton(true);
- m_pSelectButton->showButton(true);
m_pLayout->showMoreOption(false);
+ m_pSelectButton->showButton(true);
+ m_pThreadList->setDeleteMode(true);
}
void MsgThreadFrame::prepareThreadList()
{
-
+ if (!m_pThreadList) {
+ m_pThreadList = new ThreadList(*m_pLayout);
+ m_pThreadList->setListener(this);
+ m_pLayout->setContent(*m_pThreadList);
+ m_pLayout->showContent(true);
+ }
}
void MsgThreadFrame::prepareMainLayout()
setMode(DeleteMode);
}
+void MsgThreadFrame::onListItemSelected(ThreadId id)
+{
+ MSG_LOG("");
+}
+
+void MsgThreadFrame::onThreadListChanged()
+{
+ MSG_LOG("");
+}
+
+void MsgThreadFrame::onThreadListItemChecked()
+{
+ MSG_LOG("");
+}
+
+void MsgThreadFrame::onComposeButtonClicked()
+{
+ MSG_LOG("");
+}
+
+void MsgThreadFrame::onContactsButtonClicked()
+{
+ MSG_LOG("");
+}
--- /dev/null
+/*
+ * Copyright 2016 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 "ThreadList.h"
+#include "ThreadListItem.h"
+#include "PaddingListViewItem.h"
+#include "ThreadComposeListViewItem.h"
+#include "NoContentListViewItem.h"
+#include "GroupListViewItem.h"
+#include "MsgEngine.h"
+#include "App.h"
+
+using namespace Msg;
+
+namespace {
+ bool isThreadItem(const ListItem &item)
+ {
+ return dynamic_cast<const ThreadListItem*>(&item) != nullptr;
+ }
+}
+
+ThreadList::ThreadList(Evas_Object *parent)
+ : ListView(parent, App::getInst().getWindow().getCircleSurface())
+ , m_pListener(nullptr)
+ , m_App(App::getInst())
+ , m_DeleteMode(false)
+ , m_ComposeItem(nullptr)
+{
+ ListView::setListener(this);
+ ListView::setHomogeneous(false);
+ ListView::setMultiSelection(false);
+ ListView::setMode(ELM_LIST_COMPRESS);
+ ListView::setCmpFunc(cmpFunc);
+
+ m_App.getMsgEngine().getStorage().addListener(*this);
+ m_App.getContactManager().addListener(*this);
+ m_App.getSysSettingsManager().addListener(*this);
+ fillList();
+}
+
+ThreadList::~ThreadList()
+{
+ m_App.getMsgEngine().getStorage().removeListener(*this);
+ m_App.getContactManager().removeListener(*this);
+ m_App.getSysSettingsManager().removeListener(*this);
+}
+
+void ThreadList::setListener(IThreadListListener *l)
+{
+ m_pListener = l;
+}
+
+void ThreadList::setDeleteMode(bool value)
+{
+ if (m_DeleteMode != value) {
+ m_DeleteMode = value;
+ setCheckMode(value);
+ ThreadListViewItem::resetCheckMode(*this);
+ checkAllItems(false, true);
+ if (m_ComposeItem)
+ m_ComposeItem->disabled(value);
+ }
+}
+
+bool ThreadList::isDeleteModeEnabled() const
+{
+ return m_DeleteMode;
+}
+
+void ThreadList::deleteSelectedItems()
+{
+ auto items = getItems<ThreadListItem>();
+ for (ThreadListItem *it : items) {
+ if (it->getCheckedState())
+ m_App.getMsgEngine().getStorage().deleteThread(it->getThreadId());
+ }
+}
+
+int ThreadList::getThreadsCheckedCount() const
+{
+ auto items = getItems<ThreadListItem>();
+ int count = 0;
+ for (ThreadListItem *item : items) {
+ if (item->isCheckable() && item->getCheckedState())
+ ++count;
+ }
+ return count;
+}
+
+bool ThreadList::isAllThreadListItemChecked() const
+{
+ // Simple impl. but not fast:
+ auto items = getItems<ThreadListItem>();
+ for (ThreadListItem *item : items) {
+ if (item->isCheckable() && !item->getCheckedState())
+ return false;
+ }
+ return true;
+}
+
+void ThreadList::updateSelectAllItem()
+{
+ if (!m_DeleteMode)
+ return;
+
+ // bool allChecked = isAllThreadListItemChecked();
+}
+
+void ThreadList::checkHandler(ThreadListItem &item)
+{
+ ThreadId threadId = item.getThreadId();
+ MSG_LOG("Checked (id : state) = ", threadId, ":", item.getCheckedState());
+ updateSelectAllItem();
+ if (m_pListener)
+ m_pListener->onThreadListItemChecked();
+}
+
+int ThreadList::cmpFunc(const ListItem &item1, const ListItem &item2)
+{
+ bool isTh1 = isThreadItem(item1);
+ bool isTh2 = isThreadItem(item2);
+
+ if (!isTh1 && !isTh2)
+ return 0;
+
+ if (!isTh1 || !isTh2)
+ return !isTh1;
+
+ auto &threadItem1 = static_cast<const ThreadListItem&>(item1);
+ auto &threadItem2 = static_cast<const ThreadListItem&>(item2);
+ return threadItem2.getRawTime() - threadItem1.getRawTime();
+}
+
+void ThreadList::insertItem(ThreadId id)
+{
+ MsgThreadItemRef threadItem = m_App.getMsgEngine().getStorage().getThread(id);
+ if (threadItem) {
+ auto newItem = new ThreadListItem(*threadItem);
+ ListView::sortedInsertItem(*newItem);
+ navigateTo(*newItem);
+ }
+}
+
+ThreadListItem *ThreadList::getItem(ThreadId id) const
+{
+ auto items = ListView::getItems<ThreadListItem>();
+ for (ThreadListItem *item : items) {
+ if (item->getThreadId() == id)
+ return item;
+ }
+ return nullptr;
+}
+
+void ThreadList::fillList()
+{
+ // Top padding:
+ ListView::appendItem(*new PaddingListViewItem);
+
+ // Compose Item:
+ m_ComposeItem = new ThreadComposeListViewItem;
+ m_ComposeItem->setListener(this);
+ ListView::appendItem(*m_ComposeItem);
+
+ // Group item:
+ ListView::appendItem(*new GroupListViewItem("IDS_MSG_HEADER_MESSAGES"));
+
+ // Thread list:
+ MsgThreadListRef msgThreadList = m_App.getMsgEngine().getStorage().getThreadList();
+ if (msgThreadList) {
+ int length = msgThreadList->getLength();
+
+ for (int i = 0; i < length; ++i) {
+ const MsgThreadItem &msgThreadItem = msgThreadList->at(i);
+ ListView::appendItem(*new ThreadListItem(msgThreadItem));
+ }
+ }
+
+ // Bottom padding:
+ ListView::appendItem(*new PaddingListViewItem);
+}
+
+void ThreadList::deleteItems()
+{
+ MsgThreadListRef msgThreadList = m_App.getMsgEngine().getStorage().getThreadList();
+ if (!msgThreadList)
+ return;
+
+ std::set<ThreadId> threadIdSet;
+ int length = msgThreadList->getLength();
+ for (int i = 0; i < length; ++i) {
+ const MsgThreadItem &msgThreadItem = msgThreadList->at(i);
+ threadIdSet.insert(msgThreadItem.getId());
+ }
+
+ auto items = ListView::getItems<ThreadListItem>();
+
+ for (ThreadListItem *item : items) {
+ if (threadIdSet.count(item->getThreadId()) == 0)
+ ListView::deleteItem(*item);
+ }
+
+ updateSelectAllItem();
+}
+
+void ThreadList::navigateTo(ThreadListItem &item)
+{
+ ListView::showItem(item, ELM_GENLIST_ITEM_SCROLLTO_TOP);
+}
+
+void ThreadList::updateItems(const MsgIdList &idList)
+{
+ auto threadIdSet = getThreadIdSet(idList);
+ auto threadItems = getItems<ThreadListItem>();
+
+ for (ThreadListItem *item: threadItems) {
+ if (threadIdSet.count(item->getThreadId()))
+ updateItem(*item);
+ }
+}
+
+void ThreadList::updateItems()
+{
+ auto items = getItems<ThreadListItem>();
+ for (ThreadListItem *item: items) {
+ updateItem(*item);
+ }
+}
+
+void ThreadList::updateItem(ThreadListItem &item)
+{
+ MsgThreadItemRef msgThread = m_App.getMsgEngine().getStorage().getThread(item.getThreadId());
+ if (!msgThread) {
+ MSG_LOG_ERROR("msgThread is null");
+ return;
+ }
+
+ auto *next = getNextItem<ThreadListItem>(item);
+ auto *prev = getPrevItem<ThreadListItem>(item);
+ time_t threadTime = msgThread->getTime();
+
+ if ((next && threadTime < next->getRawTime()) ||
+ (prev && threadTime > prev->getRawTime())) {
+ auto newItem = new ThreadListItem(*msgThread);
+ newItem->setCheckedState(item.getCheckedState(), false);
+ item.destroy();
+ ListView::sortedInsertItem(*newItem);
+ navigateTo(*newItem);
+ } else {
+ item.update(*msgThread, true);
+ navigateTo(item);
+ }
+}
+
+std::set<ThreadId> ThreadList::getThreadIdSet(const MsgIdList &idList)
+{
+ std::set<ThreadId> res;
+ for (MsgId msgId : idList) {
+ ThreadId threadId = m_App.getMsgEngine().getStorage().getThreadId(msgId);
+ if (threadId.isValid())
+ res.insert(threadId);
+ }
+ return res;
+}
+
+void ThreadList::onListItemSelected(ListItem &listItem)
+{
+ MSG_LOG("");
+ auto *it = dynamic_cast<ThreadListItem*>(&listItem);
+ if (it && m_pListener)
+ m_pListener->onListItemSelected(it->getThreadId());
+}
+
+void ThreadList::onListItemChecked(ListItem &listItem)
+{
+ MSG_LOG("");
+ if (auto *it = dynamic_cast<ThreadListItem*>(&listItem))
+ checkHandler(*it);
+}
+
+void ThreadList::onMsgStorageThreadUpdate(const ThreadId &threadId)
+{
+ MSG_LOG("");
+ auto* item = getItem(threadId);
+ if (item)
+ updateItem(*item);
+}
+
+void ThreadList::onMsgStorageThreadInsert(const ThreadId &threadId)
+{
+ MSG_LOG("");
+ insertItem(threadId);
+ updateSelectAllItem();
+ if (m_pListener)
+ m_pListener->onThreadListChanged();
+}
+
+void ThreadList::onMsgStorageThreadDelete(const ThreadId &threadId)
+{
+ MSG_LOG("");
+ auto* thread = getItem(threadId);
+ if (thread) {
+ ListView::deleteItem(*thread);
+ updateSelectAllItem();
+ }
+
+ if (m_pListener)
+ m_pListener->onThreadListChanged();
+}
+
+void ThreadList::onContactChanged()
+{
+ MSG_LOG("");
+ updateItems();
+}
+
+void ThreadList::onTimeFormatChanged()
+{
+ MSG_LOG("");
+ auto items = ListView::getItems<ThreadListItem>();
+ for (ThreadListItem *item : items) {
+ item->updateTime();
+ }
+
+ ListView::updateRealizedItems();
+}
+
+void ThreadList::onLanguageChanged()
+{
+ MSG_LOG("");
+ updateItems();
+}
+
+void ThreadList::onComposeButtonClicked()
+{
+ MSG_LOG("");
+ if (m_pListener)
+ m_pListener->onComposeButtonClicked();
+}
+
+void ThreadList::onContactsButtonClicked()
+{
+ MSG_LOG("");
+ if (m_pListener)
+ m_pListener->onContactsButtonClicked();
+}
--- /dev/null
+/*
+ * Copyright 2016 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 "ThreadListItem.h"
+#include "ListView.h"
+#include "Logger.h"
+#include "PathUtils.h"
+#include "MsgEngine.h"
+#include "App.h"
+#include "MsgThreadItem.h"
+#include "LangUtils.h"
+#include "TimeUtils.h"
+#include "ContactManager.h"
+
+using namespace Msg;
+
+ThreadListItem::ThreadListItem(const MsgThreadItem &threadItem)
+ : ThreadListViewItem()
+ , m_ThreadId()
+ , m_RawTime()
+{
+ update(threadItem, false);
+}
+
+ThreadListItem::~ThreadListItem()
+{
+}
+
+void ThreadListItem::update(const MsgThreadItem &threadItem, bool updateUi)
+{
+ m_ThreadId = threadItem.getId();
+ State state = NormalState;
+
+ MsgConversationListRef convList = App::getInst().getMsgEngine().getStorage().getConversationList(m_ThreadId);
+ if (convList && convList->getLength() > 0) {
+ MsgConversationItem &item = convList->at(convList->getLength() - 1);
+
+ Message::NetworkStatus status = item.getNetworkStatus();
+ if (status == Message::NS_Sending) {
+ state = StatusState;
+ } else if (status == Message::NS_Send_Fail) {
+ state = StatusState;
+ } else if (item.isDraft()) {
+ state = StatusState;
+ } else if (!item.isRead()) {
+ int count = threadItem.getUnreadCount();
+ if (count > 0) {
+ state = IconState;
+ m_UnreadCount = std::to_string(count);
+ }
+ }
+ }
+
+ setState(state, false);
+ updateMessage(threadItem);
+ updateName(threadItem);
+ updateTime(threadItem.getTime());
+
+ if (updateUi)
+ ListItem::update();
+}
+
+void ThreadListItem::updateMessage(const MsgThreadItem &threadItem)
+{
+ updateMessage(threadItem.getLastMessage());
+}
+
+void ThreadListItem::updateMessage(const std::string &msg)
+{
+ m_Message = msg;
+}
+
+void ThreadListItem::updateName(const MsgThreadItem &threadItem)
+{
+ const MsgAddressListRef addressList = App::getInst().getMsgEngine().getStorage().getAddressList(threadItem.getId());
+ if (addressList)
+ updateName(*addressList);
+}
+
+void ThreadListItem::updateName(const MsgAddressList &addressList)
+{
+ int countContact = addressList.getLength();
+ if (countContact <= 0) {
+ MSG_LOG_WARN("Msg address list is empty");
+ return;
+ }
+
+ const MsgAddress &addr = addressList[0];
+
+ if (countContact > 1) {
+ updateName(addr, countContact);
+ } else if (countContact == 1) {
+ updateName(addr, countContact);
+ }
+}
+
+void ThreadListItem::updateName(const MsgAddress &address, int addressesCount)
+{
+ ContactAddressRef contactAddress = App::getInst().getContactManager().getContactAddress(address.getAddress());
+ if (contactAddress)
+ updateName(*contactAddress, addressesCount);
+ else
+ updateName(address.getAddress(), addressesCount);
+}
+
+void ThreadListItem::updateName(const ContactAddress &address, int addressesCount)
+{
+ std::string dispName = address.getDispName();
+ if (dispName.empty())
+ dispName = address.getAddress();
+ updateName(dispName, addressesCount);
+}
+
+void ThreadListItem::updateName(const std::string &address, int addressesCount)
+{
+ m_Name = address;
+ --addressesCount;
+ if (addressesCount > 0)
+ m_Name += " +" + std::to_string(addressesCount);
+}
+
+void ThreadListItem::updateTime(time_t time)
+{
+ m_RawTime = time;
+ m_Time = TimeUtils::makeThreadTimeString(time);
+}
+
+void ThreadListItem::updateTime()
+{
+ m_Time = TimeUtils::makeThreadTimeString(m_RawTime);
+}
+
+std::string ThreadListItem::getName()
+{
+ return m_Name;
+}
+
+std::string ThreadListItem::getMessage()
+{
+ return m_Message;
+}
+
+std::string ThreadListItem::getTime()
+{
+ return m_Time;
+}
+
+time_t ThreadListItem::getRawTime() const
+{
+ return m_RawTime;
+}
+
+ThreadId ThreadListItem::getThreadId() const
+{
+ return m_ThreadId;
+}
+
+std::string ThreadListItem::getUnreadCount()
+{
+ return m_UnreadCount;
+}
+
#include <string>
namespace Msg {
+
+ class IThreadComposeListViewItemListener;
+
class ThreadComposeListViewItem
: public ListItem {
ThreadComposeListViewItem();
virtual ~ThreadComposeListViewItem();
+ void setListener(IThreadComposeListViewItemListener *l);
+
protected:
- virtual void onComposeButtonClicked(Evas_Object *obj, void *event) {};
- virtual void onContactsButtonClicked(Evas_Object *obj, void *event) {};
void onAttached(ViewItem &item) override;
private:
Evas_Object *makeButton(const std::string& iconName);
Evas_Object *getContent(ListItem &item, const char *part) override;
+
+ private:
+ IThreadComposeListViewItemListener *m_pListener;
+ };
+
+ class IThreadComposeListViewItemListener {
+ public:
+ virtual ~IThreadComposeListViewItemListener() {};
+ virtual void onComposeButtonClicked() {};
+ virtual void onContactsButtonClicked() {};
};
}
public:
enum State {
NormalState,
- IconState
+ IconState,
+ StatusState
};
public:
- ThreadListViewItem(Elm_Genlist_Item_Type type = ELM_GENLIST_ITEM_NONE);
+ ThreadListViewItem();
virtual ~ThreadListViewItem();
void setState(State state, bool updateUi);
static void resetCheckMode(ListView &listView);
protected:
- virtual std::string getName();
- virtual std::string getMessage();
- virtual std::string getTime();
- virtual std::string getUnreadCount();
+ virtual std::string getName() = 0;
+ virtual std::string getMessage() = 0;
+ virtual std::string getTime() = 0;
+ virtual std::string getUnreadCount() = 0;
using ListItem::getState;
Evas_Object *makeUnreadIcon(const std::string &text) const;
ThreadComposeListViewItem::ThreadComposeListViewItem()
: ListItem(ListItemStyle::create("compose_threadlist_item"))
+ , m_pListener(nullptr)
{
}
Evas_Object *ThreadComposeListViewItem::getComposeButton()
{
Evas_Object *btn = makeButton("compose_icon");
- evas_object_smart_callback_add(btn, "clicked", makeCbFirst(&ThreadComposeListViewItem::onComposeButtonClicked), this);
+ evas_object_smart_callback_add(
+ btn, "clicked",
+ [](void *data, Evas_Object *obj, void *event)
+ {
+ auto *self = static_cast<ThreadComposeListViewItem*>(data);
+ if (self && self->m_pListener)
+ self->m_pListener->onComposeButtonClicked();
+ },
+ this);
return btn;
}
Evas_Object *ThreadComposeListViewItem::getContactsButton()
{
Evas_Object *btn = makeButton("contacts_icon");
- evas_object_smart_callback_add(btn, "clicked", makeCbFirst(&ThreadComposeListViewItem::onContactsButtonClicked), this);
+ evas_object_smart_callback_add(
+ btn, "clicked",
+ [](void *data, Evas_Object *obj, void *event)
+ {
+ auto *self = static_cast<ThreadComposeListViewItem*>(data);
+ if (self && self->m_pListener)
+ self->m_pListener->onContactsButtonClicked();
+ },
+ this);
return btn;
}
return button;
}
+
+void ThreadComposeListViewItem::setListener(IThreadComposeListViewItemListener *l)
+{
+ m_pListener = l;
+}
+
using namespace Msg;
namespace {
- ListItemStyleRef threadItemStyle = ListItemStyle::create("msg_thread");
-
const char *namePart = "elm.text";
const char *messagePart = "elm.text.1";
const char *timePart = "elm.text.2";
const char *iconPart = "elm.icon";
}
-ThreadListViewItem::ThreadListViewItem(Elm_Genlist_Item_Type type)
- : ListItem(threadItemStyle, type)
+ThreadListViewItem::ThreadListViewItem()
+ : ListItem(ListItemStyle::create("msg_thread"), ELM_GENLIST_ITEM_NONE)
, m_State(NormalState)
{
}
return icon;
}
-std::string ThreadListViewItem::getName()
-{
- return "NAME"; // only for test
-}
-
-std::string ThreadListViewItem::getMessage()
-{
- return "Message"; // only for test
-}
-
-std::string ThreadListViewItem::getTime()
-{
- return "17.45"; // only for test
-}
-
-std::string ThreadListViewItem::getUnreadCount()
-{
- return ""; // only for test
-}
-
void ThreadListViewItem::resetCheckMode(ListView &listView)
{
+ // TODO: impl if needed.
}