min: 0 BUBBLE_INFO_TEXT_HEIGHT;
max: -1 BUBBLE_INFO_TEXT_HEIGHT;
rel1.to_y: "info.status";
- rel1.to_x: "info.pad";
rel1.relative: 0.0 1.0;
rel2.to_x: "info.thumb.pad";
rel2.relative: 0.0 1.0;
align: 0.0 0.0;
rel1.to_x: "info.thumb.pad";
rel1.relative: 1.0 1.0;
- rel2.to_x: "info.pad";
+ rel2.to_x: "";
rel2.relative: 1.0 0.0;
text.style: "entry_bubble_receive_textblock_style";
}
* @retval Returns true if all sucess, false otherwise
*/
static bool remove(const std::string &path, bool removeCurrentDir = true);
+
+ /**
+ * @brief Read text file
+ * @param[in] file path name
+ * @retval Returns text content
+ */
+ static std::string readTextFile(const std::string &path);
};
}
#include <dirent.h>
#include <string.h>
#include <ctype.h>
+#include <fstream>
using namespace Msg;
return res;
}
+
+std::string FileUtils::readTextFile(const std::string &path)
+{
+ std::string text;
+ std::ifstream fs(path, std::ifstream::in | std::ifstream::binary);
+ if(fs.is_open())
+ fs >> text;
+ return text;
+}
ContextPopup &PopupManager::getCtxPopup()
{
- if(!m_pCtxPopup)
- {
- m_pCtxPopup = new ContextPopup(*this);
- eext_object_event_callback_add(*m_pCtxPopup, EEXT_CALLBACK_BACK, SMART_CALLBACK(PopupManager, onHwBackButtonCtxPopupClicked), this);
- }
-
+ reset();
+ m_pCtxPopup = new ContextPopup(*this);
+ eext_object_event_callback_add(*m_pCtxPopup, EEXT_CALLBACK_BACK, SMART_CALLBACK(PopupManager, onHwBackButtonCtxPopupClicked), this);
return *m_pCtxPopup;
}
void showPopup();
protected:
- virtual Evas_Object *getBubble();
+ virtual Evas_Object *getBubbleContent();
virtual Evas_Object *getThumbnail();
virtual std::string getText();
virtual std::string getTime();
private:
ConvListViewItem::ConvItemType getConvItemType(MsgConversationItem &item);
+ void prepareBubble(MsgConversationItem &item);
// Create Popup when message is clicked
void showMainCtxPopup();
void onFailedResendButtonClicked(Popup &popup, int buttonId);
void onPopupDel(Evas_Object *popup, void *eventInfo);
- void onBubbleResized(Evas_Object *obj, void *data);
-
private:
App &m_App;
MsgId m_MsgId;
bool m_IsDraft;
Message::Status m_Status;
Message::Type m_Type;
-
- //Fixme: temporary fix caused by genlist resize issue
- Evas_Coord m_Width;
- Evas_Coord m_Height;
+ BubbleEntity m_BubbleEntity;
};
}
#include "ConvListItem.h"
#include "MsgConversationItem.h"
-#include "BubbleView.h"
#include "ListView.h"
#include "CallbackAssist.h"
#include "ThumbnailMaker.h"
, m_IsDraft(item.isDraft())
, m_Status(item.getStatus())
, m_Type(item.getType())
- , m_Width(0)
- , m_Height(0)
+ , m_BubbleEntity()
{
+ prepareBubble(item);
}
ConvListItem::~ConvListItem()
return type;
}
-void ConvListItem::onBubbleResized(Evas_Object *obj, void *data)
+void ConvListItem::prepareBubble(MsgConversationItem &item)
{
- MSG_LOG("");
- Evas_Coord w,h;
- evas_object_geometry_get(obj, nullptr, nullptr, &w, &h);
- if(m_Height < h || m_Width < w)
+ if(m_Type == Message::MT_SMS)
+ {
+ m_BubbleEntity.addPart(BubbleEntity::TextPart, item.getText());
+ }
+ else
{
- m_Width = w;
- m_Height = h;
- MSG_LOG("sizes: ", m_Height, " ",m_Width);
- elm_genlist_item_update(this->getElmObjItem());
+ const MsgConvMediaList &list = item.getMediaList();
+ for(int i = 0; i < list.getLength(); i++)
+ {
+ std::string mime = list.at(i).getMime();
+ if(!list.at(i).getThumbPath().empty())
+ //msg service corrupts thumbnail's metadata, so it lost rotation. Use getPath instead getThumbPath until fix
+ m_BubbleEntity.addPart(BubbleEntity::ThumbnailPart, list.at(i).getPath());
+ else if(mime == "text/plain")
+ m_BubbleEntity.addPart(BubbleEntity::TextFilePart, list.at(i).getPath());
+ else if(mime != "application/smil")
+ m_BubbleEntity.addPart(BubbleEntity::TextPart, list.at(i).getName());
+ }
}
}
-Evas_Object *ConvListItem::getBubble()
+Evas_Object *ConvListItem::getBubbleContent()
{
- //TODO: implement getting of multimedia instead dummy content. Split to separate class (or update BubbleView)
- //Only for demo
- Evas_Object *box = elm_box_add(*getOwner());
- evas_object_event_callback_add(box, EVAS_CALLBACK_RESIZE, EVAS_EVENT_CALLBACK(ConvListItem, onBubbleResized), this);
- View::expand(box);
-
- Evas_Object *label = elm_label_add(box);
- elm_label_line_wrap_set(label, ELM_WRAP_MIXED);
- elm_object_part_text_set(label, nullptr, m_MessageText.c_str());
- View::expand(label);
- evas_object_show(label);
- elm_box_pack_end(box, label);
-
- //Dummy image
- Evas_Object *image = elm_image_add(box);
- elm_image_file_set(image, PathUtils::getResourcePath(TEST_IMG_PATH).c_str(), nullptr);
- evas_object_size_hint_min_set(image, 0, 150);
- View::expand(image);
- evas_object_show(image);
- elm_box_pack_end(box, image);
-
- MSG_LOG("sizes: ", m_Height, " ",m_Width);
- if(m_Height > 0 && m_Width > 0)
- {
- evas_object_size_hint_min_set(box, m_Width, m_Height);
- evas_object_size_hint_max_set(box, m_Width, m_Height);
- }
- return box;
+ BubbleView *bubble = new BubbleView(*getOwner());
+ bubble->fill(m_BubbleEntity);
+ return *bubble;
}
Evas_Object *ConvListItem::getThumbnail()
#define BubbleView_h_
#include "View.h"
+#include "MsgTypes.h"
#include <string>
+#include <list>
namespace Msg
{
- class BubbleView
- : public View
+ class BubbleView;
+
+ class BubbleEntity
{
+ friend class BubbleView;
+
public:
- enum Style
+ BubbleEntity();
+ ~BubbleEntity();
+ enum PartType
+ {
+ TextPart, //raw text
+ TextFilePart, //path to text file
+ ThumbnailPart //path to thumbnail image
+ };
+
+ /**
+ * @brief Add new part to bubble entity
+ * @param[in] type Set which type is @value
+ * @param[in] value Resource path or raw text to display
+ */
+ void addPart(PartType type, const std::string &value);
+
+ private:
+ BubbleEntity(BubbleEntity&) = delete;
+ BubbleEntity &operator=(BubbleEntity&) = delete;
+
+ struct BubblePart
{
- Sent,
- Received
+ PartType type;
+ std::string value;
};
+ private:
+ std::list<BubblePart> m_Parts;
+ };
+
+ class BubbleView
+ : public View
+ {
public:
- //TODO: remove BubbleView from project and use Body's viewer instead
- BubbleView(Evas_Object *parent, Style style);
+ BubbleView(Evas_Object *parent);
virtual ~BubbleView();
- void setText(const std::string &text);
- void setTime(const std::string &time);
+ /**
+ * @brief Draw content from @entity
+ * @param[in] entity Filled list of contents
+ */
+ void fill(const BubbleEntity &entity);
private:
void create(Evas_Object *parent);
- const char *getStyle() const;
-
- private:
- Style m_Style;
+ Evas_Object *createTextView(const std::string &text);
+ Evas_Object *createTextFileView(const std::string &path);
+ Evas_Object *createThumbView(const std::string &path);
};
}
virtual ~ConvListViewItem();
protected:
- virtual Evas_Object *getBubble() = 0;
+ virtual Evas_Object *getBubbleContent() = 0;
virtual Evas_Object *getThumbnail() = 0;
virtual std::string getText() = 0;
virtual std::string getTime() = 0;
virtual void onFailedButtonClicked(Evas_Object *obj, void *event_info) = 0;
private:
+ void onBubbleResized(Evas_Object *obj, void *data);
Evas_Object *getButton(bool isEnabled, ConvItemType type);
virtual std::string getText(ListItem &item, const char *part);
virtual Evas_Object *getContent(ListItem &item, const char *part);
virtual const char *getCheckPart(ListItem &item);
+
+ private:
+ //Fixme: temporary fix caused by genlist resize issue
+ Evas_Coord m_BubbleWidth;
+ Evas_Coord m_BubbleHeight;
};
}
*/
#include "BubbleView.h"
+#include "FileUtils.h"
#include <Elementary.h>
using namespace Msg;
-const char *bubbleSentStyle = "sentmessage/custom/sent_style_01";
-const char *bubbleRecvStyle = "readmessage/custom/recv_style_01";
+namespace
+{
+ const int verticalBoxPads = 10;
+ const int horizontalBoxPads = 0;
+ const int maxWidth = 220; //Fixme: set to 340 when apply base_scale: 2.6
+ const char *textStyle = "DEFAULT='font=Tizen:style=Regular font_size=30 wrap=mixed text_class=label'";
+}
-BubbleView::BubbleView(Evas_Object *parent, Style style)
- : m_Style(style)
+BubbleView::BubbleView(Evas_Object *parent)
{
create(parent);
}
}
-const char *BubbleView::getStyle() const
+void BubbleView::create(Evas_Object *parent)
{
- switch(m_Style)
- {
- case Sent:
- return bubbleSentStyle;
- break;
+ Evas_Object *box = elm_box_add(parent);
+ View::expand(box);
+ elm_box_padding_set(box, (int)ELM_SCALE_SIZE(horizontalBoxPads), (int)ELM_SCALE_SIZE(verticalBoxPads));
- case Received:
- return bubbleRecvStyle;
- break;
+ setEo(box);
+}
- default:
- break;
+void BubbleView::fill(const BubbleEntity &entity)
+{
+ for(const BubbleEntity::BubblePart &part : entity.m_Parts)
+ {
+ switch (part.type)
+ {
+ case BubbleEntity::TextPart:
+ elm_box_pack_end(*this, createTextView(part.value));
+ break;
+ case BubbleEntity::TextFilePart:
+ elm_box_pack_end(*this, createTextFileView(part.value));
+ break;
+ case BubbleEntity::ThumbnailPart:
+ elm_box_pack_end(*this, createThumbView(part.value));
+ break;
+ default:
+ break;
+ }
}
-
- return nullptr;
}
-void BubbleView::create(Evas_Object *parent)
+Evas_Object *BubbleView::createTextView(const std::string &text)
{
- Evas_Object *label = elm_label_add(parent);
- setEo(label);
- evas_object_show(label);
- elm_label_line_wrap_set(label, ELM_WRAP_MIXED);
- elm_object_focus_allow_set(label, true);
- elm_object_tree_focus_allow_set(label, true);
- elm_object_style_set(label, getStyle());
- evas_object_color_set(label, rand() % 230, rand() % 230, rand() % 230, 190);
+ //TODO: apply to label the same text style as to textblock (figure out how-to)
+ Evas_Coord ww, hh;
+ Evas_Object *label = elm_label_add(*this);
+ Evas_Object *textBlock = evas_object_textblock_add(evas_object_evas_get(label));
+ Evas_Textblock_Style *ts = evas_textblock_style_new();
- // edje_object_signal_emit(elm_layout_edje_get(label), "elm,state,text,status,enabled", "");
- // edje_object_signal_emit(elm_layout_edje_get(label), "elm,state,effect,show", "");
- // edje_object_signal_emit(elm_layout_edje_get(label), "elm,state,contents,enabled", "");
+ evas_textblock_style_set(ts, textStyle);
+ evas_object_textblock_style_set(textBlock, ts);
+ evas_object_textblock_text_markup_set(textBlock, text.c_str());
+ evas_object_textblock_size_native_get(textBlock, &ww, &hh);
- evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, 0);
- evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_textblock_style_free(ts);
+ evas_object_del(textBlock);
- // Demo Colors
- if(m_Style == Received)
- {
- evas_object_color_set(label, rand() % 230, rand() % 230, 255, 190);
- }
+ int wrapWidth = ww > maxWidth ? (int)ELM_SCALE_SIZE(maxWidth) : (int)ELM_SCALE_SIZE(ww);
+ elm_label_line_wrap_set(label, ELM_WRAP_MIXED);
+ elm_label_wrap_width_set(label, wrapWidth);
+ elm_object_part_text_set(label, nullptr, text.c_str());
+ evas_object_show(label);
+ evas_object_size_hint_align_set(label, 0.0, EVAS_HINT_FILL);
+ return label;
+}
+
+Evas_Object *BubbleView::createTextFileView(const std::string &path)
+{
+ std::string text = FileUtils::readTextFile(path);
+ if(text.empty())
+ return nullptr;
else
+ return createTextView(text);
+}
+
+Evas_Object *BubbleView::createThumbView(const std::string &path)
+{
+ Evas_Object *image = elm_image_add(*this);
+ elm_image_aspect_fixed_set(image, false);
+ elm_image_file_set(image, path.c_str(), nullptr);
+ int imageWidth = 0;
+ int imageHeight = 0;
+ elm_image_object_size_get(image, &imageWidth, &imageHeight);
+ if(imageWidth > maxWidth)
{
- evas_object_color_set(label, 255, rand() % 230, rand() % 230, 190);
+ double scale = maxWidth/(double)imageWidth;
+ imageWidth *= scale;
+ imageHeight *= scale;
}
- //Demo colors
+ evas_object_size_hint_min_set(image, imageWidth, imageHeight);
+ evas_object_show(image);
+ return image;
+}
+
+BubbleEntity::BubbleEntity()
+{
}
-void BubbleView::setText(const std::string &text)
+BubbleEntity::~BubbleEntity()
{
- elm_object_text_set(getEo(), text.c_str());
}
-void BubbleView::setTime(const std::string &time)
+void BubbleEntity::addPart(PartType type, const std::string &value)
{
- elm_object_part_text_set(getEo(), "elm.text.time", time.c_str());
+ m_Parts.push_back(BubblePart{type, value});
}
ConvListViewItem::ConvListViewItem(ConvItemType type)
: ListItem()
+ , m_BubbleWidth(0)
+ , m_BubbleHeight(0)
{
switch (type)
{
Evas_Object *ConvListViewItem::getContent(ListItem &item, const char *part)
{
if(!strcmp(part, bubbleContentPart))
- return getBubble();
+ {
+ Evas_Object *bubble = getBubbleContent();
+ evas_object_event_callback_add(bubble, EVAS_CALLBACK_RESIZE, EVAS_EVENT_CALLBACK(ConvListViewItem, onBubbleResized), this);
+ if(m_BubbleHeight > 0 && m_BubbleWidth > 0)
+ {
+ evas_object_size_hint_min_set(bubble, m_BubbleWidth, m_BubbleHeight);
+ evas_object_size_hint_max_set(bubble, m_BubbleWidth, m_BubbleHeight);
+ }
+ return bubble;
+ }
else if(!strcmp(part, thumbContentPart))
+ {
return getThumbnail();
+ }
else if(!strcmp(part, draftButtonPart))
+ {
return getButton(!getOwner()->getCheckMode(), Draft);
+ }
else if(!strcmp(part, failedButtonPart))
+ {
return getButton(!getOwner()->getCheckMode(), Failed);
+ }
else
+ {
return nullptr;
+ }
}
const char *ConvListViewItem::getCheckPart(ListItem &item)
}
return button;
}
+
+void ConvListViewItem::onBubbleResized(Evas_Object *obj, void *data)
+{
+ MSG_LOG("");
+ Evas_Coord w,h;
+ evas_object_geometry_get(obj, nullptr, nullptr, &w, &h);
+ if(m_BubbleHeight < h || m_BubbleWidth < w)
+ {
+ m_BubbleWidth = w;
+ m_BubbleHeight = h;
+ elm_genlist_item_update(this->getElmObjItem());
+ }
+}
return;
}
- auto msg = getMsgEngine().getComposer().createSms();
+ auto msg = getMsgEngine().getComposer().createMessage(m_IsMms ? Message::MT_MMS : Message::MT_SMS);
fillMessage(*msg);
MSG_LOG("m_ThreadId = ", m_ThreadId);
MsgTransport::SendResult sendRes = getMsgEngine().getTransport().sendMessage(*msg, &m_ThreadId);