2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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
8 * http://www.tizenopensource.org/license
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.
18 * @file download-provider-viewItem.cpp
19 * @author Jungki Kwak (jungki.kwak@samsung.com)
20 * @brief item data class for download view
22 #include "download-provider-viewItem.h"
23 #include "download-provider-items.h"
24 #include "download-provider-view.h"
26 ViewItem::ViewItem(Item *item)
31 , m_checked(EINA_FALSE)
32 , m_isRetryCase(false)
33 , m_dateGroupType(DATETIME::DATE_TYPE_NONE)
35 // FIXME need to makes exchange subject?? not yet, but keep it in mind!
37 m_aptr_observer = auto_ptr<Observer>(
38 new Observer(updateCB, this, "viewItemObserver"));
39 item->subscribe(m_aptr_observer.get());
42 dldGenlistStyle.item_style = "3text.3icon";
43 dldGenlistStyle.func.text_get = getGenlistLabelCB;
44 dldGenlistStyle.func.content_get = getGenlistIconCB;
45 dldGenlistStyle.func.state_get = NULL;
46 dldGenlistStyle.func.del = NULL;
47 dldGenlistStyle.decorate_all_item_style = "edit_default";
49 dldHistoryGenlistStyle.item_style = "3text.1icon.2";
50 dldHistoryGenlistStyle.func.text_get = getGenlistLabelCB;
51 dldHistoryGenlistStyle.func.content_get = getGenlistIconCB;
52 dldHistoryGenlistStyle.func.state_get = NULL;
53 dldHistoryGenlistStyle.func.del = NULL;
54 dldHistoryGenlistStyle.decorate_all_item_style = "edit_default";
56 dldGenlistSlideStyle.item_style = "3text.1icon.2";
57 dldGenlistSlideStyle.func.text_get = getGenlistLabelCB;
58 dldGenlistSlideStyle.func.content_get= getGenlistIconCB;
59 dldGenlistSlideStyle.func.state_get = NULL;
60 dldGenlistSlideStyle.func.del = NULL;
61 dldGenlistSlideStyle.decorate_all_item_style = "edit_default";
70 void ViewItem::create(Item *item)
72 ViewItem *newViewItem = new ViewItem(item);
74 DownloadView &view = DownloadView::getInstance();
75 view.attachViewItem(newViewItem);
78 void ViewItem::destroy()
80 DP_LOGD("ViewItem::destroy");
81 /* After item is destory,
82 view item also will be destroyed through event system */
87 void ViewItem::updateCB(void *data)
90 static_cast<ViewItem*>(data)->updateFromItem();
93 void ViewItem::updateFromItem()
95 DownloadView &view = DownloadView::getInstance();
96 DP_LOGD("ViewItem::updateFromItem() ITEM::[%d]", state());
97 if (state() == ITEM::DESTROY) {
99 DP_LOGD("ViewItem::updateFromItem() ITEM::DESTROY");
101 m_item->deSubscribe(m_aptr_observer.get());
102 m_aptr_observer->clear();
103 elm_object_item_del(m_glItem);
105 tempType = dateGroupType();
106 view.detachViewItem(this);
107 view.handleGenlistGroupItem(tempType);
111 if (state() == ITEM::WAITING_USER_RESPONSE) {
113 buf.append("Name : ");
114 buf.append(m_item->contentName());
116 buf.append("Size : ");
117 buf.append(getHumanFriendlyBytesStr(fileSize(), false));
119 buf.append("Vendor : ");
120 buf.append(m_item->vendorName());
122 if (m_item->isMidletInstalled()) {
124 buf.append(S_("IDS_COM_POP_ALREDY_EXISTS"));
126 buf.append("Want to update?");
128 view.showOMAPopup(buf, this);
132 if (state() == ITEM::DOWNLOADING) {
133 if (fileSize() > 0 && m_progressBar) {
134 double percentageProgress = 0.0;
135 percentageProgress = (double)(receivedFileSize()) /
136 (double)(fileSize());
137 DP_LOGD("progress value[%.2f]",percentageProgress);
138 elm_progressbar_value_set(m_progressBar, percentageProgress);
140 elm_genlist_item_fields_update(m_glItem,"elm.text.2",
141 ELM_GENLIST_ITEM_FIELD_TEXT);
142 } else if (m_isRetryCase && state() == ITEM::RECEIVING_DOWNLOAD_INFO) {
143 elm_genlist_item_item_class_update(m_glItem, &dldGenlistStyle);
144 } else if (!isFinished()) {
145 elm_genlist_item_update(m_glItem);
146 } else {/* finished state */
147 if (state() == ITEM::FINISH_DOWNLOAD)
148 elm_genlist_item_item_class_update(m_glItem, &dldHistoryGenlistStyle);
150 elm_genlist_item_item_class_update(m_glItem, &dldGenlistSlideStyle);
151 if (view.isGenlistEditMode())
152 elm_object_item_disabled_set(m_glItem, EINA_FALSE);
156 char *ViewItem::getGenlistLabelCB(void *data, Evas_Object *obj, const char *part)
160 if(!data || !obj || !part)
163 ViewItem *item = static_cast<ViewItem *>(data);
164 return item->getGenlistLabel(obj, part);
167 char *ViewItem::getGenlistLabel(Evas_Object *obj, const char *part)
169 DP_LOGD("ViewItem::getListLabel:part[%s]", part);
171 if (strncmp(part, "elm.text.1", strlen("elm.text.1")) == 0) {
172 return strdup(getTitle());
173 } else if (strncmp(part, "elm.text.2", strlen("elm.text.2")) == 0) {
174 return strdup(getMessage());
175 } else if (strncmp(part, "elm.text.3", strlen("elm.text.3")) == 0) {
180 DateUtil &inst = DateUtil::getInstance();
181 double udateTime = finishedTime() * 1000;
182 if (dateGroupType() == DATETIME::DATE_TYPE_PREVIOUS
183 || dateGroupType() == DATETIME::DATE_TYPE_LATER)
184 inst.getDateStr(LOCALE_STYLE::SHORT_DATE, udateTime, outBuf);
186 inst.getDateStr(LOCALE_STYLE::TIME, udateTime, outBuf);
187 return strdup(outBuf.c_str());
190 DP_LOGD("No Implementation");
195 Evas_Object *ViewItem::getGenlistIconCB(void *data, Evas_Object *obj,
199 if(!data || !obj || !part) {
200 DP_LOGE("parameter is NULL");
204 ViewItem *item = static_cast<ViewItem *>(data);
205 return item->getGenlistIcon(obj, part);
208 Evas_Object *ViewItem::getGenlistIcon(Evas_Object *obj, const char *part)
210 //DP_LOGD("ViewItem::getGenlistIcon:part[%s]state[%s]", part, stateStr());
212 if (elm_genlist_decorate_mode_get(obj) && isFinished()) {
213 if (strncmp(part,"elm.edit.icon.1", strlen("elm.edit.icon.1")) == 0) {
214 Evas_Object *checkBtn = elm_check_add(obj);
215 elm_check_state_pointer_set(checkBtn, &m_checked);
216 evas_object_smart_callback_add(checkBtn, "changed", checkChangedCB,
218 m_checkedBtn = checkBtn;
220 } else if (strncmp(part,"elm.edit.icon.2", strlen("elm.edit.icon.2")) ==
226 /* elm.icon.2 should be checked prior to elm.icon */
227 if (strncmp(part,"elm.icon.2", strlen("elm.icon.2")) == 0) {
228 if (state() == ITEM::RECEIVING_DOWNLOAD_INFO ||
229 state() == ITEM::PREPARE_TO_RETRY ||
230 state() == ITEM::DOWNLOADING ||
231 isPreparingDownload())
232 return createCancelBtn(obj);
235 } else if (strncmp(part,"elm.icon.1", strlen("elm.icon.1")) == 0 ||
236 strncmp(part, "elm.icon", strlen("elm.icon")) == 0) {
237 // if (strncmp(part,"elm.icon.1", strlen("elm.icon.1")) == 0) {
238 Evas_Object *icon = elm_icon_add(obj);
239 elm_icon_file_set(icon, getIconPath(), NULL);
240 evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL,1,1);
242 } else if (strcmp(part,"elm.swallow.progress") == 0) {
243 return createProgressBar(obj);
245 DP_LOGE("Cannot enter here");
250 void ViewItem::checkChangedCB(void *data, Evas_Object *obj,
253 DownloadView &view = DownloadView::getInstance();
255 //ViewItem *item = static_cast<ViewItem *>(data);
256 //DP_LOGD("checked[%d] viewItem[%p]",(bool)(item->checkedValue()),item);
257 view.handleCheckedState();
260 void ViewItem::clickedDeleteButton()
262 DP_LOGD("ViewItem::clickedDeleteButton()");
263 m_item->deleteFromDB();
267 void ViewItem::clickedCancelButton()
269 DP_LOG("ViewItem::clickedCancelButton()");
273 void ViewItem::requestCancel()
280 void ViewItem::clickedRetryButton()
286 void ViewItem::clickedGenlistItem()
288 DownloadView &view = DownloadView::getInstance();
291 DP_LOGE("m_item is NULL");
294 if (view.isGenlistEditMode()) {
295 m_checked = !m_checked;
297 elm_genlist_item_fields_update(genlistItem(),"elm.edit.icon.1",
298 ELM_GENLIST_ITEM_FIELD_CONTENT);
300 DP_LOGE("m_checkedBtn is NULL");
301 view.handleCheckedState();
302 } else if (state() == ITEM::FINISH_DOWNLOAD) {
303 bool ret = m_item->play();
305 string desc = __("IDS_BR_POP_UNABLE_TO_OPEN_FILE");
306 view.showErrPopup(desc);
308 } else if (isFinishedWithErr()) {
311 elm_genlist_item_selected_set(genlistItem(), EINA_FALSE);
314 Elm_Genlist_Item_Class *ViewItem::elmGenlistStyle()
316 /* Change the genlist style class in case of download history item */
317 if (state() == ITEM::FINISH_DOWNLOAD)
318 return &dldHistoryGenlistStyle;
319 else if (isFinishedWithErr())
320 return &dldGenlistSlideStyle;
322 return &dldGenlistStyle;
325 const char *ViewItem::getMessage()
327 DP_LOGD("ViewItem state() ITEM::[%d]", state());
328 const char *buff = NULL;
331 case ITEM::REQUESTING:
332 case ITEM::PREPARE_TO_RETRY:
333 case ITEM::WAITING_USER_RESPONSE:
334 case ITEM::RECEIVING_DOWNLOAD_INFO:
335 /* Do not display string and show only the progress bar */
336 // buff = __("Check for download");
339 case ITEM::DOWNLOADING:
340 buff = getHumanFriendlyBytesStr(receivedFileSize(), true);
341 // DP_LOGD("%s", buff);
344 buff = S_("IDS_COM_POP_CANCELLED");
346 case ITEM::FAIL_TO_DOWNLOAD:
349 case ITEM::REGISTERING_TO_SYSTEM:
350 buff = S_("IDS_COM_POP_INSTALLING_ING");
352 case ITEM::ACTIVATING:
353 buff = S_("IDS_COM_POP_ACTIVATING");
355 case ITEM::NOTIFYING_TO_SERVER:
356 buff = __("IDS_BR_BODY_NOTIFYING_ING");
358 case ITEM::PROCESSING_DOMAIN:
359 buff = S_("IDS_COM_POP_PROCESSING");
361 case ITEM::FINISH_PROCESSING_DOMAIN:
362 buff = __("IDS_BR_BODY_PROCESSING_COMPLETED");
364 case ITEM::FINISH_DOWNLOAD:
365 buff = __("IDS_EMAIL_BODY_COMPLETE");
374 const char *ViewItem::getHumanFriendlyBytesStr(unsigned long int bytes,
377 double doubleTypeBytes = 0.0;
378 const char *unitStr[4] = {"B", "KB", "MB", "GB"};
380 unsigned long int unitBytes = bytes;
382 /* using bit operation to avoid floating point arithmetic */
383 for (unit=0; (unitBytes > 1024 && unit < 4) ; unit++) {
384 unitBytes = unitBytes >> 10;
387 unitBytes = 1 << (10*unit);
388 doubleTypeBytes = ((double)bytes / (double)(unitBytes));
389 // FIXME following code should be broken into another function, but leave it now to save function call time.s
391 if (progressOption && fileSize() != 0) {
392 /* using fixed point arithmetic to avoid floating point arithmetic */
393 const int fixed_point = 6;
394 unsigned long long int receivedBytes = receivedFileSize() << fixed_point;
395 unsigned long long int result = (receivedBytes*100) / fileSize();
396 unsigned long long int result_int = result >> fixed_point;
397 unsigned long long int result_fraction = result &
398 ~(0xFFFFFFFF << fixed_point);
400 snprintf(str, sizeof(str), "%lu %s / %llu.%.2llu %%",
401 bytes, unitStr[unit], result_int, result_fraction);
403 snprintf(str, sizeof(str), "%.2f %s / %llu.%.2llu %%",
404 doubleTypeBytes, unitStr[unit], result_int, result_fraction);
407 snprintf(str, sizeof(str), "%lu %s", bytes, unitStr[unit]);
409 snprintf(str, sizeof(str), "%.2f %s", doubleTypeBytes, unitStr[unit]);
411 return string(str).c_str();
414 unsigned long int ViewItem::receivedFileSize()
417 return m_item->receivedFileSize();
422 unsigned long int ViewItem::fileSize()
425 return m_item->fileSize();
430 const char *ViewItem::getTitle()
432 const char *title = NULL;
434 title = m_item->title().c_str();
437 return S_("IDS_COM_BODY_NO_NAME");
442 Evas_Object *ViewItem::createProgressBar(Evas_Object *parent)
444 Evas_Object *progress = NULL;
446 DP_LOGE("parent is NULL");
449 progress = elm_progressbar_add(parent);
450 setProgressBar(progress);
452 DP_LOGE("Cannot enter here. finished item has othere genlist style");
456 if (fileSize() == 0 || isPreparingDownload()) {
457 //DP_LOGD("Pending style::progressBar[%p]",progress);
458 elm_object_style_set(progress, "pending_list");
459 elm_progressbar_horizontal_set(progress, EINA_TRUE);
460 evas_object_size_hint_align_set(progress, EVAS_HINT_FILL, EVAS_HINT_FILL);
461 evas_object_size_hint_weight_set(progress, EVAS_HINT_EXPAND,
463 elm_progressbar_pulse(progress, EINA_TRUE);
465 //DP_LOGD("List style::progressBar[%p] fileSize[%d] state[%d]",progress, fileSize(),state());
466 elm_object_style_set(progress, "list_progress");
467 elm_progressbar_horizontal_set(progress, EINA_TRUE);
469 if (isCompletedDownload())
470 elm_progressbar_value_set(progress, 1.0);
471 /* When realized event is happened, the progress is created.
472 This is needed for that case */
473 else if (state() == ITEM::DOWNLOADING) {
474 double percentageProgress = 0.0;
475 percentageProgress = (double)(receivedFileSize()) /
476 (double)(fileSize());
477 elm_progressbar_value_set(progress, percentageProgress);
480 evas_object_show(progress);
484 void ViewItem::updateCheckedBtn()
487 elm_check_state_pointer_set(m_checkedBtn,&m_checked);
490 void ViewItem::deleteBtnClickedCB(void *data, Evas_Object *obj, void *event_info)
494 DP_LOGE("data is NULL");
497 ViewItem *viewItem = static_cast<ViewItem *>(data);
498 viewItem->clickedDeleteButton();
501 void ViewItem::retryBtnClickedCB(void *data, Evas_Object *obj, void *event_info)
505 DP_LOGE("data is NULL");
508 ViewItem *viewItem = static_cast<ViewItem *>(data);
509 viewItem->clickedRetryButton();
512 Evas_Object *ViewItem::createCancelBtn(Evas_Object *parent)
515 Evas_Object *button = elm_button_add(parent);
516 elm_object_part_content_set(parent, "btn_style1", button);
517 elm_object_style_set(button, "style1/auto_expand");
518 evas_object_size_hint_aspect_set(button, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
519 elm_object_text_set(button, S_("IDS_COM_SK_CANCEL"));
520 evas_object_propagate_events_set(button, EINA_FALSE);
521 evas_object_smart_callback_add(button,"clicked", cancelBtnClickedCB, this);
525 void ViewItem::cancelBtnClickedCB(void *data, Evas_Object *obj, void *event_info)
529 DP_LOGE("data is NULL");
532 ViewItem *viewItem = static_cast<ViewItem *>(data);
533 viewItem->clickedCancelButton();
536 void ViewItem::extractDateGroupType()
540 //DP_LOGD("state[%s],finishedTime[%ld]",stateStr(),finishedTime());
541 if (isFinished() && finishedTime() > 0) {
543 DateUtil &inst = DateUtil::getInstance();
544 double nowTime = inst.nowTime();
545 double finishTime = finishedTime();
546 diffDay = inst.getDiffDays((time_t)nowTime, (time_t)finishTime);
548 m_dateGroupType = DATETIME::DATE_TYPE_TODAY;
549 else if (diffDay == 1)
550 m_dateGroupType = DATETIME::DATE_TYPE_YESTERDAY;
551 else if (diffDay > 1)
552 m_dateGroupType = DATETIME::DATE_TYPE_PREVIOUS;
554 m_dateGroupType = DATETIME::DATE_TYPE_LATER;
557 /* Item which is added now or retrying item */
558 m_dateGroupType = DATETIME::DATE_TYPE_TODAY;
562 void ViewItem::retryViewItem(void)
564 DownloadView &view = DownloadView::getInstance();
567 m_isRetryCase = true;
568 m_item->clearForRetry();
569 if (!m_item->retry()) {
570 DownloadView &view = DownloadView::getInstance();
571 string desc = S_("IDS_COM_POP_FAILED");
572 view.showErrPopup(desc);
573 m_item->deleteFromDB();
577 /* Move a item to Today group, if it is not included to Today group */
578 view.moveRetryItem(this);