fix: Remove a strong theme dependency for the application layout.
[apps/core/preloaded/calculator.git] / src / calculator_edje.c
1 /*
2 *
3 * Copyright 2012  Samsung Electronics Co., Ltd
4 *
5 * Licensed under the Flora License, Version 1.1 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *    http://floralicense.org/license
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 #include <stdbool.h>            /*  true/false */
20 #include <Elementary.h>
21 #include <dlog.h>
22
23 #include "calc-main.h"
24 #include "calculator_parser.h"
25 #include "calc-string.h"
26 #include "calc-expression.h"
27 #include "calc-view.h"
28 #include <feedback.h>
29 #include <vconf.h>
30
31 #define CALCULATOR_CHAR_IS_OPERATOR(C) ((C == '+')||(C == '-')||(C == 'x')||(C == '/')) /**<judge if a char is a basic operator*/
32 #define CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(C) ((C == 'x')||(C == '/'))                    /**<judge if an operator is "*" or "/"*/
33 #define CALCULATOR_CHAR_IS_PLUS_DEDUCT(C) ((C == '+')||(C == '-'))
34 #define CALCULATOR_CHAR_IS_DIGITAL(C)(C >= '0' && C <= '9')
35 #define CALCULATOR_IS_DIGIT_DOT(ch, decimal) (isdigit(ch) || decimal == (ch))
36
37 static Elm_Entry_Filter_Limit_Size limit_filter_data;
38 extern void _calc_view_show_newest_histroy(Evas_Object * entry);
39 extern void _calc_view_clear_histroy(Evas_Object * entry);
40 extern gboolean __calculator_search_function(char *op, int* len);
41 static void __calculator_wrong_format_create(char * wrong_string);
42 void calc_view_load(struct appdata *ad);
43
44 static struct appdata *ad;      /* will be removed */
45 static calculator_state_t calculator_state = CALCULATOR_WAITING_INPUT;
46 static double last_result = 0.0;
47 int calculator_cursor_pos = 0;
48 char calculator_input_str[MAX_EXPRESSION_LENGTH] = { 0 };
49 char calculator_before_paste_str[MAX_EXPRESSION_LENGTH] = { 0 };
50 bool paste_flag = FALSE;
51
52 struct lconv *locale = NULL;
53 char *decimal = NULL;
54 char *separator = NULL;
55 char decimal_ch = 0;
56 char separator_ch = 0;
57
58 int cur_fontsize = 70;
59 int small_fontsize = 58;
60 int default_fontsize = 0;
61 int min_len = 13;
62 int max_len = 0;
63 int scientific_result_len = 8;
64
65 bool select_mode = FALSE;
66
67 static op_item_t calc_op_item[] = {
68         {OP_INVALID, "", NULL},
69
70         /* basic */
71         {OP_PARENTHESIS, "()", NULL},
72         {OP_DELETE, "<-", NULL},
73         {OP_CLEAR, "C", NULL},
74         {OP_DIVIDE, "/", NULL},
75
76         {OP_NUM_7, "7", NULL},
77         {OP_NUM_8, "8", NULL},
78         {OP_NUM_9, "9", NULL},
79         {OP_MULTIPLY, "x", NULL},
80
81         {OP_NUM_4, "4", NULL},
82         {OP_NUM_5, "5", NULL},
83         {OP_NUM_6, "6", NULL},
84         {OP_MINUS, "-", NULL},
85
86         {OP_NUM_1, "1", NULL},
87         {OP_NUM_2, "2", NULL},
88         {OP_NUM_3, "3", NULL},
89         {OP_PLUS, "+", NULL},
90
91         {OP_DOT, ".", NULL},
92         {OP_NUM_0, "0", NULL},
93         {OP_PLUS_MINUS, "+/-", NULL},
94         {OP_EQUAL, "=", NULL},
95
96         /* functional */
97         {OP_PERCENT, "%", NULL},
98         {OP_ROOT, "sqrt", "sqrt("},
99         {OP_FACT, "x!", "!"},
100
101         {OP_SIN, "sin", "sin("},
102         {OP_COS, "cos", "cos("},
103         {OP_TAN, "tan", "tan("},
104
105         {OP_LN, "ln", "ln("},
106         {OP_LOG, "log", "log("},
107         {OP_1X, "1/x", "1/x"},
108
109         {OP_10X, "10^x", "10^("},
110         {OP_X2, "x^2", "^2"},
111         {OP_XY, "x^y", "^("},
112
113         {OP_ABS, "abs", "abs("},
114         {OP_PI, "Pi", "p"},
115         {OP_E, "e", "e"},
116 };
117 char *error_string[] = {
118     "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE",
119     "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE",
120     "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE",
121     "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO",
122     "IDS_CCL_POP_NO_NUMBER_ERROR",
123     "IDS_CCL_POP_ERROR",
124     "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR",
125     "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION",
126     "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION",
127     "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION",
128     "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION",
129     "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION",
130     "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION",
131     "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION",
132     "IDS_CCL_POP_NO_OPERATOR_ERROR",
133     "IDS_CCL_POP_SYNTAX_ERROR",
134     "IDS_CCL_POP_INPUT_ERROR",
135 };
136
137 calculator_state_t calculator_get_state()
138 {
139         return calculator_state;
140 }
141
142 void _calc_add_tag(char *string, char *format_string)
143 {
144         CALC_FUN_BEG();
145         int i = 0;
146         int begin = 0;
147         int end = 0;
148         char buf[MAX_EXPRESSION_LENGTH] = { 0 };
149         char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
150         char *p = NULL;
151         while (string[i] != '\0') {
152                 if (CALCULATOR_CHAR_IS_DIGITAL(string[i])
153                     || string[i] == separator_ch || string[i] == decimal_ch
154                     ||( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92')) {
155                         if ( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92') {
156                                 memset(buf, 0, sizeof(buf));
157                                 snprintf(buf, sizeof(buf),
158                                  "<align=right><font_size=%d><color=#505050FF>(<align=right><font_size=%d><color=#505050FF>-",
159                                  cur_fontsize, cur_fontsize);
160                                 strcat(format_string, buf);
161                                 i=i+4;
162                         }
163                         begin = i;
164                         p = &string[begin];
165                         while (CALCULATOR_CHAR_IS_DIGITAL(string[i])
166                                || string[i] == separator_ch
167                                || string[i] == decimal_ch) {
168                                 i++;
169                         }
170                         end = i - 1;
171                         strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
172                         tmp[end - begin + 1] = '\0';
173                         memset(buf, 0, sizeof(buf));
174                         snprintf(buf, sizeof(buf),
175                                  "<align=right><font_size=%d><color=#505050FF>%s",
176                                  cur_fontsize, tmp);
177                         strcat(format_string, buf);
178                 } else {
179                         begin = i;
180                         p = &string[begin];
181                         while (!CALCULATOR_CHAR_IS_DIGITAL(string[i])
182                                && string[i] != separator_ch
183                                && string[i] != decimal_ch
184                                && string[i] != '\0') {
185                                if ( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92') {
186                                         break;
187                                } else {
188                                         i++;
189                                }
190                         }
191                         end = i - 1;
192                         strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
193                         tmp[end - begin + 1] = '\0';
194                         memset(buf, 0, sizeof(buf));
195                         snprintf(buf, sizeof(buf),
196                                  "<align=right><font_size=%d><color=#505050FF>%s",
197                                  cur_fontsize, tmp);
198                         strcat(format_string, buf);
199                 }
200
201         }
202         CALC_FUN_END();
203 }
204
205 /**
206 * @describe
207 * Change line and font size when it is needed.
208 * Refer to the auto font resizing rules.
209 * @param        tag_text                The text with tags.
210 * @return       void
211 * @exception
212 */
213 void _calc_add_br(char *tag_text)
214 {
215         CALC_FUN_BEG();
216         if (tag_text  == NULL) {
217                 return;
218         }
219         app_device_orientation_e curr = app_get_device_orientation();
220         if (curr  == APP_DEVICE_ORIENTATION_270 || curr == APP_DEVICE_ORIENTATION_90) {
221                 return;
222         }
223         int line_valid_num = 0;
224         int whole_valid_num = 0;
225         int operator_tag = -1;
226         int operator_location = -1;
227         /* record is there an operator in one line? */
228         bool operator_flag = FALSE;
229         /* when change to small font, we should rescan the tag_text */
230         bool rescan_flag = FALSE;
231         int cur_len = 0;
232         char buf[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
233         strcpy(buf, tag_text);
234         int br_number = 0;
235         int i = 0;
236         int j = 0;
237         for ( ; tag_text[i] != '\0' && calculator_input_str[j] != '\0'; ) {
238                 while (tag_text[i] == '<') {
239                         while (tag_text[i++] != '>') {
240                                 /* NULL */
241                                 ;
242                         }
243                 }
244                 /* if calculator_input_str[j] is "*" or "/", tag_text[i] would be
245                         "\xc3\x97" or "\xc3\xb7" */
246                 if (tag_text[i] == calculator_input_str[j] || (tag_text[i] == '\xc3') ||
247                         ((tag_text[i] == '\xe2') && (tag_text[i+1] == '\x88') && (tag_text[i+2] == '\x92'))) {
248
249                         if ((CALCULATOR_CHAR_IS_OPERATOR(calculator_input_str[j])) &&
250                                 (!(calculator_input_str[j] == '-' && calculator_input_str[j-1] == '('))) {
251                                 if (!operator_flag || rescan_flag) {
252                                         operator_location = j;
253                                         operator_tag = i;
254                                         operator_flag = TRUE;
255                                 }
256                         }
257
258                         whole_valid_num++;
259                         line_valid_num++;
260                         if (br_number < 2) {
261                                 cur_fontsize = default_fontsize;
262                                 cur_len = min_len;
263                         } else {
264                                 if ((line_valid_num >= min_len) && (!rescan_flag)) {
265                                         rescan_flag = TRUE;
266                                         cur_fontsize = small_fontsize;
267                                         strcpy(tag_text, buf);
268                                         /* restore to the original state, then scan from the begin */
269                                         i = 0;
270                                         j = 0;
271                                         whole_valid_num = 1;
272                                         line_valid_num = 1;
273                                         operator_flag = FALSE;
274                                         operator_tag = -1;
275                                         operator_location = -1;
276                                         cur_len = max_len + 1;
277                                 }
278                         }
279
280                         if (line_valid_num >= cur_len) {
281                                 if (operator_flag && operator_tag > 0) {
282                                         string_insert(tag_text, operator_tag, "<br>");
283                                         line_valid_num = whole_valid_num-operator_location;
284                                         operator_flag = FALSE;
285                                         operator_tag = -1;
286                                         operator_location = -1;
287                                 } else {
288                                         string_insert(tag_text, i, "<br>");
289                                         line_valid_num = 0;
290
291                                 }
292                                 i = i + 4;
293                                 if (br_number < 2) {
294                                         br_number++;
295                                 }
296                         }
297                         i++;
298                         j++;
299                 }else {
300                         i++;
301                 }
302     }
303     CALC_FUN_END();
304 }
305
306
307 /**
308 * @describe
309 *
310 *
311 * @param    entry
312 * @param    str
313 * @return    void
314 * @exception
315 */
316 static void _calc_entry_text_set(Evas_Object * entry, const char *str)
317 {
318         CALC_FUN_BEG();
319         if (select_mode) {
320                 select_mode = FALSE;
321         }
322         char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
323         char tag_text[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
324         char new_font_str[MAX_EXPRESSION_LENGTH] = { 0 };
325         char old_font_str[MAX_EXPRESSION_LENGTH] = { 0 };
326
327         Eina_Bool status = elm_entry_editable_get(entry);
328         if (EINA_FALSE == status) {
329                 elm_entry_editable_set(entry, EINA_TRUE);//chx add recover the old style
330                 elm_entry_line_wrap_set(entry,ELM_WRAP_WORD);
331                 elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
332                 elm_object_style_set(entry, "black");
333                 elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data);
334                 elm_entry_text_style_user_push(entry, "DEFAULT='right_margin=32'");
335         }
336
337         if (str == NULL) {
338                 return;
339         }
340
341         if (strlen(str) == 0) {
342                 elm_entry_entry_set(entry, "");
343                 elm_entry_cursor_end_set(entry);
344                 elm_object_focus_set(entry, EINA_TRUE);
345                 CALC_FUN_END();
346                 return;
347         }
348         calc_expr_format_expression(str, tmp);
349         CALC_INFO("ASCII :: expr_out = %s", tmp);
350         CALC_INFO("ASCII :: expr_out = %d", tmp);
351         _calc_add_tag(tmp, tag_text);
352         int pre_fontsize = cur_fontsize;
353         _calc_add_br(tag_text);
354         snprintf(old_font_str, sizeof(old_font_str), "=%d", pre_fontsize);
355         snprintf(new_font_str, sizeof(new_font_str), "=%d", cur_fontsize);
356         string_replace(tag_text, old_font_str, new_font_str);
357         CALC_INFO("ASCII :: tag_text = %s", tag_text);
358         CALC_INFO("ASCII :: tag_text = %d", tag_text);
359         elm_entry_entry_set(entry, tag_text);
360         if(calculator_cursor_pos == strlen(calculator_input_str)){
361                 elm_entry_cursor_end_set(entry);
362                 elm_object_focus_set(entry, EINA_TRUE);
363         }else {
364                 calc_view_cursor_set_position(entry, calculator_cursor_pos);
365         }
366         CALC_FUN_END();
367 }
368
369 void _calc_entry_text_set_rotate(struct appdata *ad)
370 {
371     CALC_FUN_BEG();
372         if (calculator_state == CALCULATOR_CALCULATED) {
373                 _calc_view_show_newest_histroy(ad->input_entry);
374                 elm_entry_cursor_end_set(ad->input_entry);
375                 elm_object_focus_set(ad->input_entry, EINA_TRUE);
376         } else {
377                 _calc_entry_text_set(ad->input_entry, calculator_input_str);
378         }
379         CALC_FUN_END();
380 }
381
382 /**
383 * @describe
384 *
385 *
386 * @param    entry
387 * @param    str
388 * @return    void
389 * @exception
390 */
391 static void _calc_entry_text_insert(Evas_Object * entry, char *str)
392 {
393         CALC_FUN_BEG();
394         CALC_INFO("ASCII :: str = %s", str);
395         CALC_INFO("ASCII :: str = %d", str);
396         calc_expr_input_insert(calculator_input_str, &calculator_cursor_pos, str);
397         _calc_entry_text_set(entry, calculator_input_str);
398         CALC_FUN_END();
399 }
400
401 /**
402 * @describe
403 *
404 *
405 * @param    entry
406 * @param    from_pos
407 * @param    end_pos
408 * @return    void
409 * @exception
410 */
411 static void _calc_entry_text_remove(Evas_Object * entry, const int from_pos,
412                                     const int end_pos)
413 {
414         CALC_FUN_BEG();
415         string_remove_at(calculator_input_str, from_pos,
416                          end_pos - from_pos + 1);
417         calculator_cursor_pos = from_pos;
418         _calc_entry_text_set(entry, calculator_input_str);
419         CALC_FUN_END();
420 }
421
422 /**
423 * @describe
424 *       Set correct cursor position in entry.
425 *
426 * @param    entry
427 * @return    void
428 * @exception
429 */
430 static void _calc_entry_cursor_set(Evas_Object * entry)
431 {
432         CALC_FUN_BEG();
433         calc_view_cursor_set_position(entry, calculator_cursor_pos);
434         CALC_FUN_END();
435 }
436
437 /**
438 * @describe
439 *
440 *
441 * @param    entry
442 * @return    void
443 * @exception
444 */
445 static void _calc_entry_backspace(Evas_Object * entry)
446 {
447         CALC_FUN_BEG();
448         calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
449         _calc_entry_text_set(entry, calculator_input_str);
450         CALC_FUN_END();
451 }
452
453 /**
454 * @describe
455 *
456 *
457 * @param    entry
458 * @return    void
459 * @exception
460 */
461 void _calc_entry_clear(Evas_Object * entry)
462 {
463         CALC_FUN_BEG();
464         memset(calculator_input_str, 0, sizeof(calculator_input_str));
465         calculator_cursor_pos = 0;
466         _calc_entry_text_set(entry, "");
467         calc_view_cursor_set_position(entry, calculator_cursor_pos);
468         CALC_FUN_END();
469 }
470
471 /* END INPUT ENTRY RELATED */
472
473 /**
474 * @describe
475 * Get the operand start and end location where the cursor in.
476 * 1.2+6.|43 (cursor is before 4), then return begin=4 end=7
477 * Espcially, cursor is after +, it means the operand which follows
478 * the operator, so it return the same result as before.
479 * This is add by on 2012/5/29
480 *
481 * @param[in]    text    The current calculator input string
482 * @param[out]   begin   The start location of an operand
483 * @param[out]   end     The end location of an operand
484 * @return               Is cursor in an operand
485 * @retval       true    The cursor is in the operand
486 * @retval       false   The cursor is not in the operand
487 * @exception
488 */
489 static bool
490 __calculator_get_float_num_in_cursor_position(char *text, int cur_pos,
491                                               int *begin, int *end)
492 {
493         CALC_FUN_BEG();
494         if (text == NULL) {
495                 return false;
496         }
497         int pos = cur_pos - 1;
498         if (pos < 0) {
499                 pos = 0;
500         }
501         int _begin = 0;
502         int _end = 0;
503
504         if ('p' == text[pos] || 'e' == text[pos]) {
505                 *begin = pos;
506                 *end = pos;
507                 return true;
508         } else if (CALCULATOR_IS_DIGIT_DOT(text[pos], decimal_ch)) {
509                 for (_begin = pos - 1;
510                      CALCULATOR_IS_DIGIT_DOT(text[_begin], decimal_ch)
511                      && _begin >= 0; --_begin) {
512                         ;       /* NULL */
513                 }
514                 _begin++;
515                 if (_begin > 1 && '-' == text[_begin - 1]
516                     && '(' == text[_begin - 2]) {
517                         _begin--;
518                 }
519                 for (_end = pos + 1;
520                      CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
521                      && _end < strlen(text); ++_end) {
522                         ;       /* NULL */
523                 }
524                 _end--;
525
526                 *begin = _begin;
527                 *end = _end;
528                 return true;
529         } else if (CALCULATOR_CHAR_IS_OPERATOR(text[pos]) || text[pos] == '(') {
530                 for (_end = pos + 1;
531                      CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
532                      && _end < strlen(text); ++_end) {
533                         ;       /* NULL */
534                 }
535                 _end--;
536                 *begin = pos+1;
537                 *end = _end;
538                 return true;
539         } else {
540                 return false;
541         }
542         CALC_FUN_END();
543 }
544
545 /**
546 * @describe
547 * Get the operand start and end location where the cursor in the operand
548 * Actually, it would call "__calculator_get_float_num_in_cursor_position"
549 * function to recognize whether the cursor is in the operand.
550 *
551 * @param[in]    entry_text      The current calcualtor input string
552 * @param[out]   str     The operand which the cursor in
553 * @param[out]   from    The operand start location which contain the cursor
554 * @param[out]   end     The operand end location which contain the cursor
555 * @return               Is cursor in an operand
556 * @retval       true    The cursor is in the operand
557 * @retval       false   The cursor is not in the operand
558 * @exception
559 */
560 static bool
561 __calculator_get_cursor_position_float_string(char *entry_text, char *str,
562                                               int cur_pos, int *from, int *end)
563 {
564         CALC_FUN_BEG();
565         if (entry_text == NULL) {
566                 return false;
567         }
568         int from_pos = cur_pos;
569         int end_pos = cur_pos;
570
571         if (false ==
572             __calculator_get_float_num_in_cursor_position(entry_text, cur_pos, &from_pos, &end_pos)) {
573                 return false;
574         }
575
576         /* set from&end position */
577         if (from != NULL) {
578                 *from = from_pos;
579         }
580         if (end != NULL) {
581                 *end = end_pos;
582         }
583
584         strncpy(str, entry_text + from_pos, end_pos - from_pos + 1);
585         str[end_pos - from_pos + 1] = '\0';
586         CALC_FUN_END();
587         return true;
588 }
589
590 /**
591 * @describe
592 *   Get the float number in current cursor
593 *
594 * @param    entry_text
595 * @param    str
596 * @return    void
597 * @exception
598 */
599 static bool
600 __calculator_get_before_cursor_float_string(char *entry_text, char *str)
601 {
602         CALC_FUN_BEG();
603
604         int from_pos = calculator_cursor_pos;
605         int end_pos = calculator_cursor_pos;
606
607         if (false ==  __calculator_get_float_num_in_cursor_position(entry_text, calculator_cursor_pos, &from_pos, &end_pos)) {
608                 return false;
609         }
610         snprintf(str, calculator_cursor_pos - from_pos + 1, "%s", entry_text + from_pos);
611         CALC_FUN_END();
612         return true;
613 }
614
615 /**
616 * @describe
617 *   Get string before cursor in the Entry.
618 *
619 * @param    entry_text
620 * @param    str
621 * @return    void
622 * @exception
623 */
624 static void
625 __calculator_get_input_from_begin_to_cursor(char *entry_text, char *str)
626 {
627         CALC_FUN_BEG();
628
629         if (calculator_cursor_pos > 0) {
630                 strncpy(str, entry_text, calculator_cursor_pos);
631                 str[calculator_cursor_pos] = '\0';
632         } else {
633                 strcpy(str, "");
634         }
635         CALC_FUN_END();
636 }
637
638 /**
639 * @describe
640 *
641 * judge the type of current input
642 *
643 * @param    input
644 * @return    void
645 * @exception
646 */
647 static last_char_t __calculator_string_get_char_type( char ch_in)
648 {
649         CALC_FUN_BEG();
650         if (ch_in == '\0') {
651                 return CHAR_IS_NULL;
652         }
653         if (ch_in == 'p') {
654                 return CHAR_IS_PI;
655         }
656         if (ch_in == 'e') {
657                 return CHAR_IS_E;
658         }
659         if (CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(ch_in)) {
660                 return CHAR_IS_MULTIPLY_DIVIDE;
661         }
662         if (ch_in == '(') {
663                 return CHAR_IS_LEFT_PARENTHESE;
664         }
665         if (ch_in == ')') {
666                 return CHAR_IS_RIGHT_PARENTHESE;
667         }
668         if (CALCULATOR_CHAR_IS_DIGITAL(ch_in)) {
669                 return CHAR_IS_DIGIT;
670         }
671         if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(ch_in) ){
672                 return CHAR_IS_PLUS_MINUS;
673         }
674         if (ch_in == decimal_ch) {
675                 return CHAR_IS_POINT;
676         }
677         return CHAR_IS_CHARACTER;
678         CALC_FUN_END();
679 }
680
681 static bool  __calculator_string_digit_in(const char *input)
682 {
683         int i =0;
684         while(input[i]!='\0'){
685                 if(IS_DIGITAL(input[i])){/*here ,digit include "p" and "e"*/
686                         return TRUE;
687                 }else{
688                         i++;
689                 }
690         }
691          return FALSE;
692 }
693
694 /*
695 * search charactor in input string, if have charactor, return True and index of first charactor;
696 * else return False;
697 */
698 static bool __calculator_string_char_search(const char *input, int *index)
699 {
700         CALC_FUN_BEG();
701         if (input == NULL) {
702                 return FALSE;
703         }
704         int len_cp = strlen(input);
705         if(len_cp <= 0){
706                 return FALSE;
707         }
708         int i = 0;
709         for(; i < len_cp ; i++){
710                 last_char_t cur_char_type = __calculator_string_get_char_type(input[i]);
711                 if (CHAR_IS_CHARACTER == cur_char_type) {
712                         *index  = i;
713                         return TRUE;
714                 }
715         }
716         return FALSE;
717         CALC_FUN_END();
718 }
719
720 /*
721 * search invalid charactor in input string, if have invalid charactor, return True and index of first invalid charactor;
722 * else return False;
723 */
724 static bool __calculator_string_invalid_char_search(char *input, int *index)
725 {
726         int sub_index = 0;
727         char *p = input;
728         bool char_in = FALSE;
729         int len = 0;
730         char_in = __calculator_string_char_search(p, &sub_index);
731         if (!char_in) {/*no charactor*/
732                 return FALSE;
733         }
734                 *index += sub_index;
735                 p += sub_index;
736         while (p) {
737                 if (!__calculator_search_function(p, &len)) {/*charactor not a function*/
738                         return TRUE;
739                 } else {/*the first sevaral charactors are function, continue search*/
740                         *index += len;
741                         p += len;
742                 }
743                 /*Fix bug that paste did not filter invaild word, beacuse here it jump to
744                 *  the sub_index directly, but the sub_index would change with the string
745                 *  So, it should recalculate every time*/
746                 char_in = __calculator_string_char_search(p, &sub_index);
747                 if (char_in) {
748                         *index += sub_index;
749                         p += sub_index;
750                 } else {
751                         return FALSE;
752                 }
753         }
754         return FALSE;
755 }
756 /**
757 * @describe
758 *
759 *
760 * @param    entry
761 * @param    op_item
762 * @return    void
763 * @exception
764 */
765 static void
766 __calculator_control_panel_number_button_clicked(Evas *e, Evas_Object *entry, op_item_t *op_item)
767 {
768         CALC_FUN_BEG();
769         if (select_mode) {
770                 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
771                 if (selected_str) {
772                         if (calc_select_string_search(selected_str)) {
773                                 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym,
774                                         op_item->op_sym, op_item->op_sym, 0, NULL);
775                         } else {
776                                 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
777                                 calculator_cursor_pos = strlen(calculator_input_str);
778                         }
779                         SFREE(selected_str);
780                 }
781                 return;
782         }
783         /* replace special characters */
784         char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
785         snprintf(entry_text, sizeof(entry_text), "%s", calculator_input_str);
786         //Current state is calculated, clear all
787         if (calculator_state == CALCULATOR_CALCULATED) {
788                 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
789                 _calc_entry_clear(entry);
790                 _calc_entry_text_insert(entry, op_item->op_sym);
791                 calculator_state = CALCULATOR_OPERAND_INPUT;
792                 return;
793         }
794
795         char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
796         char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
797         int before_len = 0;
798         int nDigitCnt = 0;
799         int nPointCnt = 0;
800         __calculator_get_cursor_position_float_string(entry_text, str_buf, calculator_cursor_pos, NULL, NULL);
801         __calculator_get_input_from_begin_to_cursor(entry_text, before_cursor);
802         before_len = strlen(before_cursor);
803         calculator_get_digits_number(str_buf, &nDigitCnt, &nPointCnt);
804         char str_bufa[MAX_EXPRESSION_LENGTH] = { 0 };
805         __calculator_get_before_cursor_float_string(entry_text, str_bufa);
806         if (strcmp(str_bufa, "0") == 0) {
807                 _calc_entry_backspace(entry);
808         }
809
810         if (strlen(str_buf) >= MAX_NUM_LENGTH) {
811                 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
812                 return;
813         } else if (nPointCnt >= MAX_DECIMAL_NUM && calculator_cursor_pos > nDigitCnt) {
814                 __calculator_wrong_format_create(CALC_MSG_MAX_DEC_DIGIT);
815                 return;
816         } else if (before_len > 0
817                    && (__calculator_string_get_char_type(before_cursor[before_len - 1]) ==
818                    CHAR_IS_PI
819                    || __calculator_string_get_char_type(before_cursor[before_len - 1]) ==
820                    CHAR_IS_E)) {
821                 /* input digital after "e" or "p", the "x" opeartor will be added automatically */
822                 _calc_entry_text_insert(entry, "x");
823                 _calc_entry_text_insert(entry, op_item->op_sym);
824                 calculator_state = CALCULATOR_OPERAND_INPUT;
825                 return;
826         } else if (before_len > 0 && ((before_cursor[before_len - 1] == '(') ||CALCULATOR_CHAR_IS_DIGITAL(before_cursor[before_len - 1])
827                        || CALCULATOR_CHAR_IS_OPERATOR(before_cursor[before_len - 1]) || (int)before_cursor[before_len - 1] > 120))      //* or/
828         {
829                 _calc_entry_text_insert(entry, op_item->op_sym);
830                 calculator_state = CALCULATOR_OPERAND_INPUT;
831                 return;
832         } else if (before_len > 0 && (before_cursor[before_len - 1] == ')')) {
833                 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
834                 return;
835         } else {
836                 _calc_entry_text_insert(entry, op_item->op_sym);
837                 calculator_state = CALCULATOR_OPERAND_INPUT;
838                 return;
839         }
840         CALC_FUN_END();
841 }
842
843 /**
844 * @describe
845 * Deal the event when dot clicked on the keyboard
846 *
847 * @param[in]    entry   The input entry
848 * @return               void
849 * @exception
850 */
851 static void _calc_btn_dot_clicked(Evas_Object *entry)
852 {
853         CALC_FUN_BEG();
854         if (entry == NULL) {
855                 return;
856         }
857         char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
858         int str_num_len = 0;
859
860         char decimal_str[32] = { 0 };
861
862         /* replace special characters */
863         char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
864         strncpy(entry_text, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
865
866         if (calculator_state == CALCULATOR_CALCULATED) {
867                 _calc_entry_clear(entry);
868                 memset(entry_text,0x00,sizeof(entry_text));
869         }
870
871         int from_pos = 0;
872         int end_pos = 0;
873         if (!__calculator_get_cursor_position_float_string
874             (entry_text, str_num, calculator_cursor_pos, &from_pos, &end_pos)) {
875                 if (calculator_cursor_pos == 0
876                     || IS_OPERATOER(calculator_input_str[from_pos - 1])
877                         || calculator_input_str[from_pos - 1] == '(') {
878                         snprintf(decimal_str, sizeof(decimal_str), "0%c",
879                                  decimal_ch);
880                         _calc_entry_text_insert(entry, decimal_str);
881                         calculator_state = CALCULATOR_OPERAND_INPUT;
882                         return;
883                 }
884                 return;
885         } else {
886                 if (strcmp(str_num, "p") == 0 || strcmp(str_num, "e") == 0) {
887                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
888                         return;
889                 }
890         }
891
892         str_num_len = strlen(str_num);
893         if (str_num_len > 0 && str_num[str_num_len - 1] == decimal_ch) {
894                 return;
895         }
896
897         int nDigitCnt = 0;
898         int nPointCnt = 0;
899         calculator_get_digits_number(str_num, &nDigitCnt, &nPointCnt);
900
901         if (nDigitCnt >= 15) {
902                 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
903                 return;
904         }
905
906         if (nPointCnt > 0) {
907                 return;
908         }
909         if (IS_OPERATOER(calculator_input_str[calculator_cursor_pos-1])
910                 || calculator_input_str[calculator_cursor_pos-1] == '(') {
911                 snprintf(decimal_str, sizeof(decimal_str), "0%c", decimal_ch);
912         } else {
913                 snprintf(decimal_str, sizeof(decimal_str), "%c", decimal_ch);
914         }
915         _calc_entry_text_insert(entry, decimal_str);
916         calculator_state = CALCULATOR_OPERAND_INPUT;
917         CALC_FUN_END();
918         return;
919 }
920
921 /**
922 * @describe
923 *
924 *
925 * @param        entry
926 * @return       void
927 * @exception
928 */
929 static void _calc_btn_backspace_clicked(Evas *e, Evas_Object *entry)
930 {
931         CALC_FUN_BEG();
932         if (select_mode) {
933                 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
934                 if (selected_str) {
935                         if (calc_select_string_search(selected_str)) {
936                                 evas_event_feed_key_down(e, "KP_BACKSPACE", "", "", "", 0, NULL);
937                         } else {
938                                 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
939                                 calculator_cursor_pos = strlen(calculator_input_str);
940                         }
941                         SFREE(selected_str);
942                 }
943                 return;
944         }
945         if (calculator_state == CALCULATOR_CALCULATED) {
946                 calculator_state = CALCULATOR_OPERATOR_INPUT;
947                 if (calculator_cursor_pos > strlen(calculator_input_str)) {
948                         calculator_cursor_pos = strlen(calculator_input_str);   /* set last position */
949                 }
950         }
951         _calc_entry_backspace(entry);
952         CALC_FUN_END();
953 }
954
955 static int __calculator_delete_long_press(void *data)
956 {
957         CALC_FUN_BEG();
958         Evas_Object *entry = (Evas_Object *) data;
959
960         if (calculator_state == CALCULATOR_CALCULATED) {
961                 calculator_state = CALCULATOR_OPERATOR_INPUT;
962                 if (calculator_cursor_pos > strlen(calculator_input_str)) {
963                         calculator_cursor_pos = strlen(calculator_input_str);   /* set last position */
964                 }
965         }
966         _calc_entry_backspace(entry);
967         CALC_FUN_END();
968         return 1;
969 }
970
971 /**
972 * @describe
973 *   Process +.-.*.\ these four buttons clicked.
974 *
975 * @param        entry
976 * @param        op_item
977 * @return       void
978 * @exception
979 */
980 static void
981 __calculator_control_normal_func_clicked(Evas *e,Evas_Object *entry,
982                                          op_item_t *op_item)
983 {
984         CALC_FUN_BEG();
985         if (select_mode) {
986                 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
987                 if (selected_str) {
988                         if (calc_select_string_search(selected_str)) {
989                                 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym, op_item->op_sym, op_item->op_sym, 0, NULL);
990                         } else {
991                                 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
992                                 calculator_cursor_pos = strlen(calculator_input_str);
993                         }
994                         SFREE(selected_str);
995                 }
996                 return;
997         }
998         char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
999         strncpy(all_input, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
1000
1001         if (calculator_state == CALCULATOR_CALCULATED) {
1002                 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1003                 char temp[20] = { 0 };
1004
1005                 calc_expr_num_format_result(last_result, temp);
1006                 _calc_entry_clear(entry);
1007                 //result < 0 or sicience number
1008                 if (temp[0] == '-' || strchr(temp, 'E')) {
1009                         _calc_entry_text_insert(entry, "(");
1010                         _calc_entry_text_insert(entry, temp);
1011                         _calc_entry_text_insert(entry, ")");
1012                 } else {
1013                         _calc_entry_text_insert(entry, temp);
1014                 }
1015
1016                 _calc_entry_text_insert(entry, op_item->op_sym);
1017                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1018                 return;
1019
1020         }
1021         if (!strcmp(op_item->op_sym, "x") ||!strcmp(op_item->op_sym, "/") ||!strcmp(op_item->op_sym, "+")) {
1022                 if (!__calculator_string_digit_in(calculator_input_str)) {
1023                         return;
1024                 }
1025         }
1026         int nCntOp = calc_expr_get_operator_num(all_input);
1027         if (nCntOp >= MAX_OPERATOR_NUM) {       /* Can't exceed 20 operators */
1028                 __calculator_wrong_format_create(CALC_MSG_MAX_OP);
1029                 return;
1030         }
1031
1032         char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1033         int input_len = 0;
1034
1035         __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1036         input_len = strlen(before_cursor);
1037
1038         if (input_len > 0) {
1039                 if (before_cursor[input_len - 1] == '(' && !strcmp(op_item->op_sym, "-")) {
1040                         _calc_entry_text_insert(entry, op_item->op_sym);
1041                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1042                 } else if (((input_len > 1) && (before_cursor[input_len - 1] == '-') && (before_cursor[input_len - 2] == '('))  //(-
1043                            || /*before_cursor[input_len - 1] == decimal_ch ||*/ before_cursor[input_len - 1] == '(')    // . or (
1044                 {
1045
1046                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1047                         return;
1048                 } else if (IS_OPERATOER(before_cursor[input_len - 1])) {
1049                         if ((input_len > 1 || !strcmp(op_item->op_sym, "-"))
1050                             || input_len == 1) {
1051                                 _calc_entry_backspace(entry);
1052                                 _calc_entry_text_insert(entry, op_item->op_sym);
1053                                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1054                         } else {
1055                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1056                         }
1057                         return;
1058                 } else if (before_cursor[input_len - 1] == ')') //
1059                 {
1060                         _calc_entry_text_insert(entry, op_item->op_sym);
1061                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1062                         return;
1063                 } else {
1064                         if (!IS_DIGITAL(before_cursor[input_len - 1])
1065                                         && (before_cursor[input_len - 1] != decimal_ch)) {
1066                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1067                                 return;
1068                         } else {
1069                                 _calc_entry_text_insert(entry, op_item->op_sym);
1070                                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1071                                 return;
1072                         }
1073                 }
1074         } else {                /* before_cursor si empty */
1075                 _calc_entry_text_insert(entry, op_item->op_sym);
1076                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1077         }
1078         CALC_FUN_END();
1079 }
1080
1081 /**
1082 * @describe
1083 *
1084 *
1085 * @param    entry
1086 * @return    void
1087 * @exception
1088 */
1089 static void __calculator_symbol_negative_clicked(Evas_Object * entry)
1090 {
1091         CALC_FUN_BEG();
1092
1093         char result[MAX_RESULT_LENGTH] = { 0 };
1094
1095         if (calculator_state == CALCULATOR_CALCULATED) {
1096                 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1097
1098                 calc_expr_num_format_result(last_result, result);
1099                 if (last_result < 0) {
1100                         string_remove_at(result, 0, 1); //remove '-'
1101                 } else {
1102                         string_insert(result, 0, "(-"); // add (-xxx)
1103                         string_insert(result, strlen(result), ")");
1104                 }
1105
1106                 _calc_entry_clear(entry);
1107                 _calc_entry_text_insert(entry, result);
1108
1109                 calculator_state = CALCULATOR_OPERAND_INPUT;
1110                 //use_last_result = 1;
1111
1112                 return;
1113         }
1114
1115         int cursor = calculator_cursor_pos;
1116         int begin = 0, length = 0;
1117         char expr[MAX_EXPRESSION_LENGTH] = { 0 };
1118         strncpy(expr, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
1119         int flag = 0;
1120         cursor -= 1;
1121         if (expr[cursor] == ')') {
1122                 cursor -= 1;
1123                 flag = 1;       /* before current cursor is ')' */
1124         }
1125
1126         if (0 ==
1127             calc_expr_get_current_num_at_cursor(expr, cursor, &begin,
1128                                                 &length)) {
1129                 if (expr[begin] == '-') {
1130                         if (begin > 0 && expr[begin - 1] == '('
1131                             && expr[begin + length] == ')') {
1132                                 string_remove_at(expr, begin + length, 1);      //remove ')'
1133                                 string_remove_at(expr, begin - 1, 2);   // remove '(-'
1134                                 calculator_cursor_pos -= flag ? 3 : 2;
1135                         } else {
1136                                 string_remove_at(expr, begin, 1);
1137                                 calculator_cursor_pos -= 1;
1138                         }
1139
1140                 } else {
1141                         if (flag == 1)  //not '(-xxx)' but has ')'
1142                         {
1143                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1144                                 return;
1145                         } else {
1146                                 string_insert(expr, begin + length, ")");
1147                                 string_insert(expr, begin, "(-");
1148                                 calculator_cursor_pos +=
1149                                     (((begin + length) ==
1150                                       calculator_cursor_pos) ? 3 : 2);
1151                         }
1152                 }
1153                 strncpy(calculator_input_str, expr, MAX_EXPRESSION_LENGTH - 1);
1154
1155                 _calc_entry_text_set(entry, calculator_input_str);
1156                 _calc_entry_cursor_set(entry);
1157
1158                 calculator_state = CALCULATOR_OPERAND_INPUT;
1159
1160         } else {
1161                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1162         }
1163         CALC_FUN_END();
1164 }
1165
1166 /* search the previous operator and value */
1167 static char * __calculator_search_prev_input(char *input_str)
1168 {
1169         CALC_FUN_BEG();
1170         int i = 0;
1171         int bracket_number = 0;
1172         char *prev_input = NULL;
1173         for(; i< strlen(input_str); i++) {
1174                 if ('(' ==(input_str[i]) ){
1175                         bracket_number++;
1176                 }
1177                 if( ')' == input_str[i]){
1178                         bracket_number --;
1179                 }
1180                 if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(input_str[i])
1181                         || CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(input_str[i])) {
1182                         if ( !bracket_number){
1183                                 prev_input = &input_str[i];
1184                                 return prev_input;
1185                         }
1186                 }
1187         }
1188         CALC_FUN_END();
1189         return prev_input;
1190 }
1191
1192 /**
1193 * @describe
1194 * Deal the event when "=" clicked on the keyboard
1195 *
1196 * @param[in]    entry   The input entry
1197 * @return               void
1198 * @exception
1199 */
1200 static void __calculator_op_equal(Evas_Object *entry)
1201 {
1202         CALC_FUN_BEG();
1203         if (entry == NULL) {
1204                 return;
1205         }
1206         if (calculator_state == CALCULATOR_CALCULATED) {
1207                 /*duplicate previous input operator and value*/
1208                 char *p = __calculator_search_prev_input(calculator_input_str);
1209                 if (p == NULL) {
1210                         return;
1211                 }
1212                 char prev_input[32] = { 0 };
1213                 int len = g_strlcpy(prev_input, p, sizeof(prev_input));
1214                 if (len >= sizeof(prev_input)) {
1215                         return;
1216                 }
1217                 char temp[32] = { 0 };
1218                 calc_expr_num_format_result(last_result, temp);
1219                 _calc_entry_clear(entry);
1220
1221                 if (temp[0] == '-' || strchr(temp, 'E')) {
1222                         _calc_entry_text_insert(entry, "(");
1223                         _calc_entry_text_insert(entry, temp);
1224                         _calc_entry_text_insert(entry, ")");
1225                 } else {
1226                         _calc_entry_text_insert(entry, temp);
1227                 }
1228                 _calc_entry_text_insert(entry, prev_input);
1229                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1230         }
1231
1232         double result = 0;
1233         char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1234         char result_buf[MAX_RESULT_LENGTH] = { 0 };
1235         char result_format[MAX_RESULT_LENGTH] = { 0 };
1236         int str_len = 0;
1237         char error_msg[MAX_ERROR_MESSAGE_LENGTH] = { 0 };
1238         calc_expr_close_parentheses(calculator_input_str);
1239         _calc_entry_text_set(entry, calculator_input_str);
1240         snprintf(str_buf, sizeof(str_buf), "%s", calculator_input_str);
1241         str_len = strlen(str_buf);
1242         if (str_len == 0) {
1243                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1244                 return;
1245         }
1246
1247         if (!calculator_calculate(str_buf, &result, error_msg)) {
1248                 __calculator_wrong_format_create(error_msg);
1249                 calculator_state = CALCULATOR_ERROR_OCCURED;
1250                 return;
1251         } else {
1252                 last_result = result;
1253                 memset(result_buf, 0, CALCULATOR_CONTENT_LEN + 1);
1254                 calc_expr_num_format_result(result, result_buf);
1255                 /* save result */
1256
1257                 struct history_item item;
1258                 memset(item.expression, 0, sizeof(item.expression));
1259                 memset(result_format, 0, sizeof(result_format));
1260                 calc_expr_format_expression(calculator_input_str,
1261                                             item.expression);
1262                 item.result = result;
1263                 calc_expr_format_expression(result_buf, result_format);
1264                 if (result_buf[0] == '-') {
1265                         string_replace(result_format, "\xe2\x88\x92", "-");
1266                 }
1267 #ifdef SAVE_HISTORY
1268                 calc_view_save_history(&item);
1269 #endif
1270                 /* show result */
1271                 calculator_state = CALCULATOR_CALCULATED;
1272                 calc_view_show_result(result_format, ad);
1273
1274         }
1275         CALC_FUN_END();
1276 }
1277
1278 /**
1279 * @describe
1280 *
1281 *
1282 * @param        entry
1283 * @return       void
1284 * @exception    none
1285 */
1286 static void __calculator_parenthesis_clicked(Evas_Object * entry)
1287 {
1288         CALC_FUN_BEG();
1289         char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1290         snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
1291         if (calculator_state == CALCULATOR_CALCULATED) {
1292                 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1293
1294                 char temp[MAX_RESULT_LENGTH] = { 0 };
1295
1296                 calc_expr_num_format_result(last_result, temp);
1297                 _calc_entry_clear(entry);
1298
1299                 if (temp[0] == '-' || strchr(temp, 'E') != NULL)        //result < 0 or science number
1300                 {
1301                         _calc_entry_text_insert(entry, "((");
1302                         _calc_entry_text_insert(entry, temp);
1303                         _calc_entry_text_insert(entry, ")");
1304                 } else {
1305                         _calc_entry_text_insert(entry, "(");
1306                         _calc_entry_text_insert(entry, temp);
1307                 }
1308                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1309                 return;
1310         }
1311         char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1312         int input_len = 0;
1313         __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1314         input_len = strlen(before_cursor);
1315
1316         if (input_len == 0) {
1317                 _calc_entry_text_insert(entry, "(");
1318                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1319                 return;
1320         }
1321         int bracket_num = calculator_get_open_braket(all_input);
1322         if (input_len > 0) {
1323                 if (before_cursor[input_len - 1] == decimal_ch) {
1324                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1325                         return;
1326                 } else if (bracket_num > 0      //'(' is more than ')'
1327                            && before_cursor[input_len - 1] != '('
1328                            && (before_cursor[input_len - 1] == ')'
1329                                || isdigit(before_cursor[input_len - 1])
1330                                ||
1331                                (__calculator_string_get_char_type
1332                                 (before_cursor[input_len - 1]) == CHAR_IS_PI
1333                                 ||
1334                                 __calculator_string_get_char_type
1335                                 (before_cursor[input_len - 1]) == CHAR_IS_E))) {
1336                         _calc_entry_text_insert(entry, ")");
1337                         return;
1338                 } else if (bracket_num == 0) {
1339                         if (calc_expr_get_left_parentheses_num
1340                             (calculator_input_str) < MAX_PARENTHESES_NUM) {
1341                                 _calc_entry_text_insert(entry, "(");
1342                         }
1343                         return;
1344                 } else if (before_cursor[input_len - 1] != ')') //'(' is less than ')'!isdigit(before_cursor[input_len-1])&&(
1345                 {
1346                         if (calc_expr_get_left_parentheses_num
1347                             (calculator_input_str) < MAX_PARENTHESES_NUM) {
1348                                 _calc_entry_text_insert(entry, "(");
1349                         }
1350                         return;
1351                 }
1352         }
1353         CALC_FUN_END();
1354         return;
1355 }
1356
1357 /**
1358 * @describe
1359 *
1360 *
1361 * @param        entry
1362 * @param        op_item
1363 * @return       void
1364 * @exception
1365 */
1366 static void
1367 __calculator_control_functions_button_clicked(Evas *e, Evas_Object *entry, op_item_t *op_item)
1368 {
1369         CALC_FUN_BEG();
1370
1371         char *str = NULL;
1372         function_t function = { 0 };
1373
1374         memset(&function, 0x0, sizeof(function_t));
1375         str = op_item->op_name;
1376
1377         char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1378         int input_len = 0;
1379         char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1380         int before_len = 0;
1381         last_char_t last_char_type = 0;
1382
1383         snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
1384         __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1385         input_len = strlen(all_input);
1386         before_len = strlen(before_cursor);
1387         if(before_len > 0){
1388                 last_char_type = __calculator_string_get_char_type(before_cursor[before_len - 1]);
1389         }
1390
1391         switch (op_item->op_id) {
1392         case OP_PERCENT:
1393                 if (select_mode) {
1394                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1395                         calculator_cursor_pos = strlen(calculator_input_str);
1396                         return;
1397                 }
1398                 /* if it is calculated state */
1399                 if (calculator_state == CALCULATOR_CALCULATED) {
1400                         edje_object_signal_emit(_EDJ(ad->edje), "show,input","");
1401
1402                         char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1403                         double per_result = last_result / 100.0;
1404
1405                         calc_expr_num_format_result(per_result, temp);
1406                         _calc_entry_clear(entry);
1407
1408                         if (strcmp(temp, "0") == 0) {
1409                                 _calc_entry_text_insert(entry, "0");
1410                         } else if (temp[0] == '-')      //result < 0
1411                         {
1412                                 _calc_entry_text_insert(entry, "(");
1413                                 _calc_entry_text_insert(entry, temp);
1414                                 _calc_entry_text_insert(entry, ")");
1415                         } else {
1416                                 _calc_entry_text_insert(entry, temp);
1417                         }
1418                         calculator_state = CALCULATOR_OPERAND_INPUT;
1419                         return;
1420                 }
1421
1422                 {
1423                         int from_pos, end_pos;
1424                         char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
1425                         char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1426                         double per_result = 0.0;
1427
1428                         if (false ==  __calculator_get_cursor_position_float_string(all_input, str_num, calculator_cursor_pos, &from_pos, &end_pos)) {
1429                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1430                                 calculator_cursor_pos = strlen(calculator_input_str);
1431                                 return;
1432                         }
1433
1434                         {
1435                                 if (strlen(str_num) == 0) {
1436                                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1437                                         return;
1438                                 }
1439
1440                                 if (strcmp(str_num, "0") == 0) {
1441                                         return;
1442                                 }
1443
1444                                 per_result = atof(str_num);
1445                                 per_result /= 100.0;
1446
1447                                 calc_expr_num_format_result(per_result, temp);
1448
1449                                 _calc_entry_text_remove(entry, from_pos, end_pos);
1450                                 _calc_entry_text_insert(entry, temp);
1451
1452                                 calculator_state = CALCULATOR_OPERAND_INPUT;
1453                                 return;
1454                         }
1455                 }
1456                 break;
1457         case OP_PI:
1458                 if (select_mode) {
1459                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1460                         calculator_cursor_pos = strlen(calculator_input_str);
1461                         return;
1462                 }
1463                 if (calculator_state == CALCULATOR_CALCULATED) {
1464                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1465                                                 "");
1466                         _calc_entry_clear(entry);
1467                         _calc_entry_text_insert(entry, op_item->op_name);
1468                         break;
1469                 }
1470                 if ((before_len != 0) && (!IS_DIGITAL(before_cursor[before_len - 1]))
1471                     && (!IS_OPERATOER(before_cursor[before_len - 1]))
1472                     && (before_cursor[before_len - 1] != '(')
1473                     && (before_cursor[before_len - 1] != 'P')
1474                     && before_cursor[before_len - 1] != 'C') {
1475                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1476                         break;
1477                 }
1478                 /* input digital after "p", the "x" opeartor will be added automatically */
1479                 if(IS_DIGITAL(before_cursor[before_len - 1])){
1480                         _calc_entry_text_insert(entry, "x");
1481                 }
1482                 _calc_entry_text_insert(entry, op_item->op_name);
1483                 break;
1484
1485         case OP_E:
1486                 if (select_mode) {
1487                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1488                         calculator_cursor_pos = strlen(calculator_input_str);
1489                         return;
1490                 }
1491                 if (calculator_state == CALCULATOR_CALCULATED) {
1492                         edje_object_signal_emit(_EDJ(ad->edje), "show,input","");
1493                         _calc_entry_clear(entry);
1494                         _calc_entry_text_insert(entry, op_item->op_name);
1495                         break;
1496                 }
1497                 if ((before_len != 0) && (!IS_DIGITAL(before_cursor[before_len - 1]))
1498                     && (!IS_OPERATOER(before_cursor[before_len - 1]))
1499                     && (before_cursor[before_len - 1] != '(')
1500                     && (before_cursor[before_len - 1] != 'P')
1501                     && before_cursor[before_len - 1] != 'C') {
1502                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1503                         break;
1504                 }
1505                 /* input digital after "e", the "x" opeartor will be added automatically */
1506                 if(IS_DIGITAL(before_cursor[before_len - 1])){
1507                         _calc_entry_text_insert(entry, "x");
1508                 }
1509                 _calc_entry_text_insert(entry, op_item->op_name);
1510                 break;
1511
1512         case OP_SIN:            //sin()
1513         case OP_COS:            //cos()
1514         case OP_TAN:            //tan()
1515         case OP_LOG:            //log()
1516         case OP_ABS:            //abs()
1517                 if (select_mode) {
1518                         char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
1519                         if (selected_str) {
1520                                 if (calc_select_string_search(selected_str)) {
1521                                         evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym,
1522                                                 op_item->op_name, op_item->op_sym, 0, NULL);
1523                                 } else {
1524                                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1525                                         calculator_cursor_pos = strlen(calculator_input_str);
1526                                 }
1527                                 SFREE(selected_str);
1528                         }
1529                         return;
1530                 }
1531                 if (calculator_state == CALCULATOR_CALCULATED) {
1532                         edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1533
1534                         _calc_entry_clear(entry);
1535                         _calc_entry_text_insert(entry, op_item->op_name);
1536                         break;
1537                 }
1538                 if (last_char_type == CHAR_IS_PI || last_char_type == CHAR_IS_E) {
1539                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1540                         break;
1541                 }
1542
1543                 _calc_entry_text_insert(entry, op_item->op_name);
1544                 break;
1545
1546         case OP_LN:             //ln()
1547                 if (select_mode) {
1548                         char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
1549                         if (selected_str) {
1550                                 if (calc_select_string_search(selected_str)) {
1551                                         evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym, op_item->op_name,
1552                                                 op_item->op_sym, 0, NULL);
1553                                 } else {
1554                                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1555                                         calculator_cursor_pos = strlen(calculator_input_str);
1556                                 }
1557                                 SFREE(selected_str);
1558                         }
1559                         return;
1560                 }
1561                 if (calculator_state == CALCULATOR_CALCULATED) {
1562                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1563                                                 "");
1564                         _calc_entry_clear(entry);
1565                         _calc_entry_text_insert(entry, op_item->op_name);
1566                         break;
1567                 }
1568                 if (last_char_type == CHAR_IS_PI) {
1569                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1570                         break;
1571                 }
1572                 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1573                     && (before_cursor[before_len - 1] != '-')
1574                     && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1575                     && (before_cursor[before_len - 1] != '^')
1576                     && (before_cursor[before_len - 1] != '(')
1577                     && (before_cursor[before_len - 1] != 'C')
1578                     && (before_cursor[before_len - 1] != 'P')) {
1579                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1580                         break;
1581                 }
1582                 _calc_entry_text_insert(entry, op_item->op_name);
1583                 break;
1584
1585         case OP_ROOT:           //sqrt()
1586                 if (select_mode) {
1587                         char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
1588                         if (selected_str) {
1589                                 if (calc_select_string_search(selected_str)) {
1590                                         evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym, op_item->op_name,
1591                                                 op_item->op_sym, 0, NULL);
1592                                 } else {
1593                                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1594                                         calculator_cursor_pos = strlen(calculator_input_str);
1595                                 }
1596                                 SFREE(selected_str);
1597                         }
1598                         return;
1599                 }
1600                 if (calculator_state == CALCULATOR_CALCULATED) {
1601                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1602                                                 "");
1603
1604                         _calc_entry_clear(entry);
1605                         _calc_entry_text_insert(entry, op_item->op_name);
1606                         break;
1607                 }
1608                 if (last_char_type == CHAR_IS_PI) {
1609                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1610                         break;
1611                 }
1612                 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1613                     && (before_cursor[before_len - 1] != '-')
1614                     && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1615                     && (before_cursor[before_len - 1] != '^')
1616                     && (before_cursor[before_len - 1] != '(')
1617                     && (before_cursor[before_len - 1] != 'C')
1618                     && (before_cursor[before_len - 1] != 'P')) {
1619                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1620                         break;
1621                 }
1622                 _calc_entry_text_insert(entry, op_item->op_name);
1623                 break;
1624
1625         case OP_10X:            //10^
1626                 if (calculator_state == CALCULATOR_CALCULATED) {
1627                         edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1628                         _calc_entry_clear(entry);
1629                         _calc_entry_text_insert(entry, op_item->op_name);
1630                         break;
1631                 }
1632                 if (last_char_type == CHAR_IS_PI) {
1633                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1634                         break;
1635                 }
1636                 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1637                     && (before_cursor[before_len - 1] != '-')
1638                     && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1639                     && (before_cursor[before_len - 1] != '^')
1640                     && (before_cursor[before_len - 1] != '(')
1641                     && (before_cursor[before_len - 1] != 'C')
1642                     && (before_cursor[before_len - 1] != 'P')) {
1643                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1644                         break;
1645                 }
1646                 _calc_entry_text_insert(entry, op_item->op_name);
1647                 break;
1648
1649         case OP_X2:             //x^2
1650                 if (calculator_state == CALCULATOR_CALCULATED) {
1651                         edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1652
1653                         char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1654                         calc_expr_num_format_result(last_result, temp);
1655                         _calc_entry_clear(entry);
1656
1657                         if (temp[0] == '-' || strchr(temp, 'E'))        //result < 0 or science number
1658                         {
1659                                 _calc_entry_text_insert(entry, "(");
1660                                 _calc_entry_text_insert(entry, temp);
1661                                 _calc_entry_text_insert(entry, ")");
1662                         } else {
1663                                 _calc_entry_text_insert(entry, temp);
1664                         }
1665                         _calc_entry_text_insert(entry, op_item->op_name);
1666                         calculator_state = CALCULATOR_OPERAND_INPUT;
1667                         //use_last_result = 1;
1668                         return;
1669                 }
1670
1671                 if (input_len == 0) {
1672                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
1673                         break;
1674                 }
1675                 if (last_char_type == CHAR_IS_PI) {
1676                         _calc_entry_text_insert(entry, op_item->op_name);
1677                         calculator_state = CALCULATOR_OPERAND_INPUT;
1678                         break;
1679                 } else if ((before_len > 0)
1680                            && (!isdigit(before_cursor[before_len - 1]))
1681                            && (before_cursor[before_len - 1] != ')')) {
1682                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
1683                         break;
1684                 }
1685                 _calc_entry_text_insert(entry, op_item->op_name);
1686                 calculator_state = CALCULATOR_OPERAND_INPUT;
1687                 break;
1688         case OP_XY:             //x^y
1689                 if (calculator_state == CALCULATOR_CALCULATED) {
1690                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1691                                                 "");
1692
1693                         char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1694
1695                         calc_expr_num_format_result(last_result, temp);
1696                         _calc_entry_clear(entry);
1697
1698                         if (temp[0] == '-' || strchr(temp, 'E'))        //result < 0 or science number
1699                         {
1700                                 _calc_entry_text_insert(entry, "(");
1701                                 _calc_entry_text_insert(entry, temp);
1702                                 _calc_entry_text_insert(entry, ")");
1703                         } else {
1704                                 _calc_entry_text_insert(entry, temp);
1705                         }
1706                         _calc_entry_text_insert(entry, op_item->op_name);
1707                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1708                         return;
1709                 }
1710
1711                 if (input_len == 0) {
1712                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
1713                         break;
1714                 }
1715                 if ((last_char_type == CHAR_IS_PI)
1716                     || (last_char_type == CHAR_IS_E)) {
1717                         _calc_entry_text_insert(entry, op_item->op_name);
1718                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1719                         break;
1720                 } else if ((before_len > 0)
1721                            && !isdigit(before_cursor[before_len - 1])
1722                            && (before_cursor[before_len - 1] != ')')) {
1723                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
1724                         break;
1725                 }
1726                 _calc_entry_text_insert(entry, op_item->op_name);
1727                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1728                 break;
1729
1730         case OP_FACT:           //x!
1731                 if (select_mode) {
1732                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1733                         calculator_cursor_pos = strlen(calculator_input_str);
1734                         return;
1735                 }
1736                 if (calculator_state == CALCULATOR_CALCULATED) {
1737                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1738                                                 "");
1739
1740                         char temp[MAX_RESULT_LENGTH] = { 0 };
1741
1742                         calc_expr_num_format_result(last_result, temp);
1743
1744                         if (strchr(temp, decimal_ch) != NULL || strchr(temp, '-') != NULL)      //revise by bfl
1745                         {
1746                                 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1747                                 calculator_state = CALCULATOR_WAITING_INPUT;    //revise by bfl
1748                                 return;
1749                         }
1750
1751                         _calc_entry_clear(entry);
1752                         _calc_entry_text_insert(entry, "(");
1753                         _calc_entry_text_insert(entry, temp);
1754                         _calc_entry_text_insert(entry, "!)");
1755
1756                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1757                         return;
1758                 }
1759
1760                 if (input_len == 0) {
1761                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_FAC);
1762                         break;
1763                 }
1764                 if ((last_char_type == CHAR_IS_PI)
1765                     || (last_char_type == CHAR_IS_E)) {
1766                         __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1767                         break;
1768                 }
1769
1770                 /* check if it is natural */
1771                 {
1772                         char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1773                         int from_pos = 0, end_pos = 0;
1774
1775                         if (false ==
1776                             __calculator_get_cursor_position_float_string
1777                             (all_input, str_buf, calculator_cursor_pos,
1778                              &from_pos, &end_pos)) {
1779                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1780                                 break;
1781                         }
1782
1783                         if (strchr(str_buf, decimal_ch) != NULL
1784                             || str_buf[0] == '-') {
1785                                 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1786                                 break;
1787                         }
1788
1789                         _calc_entry_text_remove(entry, from_pos, end_pos);
1790                         _calc_entry_text_insert(entry, "(");
1791                         _calc_entry_text_insert(entry, str_buf);
1792                         _calc_entry_text_insert(entry, "!)");
1793                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1794                 }
1795                 break;
1796         case OP_1X:
1797                 if (calculator_state == CALCULATOR_CALCULATED) {
1798                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1799                                                 "");
1800
1801                         char temp[MAX_RESULT_LENGTH] = { 0 };
1802                         int i = 0;
1803
1804                         calc_expr_num_format_result(last_result, temp);
1805                         if (strchr(temp, 'E') != NULL)  //science number
1806                         {
1807                                 temp[strlen(temp)] = ')';
1808                                 for (i = strlen(temp); i > 0; --i) {
1809                                         temp[i] = temp[i - 1];
1810                                 }
1811                                 temp[0] = '(';
1812                         }
1813
1814                         _calc_entry_clear(entry);
1815                         if (temp[0] == '-') {
1816                                 _calc_entry_text_insert(entry, "(-1");
1817                                 _calc_entry_text_insert(entry, "/");
1818
1819                                 _calc_entry_text_insert(entry, &temp[1]);
1820                                 _calc_entry_text_insert(entry, ")");
1821                         } else {
1822                                 _calc_entry_text_insert(entry, "(1");
1823                                 _calc_entry_text_insert(entry, "/");
1824
1825                                 _calc_entry_text_insert(entry, temp);
1826                                 _calc_entry_text_insert(entry, ")");
1827                         }
1828
1829                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1830                         //use_last_result = 1;
1831                         return;
1832                 }
1833                 if (input_len == 0) {
1834                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
1835                         break;
1836                 }
1837
1838                 /* check if it is digit */
1839                 {
1840                         char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1841                         int from_pos = 0, end_pos = 0;
1842
1843                         if (false ==
1844                             __calculator_get_cursor_position_float_string
1845                             (all_input, str_buf, calculator_cursor_pos,
1846                              &from_pos, &end_pos)) {
1847                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
1848                                 break;
1849                         }
1850
1851                         if (strcmp(str_buf, "p") && strcmp(str_buf, "e")
1852                             && atof(str_buf) == 0) {
1853                                 __calculator_wrong_format_create(CALC_MSG_DIVIDE_BY_ZERO);
1854                                 break;
1855                         }
1856
1857                         _calc_entry_text_remove(entry, from_pos, end_pos);
1858                         if (str_buf[0] == '-') {
1859                                 _calc_entry_text_insert(entry, "(-1");
1860                                 _calc_entry_text_insert(entry, "/");
1861
1862                                 _calc_entry_text_insert(entry, &str_buf[1]);
1863                                 _calc_entry_text_insert(entry, ")");
1864                         } else {
1865                                 _calc_entry_text_insert(entry, "(1");
1866                                 _calc_entry_text_insert(entry, "/");
1867
1868                                 _calc_entry_text_insert(entry, str_buf);
1869                                 _calc_entry_text_insert(entry, ")");
1870                         }
1871
1872                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1873                 }
1874                 break;
1875
1876         default:
1877                 break;
1878         }
1879         calculator_state = CALCULATOR_SPECIAL_FUNCTION_INPUT;
1880         CALC_FUN_END();
1881         return;
1882 }
1883
1884 /////////////////////////// input text finish ////////////////////////////
1885
1886 /**
1887 * @describe
1888 *
1889 *
1890 * @param    evas_obj
1891 * @param    obj
1892 * @return    void
1893 * @exception
1894 */
1895 static int _calculator_get_input_item(Evas_Object * evas_obj, Evas_Object * obj)
1896 {
1897         CALC_FUN_BEG();
1898
1899         int val = 0;
1900         if (evas_obj == edje_object_part_object_get(obj, "item_brack")) {
1901                 val = OP_PARENTHESIS;
1902         } else if (evas_obj == edje_object_part_object_get(obj, "item_del")) {
1903                 val = OP_DELETE;
1904         } else if (evas_obj == edje_object_part_object_get(obj, "item_c")) {
1905                 val = OP_CLEAR;
1906         } else if (evas_obj == edje_object_part_object_get(obj, "item_div")) {
1907                 val = OP_DIVIDE;
1908         } else if (evas_obj == edje_object_part_object_get(obj, "item_num7")) {
1909                 val = OP_NUM_7;
1910         } else if (evas_obj == edje_object_part_object_get(obj, "item_num8")) {
1911                 val = OP_NUM_8;
1912         } else if (evas_obj == edje_object_part_object_get(obj, "item_num9")) {
1913                 val = OP_NUM_9;
1914         } else if (evas_obj == edje_object_part_object_get(obj, "item_mul")) {
1915                 val = OP_MULTIPLY;
1916         } else if (evas_obj == edje_object_part_object_get(obj, "item_num4")) {
1917                 val = OP_NUM_4;
1918         } else if (evas_obj == edje_object_part_object_get(obj, "item_num5")) {
1919                 val = OP_NUM_5;
1920         } else if (evas_obj == edje_object_part_object_get(obj, "item_num6")) {
1921                 val = OP_NUM_6;
1922         } else if (evas_obj == edje_object_part_object_get(obj, "item_sub")) {
1923                 val = OP_MINUS;
1924         } else if (evas_obj == edje_object_part_object_get(obj, "item_num1")) {
1925                 val = OP_NUM_1;
1926         } else if (evas_obj == edje_object_part_object_get(obj, "item_num2")) {
1927                 val = OP_NUM_2;
1928         } else if (evas_obj == edje_object_part_object_get(obj, "item_num3")) {
1929                 val = OP_NUM_3;
1930         } else if (evas_obj == edje_object_part_object_get(obj, "item_plus")) {
1931                 val = OP_PLUS;
1932         } else if (evas_obj == edje_object_part_object_get(obj, "item_dot")) {
1933                 val = OP_DOT;
1934         } else if (evas_obj == edje_object_part_object_get(obj, "item_num0")) {
1935                 val = OP_NUM_0;
1936         } else if (evas_obj == edje_object_part_object_get(obj, "item_neg")) {
1937                 val = OP_PLUS_MINUS;
1938         } else if (evas_obj == edje_object_part_object_get(obj, "item_eq")) {
1939                 val = OP_EQUAL;
1940         } else if (evas_obj == edje_object_part_object_get(obj, "item_per")) {
1941                 val = OP_PERCENT;
1942         } else if (evas_obj == edje_object_part_object_get(obj, "item_sqr")) {
1943                 val = OP_ROOT;
1944         } else if (evas_obj == edje_object_part_object_get(obj, "item_fac")) {
1945                 val = OP_FACT;
1946         } else if (evas_obj == edje_object_part_object_get(obj, "item_sin")) {
1947                 val = OP_SIN;
1948         } else if (evas_obj == edje_object_part_object_get(obj, "item_cos")) {
1949                 val = OP_COS;
1950         } else if (evas_obj == edje_object_part_object_get(obj, "item_tan")) {
1951                 val = OP_TAN;
1952         } else if (evas_obj == edje_object_part_object_get(obj, "item_ln")) {
1953                 val = OP_LN;
1954         } else if (evas_obj == edje_object_part_object_get(obj, "item_log")) {
1955                 val = OP_LOG;
1956         } else if (evas_obj == edje_object_part_object_get(obj, "item_1x")) {
1957                 val = OP_1X;
1958         } else if (evas_obj == edje_object_part_object_get(obj, "item_10x")) {
1959                 val = OP_10X;
1960         } else if (evas_obj == edje_object_part_object_get(obj, "item_x2")) {
1961                 val = OP_X2;
1962         } else if (evas_obj == edje_object_part_object_get(obj, "item_xy")) {
1963                 val = OP_XY;
1964         } else if (evas_obj == edje_object_part_object_get(obj, "item_abs")) {
1965                 val = OP_ABS;
1966         } else if (evas_obj == edje_object_part_object_get(obj, "item_pi")) {
1967                 val = OP_PI;
1968         } else if (evas_obj == edje_object_part_object_get(obj, "item_e")) {
1969                 val = OP_E;
1970         }
1971         CALC_FUN_END();
1972         return val;
1973 }
1974
1975 /////////////////////////// input text finish ////////////////////////////
1976
1977 #ifdef __i386__
1978 /**
1979 * @describe
1980 *
1981 *
1982 * @param    evas_obj
1983 * @param    obj
1984 * @return    void
1985 * @exception
1986 */
1987 static int _calculator_get_input_item_hd(const char *keyname, Evas_Object * obj)
1988 {
1989         CALC_FUN_BEG();
1990         int val = 0;
1991         if (0 == strcmp(keyname, "KP_7")) {
1992                 val = OP_NUM_7;
1993         } else if (0 == strcmp(keyname, "KP_8")) {
1994                 val = OP_NUM_8;
1995         } else if (0 == strcmp(keyname, "KP_9")) {
1996                 val = OP_NUM_9;
1997         } else if (0 == strcmp(keyname, "KP_4")) {
1998                 val = OP_NUM_4;
1999         } else if (0 == strcmp(keyname, "KP_5")) {
2000                 val = OP_NUM_5;
2001         } else if (0 == strcmp(keyname, "KP_6")) {
2002                 val = OP_NUM_6;
2003         } else if (0 == strcmp(keyname, "KP_1")) {
2004                 val = OP_NUM_1;
2005         } else if (0 == strcmp(keyname, "KP_2")) {
2006                 val = OP_NUM_2;
2007         } else if (0 == strcmp(keyname, "KP_3")) {
2008                 val = OP_NUM_3;
2009         } else if (0 == strcmp(keyname, "KP_0")) {
2010                 val = OP_NUM_0;
2011         }else if (0 == strcmp(keyname, "KP_Decimal")) {
2012                 val = OP_DOT;
2013         } else if (0 == strcmp(keyname, "Return")) {
2014                 val = OP_EQUAL;
2015         } else if (0 == strcmp(keyname, "KP_Add")) {
2016                 val = OP_PLUS;
2017         } else if (0 == strcmp(keyname, "KP_Subtract")) {
2018                 val = OP_MINUS;
2019         } else if (0 == strcmp(keyname, "minus")) {
2020                 val = OP_MINUS;
2021         } else if (0 == strcmp(keyname, "KP_Multiply")) {
2022                 val = OP_MULTIPLY;
2023         } else if (0 == strcmp(keyname, "slash")) {
2024                 val = OP_DIVIDE;
2025         } else if (0 == strcmp(keyname, "KP_Divide")) {
2026                 val = OP_DIVIDE;
2027         }else if (0 == strcmp(keyname, "BackSpace")) {
2028                 val = OP_DELETE;
2029         }
2030         CALC_FUN_END();
2031         return val;
2032 }
2033 #endif
2034
2035 /**
2036 * @description
2037 *   Interpret all of our different signals, and do things !
2038 *
2039 * @param        data
2040 * @param        e
2041 * @param        evas_obj
2042 * @param        event_info
2043 * @return       void
2044 * @exception    none
2045 */
2046 static void
2047 _calculator_interp(void *data, Evas * e, Evas_Object * evas_obj, void *event_info)
2048 {
2049
2050         CALC_FUN_BEG();
2051         int val = 0;
2052         if (data) {
2053
2054                 Evas_Object *obj = (Evas_Object *) data;
2055                 val = _calculator_get_input_item(evas_obj, obj);
2056                 if (ad->wrong_timer) {
2057                         ecore_timer_del(ad->wrong_timer);
2058                         ad->wrong_timer = NULL;
2059                 }
2060                 switch (val) {
2061                 case OP_DELETE:
2062                         _calc_btn_backspace_clicked(e, ad->input_entry);
2063                         if (ad->calc_timer) {
2064                                 ecore_timer_del(ad->calc_timer);
2065                                 ad->calc_timer = NULL;
2066                         }
2067                         ad->calc_timer =
2068                             ecore_timer_add(0.1, (Ecore_Task_Cb)__calculator_delete_long_press, ad->input_entry);
2069                         break;
2070                 case OP_CLEAR:
2071                         edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
2072                         _calc_entry_clear(ad->input_entry);
2073                         calculator_state = CALCULATOR_WAITING_INPUT;
2074                         break;
2075                 case OP_PLUS:
2076                 case OP_MINUS:
2077                 case OP_MULTIPLY:
2078                 case OP_DIVIDE:
2079                         __calculator_control_normal_func_clicked(e, ad->input_entry, &calc_op_item[val]);
2080                         break;
2081                 case OP_DOT:
2082                         _calc_btn_dot_clicked(ad->input_entry);
2083                         break;
2084                 case OP_PARENTHESIS:
2085                         __calculator_parenthesis_clicked(ad->input_entry);
2086                         break;
2087                 case OP_EQUAL:
2088                         __calculator_op_equal(ad->input_entry);
2089                         break;
2090                 case OP_NUM_0:
2091                 case OP_NUM_1:
2092                 case OP_NUM_2:
2093                 case OP_NUM_3:
2094                 case OP_NUM_4:
2095                 case OP_NUM_5:
2096                 case OP_NUM_6:
2097                 case OP_NUM_7:
2098                 case OP_NUM_8:
2099                 case OP_NUM_9:
2100                         __calculator_control_panel_number_button_clicked(e, ad->input_entry, &calc_op_item[val]);
2101                         break;
2102                 case OP_PLUS_MINUS:
2103                         __calculator_symbol_negative_clicked(ad->input_entry);
2104                         break;
2105                 case OP_PERCENT...OP_E:
2106                         __calculator_control_functions_button_clicked(e, ad->input_entry, &calc_op_item[val]);
2107                         break;
2108                 default:
2109                         break;
2110                 }
2111                 if (val == OP_DELETE) {
2112                         feedback_play(FEEDBACK_PATTERN_SIP_BACKSPACE);
2113                 } else {
2114                         feedback_play(FEEDBACK_PATTERN_SIP);
2115                 }
2116         }
2117
2118         CALC_FUN_END();
2119 }
2120
2121 static void __calculator_wrong_format_delete(Evas_Object *in_entry)
2122 {
2123         _calc_entry_text_set(in_entry, calculator_input_str);
2124         if (ad->wrong_timer) {
2125                 ecore_timer_del(ad->wrong_timer);
2126                 ad->wrong_timer = NULL;
2127         }
2128 }
2129
2130 static void __calculator_wrong_text_set(char * wrong_string)
2131 {
2132         char buf[MAX_EXPRESSION_LENGTH] = { 0 };
2133         int fontsize = 50;
2134         memset(buf, 0, sizeof(buf));
2135         snprintf(buf, sizeof(buf),
2136                  "<align=right><+ font_size=%d><color=#855B11FF>%s",
2137                  fontsize, wrong_string);
2138         elm_entry_editable_set(ad->input_entry, EINA_FALSE);//chx add avoid the word splited
2139         elm_entry_line_wrap_set(ad->input_entry,ELM_WRAP_MIXED);
2140         elm_entry_input_panel_enabled_set(ad->input_entry, EINA_FALSE);
2141         elm_entry_entry_set(ad->input_entry, buf);
2142         elm_entry_cursor_end_set(ad->input_entry);
2143         elm_object_focus_set(ad->input_entry, EINA_TRUE);
2144         calc_view_revise_input_scroller(ad);
2145 }
2146
2147 /**
2148 * @describe
2149 *
2150 *
2151 * @param        msg
2152 * @return       void
2153 * @exception    none
2154 */
2155 static void __calculator_wrong_format_create(char * wrong_string)
2156 {
2157         __calculator_wrong_text_set(wrong_string);
2158         if (ad->wrong_timer) {
2159                 ecore_timer_del(ad->wrong_timer);
2160                 ad->wrong_timer = NULL;
2161         }
2162         ad->wrong_timer = ecore_timer_add(3, (Ecore_Task_Cb)__calculator_wrong_format_delete, ad->input_entry);
2163 }
2164
2165 /* mouse up for delete button. */
2166 static void
2167 __calculator_delelte_up(void *data, Evas * e, Evas_Object * evas_obj,
2168                         void *event_info)
2169 {
2170         CALC_FUN_BEG();
2171         if (ad->calc_timer) {
2172                 ecore_timer_del(ad->calc_timer);
2173                 ad->calc_timer = NULL;
2174         }
2175         CALC_FUN_END();
2176 }
2177
2178 /**
2179 * @describe
2180 *   Register clicked callback of the keys on the keypad.
2181 *
2182 * @param    keypad      the keypad
2183 * @return   void
2184 */
2185 void _calc_view_keypad_cb_register(Evas_Object * keypad)
2186 {
2187         CALC_FUN_BEG();
2188         char *key_name[] = {
2189                 "item_per", "item_sqr", "item_fac", "item_c", "item_div",
2190                     "item_mul", "item_del",
2191                 "item_sin", "item_cos", "item_tan", "item_num7", "item_num8",
2192                     "item_num9", "item_sub",
2193                 "item_ln", "item_log", "item_1x", "item_num4", "item_num5",
2194                     "item_num6", "item_plus",
2195                 "item_10x", "item_x2", "item_xy", "item_num1", "item_num2",
2196                     "item_num3", "item_brack",
2197                 "item_abs", "item_pi", "item_e", "item_num0", "item_dot",
2198                     "item_neg", "item_eq",
2199         };
2200
2201         Evas_Object *item = NULL;
2202         int key_num = sizeof(key_name) / sizeof(key_name[0]);
2203         int i = 0;
2204
2205         for (i = 0; i < key_num; ++i) {
2206                 item =
2207                     (Evas_Object *) edje_object_part_object_get(keypad,
2208                                                                 key_name[i]);
2209                 if (item != NULL) {
2210                         evas_object_event_callback_add(item, EVAS_CALLBACK_MOUSE_DOWN, _calculator_interp, (void *)keypad);
2211                         if (0 == strcmp(key_name[i], "item_del")) {
2212                                 evas_object_event_callback_add(item,
2213                                                                EVAS_CALLBACK_MOUSE_UP,
2214                                                                __calculator_delelte_up,
2215                                                                (void *)keypad);
2216                         }
2217
2218                 }
2219         }
2220         CALC_FUN_END();
2221 }
2222
2223 /**
2224 * @description
2225 *   The callback of input entry when mouse up.
2226 *
2227 * @param    data        unused
2228 * @param    e           unused
2229 * @param    entry       the input entry
2230 * @param    event_info  unused
2231 * @return   void
2232 */
2233 static void
2234 _calc_view_input_entry_mouseup_cb(void *data, Evas * e, Evas_Object * entry,
2235                                   void *event_info)
2236 {       if (data == NULL) {
2237                 return;
2238         }
2239         /* if entry is showing warning message, then input operation is unavailable, just return*/
2240         struct appdata *ad = (struct appdata *)data;
2241         if (ad->wrong_timer) {
2242                 return;
2243         }
2244         calculator_cursor_pos = calc_view_cursor_get_position(entry);   //for  softkey input and mouse move
2245 }
2246
2247 static void
2248 _calc_view_input_entry_to_str(char *entry_str, char *internal_str, int buf_size)
2249 {
2250         CALC_FUN_BEG();
2251         if (entry_str == NULL) {
2252                 return;
2253         }
2254         strncpy(internal_str, entry_str, buf_size - 1);
2255         /* remove result that behind '='(include '=') */
2256         char *enter = strchr(internal_str, '=');
2257         if (enter != NULL) {
2258                 enter--;
2259                 *enter = '\0';
2260         }
2261         calc_expr_replace_from_special_char(internal_str);
2262         /* remove all ','  and '\n'*/
2263         int i = 0;
2264         int j = 0;
2265         while (internal_str[j] != '\0'){
2266
2267                 if (internal_str[j] == separator_ch || internal_str[j] == '\n'){
2268                         j++;
2269                 } else {
2270                         internal_str[i++] = internal_str[j++];
2271                 }
2272         }
2273         internal_str[i] = '\0';
2274         CALC_FUN_END();
2275 }
2276
2277 #ifdef __i386__
2278 static void
2279 _calc_view_input_entry_keyup_cb(void *data, Evas * e, Evas_Object * entry,
2280                                 void *event_info)
2281 {
2282         CALC_FUN_BEG();
2283         calculator_cursor_pos = calc_view_cursor_get_position(entry);   //for hardkey input
2284         int val = 0;
2285         if (data) {
2286                 Evas_Object *obj = (Evas_Object *) data;
2287                 Evas_Event_Key_Up *evt = (Evas_Event_Key_Up *) event_info;
2288                 if (0 == strcmp(evt->key, "Return")) {
2289                         //calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
2290                         __calculator_op_equal(entry);
2291
2292                 }
2293                 val = _calculator_get_input_item_hd(evt->key, obj);
2294                 switch (val) {
2295                 case OP_PLUS:
2296                 case OP_MINUS:
2297                 case OP_MULTIPLY:
2298                 case OP_DIVIDE:
2299                         __calculator_control_normal_func_clicked(e, ad->input_entry, &calc_op_item[val]);
2300                         break;
2301                 case OP_DOT:
2302                         _calc_btn_dot_clicked(ad->input_entry);
2303                         break;
2304                 case OP_NUM_0:
2305                 case OP_NUM_1:
2306                 case OP_NUM_2:
2307                 case OP_NUM_3:
2308                 case OP_NUM_4:
2309                 case OP_NUM_5:
2310                 case OP_NUM_6:
2311                 case OP_NUM_7:
2312                 case OP_NUM_8:
2313                 case OP_NUM_9:
2314                         __calculator_control_panel_number_button_clicked(e, ad-> input_entry, &calc_op_item[val]);
2315                         break;
2316                 case OP_DELETE:
2317                         calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
2318                         break;
2319                 default:
2320                         break;
2321                 }
2322         }
2323         CALC_FUN_END();
2324 }
2325 #endif
2326
2327 static bool
2328 _calc_view_input_entry_error_include(char *string)
2329 {
2330     int i = 0;
2331     for(; i < ARRAY_SIZE(error_string); i++)
2332         {
2333                 if(!strcmp(string, _(error_string[i]))){
2334                         return TRUE;
2335             }
2336     }
2337     return FALSE;
2338 }
2339
2340 /**
2341 * @description
2342 * The callback of input entry when text changed
2343 *
2344 * @param[in]    data    the appdata
2345 * @param[in]    obj     the input entry
2346 * @param[in]    event_info      unused
2347 * @return       void
2348 */
2349 static void
2350 _calc_view_input_entry_changed_cb(void *data, Evas_Object *obj,
2351                                   void *event_info)
2352 {
2353         CALC_FUN_BEG();
2354         if (data == NULL || obj == NULL) {
2355                 return;
2356         }
2357         struct appdata *ad = (struct appdata *)data;
2358         const char *str = (char *)elm_entry_entry_get(obj);
2359
2360         if (paste_flag) {
2361                 char *entry_tmp = elm_entry_markup_to_utf8(str);
2362                 char *entry_expr= elm_entry_markup_to_utf8(entry_tmp);/*because the string format from clipboard is not correct*/
2363                 char internal_expr[MAX_EXPRESSION_LENGTH] = { 0 };
2364                 char f_number_buf[NUMBER_LENGTH] = { 0 };
2365                 char s_number_buf[NUMBER_LENGTH] = { 0 };
2366                 paste_flag = FALSE;
2367                 _calc_view_input_entry_to_str(entry_expr, internal_expr, MAX_EXPRESSION_LENGTH);
2368                 int index = 0;
2369                 bool char_in =__calculator_string_invalid_char_search(internal_expr, &index);
2370                 __calculator_get_cursor_position_float_string(internal_expr, f_number_buf, calculator_cursor_pos, NULL, NULL);
2371                 int cur_pos = calc_view_cursor_get_position(ad->input_entry);
2372                 __calculator_get_cursor_position_float_string(internal_expr, s_number_buf, cur_pos, NULL, NULL);
2373                 int nCntOp = calc_expr_get_operator_num(internal_expr);
2374
2375                 if ((strlen(f_number_buf) > MAX_NUM_LENGTH) || (strlen(s_number_buf) > MAX_NUM_LENGTH)) {
2376                         __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
2377                 } else if (nCntOp >= MAX_OPERATOR_NUM) {
2378                         __calculator_wrong_format_create(CALC_MSG_MAX_OP);
2379                 } else {
2380                         if (char_in) {
2381                                 strncpy(calculator_input_str, internal_expr, index);
2382                                 calculator_cursor_pos = index;
2383                         } else {
2384                                 strncpy(calculator_input_str, internal_expr, sizeof(calculator_input_str) - 1);
2385                                 calculator_cursor_pos = cur_pos;
2386                         }
2387                         _calc_entry_text_set(ad->input_entry, calculator_input_str);
2388                 }
2389
2390                 if (entry_tmp) {
2391                         free(entry_tmp);
2392                         entry_tmp = NULL;
2393                 }
2394                 if (entry_expr) {
2395                         free(entry_expr);
2396                         entry_expr = NULL;
2397                 }
2398         } else {
2399                 if (select_mode) {
2400                         char *entry_expr_s = elm_entry_markup_to_utf8(str);
2401                         char internal_expr_s[MAX_EXPRESSION_LENGTH] = { 0 };
2402                         _calc_view_input_entry_to_str(entry_expr_s, internal_expr_s, MAX_EXPRESSION_LENGTH);
2403                         if(!_calc_view_input_entry_error_include(internal_expr_s)){
2404                                 /*change calculator_input_str, after cut operation*/
2405                                 if(calculator_state == CALCULATOR_CALCULATED){
2406                                         calculator_state = CALCULATOR_OPERAND_INPUT;
2407                                 }
2408                                 strncpy(calculator_input_str, internal_expr_s, MAX_EXPRESSION_LENGTH - 1);
2409                                 calculator_cursor_pos = calc_view_cursor_get_position(obj);
2410                         }
2411                         _calc_entry_text_set(obj, calculator_input_str);
2412                         if (entry_expr_s) {
2413                                 free(entry_expr_s);
2414                                 entry_expr_s = NULL;
2415                         }
2416                 }
2417         }
2418         /*
2419          * Prevent pasting images into entry.
2420          * If a image pasted, "<item absize=... href=...>" will be appended into entry.
2421          */
2422         if (strstr(str, "item") != NULL) {
2423                 int pos = 0;
2424                 char buf[MAX_EXPRESSION_LENGTH] = { 0 };
2425
2426                 while (elm_entry_cursor_prev(obj)) {
2427                         pos++;
2428                 }               /* save cursor position */
2429                 pos -= 1;       /* correct */
2430
2431                 strncpy(buf, str, sizeof(buf));
2432                 char *begin = strstr(buf, "<item");
2433                 if (begin != NULL) {
2434                         char *end = strchr(begin, '>');
2435                         string_remove_at(buf, begin - buf, end - begin + 1);    /* remove "<item...>" */
2436                         elm_entry_entry_set(obj, buf);
2437                 }
2438
2439                 while (pos--) {
2440                         elm_entry_cursor_next(obj);
2441                 }               /* retrieve cursor position */
2442
2443                 calc_view_revise_input_scroller(ad);
2444         }
2445         CALC_FUN_END();
2446 }
2447
2448 static void
2449 _calc_view_input_entry_paste_cb(void *data, Evas_Object * obj, void *event_info)
2450 {
2451         CALC_FUN_BEG();
2452         paste_flag = TRUE;
2453         strncpy(calculator_before_paste_str, calculator_input_str,
2454                 MAX_EXPRESSION_LENGTH - 1);
2455         CALC_FUN_END();
2456 }
2457
2458 static void
2459 _calc_view_input_entry_select_start_cb(void *data, Evas_Object * obj, void *event_info)
2460 {
2461         CALC_FUN_BEG();
2462         select_mode = TRUE;
2463         CALC_FUN_END();
2464 }
2465
2466 static void
2467 _calc_view_input_entry_select_changed_cb(void *data, Evas_Object * obj, void *event_info)
2468 {
2469         CALC_FUN_BEG();
2470         CALC_FUN_END();
2471 }
2472
2473 static void
2474 _calc_view_input_entry_select_cleared_cb(void *data, Evas_Object * obj, void *event_info)
2475 {
2476         CALC_FUN_BEG();
2477         select_mode = FALSE;
2478         CALC_FUN_END();
2479 }
2480
2481
2482 /**
2483 * @description
2484 *   Create an entry for inputing expression.
2485 *
2486 * @param    parent          the entry's parent
2487 * @param    ad              the appdata
2488 * @return   Evas_Object*    the input entry
2489 */
2490 static Evas_Object *_calc_view_create_input_entry(Evas_Object * parent,
2491                                                   struct appdata *ad)
2492 {
2493         CALC_FUN_BEG();
2494         Evas_Object *entry = elm_entry_add(ad->edje);
2495         elm_entry_single_line_set(entry, EINA_FALSE);
2496         elm_entry_editable_set(entry, EINA_TRUE);
2497         elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
2498         if (strlen(calculator_input_str) > 0) {
2499                 _calc_entry_text_set(entry, calculator_input_str);
2500         } else {
2501                 elm_entry_entry_set(entry, "");
2502         }
2503         elm_entry_cnp_mode_set(entry, ELM_CNP_MODE_NO_IMAGE);
2504 #if (ELM_VERSION_MAJOR == 1) && (ELM_VERSION_MINOR < 8)
2505         elm_entry_magnifier_disabled_set(entry, EINA_TRUE);
2506 #else
2507         elm_config_magnifier_enable_set(EINA_FALSE);
2508 #endif
2509         elm_entry_cursor_end_set(entry);
2510         elm_object_focus_set(entry, EINA_TRUE);
2511     elm_object_style_set(entry, "black");
2512         evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND,
2513                                          EVAS_HINT_EXPAND);
2514         evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
2515
2516         evas_object_event_callback_add(entry, EVAS_CALLBACK_MOUSE_UP,
2517                                        _calc_view_input_entry_mouseup_cb, ad);
2518         evas_object_smart_callback_add(entry, "changed",
2519                                        _calc_view_input_entry_changed_cb, ad);
2520         evas_object_smart_callback_add(entry, "selection,paste",
2521                                        _calc_view_input_entry_paste_cb, ad);
2522         evas_object_smart_callback_add(entry, "selection,start",
2523                                        _calc_view_input_entry_select_start_cb, ad);
2524         evas_object_smart_callback_add(entry, "selection,changed",
2525                                        _calc_view_input_entry_select_changed_cb, ad);
2526         evas_object_smart_callback_add(entry, "selection,cleared",
2527                                        _calc_view_input_entry_select_cleared_cb, ad);
2528 #ifdef __i386__
2529         evas_object_event_callback_add(entry, EVAS_CALLBACK_KEY_UP,
2530                                        _calc_view_input_entry_keyup_cb, ad);
2531         evas_object_smart_callback_del (entry, "changed",  _calc_view_input_entry_changed_cb);
2532 #endif
2533         evas_object_show(entry);
2534         limit_filter_data.max_char_count = 0;
2535         limit_filter_data.max_byte_count = 419 + 20;    //19*21+20//result:20
2536         elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size,
2537                                      &limit_filter_data);
2538         elm_entry_text_style_user_push(entry, "DEFAULT='right_margin=32'");
2539         CALC_FUN_END();
2540         return entry;
2541 }
2542
2543 /**
2544 * @description
2545 *   Create a input scrooler which around the input entry.
2546 *   It can give a input entry a scroller.
2547 *
2548 * @param    parent          the parent of input scroller
2549 * @return   Evas_Object*    the input scroller
2550 * @exception
2551 */
2552 static Evas_Object *_calc_view_create_input_scroller(Evas_Object * parent)
2553 {
2554         CALC_FUN_BEG();
2555         Evas_Object *scroller = elm_scroller_add(parent);
2556         elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
2557         evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND,
2558                                          EVAS_HINT_EXPAND);
2559         evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL,
2560                                         EVAS_HINT_FILL);
2561
2562         evas_object_show(scroller);
2563         CALC_FUN_END();
2564         return scroller;
2565 }
2566
2567 /**
2568 * @description
2569 * Create the background
2570 *
2571 * @param[in]    parent  background's parent
2572 * @return               when success return background, return NULL oppositely
2573 * @retval       layout  if success, return the background
2574 * @retval       NULL    if create failed or parent is null, return null
2575 * @exception
2576 */
2577 static Evas_Object *__create_bg(Evas_Object *parent)
2578 {
2579         CALC_FUN_BEG();
2580         if (parent == NULL) {
2581                 return NULL;
2582         }
2583         Evas_Object *bg = elm_bg_add(parent);
2584         if (bg == NULL) {
2585                 return NULL;
2586         }
2587         evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2588         elm_win_resize_object_add(parent, bg);
2589         evas_object_show(bg);
2590         CALC_FUN_END();
2591         return bg;
2592 }
2593
2594 void _btn_clicked_cb(void *data, Evas_Object * obj, void *event_info)
2595 {
2596         CALC_FUN_BEG();
2597         Evas_Object *win_main = (Evas_Object *) data;
2598         elm_win_lower(win_main);
2599         CALC_FUN_END();
2600 }
2601
2602 /**
2603 * @description
2604 *   Callback function of "Clear" Button on naviframe
2605 *
2606 * @param    data      the appdata
2607 * @param    obj
2608 * @param    event_info
2609 * @return   void
2610
2611 */
2612 static void
2613 __calc_view_clear_clicked_cb(void *data, Evas_Object *obj, void *event_info)
2614 {
2615         CALC_FUN_BEG();
2616         struct appdata *ad = (struct appdata *)data;
2617         if (ad->more_btn_popup) {
2618                 evas_object_hide(ad->more_btn_popup);
2619                 //ad->more_btn_popup= NULL;
2620         }
2621         elm_entry_entry_set(ad->hist_area, "");
2622         elm_entry_entry_set(ad->input_entry, "");
2623         _calc_view_clear_histroy(ad->hist_area);
2624         /* Set input entry as initial state */
2625         _calc_entry_clear(ad->input_entry);
2626         calculator_state = CALCULATOR_WAITING_INPUT;
2627         CALC_FUN_END();
2628 }
2629
2630 Evas_Object *create_toolbar_more_btn(Evas_Object *parent, Evas_Smart_Cb func, void *data)
2631 {
2632         Evas_Object *btn = elm_button_add(parent);
2633         if (!btn) {
2634                 return NULL;
2635         }
2636         elm_object_style_set(btn, "naviframe/more/default");
2637         if (func) {
2638                 evas_object_smart_callback_add(btn, "clicked", func, data);
2639         }
2640         return btn;
2641 }
2642
2643 static void __gl_ctxpopup_hide_cb(void *data, Evas_Object *obj, void *event_info)
2644 {
2645         evas_object_del(obj);
2646 }
2647
2648 static void __calc_view_create_popup(void *data, Evas_Object *parent)
2649 {
2650         if (data == NULL) {
2651                 return;
2652         }
2653         struct appdata *ad = (struct appdata *)data;
2654         ad->more_btn_popup = elm_ctxpopup_add(parent);
2655         const char *profile = elm_config_profile_get();
2656         if (!strcmp(profile, "mobile")) {
2657                 ad->clear_item = elm_ctxpopup_item_append(ad->more_btn_popup,
2658                         CALC_MSG_CLEAR_HISTTORY, NULL, __calc_view_clear_clicked_cb, ad);
2659         } else if (!strcmp(profile, "desktop")) {
2660                 ad->clear_item = elm_ctxpopup_item_append(ad->more_btn_popup,
2661                         CALC_MSG_CLEAR_HISTTORY,  NULL, __calc_view_clear_clicked_cb, ad);
2662         }
2663
2664         Evas_Object *more_btn = NULL;
2665         more_btn = elm_object_item_part_content_get(ad->navi_it, "toolbar_more_btn");
2666         if (more_btn) {
2667                 int x_position = 0;
2668                 int y_position = 0;
2669                 int w = 0;
2670                 int h = 0;
2671                 evas_object_geometry_get(more_btn, &x_position, &y_position, &w, &h);
2672                 evas_object_move(ad->more_btn_popup, x_position + w/4, y_position+h/2);
2673         }
2674
2675         evas_object_show(ad->more_btn_popup);
2676         evas_object_smart_callback_add(ad->more_btn_popup, "dismissed",  __gl_ctxpopup_hide_cb, data);
2677
2678 }
2679
2680 void __calc_view_create_nf_more_btn_cb(void *data, Evas_Object * obj, void *event_info)
2681 {
2682         struct appdata *ad = (struct appdata *)data;
2683         __calc_view_create_popup(data, ad->nf);
2684 }
2685
2686
2687 /**
2688 * @description
2689 *   Load the Naviframe.
2690 *
2691 * @param    ad      the appdata
2692 * @return   naviframe object
2693
2694 */
2695 static Eina_Bool  __calc_view_create_navigation_layout(struct appdata *ad)
2696 {
2697         CALC_FUN_BEG();
2698         Evas_Object *nf = elm_naviframe_add(ad->conform);
2699         if (nf == NULL) {
2700                 return EINA_FALSE;
2701         }
2702         ad->nf = nf;
2703         if (!ad->back_btn) {
2704                 Evas_Object *back_btn = elm_button_add(nf);
2705                 elm_object_style_set(back_btn, "naviframe/end_btn/default");
2706                 evas_object_smart_callback_add(back_btn, "clicked", _btn_clicked_cb, ad->win);
2707                 ad->back_btn = back_btn;
2708         }
2709         ad->navi_it = elm_naviframe_item_push(nf, NULL, ad->back_btn, NULL, ad->edje, NULL);
2710         elm_naviframe_item_title_visible_set(ad->navi_it, EINA_FALSE);
2711         ad->more_btn = create_toolbar_more_btn(nf, __calc_view_create_nf_more_btn_cb, ad);
2712         elm_object_item_part_content_set(ad->navi_it, "toolbar_more_btn", ad->more_btn);
2713         elm_object_content_set(ad->conform, nf);
2714         evas_object_show(nf);
2715         CALC_FUN_END();
2716         return EINA_TRUE;
2717 }
2718
2719 /**
2720 * @description
2721 *   Load the main view of calculator.
2722 *   Create the input entry and keypad.
2723 *
2724 * @param    ad      the appdata
2725 * @return   void
2726 */
2727 void calc_view_load(struct appdata *ad)
2728 {
2729         CALC_FUN_BEG();
2730         if (ad->bg == NULL) {
2731                 ad->bg = __create_bg(ad->win);
2732         }
2733         ad->conform = elm_conformant_add(ad->win);
2734         evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2735         elm_win_resize_object_add(ad->win, ad->conform);
2736         elm_object_style_set(ad->conform, "nokeypad");
2737         evas_object_show(ad->conform);
2738         ad->edje = load_edj(ad->win, LAYOUT_EDJ_NAME, GRP_MAIN);
2739         evas_object_show(ad->edje);
2740         evas_object_name_set(ad->edje, "edje");
2741
2742         __calc_view_create_navigation_layout(ad);
2743
2744         /* inititialize environment variable */
2745         locale = localeconv();
2746         decimal = locale->decimal_point;
2747         separator = locale->thousands_sep;
2748         int len_seq = strlen(separator);
2749         decimal_ch = decimal[0];
2750         separator_ch = separator[0];
2751         if (len_seq == 2 || len_seq == 0) {
2752                 separator_ch = 32;
2753         }
2754
2755         /*init svi */
2756         feedback_initialize();
2757
2758         /* input area */
2759         ad->input_entry = _calc_view_create_input_entry(ad->edje, ad);
2760         ad->input_scroller = _calc_view_create_input_scroller(ad->edje);
2761         elm_object_content_set(ad->input_scroller, ad->input_entry);
2762         edje_object_part_swallow(_EDJ(ad->edje), "input/entry",
2763                                  ad->input_scroller);
2764         CALC_FUN_END();
2765
2766 }
2767
2768 /**
2769 * @description
2770 *   assign global variable  , this will be removed
2771 *
2772 * @param        ad
2773 * @return       void
2774 * @exception
2775 */
2776 void calc_xxx(struct appdata *ap)
2777 {
2778         ad = ap;
2779 }
2780
2781 static Evas_Object* __set_win_icon(struct appdata *ad)
2782 {
2783         /* set window icon*/
2784         Evas_Object *icon = evas_object_image_add(evas_object_evas_get(ad->win));
2785         evas_object_image_file_set(icon, DESKTOP_MODE_ICON, NULL);
2786         elm_win_icon_object_set(ad->win, icon);
2787         return icon;
2788 }
2789
2790 void win_profile_changed_cb(void *data, Evas_Object * obj, void *event_info)
2791 {
2792         CALC_FUN_BEG();
2793         if (data == NULL) {
2794                 return;
2795         }
2796         struct appdata *ad = (struct appdata *)data;
2797         const char *profile = elm_config_profile_get();
2798         if (!strcmp(profile, "desktop")) {
2799                 /*In destktop mode, Hide indicator & hide back button on the naviframe */
2800                 elm_object_item_part_content_set(ad->navi_it, "prev_btn", NULL);
2801                 elm_object_item_part_content_set(ad->navi_it , "toolbar_button1", NULL);
2802                 elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_HIDE);
2803
2804                 /* Show window Icon */
2805                 if (!ad->window_icon) {
2806                         ad->window_icon = __set_win_icon(ad);
2807                 }
2808
2809         } else if (!strcmp(profile, "mobile")) {
2810                 /* In mobile phone mode, show indicator and show back button*/
2811                 elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
2812                 Evas_Object *back_btn = elm_button_add(ad->nf);
2813                 elm_object_style_set(back_btn, "naviframe/end_btn/default");
2814                 evas_object_smart_callback_add(back_btn, "clicked", _btn_clicked_cb, ad->win);
2815                 ad->back_btn = back_btn;
2816                 elm_object_item_part_content_set(ad->navi_it, "prev_btn", ad->back_btn);
2817         }
2818         CALC_FUN_END();
2819 }