Task TT-75 Implement "Main page loading UI" view
[profile/tv/apps/web/browser.git] / services / SimpleUI / HistoryList.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "HistoryList.h"
18 #include "BrowserAssert.h"
19 #include "BrowserLogger.h"
20 #include "HistoryItem.h"
21 #include "EflTools.h"
22 #include <Evas.h>
23
24 #if MERGE_ME
25 #include <boost/date_time/posix_time/posix_time.hpp>
26 #include <boost/date_time/date.hpp>
27 #include <boost/date_time/date_defs.hpp>
28 #include <boost/date_time/gregorian/gregorian.hpp>
29 #endif
30
31 namespace tizen_browser
32 {
33 namespace base_ui
34 {
35
36
37 HistoryList::HistoryList(std::shared_ptr<Evas_Object> mainWindow, Evas_Object* parentButton)
38     : MenuButton(mainWindow, parentButton)
39     ,m_genList(NULL)
40     ,m_itemClass(NULL)
41     ,m_lastFocusedItem(NULL)
42     ,m_deleteSelected(false)
43 {
44     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
45     std::string edjFilePath = EDJE_DIR;
46     edjFilePath.append("SimpleUI/HistoryItem.edj");
47     elm_theme_extension_add(0, edjFilePath.c_str());
48
49     itemWidth = atoi(edje_file_data_get(edjFilePath.c_str(),"item_width"));
50     itemHeight = atoi(edje_file_data_get(edjFilePath.c_str(),"item_height"));
51     parentItemHeight = atoi(edje_file_data_get(edjFilePath.c_str(),"parent_item_height"));
52     itemsCounter = 0;
53     parentItemsCounter = 0;
54
55     m_genList = elm_genlist_add(m_window.get());
56     elm_object_style_set(m_genList, "history");
57     elm_genlist_homogeneous_set(m_genList, EINA_FALSE);
58     elm_genlist_multi_select_set(m_genList, EINA_FALSE);
59     elm_genlist_select_mode_set(m_genList, ELM_OBJECT_SELECT_MODE_ALWAYS);
60     elm_genlist_mode_set(m_genList, ELM_LIST_LIMIT);
61     elm_genlist_decorate_mode_set(m_genList, EINA_TRUE);
62     evas_object_size_hint_weight_set(m_genList, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
63
64     evas_object_smart_callback_add(m_genList, "item,focused", focusItem, this);
65     evas_object_smart_callback_add(m_genList, "item,unfocused", unFocusItem, NULL);
66
67     m_itemClass = elm_genlist_item_class_new();
68     m_itemClass->item_style = "history_item";
69     m_itemClass->func.text_get = &listItemTextGet;
70     m_itemClass->func.content_get = &listItemContentGet;
71     m_itemClass->func.state_get = 0;
72     m_itemClass->func.del = 0;
73
74     m_itemClassNoFavicon = elm_genlist_item_class_new();
75     m_itemClassNoFavicon->item_style = "history_item_no_favicon";
76     m_itemClassNoFavicon->func.text_get = &listItemTextGet;
77     m_itemClassNoFavicon->func.content_get = &listItemContentGet;
78     m_itemClassNoFavicon->func.state_get = 0;
79     m_itemClassNoFavicon->func.del = 0;
80
81     m_parentItemClass= elm_genlist_item_class_new();
82     m_parentItemClass->item_style = "history_parent_item";
83     m_parentItemClass->func.text_get = &listParentItemTextGet;
84     m_parentItemClass->func.content_get = 0;
85     m_parentItemClass->func.state_get = 0;
86     m_parentItemClass->func.del = 0;
87 }
88
89 HistoryList::~HistoryList()
90 {
91     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
92 }
93
94 void HistoryList::addItem(const std::shared_ptr<tizen_browser::services::HistoryItem> item)
95 {
96     BROWSER_LOGD("[%s:%d]:%s ", __PRETTY_FUNCTION__, __LINE__, item->getTitle().c_str());
97     //first check if ther's a date item.
98     GroupIterator parenIter = m_groupParent.find(item->getLastVisit().date());
99     Elm_Object_Item* groupParent;
100
101     ItemData * id = new ItemData;
102     id->h_list = this;
103     id->h_item = item.get();
104     if(parenIter == m_groupParent.end()){
105         groupParent = elm_genlist_item_append(m_genList,           //genlist
106                                         m_parentItemClass,    //item Class
107                                         //id.get(),                 //item data
108                                         id,
109                                         0,                    //parent item
110                                         ELM_GENLIST_ITEM_GROUP,//item type
111                                         paretn_item_clicked_cb,
112                                         NULL                 //data passed to above function
113                                         );
114         elm_object_item_disabled_set(groupParent, EINA_TRUE);
115         m_groupParent[item->getLastVisit().date()] = groupParent;
116         ++parentItemsCounter;
117     } else {
118         groupParent = parenIter->second;
119     }
120
121     Elm_Object_Item* elmItem = elm_genlist_item_append(m_genList,            //genlist
122                                                       item->getFavIcon()->dataSize ? m_itemClass : m_itemClassNoFavicon,          //item Class
123                                                       //id.get(),        //item data
124                                                       id,
125                                                       groupParent,                    //parent item
126                                                       ELM_GENLIST_ITEM_NONE,//item type
127                                                       NULL,
128                                                       NULL                  //data passed to above function
129                                                      );
130     id->e_item = elmItem;
131
132 //    m_items.push_back(item);
133     ++itemsCounter;
134 }
135
136 void HistoryList::clearList()
137 {
138         elm_genlist_clear(m_genList);
139         itemsCounter = 0;
140         parentItemsCounter = 0;
141         m_groupParent.clear();
142 }
143
144 void HistoryList::addItems(tzSrv::HistoryItemVector items)
145 {
146     clearList();
147     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
148     tzSrv::HistoryItemVectorConstIter end = items.end();
149     for(tzSrv::HistoryItemVectorConstIter item = items.begin();  item!=end; item++){
150         addItem(*item);
151     }
152 }
153
154 Evas_Object* HistoryList::getContent()
155 {
156     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
157     return m_genList;
158 }
159
160 MenuButton::ListSize HistoryList::calculateSize()
161 {
162     ListSize result;
163
164     result.width = itemWidth;
165
166     result.height = itemsCounter*itemHeight + parentItemsCounter*parentItemHeight + 16; //"16" is size of frame
167     if (result.height > 868)
168         result.height = 868;
169
170     return result;
171 }
172
173 Evas_Object* HistoryList::getFirstFocus()
174 {
175     return m_genList;
176 }
177
178 Evas_Object* HistoryList::listItemContentGet(void* data, Evas_Object* obj, const char* part)
179 {
180     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
181     ItemData * id = static_cast<ItemData *>(data);
182     if(!strcmp(part, "favicon") && id->h_item->getFavIcon())
183     {
184         return tizen_browser::tools::EflTools::getEvasImage(id->h_item->getFavIcon(), obj);
185     }
186     else if(!strcmp(part, "content_click"))
187     {
188         Evas_Object *content_click = elm_button_add(obj);
189         elm_object_style_set(content_click, "invisible_button");
190         evas_object_smart_callback_add(content_click, "clicked", HistoryList::item_clicked_cb, id);
191         return content_click;
192     }
193     else if(!strcmp(part, "del_click"))
194     {
195         Evas_Object *del_click = elm_button_add(obj);
196         elm_object_style_set(del_click, "invisible_button");
197         evas_object_smart_callback_add(del_click, "clicked", HistoryList::item_delete_clicked_cb, id);
198         return del_click;
199     }
200     return NULL;
201 }
202
203 char* HistoryList::listItemTextGet(void* data, Evas_Object* /* obj */, const char* part)
204 {
205     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
206     ItemData * id = static_cast<ItemData *>(data);
207     if(!strcmp(part, "page_title"))
208     {
209         if(!id->h_item->getTitle().empty()){
210             return strdup(id->h_item->getTitle().c_str());
211         }
212     }
213     else if(!strcmp(part, "page_url"))
214         {
215         if(!id->h_item->getUrl().empty()){
216             return strdup(id->h_item->getUrl().c_str());
217         }
218     }
219 #if MERGE_ME
220     else if(!strcmp(part, "page_time"))
221     {
222         std::string retstr = boost::posix_time::to_simple_string(id->h_item->getLastVisit().time_of_day());
223         return strdup(retstr.c_str());
224     }
225 #endif
226     return strdup("");
227 }
228
229 void HistoryList::item_clicked_cb(void* data, Evas_Object* /* obj */, void* /* event_info */)
230 {
231     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
232     ItemData * id = static_cast<ItemData *>(data);
233     id->h_list->clickedHistoryItem(id->h_item->getUrl());
234 }
235
236 void HistoryList::item_delete_clicked_cb(void* data, Evas_Object* /* obj */, void* /* event_info */)
237 {
238     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
239     ItemData * id = static_cast<ItemData *>(data);
240     id->h_list->deleteHistoryItem(id->h_item->getUrl());
241     elm_object_item_del(id->e_item);
242     elm_genlist_item_update(id->e_item);
243     BROWSER_LOGD("[%s:%d] Genlist count: %d", __PRETTY_FUNCTION__, __LINE__, elm_genlist_items_count(id->h_list->m_genList));
244 }
245
246 char* HistoryList::listParentItemTextGet(void* data, Evas_Object* /* obj */, const char* /* part */ )
247 {
248     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
249     ///\todo fix year out of range
250     ItemData * id = static_cast<ItemData *>(data);
251     std::string retstr = boost::gregorian::to_simple_string(id->h_item->getLastVisit().date());
252     return strdup(retstr.c_str());
253
254 }
255
256 void HistoryList::paretn_item_clicked_cb(void* /* data */, Evas_Object* /* obj */, void* /* event_info */)
257 {
258     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
259 }
260
261 void HistoryList::focusItem(void* data, Evas_Object* /*obj*/, void* event_info)
262 {
263     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
264     Elm_Object_Item *item = reinterpret_cast<Elm_Object_Item*>(event_info);
265     elm_object_item_signal_emit( item, "mouse,in", "content_click");
266
267     HistoryList *self = static_cast<HistoryList*>(data);
268     self->m_lastFocusedItem = item;
269 }
270
271 void HistoryList::unFocusItem(void* /*data*/, Evas_Object* /*obj*/, void* event_info)
272 {
273     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
274     Elm_Object_Item *item = reinterpret_cast<Elm_Object_Item*>(event_info);
275     ItemData * id = reinterpret_cast<ItemData *>(elm_object_item_data_get(item));
276     M_ASSERT(id);
277     elm_object_item_signal_emit(item, "mouse,out", "content_click");
278     elm_object_item_signal_emit(item, "mouse,out", "del_click");
279     id->h_list->m_deleteSelected = false;
280 }
281
282 void HistoryList::rightPressed()
283 {
284     if(m_lastFocusedItem && elm_object_focus_get(elm_object_item_widget_get(m_lastFocusedItem))) {
285         elm_object_item_signal_emit(m_lastFocusedItem, "mouse,in", "del_click");
286         m_deleteSelected = true;
287     }
288 }
289
290 void HistoryList::leftPressed()
291 {
292     if(m_lastFocusedItem && elm_object_focus_get(elm_object_item_widget_get(m_lastFocusedItem))) {
293         elm_object_item_signal_emit(m_lastFocusedItem, "mouse,out", "del_click");
294         elm_object_item_signal_emit(m_lastFocusedItem, "mouse,in", "content_click");
295         m_deleteSelected = false;
296     }
297 }
298
299 void HistoryList::enterPressed()
300 {
301     if(m_lastFocusedItem && elm_object_focus_get(elm_object_item_widget_get(m_lastFocusedItem))) {
302         BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
303
304         ItemData * id = reinterpret_cast<ItemData *>(elm_object_item_data_get(m_lastFocusedItem));
305         M_ASSERT(id);
306         if(m_deleteSelected) {
307             deleteHistoryItem(id->h_item->getUrl());
308             elm_object_item_del(m_lastFocusedItem);
309             elm_genlist_item_update(m_lastFocusedItem);
310         }
311         else
312             clickedHistoryItem(id->h_item->getUrl());
313     }
314 }
315
316 } /* end of namespace base_ui */
317 } /* end of namespace tizen_browser */