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-manager-viewItem.cpp
19 * @author Jungki Kwak (jungki.kwak@samsung.com)
20 * @brief item data class for download view
22 #include "download-manager-viewItem.h"
23 #include "download-manager-items.h"
24 #include "download-manager-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";
44 dldGenlistStyle.decorate_item_style = "mode/slide";
46 dldGenlistStyle.func.text_get = getGenlistLabelCB;
47 dldGenlistStyle.func.content_get = getGenlistIconCB;
48 dldGenlistStyle.func.state_get = NULL;
49 dldGenlistStyle.func.del = NULL;
50 dldGenlistStyle.decorate_all_item_style = "edit_default";
52 dldHistoryGenlistStyle.item_style = "3text.1icon.2";
54 dldHistoryGenlistStyle.decorate_item_style = "mode/slide";
56 dldHistoryGenlistStyle.func.text_get = getGenlistLabelCB;
57 dldHistoryGenlistStyle.func.content_get = getGenlistIconCB;
58 dldHistoryGenlistStyle.func.state_get = NULL;
59 dldHistoryGenlistStyle.func.del = NULL;
60 dldHistoryGenlistStyle.decorate_all_item_style = "edit_default";
62 dldGenlistSlideStyle.item_style = "3text.1icon.2";
64 dldGenlistSlideStyle.decorate_item_style = "mode/slide2";
66 dldGenlistSlideStyle.func.text_get = getGenlistLabelCB;
67 dldGenlistSlideStyle.func.content_get= getGenlistIconCB;
68 dldGenlistSlideStyle.func.state_get = NULL;
69 dldGenlistSlideStyle.func.del = NULL;
70 dldGenlistSlideStyle.decorate_all_item_style = "edit_default";
79 void ViewItem::create(Item *item)
81 ViewItem *newViewItem = new ViewItem(item);
83 DownloadView &view = DownloadView::getInstance();
84 view.attachViewItem(newViewItem);
87 void ViewItem::destroy()
89 DP_LOGD("ViewItem::destroy");
90 /* After item is destory,
91 view item also will be destroyed through event system */
94 DownloadView &view = DownloadView::getInstance();
95 if (this == view.sweepedItem()) {
96 DP_LOGD("reset sweeped item[%p]", view.sweepedItem());
97 view.setSweepedItem(NULL);
104 void ViewItem::updateCB(void *data)
107 static_cast<ViewItem*>(data)->updateFromItem();
110 void ViewItem::updateFromItem()
112 DownloadView &view = DownloadView::getInstance();
113 DP_LOGD("ViewItem::updateFromItem() ITEM::[%d]", state());
114 if (state() == ITEM::DESTROY) {
116 DP_LOGD("ViewItem::updateFromItem() ITEM::DESTROY");
118 m_item->deSubscribe(m_aptr_observer.get());
119 m_aptr_observer->clear();
120 elm_object_item_del(m_glItem);
122 tempType = dateGroupType();
123 view.detachViewItem(this);
124 view.handleGenlistGroupItem(tempType);
127 if (m_glItem == NULL) {
130 if (state() == ITEM::SUSPENDED) {
132 } else 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 #ifndef _TIZEN_PUBLIC
172 if (strncmp(part, "elm.text.1", strlen("elm.text.1")) == 0 ||
173 strncmp(part, "elm.slide.text.1", strlen("elm.slide.text.1")) == 0 ||
174 strncmp(part, "elm.slide.text.2", strlen("elm.slide.text.2")) == 0) {
176 if (strncmp(part, "elm.text.1", strlen("elm.text.1")) == 0) {
178 return strdup(getTitle());
179 } else if (strncmp(part, "elm.text.2", strlen("elm.text.2")) == 0) {
180 return strdup(getMessage());
181 } else if (strncmp(part, "elm.text.3", strlen("elm.text.3")) == 0) {
186 DateUtil &inst = DateUtil::getInstance();
187 double udateTime = finishedTime() * 1000;
188 if (dateGroupType() == DATETIME::DATE_TYPE_PREVIOUS
189 || dateGroupType() == DATETIME::DATE_TYPE_LATER)
190 inst.getDateStr(LOCALE_STYLE::SHORT_DATE, udateTime, outBuf);
192 inst.getDateStr(LOCALE_STYLE::TIME, udateTime, outBuf);
193 return strdup(outBuf.c_str());
196 DP_LOGD("No Implementation");
201 Evas_Object *ViewItem::getGenlistIconCB(void *data, Evas_Object *obj,
205 if(!data || !obj || !part) {
206 DP_LOGE("parameter is NULL");
210 ViewItem *item = static_cast<ViewItem *>(data);
211 return item->getGenlistIcon(obj, part);
214 Evas_Object *ViewItem::getGenlistIcon(Evas_Object *obj, const char *part)
216 //DP_LOGD("ViewItem::getGenlistIcon:part[%s]state[%s]", part, stateStr());
218 if (elm_genlist_decorate_mode_get(obj) && isFinished()) {
219 if (strncmp(part,"elm.edit.icon.1", strlen("elm.edit.icon.1")) == 0) {
220 Evas_Object *checkBtn = elm_check_add(obj);
221 elm_check_state_pointer_set(checkBtn, &m_checked);
222 evas_object_smart_callback_add(checkBtn, "changed", checkChangedCB,
224 m_checkedBtn = checkBtn;
226 } else if (strncmp(part,"elm.edit.icon.2", strlen("elm.edit.icon.2")) ==
232 /* elm.icon.2 should be checked prior to elm.icon */
233 if (strncmp(part,"elm.icon.2", strlen("elm.icon.2")) == 0) {
234 if (state() == ITEM::RECEIVING_DOWNLOAD_INFO ||
235 state() == ITEM::DOWNLOADING ||
236 isPreparingDownload())
237 return createCancelBtn(obj);
240 } else if (strncmp(part,"elm.icon.1", strlen("elm.icon.1")) == 0 ||
241 strncmp(part, "elm.icon", strlen("elm.icon")) == 0) {
242 // if (strncmp(part,"elm.icon.1", strlen("elm.icon.1")) == 0) {
243 Evas_Object *icon = elm_icon_add(obj);
244 elm_icon_file_set(icon, getIconPath(), NULL);
245 evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL,1,1);
247 } else if (strcmp(part,"elm.swallow.progress") == 0) {
248 return createProgressBar(obj);
249 #ifndef _TIZEN_PUBLIC
250 } else if (strcmp(part,"elm.slide.swallow.1") == 0) {
252 return createDeleteBtn(obj);
255 } else if (strcmp(part,"elm.slide.swallow.2") == 0) {
256 if (isFinishedWithErr())
257 return createRetryBtn(obj);
262 DP_LOGE("Cannot enter here");
267 void ViewItem::checkChangedCB(void *data, Evas_Object *obj,
270 DownloadView &view = DownloadView::getInstance();
272 //ViewItem *item = static_cast<ViewItem *>(data);
273 //DP_LOGD("checked[%d] viewItem[%p]",(bool)(item->checkedValue()),item);
274 view.handleCheckedState();
277 #ifndef _TIZEN_PUBLIC
278 void ViewItem::sweepRight()
282 DP_LOGE("genlist item is NULL");
285 elm_genlist_item_decorate_mode_set(m_glItem,"slide", EINA_TRUE);
286 elm_genlist_item_select_mode_set(m_glItem, ELM_OBJECT_SELECT_MODE_NONE);
289 void ViewItem::sweepLeft()
293 DP_LOGE("genlist item is NULL");
296 elm_genlist_item_decorate_mode_set(m_glItem,"slide", EINA_FALSE);
297 elm_genlist_item_select_mode_set(m_glItem, ELM_OBJECT_SELECT_MODE_NONE);
301 void ViewItem::clickedDeleteButton()
303 DP_LOGD("ViewItem::clickedDeleteButton()");
304 m_item->deleteFromDB();
308 void ViewItem::clickedCancelButton()
310 DP_LOG("ViewItem::clickedCancelButton()");
314 void ViewItem::requestCancel()
321 void ViewItem::clickedRetryButton()
327 void ViewItem::clickedGenlistItem()
329 DownloadView &view = DownloadView::getInstance();
332 DP_LOGE("m_item is NULL");
335 if (view.isGenlistEditMode()) {
336 m_checked = !m_checked;
338 elm_genlist_item_fields_update(genlistItem(),"elm.edit.icon.1",
339 ELM_GENLIST_ITEM_FIELD_CONTENT);
341 DP_LOGE("m_checkedBtn is NULL");
342 view.handleCheckedState();
343 } else if (state() == ITEM::FINISH_DOWNLOAD) {
344 bool ret = m_item->play();
346 string desc = __("IDS_BR_POP_UNABLE_TO_OPEN_FILE");
347 view.showErrPopup(desc);
349 } else if (isFinishedWithErr()) {
352 elm_genlist_item_selected_set(genlistItem(), EINA_FALSE);
355 Elm_Genlist_Item_Class *ViewItem::elmGenlistStyle()
357 /* Change the genlist style class in case of download history item */
358 if (state() == ITEM::FINISH_DOWNLOAD)
359 return &dldHistoryGenlistStyle;
360 else if (isFinishedWithErr())
361 return &dldGenlistSlideStyle;
363 return &dldGenlistStyle;
366 const char *ViewItem::getMessage()
368 DP_LOGD("ViewItem state() ITEM::[%d]", state());
369 const char *buff = NULL;
372 case ITEM::REQUESTING:
373 case ITEM::PREPARE_TO_RETRY:
374 case ITEM::RECEIVING_DOWNLOAD_INFO:
375 /* Do not display string and show only the progress bar */
376 // buff = __("Check for download");
379 case ITEM::DOWNLOADING:
380 case ITEM::SUSPENDED:
381 buff = getHumanFriendlyBytesStr(receivedFileSize(), true);
382 // DP_LOGD("%s", buff);
385 buff = S_("IDS_COM_POP_CANCELLED");
387 case ITEM::FAIL_TO_DOWNLOAD:
390 case ITEM::REGISTERING_TO_SYSTEM:
393 case ITEM::FINISH_DOWNLOAD:
394 buff = __("IDS_EMAIL_BODY_COMPLETE");
403 const char *ViewItem::getHumanFriendlyBytesStr(unsigned long int bytes,
406 double doubleTypeBytes = 0.0;
407 const char *unitStr[4] = {"B", "KB", "MB", "GB"};
409 unsigned long int unitBytes = bytes;
411 /* using bit operation to avoid floating point arithmetic */
412 for (unit=0; (unitBytes > 1024 && unit < 4) ; unit++) {
413 unitBytes = unitBytes >> 10;
416 unitBytes = 1 << (10*unit);
417 doubleTypeBytes = ((double)bytes / (double)(unitBytes));
418 // FIXME following code should be broken into another function, but leave it now to save function call time.s
420 if (progressOption && fileSize() != 0) {
421 /* using fixed point arithmetic to avoid floating point arithmetic */
422 const int fixed_point = 6;
423 unsigned long long int receivedBytes = receivedFileSize() << fixed_point;
424 unsigned long long int result = (receivedBytes*100) / fileSize();
425 unsigned long long int result_int = result >> fixed_point;
426 unsigned long long int result_fraction = result &
427 ~(0xFFFFFFFF << fixed_point);
429 snprintf(str, sizeof(str), "%lu %s / %llu.%.2llu %%",
430 bytes, unitStr[unit], result_int, result_fraction);
432 snprintf(str, sizeof(str), "%.2f %s / %llu.%.2llu %%",
433 doubleTypeBytes, unitStr[unit], result_int, result_fraction);
436 snprintf(str, sizeof(str), "%lu %s", bytes, unitStr[unit]);
438 snprintf(str, sizeof(str), "%.2f %s", doubleTypeBytes, unitStr[unit]);
440 return string(str).c_str();
443 unsigned long int ViewItem::receivedFileSize()
446 return m_item->receivedFileSize();
451 unsigned long int ViewItem::fileSize()
454 return m_item->fileSize();
459 const char *ViewItem::getTitle()
461 const char *title = NULL;
463 title = m_item->title().c_str();
466 return S_("IDS_COM_BODY_NO_NAME");
471 Evas_Object *ViewItem::createProgressBar(Evas_Object *parent)
473 Evas_Object *progress = NULL;
475 DP_LOGE("parent is NULL");
478 progress = elm_progressbar_add(parent);
479 setProgressBar(progress);
481 DP_LOGE("Cannot enter here. finished item has othere genlist style");
485 if (fileSize() == 0 || isPreparingDownload()) {
486 //DP_LOGD("Pending style::progressBar[%p]",progress);
487 elm_object_style_set(progress, "pending_list");
488 elm_progressbar_horizontal_set(progress, EINA_TRUE);
489 evas_object_size_hint_align_set(progress, EVAS_HINT_FILL, EVAS_HINT_FILL);
490 evas_object_size_hint_weight_set(progress, EVAS_HINT_EXPAND,
492 elm_progressbar_pulse(progress, EINA_TRUE);
494 //DP_LOGD("List style::progressBar[%p] fileSize[%d] state[%d]",progress, fileSize(),state());
495 elm_object_style_set(progress, "list_progress");
496 elm_progressbar_horizontal_set(progress, EINA_TRUE);
498 if (isCompletedDownload())
499 elm_progressbar_value_set(progress, 1.0);
500 /* When realized event is happened, the progress is created.
501 This is needed for that case */
502 else if (state() == ITEM::DOWNLOADING) {
503 double percentageProgress = 0.0;
504 percentageProgress = (double)(receivedFileSize()) /
505 (double)(fileSize());
506 elm_progressbar_value_set(progress, percentageProgress);
509 evas_object_show(progress);
513 void ViewItem::updateCheckedBtn()
516 elm_check_state_pointer_set(m_checkedBtn,&m_checked);
519 #ifndef _TIZEN_PUBLIC
520 Evas_Object *ViewItem::createDeleteBtn(Evas_Object *parent)
522 DP_LOGD("DeleteButton::create()");
523 Evas_Object *button = elm_button_add(parent);
524 elm_object_style_set(button, "text_only/sweep");
525 elm_object_text_set(button, S_("IDS_COM_OPT_DELETE"));
526 evas_object_propagate_events_set(button, EINA_FALSE);
527 evas_object_smart_callback_add(button ,"clicked", deleteBtnClickedCB, this);
531 Evas_Object *ViewItem::createRetryBtn(Evas_Object *parent)
533 DP_LOGD("DeleteButton::create()");
534 Evas_Object *button = elm_button_add(parent);
535 elm_object_style_set(button, "text_only/sweep");
536 elm_object_text_set(button, __("IDS_BR_SK_RETRY"));
537 evas_object_propagate_events_set(button, EINA_FALSE);
538 evas_object_smart_callback_add(button ,"clicked", retryBtnClickedCB, this);
543 void ViewItem::deleteBtnClickedCB(void *data, Evas_Object *obj, void *event_info)
547 DP_LOGE("data is NULL");
550 ViewItem *viewItem = static_cast<ViewItem *>(data);
551 viewItem->clickedDeleteButton();
554 void ViewItem::retryBtnClickedCB(void *data, Evas_Object *obj, void *event_info)
558 DP_LOGE("data is NULL");
561 ViewItem *viewItem = static_cast<ViewItem *>(data);
562 viewItem->clickedRetryButton();
565 Evas_Object *ViewItem::createCancelBtn(Evas_Object *parent)
568 Evas_Object *button = elm_button_add(parent);
569 elm_object_part_content_set(parent, "btn_style1", button);
570 elm_object_style_set(button, "style1/auto_expand");
571 evas_object_size_hint_aspect_set(button, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
572 elm_object_text_set(button, S_("IDS_COM_SK_CANCEL"));
573 evas_object_propagate_events_set(button, EINA_FALSE);
574 evas_object_smart_callback_add(button,"clicked", cancelBtnClickedCB, this);
578 void ViewItem::cancelBtnClickedCB(void *data, Evas_Object *obj, void *event_info)
582 DP_LOGE("data is NULL");
585 ViewItem *viewItem = static_cast<ViewItem *>(data);
586 viewItem->clickedCancelButton();
589 void ViewItem::extractDateGroupType()
593 //DP_LOGD("state[%s],finishedTime[%ld]",stateStr(),finishedTime());
594 if (isFinished() && finishedTime() > 0) {
596 DateUtil &inst = DateUtil::getInstance();
597 double nowTime = inst.nowTime();
598 double finishTime = finishedTime();
599 diffDay = inst.getDiffDays((time_t)nowTime, (time_t)finishTime);
601 m_dateGroupType = DATETIME::DATE_TYPE_TODAY;
602 else if (diffDay == 1)
603 m_dateGroupType = DATETIME::DATE_TYPE_YESTERDAY;
604 else if (diffDay > 1)
605 m_dateGroupType = DATETIME::DATE_TYPE_PREVIOUS;
607 m_dateGroupType = DATETIME::DATE_TYPE_LATER;
610 /* Item which is added now or retrying item */
611 m_dateGroupType = DATETIME::DATE_TYPE_TODAY;
615 void ViewItem::retryViewItem(void)
617 DownloadView &view = DownloadView::getInstance();
620 m_isRetryCase = true;
621 m_item->clearForRetry();
622 if (!m_item->retry()) {
623 DownloadView &view = DownloadView::getInstance();
624 string desc = S_("IDS_COM_POP_FAILED");
625 view.showErrPopup(desc);
626 m_item->deleteFromDB();
630 /* Move a item to Today group, if it is not included to Today group */
631 view.moveRetryItem(this);