4 * Copyright 2012 Samsung Electronics Co., Ltd
6 * Licensed under the Flora License, Version 1.1 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://floralicense.org/license/
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 #include <ui-gadget.h>
23 #include <vconf-keys.h>
25 #include <efl_assist.h>
26 #include <syspopup_caller.h>
27 #include "mobileprint.h"
28 #include "image_editor_conn.h"
29 #include "pts_main_view.h"
30 #include "preview_util.h"
32 Evas_Object *pts_create_custom_popup(Evas_Object *parent, pts_appdata_t *ad);
33 void __pts_main_view_create_list_view(pts_appdata_t *ad);
34 void main_quit_cb(void *data, Evas_Object *obj,
35 const char *emission, const char *source);
37 static Evas_Object *scaling_radio_main = NULL;
38 static Evas_Object *size_radio_main = NULL;
39 static Elm_Genlist_Item_Class scaling_itc;
40 static Elm_Genlist_Item_Class size_itc;
41 static Elm_Genlist_Item_Class title_itc;
42 static Elm_Genlist_Item_Class text_itc;
43 static Elm_Genlist_Item_Class check_itc;
44 static Elm_Genlist_Item_Class button_itc;
45 static int scaling_index = 0;
48 static Eina_Bool aspect_ratio = 0;
50 static Evas_Object *width_layout;
51 static Evas_Object *width_entry;
52 static Evas_Object *height_layout;
53 static Evas_Object *height_entry;
55 int pts_unstandardization(char *name)
57 char *ptr = NULL;/* Pointer into name */
58 PTS_RETV_IF(name == NULL, -1, "Invalid argument");
60 for (ptr = name; *ptr; ptr++) {
63 } else if ((*ptr >= 0 && *ptr < ' ') ||
64 *ptr == 127 || *ptr == '/' ||*ptr == '#') {
66 } else if (*ptr == 0x5F) {
67 *ptr = 0x20; /*convert _ to space*/
68 } else if (*ptr == '[' || *ptr == '(') {
84 char* pts_parse_protocol(char *addr)
87 char *printer_protocol = NULL;
89 PTS_RETV_IF(addr == NULL, NULL, "Invalid argument");
91 if (strstr(addr, "_pdl-datastream.") != NULL) {
92 printer_protocol = strdup("Network (RAW)");
93 } else if (strstr(addr, "_ipp.") != NULL) {
94 printer_protocol = strdup("Network (IPP)");
95 } else if (strstr(addr, "_printer.") != NULL) {
96 printer_protocol = strdup("Network (LPD)");
97 } else if (strstr(addr, "usb") != NULL) {
98 printer_protocol = strdup("USB");
100 printer_protocol = strdup("Unknown");
104 return printer_protocol;
109 * This function let the app create the label
111 * @param[in] parent the pointer to the parent of the label
112 * @param[in] desc the pointer to label text
114 Evas_Object *pts_create_label_btn(Evas_Object *parent, const char *label)
117 Evas_Object *btn = elm_button_add(parent);
118 elm_object_text_set(btn, label);
119 evas_object_show(btn);
126 * This function let the app create the base layout
128 * @param[in] parent the pointer to the parent of the base layout
129 * @param[in] desc the pointer to group of the base layout
131 Evas_Object *pts_create_base_layout_with_conform(Evas_Object *parent, const char *group)
134 char edj_file[128] = {0};
135 Evas_Object *base = NULL;
136 Evas_Object *conform = NULL;
140 app_get_resource("edje/mobileprint.edj", edj_file, 128);
142 conform = elm_conformant_add(parent);
143 evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
145 evas_object_size_hint_align_set(conform, EVAS_HINT_FILL, EVAS_HINT_FILL);
147 elm_win_resize_object_add(parent, conform);
149 base = elm_layout_add(conform);
151 r = elm_layout_file_set(base, edj_file, group);
153 evas_object_del(base);
156 elm_object_content_set(conform, base);
158 evas_object_show(conform);
164 Evas_Object *pts_create_base_layout(Evas_Object *parent, const char *group)
167 char edj_file[128] = {0};
168 Evas_Object *base = NULL;
172 app_get_resource("edje/mobileprint.edj", edj_file, 128);
174 base = elm_layout_add(parent);
176 r = elm_layout_file_set(base, edj_file, group);
178 evas_object_del(base);
181 evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
190 * This function let the app create the popup element
192 * @param[in] parent the pointer to the parent of the popup element
193 * @param[in] desc the pointer to description of the popup element
194 * @param[in] timeout the timeout value
196 Evas_Object *pts_create_popup(Evas_Object *parent, const char *desc, double timeout)
199 Evas_Object *notify = NULL;
200 notify = elm_popup_add(parent);
201 evas_object_size_hint_weight_set(notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
202 //elm_popup_mode_set(notify, ELM_POPUP_TYPE_ALERT);
203 elm_popup_timeout_set(notify, timeout);
204 elm_object_text_set(notify, desc);
205 evas_object_show(notify);
210 static void _pts_scaling_set_cb(void *data, Evas_Object *obj, void *event_info)
213 pts_appdata_t *ad = (pts_appdata_t *)data;
214 PTS_RET_IF(ad == NULL, "ad is NULL");
216 PTS_IF_DEL_OBJ(scaling_radio_main);
217 PTS_IF_DEL_OBJ(ad->scaling_popup_info.scaling_popup);
219 pts_main_view_rotate_image(ad, app_get_device_orientation());
223 static char *__pts_scaling_label_get(void *data, Evas_Object *obj, const char *part)
226 int index = (int)data;
228 char temp[1024] = {0};
230 if (strcmp(part, "elm.text") == 0) {
232 case PT_SCALING_FIT_TO_PAGE:
233 label = strdup(_("IDS_BT_OPT_FIT_TO_PAPER"));
235 case PT_SCALING_2_PAGES:
236 snprintf(temp,1024,_("IDS_PRT_BODY_PD_PAGES_ON_1_SHEET_ABB"),2);
237 label = strdup(temp);
239 case PT_SCALING_4_PAGES:
240 snprintf(temp,1024,_("IDS_PRT_BODY_PD_PAGES_ON_1_SHEET_ABB"),4);
241 label = strdup(temp);
244 label = strdup("Unknown option");
253 static Evas_Object *__pts_scaling_icon_get(void *data, Evas_Object *obj, const char *part)
257 int index = (int)data;
258 PTS_DEBUG("Passed index : %d", index);
261 if (!strcmp(part, "elm.icon") || !strcmp(part, "elm.swallow.icon")) {
262 radio = elm_radio_add(obj);
263 elm_radio_state_value_set(radio, index);
264 elm_radio_group_add(radio, scaling_radio_main);
265 PTS_DEBUG("scaling_index[%d]", scaling_index);
266 // It's filter to avoid all radio selection
267 if (scaling_index == index) {
268 elm_radio_value_set(radio, scaling_index);
269 PTS_DEBUG("OK...Set radio button using scaling_index[%d]", scaling_index);
272 evas_object_size_hint_weight_set(radio, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
273 evas_object_size_hint_align_set(radio, EVAS_HINT_FILL, EVAS_HINT_FILL);
282 static void __pts_scaling_sel(void *data, Evas_Object *obj, void *event_info)
286 pts_appdata_t *ad = (pts_appdata_t *)data;
287 PTS_RET_IF(NULL == ad, "ad is NULL");
290 Elm_Object_Item *item = event_info;
293 elm_genlist_item_selected_set(item, EINA_FALSE);
295 scaling = (int)elm_object_item_data_get(item);
297 PTS_DEBUG("Selected scaling : %d", scaling);
299 scaling_index = ad->list_info.active_printer->scaling = scaling;
301 // Now call real event trigger to update radio button when selected.
302 elm_genlist_item_update(item);
308 static void _pts_scaling_cancel_cb(void *data, Evas_Object *obj, void *event_info)
311 pts_appdata_t *ad = (pts_appdata_t *)data;
312 PTS_RET_IF(NULL == ad, "ad is NULL");
314 PTS_IF_DEL_OBJ(scaling_radio_main);
316 PTS_IF_DEL_OBJ(ad->scaling_popup_info.scaling_popup);
320 Evas_Object *pts_create_scaling_popup(Evas_Object *parent, pts_appdata_t *ad)
324 Evas_Object *genlist;
328 popup = elm_popup_add(parent);
329 elm_object_style_set(popup,"content_no_vhpad");
330 elm_object_part_text_set(popup, "title,text", _("IDS_PRT_BODY_SCALING_ABB"));
332 evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
334 Evas_Object *layout = elm_layout_add(popup);
335 elm_layout_theme_set(layout, "layout", "content", "min_menustyle");
336 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
338 btn1 = elm_button_add(popup);
339 elm_object_style_set(btn1,"popup_button/default");
340 elm_object_text_set(btn1, _("IDS_PRT_BODY_SCALING_ABB"));
341 elm_object_part_content_set(popup, "button1", btn1);
342 evas_object_smart_callback_add(btn1, "clicked", _pts_scaling_set_cb, ad);
344 genlist = elm_genlist_add(popup);
345 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
346 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
348 ea_object_event_callback_add(popup, EA_CALLBACK_BACK, _pts_scaling_cancel_cb, ad);
351 if (!scaling_radio_main) {
352 scaling_radio_main = elm_radio_add(genlist);
353 elm_radio_state_value_set(scaling_radio_main, scaling_index);
354 elm_radio_value_set(scaling_radio_main, scaling_index);
357 scaling_itc.item_style = "1text.1icon.2";
358 scaling_itc.func.text_get = __pts_scaling_label_get;
359 scaling_itc.func.content_get = __pts_scaling_icon_get;
360 scaling_itc.func.state_get = NULL;
361 scaling_itc.func.del = NULL;
363 Elm_Object_Item *item = NULL;
364 for (index = 0; index < (PT_SCALING_4_PAGES+1); index++) {
365 item = elm_genlist_item_append(genlist, &scaling_itc, (void *)index, NULL, ELM_GENLIST_ITEM_NONE, __pts_scaling_sel, ad);
366 PTS_DEBUG("index[%d] - item added : %s", index, (NULL == item)? "FAILURE" : "SUCCESS");
369 Evas_Object *box = elm_box_add(popup);
370 evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
372 elm_box_pack_end(box, genlist);
373 evas_object_show(genlist);
374 evas_object_size_hint_min_set(box, 400 * elm_config_scale_get(), elm_genlist_items_count(genlist) * 114 * elm_config_scale_get());
375 evas_object_show(box);
376 elm_object_part_content_set(layout, "elm.swallow.content" , box);
377 elm_object_content_set(popup, box);
378 elm_object_focus_set(popup, EINA_TRUE);
380 evas_object_show(popup);
382 ad->scaling_popup_info.scaling_popup = popup;
388 static void _pts_size_cancel_cb(void *data, Evas_Object *obj, void *event_info)
391 pts_appdata_t *ad = (pts_appdata_t *)data;
392 PTS_RET_IF(NULL == ad, "ad is NULL");
393 PTS_IF_DEL_OBJ(size_radio_main);
395 PTS_IF_DEL_OBJ(ad->size_popup_info.size_popup);
399 static char *__pts_size_label_get(void *data, Evas_Object *obj, const char *part)
402 int index = (int)data;
404 char custom[32] = {0,};
405 pts_appdata_t *ad = pts_get_appdata();
407 if (strcmp(part, "elm.text") == 0) {
409 case PTS_SIZE_FIT_TO_PAPER:
410 label = strdup(_("IDS_BT_OPT_FIT_TO_PAPER"));
413 label = strdup(IDS_BR_OPT_5X7);
416 label = strdup(IDS_BR_OPT_4X6);
419 label = strdup(IDS_BR_OPT_3_5X5);
421 case PTS_SIZE_WALLET:
422 label = strdup(IDS_BR_OPT_WALLET);
424 case PTS_SIZE_CUSTOM:
425 if (ad->size_popup_info.custom_unit == 1) { // cm unit
426 snprintf(custom, 32, "%s (%.1lfx%.1lfcm)", _("IDS_COM_SK_CUSTOM"), ad->size_popup_info.custom_height, ad->size_popup_info.custom_width);
427 } else if (ad->size_popup_info.custom_unit == 2) { // inch unit
428 snprintf(custom, 32, "%s (%.1lf\"x%.1lf\")", _("IDS_COM_SK_CUSTOM"), ad->size_popup_info.custom_height, ad->size_popup_info.custom_width);
430 snprintf(custom, 32, "%s (%.1lfx%.1lf)", _("IDS_COM_SK_CUSTOM"), ad->size_popup_info.custom_height, ad->size_popup_info.custom_width);
433 label = strdup(custom);
436 label = strdup("Unknown option");
445 static Evas_Object *__pts_size_icon_get(void *data, Evas_Object *obj, const char *part)
449 int index = (int)data;
450 PTS_DEBUG("Passed index : %d", index);
453 if (!strcmp(part, "elm.icon") || !strcmp(part, "elm.swallow.icon")) {
454 radio = elm_radio_add(obj);
455 elm_radio_state_value_set(radio, index);
456 elm_radio_group_add(radio, size_radio_main);
457 PTS_DEBUG("size_index[%d]", size_index);
458 // It's filter to avoid all radio selection
459 if (size_index == index) {
460 elm_radio_value_set(radio, size_index);
461 PTS_DEBUG("OK...Set radio button using size_index[%d]", size_index);
464 evas_object_size_hint_weight_set(radio, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
465 evas_object_size_hint_align_set(radio, EVAS_HINT_FILL, EVAS_HINT_FILL);
474 static void __pts_size_sel(void *data, Evas_Object *obj, void *event_info)
478 pts_appdata_t *ad = (pts_appdata_t *)data;
479 PTS_RET_IF(ad == NULL, "ad is NULL");
482 Elm_Object_Item *item = event_info;
485 elm_genlist_item_selected_set(item, EINA_FALSE);
487 size = (int)elm_object_item_data_get(item);
488 if (size > PTS_SIZE_FIT_TO_PAPER && size < PTS_SIZE_CUSTOM) {
489 PTS_DEBUG("Selected size : %d", size);
491 ad->size_popup_info.image_size = size;
493 // Now call real event trigger to update radio button when selected.
494 elm_genlist_item_update(item);
496 load_image_editor_ug(ad);
497 } else if (size == PTS_SIZE_CUSTOM) {
498 pts_create_custom_popup(ad->main_info.navi, ad);
499 } else if (size == PTS_SIZE_FIT_TO_PAPER) {
500 size_index = ad->size_popup_info.image_size = size;
501 // just back to fit-to-paper of original image
502 PTS_IF_FREE_MEM(ad->printing_data.request_files[0]);
503 ad->printing_data.request_files[0] = strdup(ad->printing_data.input_file);
504 PTS_DEBUG("original_image_path: %s", ad->printing_data.request_files[0]);
505 pts_main_view_rotate_image(ad, app_get_device_orientation());
507 PTS_DEBUG("Unknown size");
510 PTS_IF_DEL_OBJ(ad->size_popup_info.size_popup);
511 PTS_IF_DEL_OBJ(size_radio_main);
516 Evas_Object *pts_create_size_popup(Evas_Object *parent, pts_appdata_t *ad)
520 Evas_Object *genlist;
524 popup = elm_popup_add(parent);
525 elm_object_style_set(popup,"content_no_vhpad");
526 elm_object_part_text_set(popup, "title,text", _("IDS_IMGE_BODY_SIZE"));
528 evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
530 Evas_Object *layout = elm_layout_add(popup);
531 elm_layout_theme_set(layout, "layout", "content", "min_menustyle");
532 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
534 btn1 = elm_button_add(popup);
535 elm_object_style_set(btn1, "popup_button/default");
536 elm_object_text_set(btn1, _("IDS_COM_SK_CANCEL"));
537 elm_object_part_content_set(popup, "button1", btn1);
538 evas_object_smart_callback_add(btn1, "clicked", _pts_size_cancel_cb, ad);
540 ea_object_event_callback_add(popup, EA_CALLBACK_BACK, _pts_size_cancel_cb, ad);
542 genlist = elm_genlist_add(popup);
543 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
544 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
546 if (!size_radio_main) {
547 size_radio_main = elm_radio_add(genlist);
548 elm_radio_state_value_set(size_radio_main, size_index);
549 elm_radio_value_set(size_radio_main, size_index);
552 size_itc.item_style = "1text.1icon.2";
553 size_itc.func.text_get = __pts_size_label_get;
554 size_itc.func.content_get = __pts_size_icon_get;
555 size_itc.func.state_get = NULL;
556 size_itc.func.del = NULL;
558 Elm_Object_Item *item = NULL;
559 for (index = 0; index < PTS_SIZE_MAX; index++) {
560 item = elm_genlist_item_append(genlist, &size_itc, (void *)index, NULL, ELM_GENLIST_ITEM_NONE, __pts_size_sel, ad);
561 PTS_DEBUG("index[%d] - item added : %s", index, (NULL == item)? "FAILURE" : "SUCCESS");
564 Evas_Object *box = elm_box_add(popup);
565 evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
567 elm_box_pack_end(box, genlist);
569 ad->size_popup_info.size_popup_portrait_height = elm_genlist_items_count(genlist) * 114 * elm_config_scale_get();
570 ad->size_popup_info.size_popup_landscape_height = 300;
574 orientation = elm_win_rotation_get(ad->win);
576 if (APP_DEVICE_ORIENTATION_0 == orientation ||
577 APP_DEVICE_ORIENTATION_180 == orientation) {
578 evas_object_size_hint_min_set(box, 400 * elm_config_scale_get(), ad->size_popup_info.size_popup_portrait_height);
580 evas_object_size_hint_min_set(box, 400 * elm_config_scale_get(), ad->size_popup_info.size_popup_landscape_height);
583 evas_object_show(box);
584 elm_object_part_content_set(layout, "elm.swallow.content" , box);
585 elm_object_content_set(popup, box);
586 ad->size_popup_info.size_popup_box = box;
587 elm_object_focus_set(popup, EINA_TRUE);
588 evas_object_show(genlist);
589 evas_object_show(popup);
591 ad->size_popup_info.size_popup = popup;
597 static void _pts_custom_ok_cb(void *data, Evas_Object *obj, void *event_info)
601 pts_appdata_t *ad = (pts_appdata_t *)data;
602 PTS_RET_IF(ad == NULL, "ad is NULL");
604 ad->size_popup_info.image_size = PTS_SIZE_CUSTOM;
605 load_image_editor_ug(ad);
608 PTS_IF_DEL_OBJ(ad->size_popup_info.custom_popup);
609 elm_theme_extension_del(NULL, RESDIR"/edje/genlist_custom.edj");
614 static void _pts_custom_cancel_cb(void *data, Evas_Object *obj, void *event_info)
618 pts_appdata_t *ad = (pts_appdata_t *)data;
619 PTS_RET_IF(ad == NULL, "ad is NULL");
621 PTS_IF_DEL_OBJ(ad->size_popup_info.custom_popup);
623 // FIXME - just back to original size
627 get_image_resolution(ad->printing_data.input_file, &tmp_width, &tmp_height);
628 ad->size_popup_info.custom_width = (double)tmp_width;
629 ad->size_popup_info.custom_height = (double)tmp_height;
630 ad->size_popup_info.custom_w_ratio = ad->size_popup_info.custom_width / ad->size_popup_info.custom_height;
631 PTS_DEBUG("Original image size : %lfx%lf(%lfx1)", ad->size_popup_info.custom_width, ad->size_popup_info.custom_height, ad->size_popup_info.custom_w_ratio);
632 // original image size (unit cm) calculated by 300dpi
633 ad->size_popup_info.custom_width = (ad->size_popup_info.custom_width / 300) * 2.54;
634 ad->size_popup_info.custom_height = (ad->size_popup_info.custom_height / 300) * 2.54;
635 ad->size_popup_info.custom_unit = 1; // cm unit
637 elm_theme_extension_del(NULL, RESDIR"/edje/genlist_custom.edj");
642 static char *__pts_custom_label_get(void *data, Evas_Object *obj, const char *part)
645 int index = (int)data;
648 if (strcmp(part, "elm.text") == 0) {
650 label = strdup(_("IDS_IMGE_BODY_WIDTH"));
651 } else if (index == 2) {
652 label = strdup(_("IDS_IMGE_BODY_HEIGHT"));
653 } else if (index == 4) {
654 label = strdup(_("IDS_PRT_BODY_KEEP_ASPECT_RATIO_ABB"));
656 label = strdup("Unknown label");
664 static void _changed_cb(void *data, Evas_Object *obj, void *event_info)
667 char *input_str = NULL;
668 const char *entry_text = NULL;
669 int index = (int)data;
671 entry_text = elm_entry_entry_get(obj);
672 if ((input_str = elm_entry_markup_to_utf8(entry_text))) {
673 pts_appdata_t *ad = pts_get_appdata();
676 ad->size_popup_info.custom_width = atoi(input_str);
677 } else if (index == 3) {
678 ad->size_popup_info.custom_height = atoi(input_str);
680 PTS_DEBUG("Unknown index : %d", index);
683 PTS_DEBUG("Typed custom value : width[%lf] x height[%lf]", ad->size_popup_info.custom_width, ad->size_popup_info.custom_height);
685 PTS_IF_FREE_MEM(input_str);
690 static void _focused_cb(void *data, Evas_Object *obj, void *event_info) // Focused callback will show X marked button and hide guidetext.
693 elm_object_signal_emit(data, "elm,state,guidetext,hide", "elm");
697 static void _unfocused_cb(void *data, Evas_Object *obj, void *event_info) // Unfocused callback will show guidetext and hide X marked button.
700 char temp_size[32] = {0,};
702 if (elm_entry_is_empty(obj)) {
703 elm_object_signal_emit(data, "elm,state,guidetext,show", "elm");
707 pts_appdata_t *ad = pts_get_appdata();
709 if (obj == width_entry) {
710 ad->size_popup_info.custom_height = ad->size_popup_info.custom_width / ad->size_popup_info.custom_w_ratio;
711 snprintf(temp_size, 32, "%.1lf", ad->size_popup_info.custom_height);
712 elm_object_signal_emit(height_layout, "elm,state,guidetext,hide", "elm");
713 elm_entry_entry_set(height_entry, temp_size);
714 } else if (obj == height_entry) {
715 ad->size_popup_info.custom_width = ad->size_popup_info.custom_height * ad->size_popup_info.custom_w_ratio;
716 snprintf(temp_size, 32, "%.1lf", ad->size_popup_info.custom_width);
717 elm_object_signal_emit(width_layout, "elm,state,guidetext,hide", "elm");
718 elm_entry_entry_set(width_entry, temp_size);
720 PTS_DEBUG("Unknown entry : %p", obj);
726 static void _eraser_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source) // When X marked button clicked, make string as empty.
729 elm_entry_entry_set(data, "");
733 static Evas_Object *__pts_singleline_editfield_add(Evas_Object *parent, int index) // For single lined editfield without top title.
736 Evas_Object *layout, *entry;
737 static Elm_Entry_Filter_Accept_Set digits_filter_data;
738 char temp_size[32] = {0,};
739 pts_appdata_t *ad = pts_get_appdata();
741 layout = elm_layout_add(parent);
742 elm_layout_theme_set(layout, "layout", "editfield", "default"); // Default editfield layout style without top title.
744 entry = elm_entry_add(layout);
745 elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NUMBER);
746 elm_entry_scrollable_set(entry, EINA_TRUE); // Make entry as scrollable single line.
747 elm_entry_single_line_set(entry, EINA_TRUE);
748 elm_object_signal_emit(layout, "elm,state,eraser,show", "elm");
749 evas_object_smart_callback_add(entry, "changed", _changed_cb, (void *)index);
750 evas_object_smart_callback_add(entry, "focused", _focused_cb, layout);
751 evas_object_smart_callback_add(entry, "unfocused", _unfocused_cb, layout);
753 digits_filter_data.accepted = "0123456789.";
754 digits_filter_data.rejected = NULL;
755 elm_entry_markup_filter_append(entry, elm_entry_filter_accept_set, &digits_filter_data);
757 elm_object_part_content_set(layout, "elm.swallow.content", entry);
759 snprintf(temp_size, 32, "%.1lf", ad->size_popup_info.custom_width);
760 elm_object_part_text_set(layout, "elm.guidetext", temp_size);
761 width_layout = layout;
763 } else if (index == 3) {
764 snprintf(temp_size, 32, "%.1lf", ad->size_popup_info.custom_height);
765 elm_object_part_text_set(layout, "elm.guidetext", temp_size);
766 height_layout = layout;
767 height_entry = entry;
769 elm_object_part_text_set(layout, "elm.guidetext", "Custom Size");
772 elm_object_signal_callback_add(layout, "elm,eraser,clicked", "elm", _eraser_clicked_cb, entry);
774 evas_object_show(entry);
780 static void _pts_custom_unit_cb(void *data, Evas_Object *obj, void *event_info)
783 char temp[32] = {0,};
784 pts_appdata_t *ad = pts_get_appdata();
785 PTS_DEBUG("Current unit : %d", ad->size_popup_info.custom_unit);
787 if (ad->size_popup_info.custom_unit == 1) { // cm to inch
788 ad->size_popup_info.custom_unit = 2;
789 ad->size_popup_info.custom_width = ad->size_popup_info.custom_width / 2.54;
790 ad->size_popup_info.custom_height = ad->size_popup_info.custom_height / 2.54;
791 snprintf(temp, 32, "%s", _("IDS_COM_BODY_UNIT_CM"));
792 } else if (ad->size_popup_info.custom_unit == 2) { // inch to cm
793 ad->size_popup_info.custom_unit = 1;
794 ad->size_popup_info.custom_width = ad->size_popup_info.custom_width * 2.54;
795 ad->size_popup_info.custom_height = ad->size_popup_info.custom_height * 2.54;
796 snprintf(temp, 32, "%s", _("IDS_COM_BODY_UNIT_INCH"));
798 PTS_DEBUG("Unknown unit");
803 elm_object_text_set(obj, temp);
805 snprintf(temp, 32, "%.1lf", ad->size_popup_info.custom_width);
806 elm_object_signal_emit(width_layout, "elm,state,guidetext,hide", "elm");
807 elm_entry_entry_set(width_entry, temp);
808 snprintf(temp, 32, "%.1lf", ad->size_popup_info.custom_height);
809 elm_object_signal_emit(height_layout, "elm,state,guidetext,hide", "elm");
810 elm_entry_entry_set(height_entry, temp);
812 PTS_DEBUG("Changed unit : %d", ad->size_popup_info.custom_unit);
816 static void _pts_custom_unit_inch_cb(void *data, Evas_Object *obj, void *event_info)
819 char temp[32] = {0,};
820 pts_appdata_t *ad = pts_get_appdata();
821 PTS_DEBUG("Current unit : %d", ad->size_popup_info.custom_unit);
823 if (ad->size_popup_info.custom_unit == 1) { // cm to inch
824 ad->size_popup_info.custom_unit = 2;
825 ad->size_popup_info.custom_width = ad->size_popup_info.custom_width / 2.54;
826 ad->size_popup_info.custom_height = ad->size_popup_info.custom_height / 2.54;
828 PTS_DEBUG("Unknown unit");
833 snprintf(temp, 32, "%.1lf", ad->size_popup_info.custom_width);
834 elm_object_signal_emit(width_layout, "elm,state,guidetext,hide", "elm");
835 elm_entry_entry_set(width_entry, temp);
836 snprintf(temp, 32, "%.1lf", ad->size_popup_info.custom_height);
837 elm_object_signal_emit(height_layout, "elm,state,guidetext,hide", "elm");
838 elm_entry_entry_set(height_entry, temp);
840 PTS_DEBUG("Changed unit : %d", ad->size_popup_info.custom_unit);
844 static void _pts_custom_unit_cm_cb(void *data, Evas_Object *obj, void *event_info)
847 char temp[32] = {0,};
848 pts_appdata_t *ad = pts_get_appdata();
849 PTS_DEBUG("Current unit : %d", ad->size_popup_info.custom_unit);
851 if (ad->size_popup_info.custom_unit == 2) { // inch to cm
852 ad->size_popup_info.custom_unit = 1;
853 ad->size_popup_info.custom_width = ad->size_popup_info.custom_width * 2.54;
854 ad->size_popup_info.custom_height = ad->size_popup_info.custom_height * 2.54;
856 PTS_DEBUG("Unknown unit");
861 snprintf(temp, 32, "%.1lf", ad->size_popup_info.custom_width);
862 elm_object_signal_emit(width_layout, "elm,state,guidetext,hide", "elm");
863 elm_entry_entry_set(width_entry, temp);
864 snprintf(temp, 32, "%.1lf", ad->size_popup_info.custom_height);
865 elm_object_signal_emit(height_layout, "elm,state,guidetext,hide", "elm");
866 elm_entry_entry_set(height_entry, temp);
868 PTS_DEBUG("Changed unit : %d", ad->size_popup_info.custom_unit);
872 static Evas_Object *__pts_custom_icon_get(void *data, Evas_Object *obj, const char *part)
875 Evas_Object *editfield = NULL;
876 Evas_Object *check = NULL;
877 Evas_Object *button = NULL;
878 int index = (int)data;
879 char unit[32] = {0,};
881 PTS_DEBUG("index: %d, passed part: %s", index, part);
882 if (!strcmp(part, "elm.icon")) {
884 case 1: // width text field
885 case 3: // height text field
886 editfield = __pts_singleline_editfield_add(obj, index);
888 case 4: // check aspect ratio
889 check = elm_check_add(obj);
890 //set the State pointer to keep the current UI state of Checkbox.
891 elm_check_state_pointer_set(check, &aspect_ratio);
893 evas_object_size_hint_weight_set(check, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
894 evas_object_size_hint_align_set(check, EVAS_HINT_FILL, EVAS_HINT_FILL);
896 case 5: // change unit button
897 button = elm_button_add(obj);
898 snprintf(unit, 32, "%s", _("IDS_COM_BODY_UNIT_INCH"));
899 elm_object_text_set(button, unit);
900 elm_object_part_content_set(obj, "button1", button);
901 evas_object_smart_callback_add(button, "clicked", _pts_custom_unit_cb, obj);
904 } else if (!strcmp(part, "elm.icon.1")) {
905 button = elm_button_add(obj);
906 snprintf(unit, 32, "%s", _("IDS_COM_BODY_UNIT_INCH"));
907 elm_object_text_set(button, unit);
908 elm_object_part_content_set(obj, "button1", button);
909 evas_object_smart_callback_add(button, "clicked", _pts_custom_unit_inch_cb, obj);
911 } else if (!strcmp(part, "elm.icon.2")) {
912 button = elm_button_add(obj);
913 snprintf(unit, 32, "%s", _("IDS_COM_BODY_UNIT_CM"));
914 elm_object_text_set(button, unit);
915 elm_object_part_content_set(obj, "button2", button);
916 evas_object_smart_callback_add(button, "clicked", _pts_custom_unit_cm_cb, obj);
919 PTS_DEBUG("Index: %d, Unknown part: %s", index, part);
926 static void __pts_custom_sel(void *data, Evas_Object *obj, void *event_info)
930 pts_appdata_t *ad = (pts_appdata_t *)data;
931 PTS_RET_IF(ad == NULL, "ad is NULL");
934 Elm_Object_Item *item = event_info;
937 elm_genlist_item_selected_set(item, EINA_FALSE);
939 index = (int)elm_object_item_data_get(item);
941 aspect_ratio = !aspect_ratio;
942 PTS_DEBUG("Preserve aspect ratio : %d", aspect_ratio);
944 elm_genlist_item_update(item);
946 PTS_DEBUG("Unknown index");
952 Evas_Object *pts_create_custom_popup(Evas_Object *parent, pts_appdata_t *ad)
956 Evas_Object *genlist;
957 Evas_Object *ok_button;
958 Evas_Object *cancel_button;
961 popup = elm_popup_add(parent);
962 elm_object_style_set(popup,"content_no_vhpad");
963 elm_object_part_text_set(popup, "title,text", _("IDS_COM_SK_CUSTOM"));
964 evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
966 Evas_Object *layout = elm_layout_add(popup);
967 elm_layout_theme_set(layout, "layout", "content", "min_menustyle");
968 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
970 cancel_button = elm_button_add(popup);
971 elm_object_style_set(cancel_button,"popup_button/default");
972 elm_object_text_set(cancel_button, _("IDS_COM_SK_CANCEL"));
973 elm_object_part_content_set(popup, "button1", cancel_button);
974 evas_object_smart_callback_add(cancel_button, "clicked", _pts_custom_cancel_cb, ad);
976 ok_button = elm_button_add(popup);
977 elm_object_style_set(ok_button,"popup_button/default");
978 elm_object_text_set(ok_button, _("IDS_COM_SK_OK"));
979 elm_object_part_content_set(popup, "button2", ok_button);
980 evas_object_smart_callback_add(ok_button, "clicked", _pts_custom_ok_cb, ad);
982 elm_theme_extension_add(NULL, RESDIR"/edje/genlist_custom.edj");
983 PTS_DEBUG("Added extension theme");
985 genlist = elm_genlist_add(popup);
986 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
987 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
989 title_itc.item_style = "dialogue/title";
990 title_itc.func.text_get = __pts_custom_label_get;
991 title_itc.func.content_get = NULL;
992 title_itc.func.state_get = NULL;
993 title_itc.func.del = NULL;
995 text_itc.item_style = "1icon";
996 text_itc.func.text_get = NULL;
997 text_itc.func.content_get = __pts_custom_icon_get;
998 text_itc.func.state_get = NULL;
999 text_itc.func.del = NULL;
1001 check_itc.item_style = "1text.1icon.2";
1002 check_itc.func.text_get = __pts_custom_label_get;
1003 check_itc.func.content_get = __pts_custom_icon_get;
1004 check_itc.func.state_get = NULL;
1005 check_itc.func.del = NULL;
1007 //button_itc.item_style = "dialogue/bg/2icon";
1008 button_itc.item_style = "custom/2icon";
1009 button_itc.func.text_get = NULL;
1010 button_itc.func.content_get = __pts_custom_icon_get;
1011 button_itc.func.state_get = NULL;
1012 button_itc.func.del = NULL;
1014 Elm_Object_Item *item = NULL;
1015 Elm_Genlist_Item_Class *temp_itc = NULL;
1016 Evas_Smart_Cb temp_cb = NULL;
1018 for (index = 0; index < 6; index++) {
1019 if (index == 0 || index == 2) { // width&height title
1020 temp_itc = &title_itc;
1021 } else if (index == 1 || index == 3) { // width&height text field
1022 temp_itc = &text_itc;
1023 } else if (index == 4) { // aspect ratio check
1024 temp_itc = &check_itc;
1025 temp_cb = __pts_custom_sel;
1026 } else if (index == 5) { // change unit button
1027 temp_itc = &button_itc;
1031 item = elm_genlist_item_append(genlist, temp_itc, (void *)index, NULL, ELM_GENLIST_ITEM_NONE, temp_cb, ad);
1033 elm_genlist_item_select_mode_set(item, ELM_OBJECT_SELECT_MODE_NONE);
1035 PTS_DEBUG("index[%d] - item added : %s", index, (NULL == item)? "FAILURE" : "SUCCESS");
1038 Evas_Object *box = elm_box_add(popup);
1039 evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1041 elm_box_pack_end(box, genlist);
1043 ad->size_popup_info.custom_popup_portrait_height = (5 * 114 + 4) * elm_config_scale_get();
1044 ad->size_popup_info.custom_popup_landscape_height = 300;
1045 int orientation = 0;
1047 orientation = elm_win_rotation_get(ad->win);
1049 if (APP_DEVICE_ORIENTATION_0 == orientation ||
1050 APP_DEVICE_ORIENTATION_180 == orientation) {
1051 evas_object_size_hint_min_set(box, 400 * elm_config_scale_get(), ad->size_popup_info.custom_popup_portrait_height);
1053 evas_object_size_hint_min_set(box, 400 * elm_config_scale_get(), ad->size_popup_info.custom_popup_landscape_height);
1056 elm_object_part_content_set(layout, "elm.swallow.content" , box);
1057 //evas_object_event_callback_add(popup, EVAS_CALLBACK_MOUSE_UP, _pts_mouse_cb, ad);
1058 ea_object_event_callback_add(popup, EA_CALLBACK_BACK, _pts_custom_cancel_cb, ad);
1059 elm_object_focus_set(popup, EINA_TRUE);
1061 elm_object_content_set(popup, box);
1062 ad->size_popup_info.custom_popup_box = box;
1064 evas_object_show(genlist);
1065 evas_object_show(popup);
1067 ad->size_popup_info.custom_popup = popup;
1073 static Evas_Object *__pts_utils_create_conformant(Evas_Object *parent)
1076 Evas_Object *conform = NULL;
1077 elm_win_conformant_set(parent, TRUE);
1078 conform = elm_conformant_add(parent);
1080 elm_object_style_set(conform, "internal_layout");
1082 //evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1083 //evas_object_size_hint_align_set(conform, EVAS_HINT_FILL, EVAS_HINT_FILL);
1085 evas_object_show(conform);
1090 Evas_Object *pts_utils_create_layout(Evas_Object *navi_frame)
1092 Evas_Object *layout;
1093 layout = elm_layout_add(navi_frame);
1094 elm_layout_theme_set(layout, "layout", "application", "default");
1095 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1097 //Evas_Object *bg = elm_bg_add(layout);
1098 //evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1099 //elm_object_style_set(bg, "group_list");
1100 //elm_object_part_content_set(layout, "elm.swallow.bg", bg);
1102 //Evas_Object *conform = __pts_utils_create_conformant(layout);
1103 //assertm_if(NULL == conform, "NULL!!");
1104 //elm_object_part_content_set(layout, "elm.swallow.content", conform);
1105 //elm_object_part_content_set(layout, "elm.swallow.content", layout);
1106 evas_object_show(layout);
1112 * this function is used to compose folder and filename.
1114 char **__compose_image_files_path(char *folder, const char **filesname, const int num_of_files)
1117 PTS_RETV_IF(folder == NULL, NULL, "folder is NULL");
1118 PTS_RETV_IF(filesname == NULL, NULL, "filesname is NULL");
1119 PTS_RETV_IF(num_of_files <= 0, NULL, "num is invalid(%d)",num_of_files);
1121 char **paths = NULL;
1122 paths = (char **)malloc(sizeof(char *)*num_of_files);
1123 PTS_RETV_IF(paths == NULL , NULL, "malloc failed!");
1127 char filepath[512] = {0};
1129 for (; count < num_of_files ; count++) {
1130 snprintf(filepath, 512, "%s/%s", folder, filesname[count]);
1132 paths[count] = strdup(filepath);
1133 if (paths[count] == NULL) {
1134 PTS_DEBUG("Failed to strdup");
1135 for (index = 0 ; index < count ; index++) {
1136 PTS_IF_FREE_MEM(paths[index]);
1138 PTS_IF_FREE_MEM(paths);
1141 PTS_DEBUG("files[%d]: %s", count, paths[count]);
1149 * validate the path of image files.
1151 bool __validate_file_type(char **files, int num)
1155 PTS_RETV_IF(files == NULL || num <= 0, false, "the input param is invalid!");
1159 const int filters_num = 16;
1160 /* the image type that cups supports */
1161 const char *filters[] = {".gif", ".bmp", ".sgi", ".ras", ".pbm", ".pgm", ".ppm", ".pcd",
1162 ".pix", ".png", ".jpeg", ".jpg", ".jpe", ".tiff", ".tif", ".pdf"
1165 for (; i < num; i++) {
1166 path = *(files + i);
1168 /* check whether the file is exist */
1172 ret = stat(path, &buf);
1173 PTS_RETV_IF(ret != 0, false, "get file(%s) status failed!", path);
1175 /* check whether the file can be supported */
1177 p = strrchr(path, '.');
1178 PTS_RETV_IF(p == NULL, false, "get file(%s) filter failed!", path);
1183 for (; j < filters_num; j++) {
1184 if (0 == strcasecmp(p, filters[j])) {
1189 PTS_RETV_IF(tag == 0, false, "the file(%s) can't be supported!", path);
1197 * validate the path of image files.
1199 bool _is_pdf_file_type(char **files, int num)
1203 PTS_RETV_IF(files == NULL || num <= 0, false, "the input param is invalid!");
1207 const int filters_num = 1;
1208 /* the image type that cups supports */
1209 const char *filters[] = {".pdf"};
1211 for (; i < num; i++) {
1212 path = *(files + i);
1214 /* check whether the file is exist */
1218 ret = stat(path, &buf);
1219 PTS_RETV_IF(ret != 0, false, "get file(%s) status failed!", path);
1221 /* check whether the file can be supported */
1223 p = strrchr(path, '.');
1224 PTS_RETV_IF(p == NULL, false, "get file(%s) filter failed!", path);
1229 for (; j < filters_num; j++) {
1230 if (0 == strcasecmp(p, filters[j])) {
1235 PTS_RETV_IF(tag == 0, false, "the file(%s) can't be supported!", path);
1243 * validate the path of image files.
1245 bool _is_img_file_type(char **files, int num)
1249 PTS_RETV_IF(files == NULL || num <= 0, false, "the input param is invalid!");
1253 const int filters_num = 15;
1254 /* the image type that cups supports */
1255 const char *filters[] = {".gif", ".bmp", ".sgi", ".ras", ".pbm", ".pgm", ".ppm", ".pcd",
1256 ".pix", ".png", ".jpeg", ".jpg", ".jpe", ".tiff", ".tif"};
1258 for (; i < num; i++) {
1259 path = *(files + i);
1261 /* check whether the file is exist */
1265 ret = stat(path, &buf);
1266 PTS_RETV_IF(ret != 0, false, "get file(%s) status failed!", path);
1268 /* check whether the file can be supported */
1270 p = strrchr(path, '.');
1271 PTS_RETV_IF(p == NULL, false, "get file(%s) filter failed!", path);
1276 for (; j < filters_num; j++) {
1277 if (0 == strcasecmp(p, filters[j])) {
1282 PTS_RETV_IF(tag == 0, false, "the file(%s) can't be supported!", path);
1289 inline char *_pts_printing_data_get_directory(pts_printing_data_t *data)
1291 return data->directory;
1294 inline char **_pts_printing_data_get_request_files(pts_printing_data_t *data)
1296 return data->request_files;
1298 inline int _pts_printing_data_get_files_count(pts_printing_data_t *data)
1300 return data->num_of_files;
1303 inline int _pts_printing_data_get_index(pts_printing_data_t *data)
1305 return data->current_index;
1308 inline char *_pts_printing_data_get_type(pts_printing_data_t *data)
1313 Eina_Bool _pts_printing_data_set_directory(const char *directory, pts_printing_data_t *data)
1315 PTS_RETV_IF(directory == NULL, EINA_FALSE, "directory is NULL");
1316 PTS_RETV_IF(data == NULL, EINA_FALSE, "data is NULL");
1318 data->directory = strdup(directory);
1320 PTS_RETV_IF(data->directory == NULL, EINA_FALSE, "Failed to strdup");
1324 Eina_Bool _pts_printing_data_set_request_files(const char **request_files, const int files_count, pts_printing_data_t *data)
1326 PTS_RETV_IF(request_files == NULL, EINA_FALSE, "request_files is NULL");
1327 PTS_RETV_IF(files_count <= 0, EINA_FALSE, "files_count is less than zero");
1330 count = _pts_printing_data_get_files_count(data);
1331 PTS_RETV_IF(count != files_count, EINA_FALSE, "files count is not same with argument");
1334 char **composite_files = NULL;
1337 temp = _pts_printing_data_get_directory(data);
1339 composite_files = __compose_image_files_path(temp, request_files, count);
1340 PTS_RETV_IF(composite_files == NULL, EINA_FALSE, "compose the path of print files failed!");
1341 data->request_files = composite_files;
1343 data->request_files = (char **)calloc(count, sizeof(char *));
1344 PTS_RETV_IF(data->request_files == NULL, EINA_FALSE, "Failed to calloc");
1347 for (index = 0 ; index < count ; index++) {
1348 temp = strdup(request_files[index]);
1349 PTS_RETV_IF(temp == NULL, EINA_FALSE, "Failed to strdup");
1350 data->request_files[index] = temp;
1355 ret = __validate_file_type(data->request_files, files_count);
1356 PTS_RETV_IF(ret != true, EINA_FALSE, "files is invalid");
1362 Eina_Bool _pts_printing_data_set_files_count(const char *num_of_files, pts_printing_data_t *data)
1364 PTS_RETV_IF(num_of_files == NULL, EINA_FALSE,"num_of_files is NULL");
1365 PTS_RETV_IF(data == NULL, EINA_FALSE, "data is NULL");
1368 count = atoi(num_of_files);
1369 PTS_RETV_IF(count <=0, EINA_FALSE, "num_of_files is less or equal than zero");
1370 data->num_of_files = count;
1374 Eina_Bool _pts_printing_data_set_index(const char *current_index, pts_printing_data_t *data)
1376 PTS_RETV_IF(current_index == NULL, EINA_FALSE,"current_index is NULL");
1377 PTS_RETV_IF(data == NULL, EINA_FALSE, "data is NULL");
1380 index = atoi(current_index);
1382 PTS_RETV_IF(index < 0, EINA_FALSE, "index is less than zero");
1383 if (index >= _pts_printing_data_get_files_count(data)) {
1384 PTS_DEBUG("the current index of print files(%s) is invalid!", index);
1387 data->current_index = index;
1392 Eina_Bool _is_document_ux_type(const char *type)
1394 PTS_RETV_IF(type == NULL, EINA_FALSE, "type is NULL");
1395 if (strcasecmp(type, "DOC") == 0) {
1401 Eina_Bool _is_image_ux_type(const char *type)
1403 PTS_RETV_IF(type == NULL, EINA_FALSE, "type is NULL");
1404 if (strcasecmp(type, "IMG") == 0) {
1410 Eina_Bool _is_valid_print_file_type(const char *type)
1412 if (strcasecmp(type, "IMG") && strcasecmp(type,"DOC") && strcasecmp(type,"WEB")) {
1413 PTS_DEBUG("the type of print files(%s) is invalid!", type);
1420 Eina_Bool _pts_printing_data_set_type(const char *type, pts_printing_data_t *data)
1422 PTS_RETV_IF(type == NULL, EINA_FALSE, "type is NULL");
1423 PTS_RETV_IF(data == NULL, EINA_FALSE, "data is NULL");
1424 PTS_RETV_IF(_is_valid_print_file_type(type) == EINA_FALSE, EINA_FALSE, "invalid type");
1426 data->type = strdup(type);
1427 PTS_RETV_IF(data->type == NULL, EINA_FALSE, "Failed to strdup");