3 * Copyright 2012 Samsung Electronics Co., Ltd
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
9 * http://floralicense.org/license
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.
19 #include <stdbool.h> /* true/false */
20 #include <Elementary.h>
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"
32 #define CALCULATOR_CHAR_IS_OPERATOR(C) ((C == '+')||(C == '-')||(C == 'x')||(C == '/')) /**<judge if a char is a basic operator*/
33 #define CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(C) ((C == 'x')||(C == '/')) /**<judge if an operator is "*" or "/"*/
34 #define CALCULATOR_CHAR_IS_PLUS_DEDUCT(C) ((C == '+')||(C == '-'))
35 #define CALCULATOR_CHAR_IS_DIGITAL(C)(C >= '0' && C <= '9')
36 #define CALCULATOR_IS_DIGIT_DOT(ch, decimal) (isdigit(ch) || decimal == (ch))
38 static Elm_Entry_Filter_Limit_Size limit_filter_data;
39 extern void _calc_view_show_newest_histroy(Evas_Object * entry);
40 extern void _calc_view_clear_histroy(Evas_Object * entry);
41 extern gboolean __calculator_search_function(char *op, int* len);
42 static void __calculator_wrong_format_create(char * wrong_string);
43 void calc_view_load(struct appdata *ad);
45 static struct appdata *ad; /* will be removed */
46 static calculator_state_t calculator_state = CALCULATOR_WAITING_INPUT;
47 static double last_result = 0.0;
48 int calculator_cursor_pos = 0;
49 char calculator_input_str[MAX_EXPRESSION_LENGTH] = { 0 };
50 char calculator_before_paste_str[MAX_EXPRESSION_LENGTH] = { 0 };
51 bool paste_flag = FALSE;
53 struct lconv *locale = NULL;
55 char *separator = NULL;
57 char separator_ch = 0;
59 int cur_fontsize = 70;
60 int small_fontsize = 58;
61 int default_fontsize = 0;
64 int scientific_result_len = 8;
66 bool select_mode = FALSE;
68 static op_item_t calc_op_item[] = {
69 {OP_INVALID, "", NULL},
72 {OP_PARENTHESIS, "()", NULL},
73 {OP_DELETE, "<-", NULL},
74 {OP_CLEAR, "C", NULL},
75 {OP_DIVIDE, "/", NULL},
77 {OP_NUM_7, "7", NULL},
78 {OP_NUM_8, "8", NULL},
79 {OP_NUM_9, "9", NULL},
80 {OP_MULTIPLY, "x", NULL},
82 {OP_NUM_4, "4", NULL},
83 {OP_NUM_5, "5", NULL},
84 {OP_NUM_6, "6", NULL},
85 {OP_MINUS, "-", NULL},
87 {OP_NUM_1, "1", NULL},
88 {OP_NUM_2, "2", NULL},
89 {OP_NUM_3, "3", NULL},
93 {OP_NUM_0, "0", NULL},
94 {OP_PLUS_MINUS, "+/-", NULL},
95 {OP_EQUAL, "=", NULL},
98 {OP_PERCENT, "%", NULL},
99 {OP_ROOT, "sqrt", "sqrt("},
100 {OP_FACT, "x!", "!"},
102 {OP_SIN, "sin", "sin("},
103 {OP_COS, "cos", "cos("},
104 {OP_TAN, "tan", "tan("},
106 {OP_LN, "ln", "ln("},
107 {OP_LOG, "log", "log("},
108 {OP_1X, "1/x", "1/x"},
110 {OP_10X, "10^x", "10^("},
111 {OP_X2, "x^2", "^2"},
112 {OP_XY, "x^y", "^("},
114 {OP_ABS, "abs", "abs("},
118 char *error_string[] = {
119 "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE",
120 "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE",
121 "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE",
122 "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO",
123 "IDS_CCL_POP_NO_NUMBER_ERROR",
125 "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR",
126 "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION",
127 "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION",
128 "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION",
129 "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION",
130 "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION",
131 "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION",
132 "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION",
133 "IDS_CCL_POP_NO_OPERATOR_ERROR",
134 "IDS_CCL_POP_SYNTAX_ERROR",
135 "IDS_CCL_POP_INPUT_ERROR",
138 calculator_state_t calculator_get_state()
140 return calculator_state;
143 void _calc_add_tag(char *string, char *format_string)
149 char buf[MAX_EXPRESSION_LENGTH] = { 0 };
150 char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
152 while (string[i] != '\0') {
153 if (CALCULATOR_CHAR_IS_DIGITAL(string[i])
154 || string[i] == separator_ch || string[i] == decimal_ch
155 ||( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92')) {
156 if ( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92') {
157 memset(buf, 0, sizeof(buf));
158 snprintf(buf, sizeof(buf),
159 "<align=right><font_size=%d><color=#505050FF>(<align=right><font_size=%d><color=#505050FF>-",
160 cur_fontsize, cur_fontsize);
161 strcat(format_string, buf);
166 while (CALCULATOR_CHAR_IS_DIGITAL(string[i])
167 || string[i] == separator_ch
168 || string[i] == decimal_ch) {
172 strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
173 tmp[end - begin + 1] = '\0';
174 memset(buf, 0, sizeof(buf));
175 snprintf(buf, sizeof(buf),
176 "<align=right><font_size=%d><color=#505050FF>%s",
178 strcat(format_string, buf);
182 while (!CALCULATOR_CHAR_IS_DIGITAL(string[i])
183 && string[i] != separator_ch
184 && string[i] != decimal_ch
185 && string[i] != '\0') {
186 if ( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92') {
193 strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
194 tmp[end - begin + 1] = '\0';
195 memset(buf, 0, sizeof(buf));
196 snprintf(buf, sizeof(buf),
197 "<align=right><font_size=%d><color=#505050FF>%s",
199 strcat(format_string, buf);
208 * Change line and font size when it is needed.
209 * Refer to the auto font resizing rules.
210 * @param tag_text The text with tags.
214 void _calc_add_br(char *tag_text)
217 if (tag_text == NULL) {
220 app_device_orientation_e curr = app_get_device_orientation();
221 if (curr == APP_DEVICE_ORIENTATION_270 || curr == APP_DEVICE_ORIENTATION_90) {
224 int line_valid_num = 0;
225 int whole_valid_num = 0;
226 int operator_tag = -1;
227 int operator_location = -1;
228 /* record is there an operator in one line? */
229 bool operator_flag = FALSE;
230 /* when change to small font, we should rescan the tag_text */
231 bool rescan_flag = FALSE;
233 char buf[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
234 strcpy(buf, tag_text);
238 for ( ; tag_text[i] != '\0' && calculator_input_str[j] != '\0'; ) {
239 while (tag_text[i] == '<') {
240 while (tag_text[i++] != '>') {
245 /* if calculator_input_str[j] is "*" or "/", tag_text[i] would be
246 "\xc3\x97" or "\xc3\xb7" */
247 if (tag_text[i] == calculator_input_str[j] || (tag_text[i] == '\xc3') ||
248 ((tag_text[i] == '\xe2') && (tag_text[i+1] == '\x88') && (tag_text[i+2] == '\x92'))) {
250 if ((CALCULATOR_CHAR_IS_OPERATOR(calculator_input_str[j])) &&
251 (!(calculator_input_str[j] == '-' && calculator_input_str[j-1] == '('))) {
252 if (!operator_flag || rescan_flag) {
253 operator_location = j;
255 operator_flag = TRUE;
262 cur_fontsize = default_fontsize;
265 if ((line_valid_num >= min_len) && (!rescan_flag)) {
267 cur_fontsize = small_fontsize;
268 strcpy(tag_text, buf);
269 /* restore to the original state, then scan from the begin */
274 operator_flag = FALSE;
276 operator_location = -1;
277 cur_len = max_len + 1;
281 if (line_valid_num >= cur_len) {
282 if (operator_flag && operator_tag > 0) {
283 string_insert(tag_text, operator_tag, "<br>");
284 line_valid_num = whole_valid_num-operator_location;
285 operator_flag = FALSE;
287 operator_location = -1;
289 string_insert(tag_text, i, "<br>");
317 static void _calc_entry_text_set(Evas_Object * entry, const char *str)
323 char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
324 char tag_text[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
325 char new_font_str[MAX_EXPRESSION_LENGTH] = { 0 };
326 char old_font_str[MAX_EXPRESSION_LENGTH] = { 0 };
328 Eina_Bool status = elm_entry_editable_get(entry);
329 if (EINA_FALSE == status) {
330 elm_entry_editable_set(entry, EINA_TRUE);//chx add recover the old style
331 elm_entry_line_wrap_set(entry,ELM_WRAP_WORD);
332 elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
333 elm_object_style_set(entry, "black");
334 elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data);
335 elm_entry_text_style_user_push(entry, "DEFAULT='right_margin=32'");
342 if (strlen(str) == 0) {
343 elm_entry_entry_set(entry, "");
344 elm_entry_cursor_end_set(entry);
345 elm_object_focus_set(entry, EINA_TRUE);
349 calc_expr_format_expression(str, tmp);
350 CALC_INFO("ASCII :: expr_out = %s", tmp);
351 CALC_INFO("ASCII :: expr_out = %d", tmp);
352 _calc_add_tag(tmp, tag_text);
353 int pre_fontsize = cur_fontsize;
354 _calc_add_br(tag_text);
355 snprintf(old_font_str, sizeof(old_font_str), "=%d", pre_fontsize);
356 snprintf(new_font_str, sizeof(new_font_str), "=%d", cur_fontsize);
357 string_replace(tag_text, old_font_str, new_font_str);
358 CALC_INFO("ASCII :: tag_text = %s", tag_text);
359 CALC_INFO("ASCII :: tag_text = %d", tag_text);
360 elm_entry_entry_set(entry, tag_text);
361 if(calculator_cursor_pos == strlen(calculator_input_str)){
362 elm_entry_cursor_end_set(entry);
363 elm_object_focus_set(entry, EINA_TRUE);
365 calc_view_cursor_set_position(entry, calculator_cursor_pos);
370 void _calc_entry_text_set_rotate(struct appdata *ad)
373 if (calculator_state == CALCULATOR_CALCULATED) {
374 _calc_view_show_newest_histroy(ad->input_entry);
375 elm_entry_cursor_end_set(ad->input_entry);
376 elm_object_focus_set(ad->input_entry, EINA_TRUE);
378 _calc_entry_text_set(ad->input_entry, calculator_input_str);
392 static void _calc_entry_text_insert(Evas_Object * entry, char *str)
395 CALC_INFO("ASCII :: str = %s", str);
396 CALC_INFO("ASCII :: str = %d", str);
397 calc_expr_input_insert(calculator_input_str, &calculator_cursor_pos, str);
398 _calc_entry_text_set(entry, calculator_input_str);
412 static void _calc_entry_text_remove(Evas_Object * entry, const int from_pos,
416 string_remove_at(calculator_input_str, from_pos,
417 end_pos - from_pos + 1);
418 calculator_cursor_pos = from_pos;
419 _calc_entry_text_set(entry, calculator_input_str);
425 * Set correct cursor position in entry.
431 static void _calc_entry_cursor_set(Evas_Object * entry)
434 calc_view_cursor_set_position(entry, calculator_cursor_pos);
446 static void _calc_entry_backspace(Evas_Object * entry)
449 calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
450 _calc_entry_text_set(entry, calculator_input_str);
462 void _calc_entry_clear(Evas_Object * entry)
465 memset(calculator_input_str, 0, sizeof(calculator_input_str));
466 calculator_cursor_pos = 0;
467 _calc_entry_text_set(entry, "");
468 calc_view_cursor_set_position(entry, calculator_cursor_pos);
472 /* END INPUT ENTRY RELATED */
476 * Get the operand start and end location where the cursor in.
477 * 1.2+6.|43 (cursor is before 4), then return begin=4 end=7
478 * Espcially, cursor is after +, it means the operand which follows
479 * the operator, so it return the same result as before.
480 * This is add by on 2012/5/29
482 * @param[in] text The current calculator input string
483 * @param[out] begin The start location of an operand
484 * @param[out] end The end location of an operand
485 * @return Is cursor in an operand
486 * @retval true The cursor is in the operand
487 * @retval false The cursor is not in the operand
491 __calculator_get_float_num_in_cursor_position(char *text, int cur_pos,
492 int *begin, int *end)
498 int pos = cur_pos - 1;
505 if ('p' == text[pos] || 'e' == text[pos]) {
509 } else if (CALCULATOR_IS_DIGIT_DOT(text[pos], decimal_ch)) {
510 for (_begin = pos - 1;
511 CALCULATOR_IS_DIGIT_DOT(text[_begin], decimal_ch)
512 && _begin >= 0; --_begin) {
516 if (_begin > 1 && '-' == text[_begin - 1]
517 && '(' == text[_begin - 2]) {
521 CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
522 && _end < strlen(text); ++_end) {
530 } else if (CALCULATOR_CHAR_IS_OPERATOR(text[pos]) || text[pos] == '(') {
532 CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
533 && _end < strlen(text); ++_end) {
548 * Get the operand start and end location where the cursor in the operand
549 * Actually, it would call "__calculator_get_float_num_in_cursor_position"
550 * function to recognize whether the cursor is in the operand.
552 * @param[in] entry_text The current calcualtor input string
553 * @param[out] str The operand which the cursor in
554 * @param[out] from The operand start location which contain the cursor
555 * @param[out] end The operand end location which contain the cursor
556 * @return Is cursor in an operand
557 * @retval true The cursor is in the operand
558 * @retval false The cursor is not in the operand
562 __calculator_get_cursor_position_float_string(char *entry_text, char *str,
563 int cur_pos, int *from, int *end)
566 if (entry_text == NULL) {
569 int from_pos = cur_pos;
570 int end_pos = cur_pos;
573 __calculator_get_float_num_in_cursor_position(entry_text, cur_pos, &from_pos, &end_pos)) {
577 /* set from&end position */
585 strncpy(str, entry_text + from_pos, end_pos - from_pos + 1);
586 str[end_pos - from_pos + 1] = '\0';
593 * Get the float number in current cursor
601 __calculator_get_before_cursor_float_string(char *entry_text, char *str)
605 int from_pos = calculator_cursor_pos;
606 int end_pos = calculator_cursor_pos;
608 if (false == __calculator_get_float_num_in_cursor_position(entry_text, calculator_cursor_pos, &from_pos, &end_pos)) {
611 snprintf(str, calculator_cursor_pos - from_pos + 1, "%s", entry_text + from_pos);
618 * Get string before cursor in the Entry.
626 __calculator_get_input_from_begin_to_cursor(char *entry_text, char *str)
630 if (calculator_cursor_pos > 0) {
631 strncpy(str, entry_text, calculator_cursor_pos);
632 str[calculator_cursor_pos] = '\0';
642 * judge the type of current input
648 static last_char_t __calculator_string_get_char_type( char ch_in)
660 if (CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(ch_in)) {
661 return CHAR_IS_MULTIPLY_DIVIDE;
664 return CHAR_IS_LEFT_PARENTHESE;
667 return CHAR_IS_RIGHT_PARENTHESE;
669 if (CALCULATOR_CHAR_IS_DIGITAL(ch_in)) {
670 return CHAR_IS_DIGIT;
672 if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(ch_in) ){
673 return CHAR_IS_PLUS_MINUS;
675 if (ch_in == decimal_ch) {
676 return CHAR_IS_POINT;
678 return CHAR_IS_CHARACTER;
682 static bool __calculator_string_digit_in(const char *input)
685 while(input[i]!='\0'){
686 if(IS_DIGITAL(input[i])){/*here ,digit include "p" and "e"*/
696 * search charactor in input string, if have charactor, return True and index of first charactor;
699 static bool __calculator_string_char_search(const char *input, int *index)
705 int len_cp = strlen(input);
710 for(; i < len_cp ; i++){
711 last_char_t cur_char_type = __calculator_string_get_char_type(input[i]);
712 if (CHAR_IS_CHARACTER == cur_char_type) {
722 * search invalid charactor in input string, if have invalid charactor, return True and index of first invalid charactor;
725 static bool __calculator_string_invalid_char_search(char *input, int *index)
729 bool char_in = FALSE;
731 char_in = __calculator_string_char_search(p, &sub_index);
732 if (!char_in) {/*no charactor*/
738 if (!__calculator_search_function(p, &len)) {/*charactor not a function*/
740 } else {/*the first sevaral charactors are function, continue search*/
744 /*Fix bug that paste did not filter invaild word, beacuse here it jump to
745 * the sub_index directly, but the sub_index would change with the string
746 * So, it should recalculate every time*/
747 char_in = __calculator_string_char_search(p, &sub_index);
767 __calculator_control_panel_number_button_clicked(Evas *e, Evas_Object *entry, op_item_t *op_item)
771 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
773 if (calc_select_string_search(selected_str)) {
774 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym,
775 op_item->op_sym, op_item->op_sym, 0, NULL);
777 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
778 calculator_cursor_pos = strlen(calculator_input_str);
784 /* replace special characters */
785 char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
786 snprintf(entry_text, sizeof(entry_text), "%s", calculator_input_str);
787 //Current state is calculated, clear all
788 if (calculator_state == CALCULATOR_CALCULATED) {
789 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
790 _calc_entry_clear(entry);
791 _calc_entry_text_insert(entry, op_item->op_sym);
792 calculator_state = CALCULATOR_OPERAND_INPUT;
796 char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
797 char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
801 __calculator_get_cursor_position_float_string(entry_text, str_buf, calculator_cursor_pos, NULL, NULL);
802 __calculator_get_input_from_begin_to_cursor(entry_text, before_cursor);
803 before_len = strlen(before_cursor);
804 calculator_get_digits_number(str_buf, &nDigitCnt, &nPointCnt);
805 char str_bufa[MAX_EXPRESSION_LENGTH] = { 0 };
806 __calculator_get_before_cursor_float_string(entry_text, str_bufa);
807 if (strcmp(str_bufa, "0") == 0) {
808 _calc_entry_backspace(entry);
811 if (strlen(str_buf) >= MAX_NUM_LENGTH) {
812 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
814 } else if (nPointCnt >= MAX_DECIMAL_NUM && calculator_cursor_pos > nDigitCnt) {
815 __calculator_wrong_format_create(CALC_MSG_MAX_DEC_DIGIT);
817 } else if (before_len > 0
818 && (__calculator_string_get_char_type(before_cursor[before_len - 1]) ==
820 || __calculator_string_get_char_type(before_cursor[before_len - 1]) ==
822 /* input digital after "e" or "p", the "x" opeartor will be added automatically */
823 _calc_entry_text_insert(entry, "x");
824 _calc_entry_text_insert(entry, op_item->op_sym);
825 calculator_state = CALCULATOR_OPERAND_INPUT;
827 } else if (before_len > 0 && ((before_cursor[before_len - 1] == '(') ||CALCULATOR_CHAR_IS_DIGITAL(before_cursor[before_len - 1])
828 || CALCULATOR_CHAR_IS_OPERATOR(before_cursor[before_len - 1]) || (int)before_cursor[before_len - 1] > 120)) //* or/
830 _calc_entry_text_insert(entry, op_item->op_sym);
831 calculator_state = CALCULATOR_OPERAND_INPUT;
833 } else if (before_len > 0 && (before_cursor[before_len - 1] == ')')) {
834 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
837 _calc_entry_text_insert(entry, op_item->op_sym);
838 calculator_state = CALCULATOR_OPERAND_INPUT;
846 * Deal the event when dot clicked on the keyboard
848 * @param[in] entry The input entry
852 static void _calc_btn_dot_clicked(Evas_Object *entry)
858 char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
861 char decimal_str[32] = { 0 };
863 /* replace special characters */
864 char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
865 strncpy(entry_text, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
867 if (calculator_state == CALCULATOR_CALCULATED) {
868 _calc_entry_clear(entry);
869 memset(entry_text,0x00,sizeof(entry_text));
874 if (!__calculator_get_cursor_position_float_string
875 (entry_text, str_num, calculator_cursor_pos, &from_pos, &end_pos)) {
876 if (calculator_cursor_pos == 0
877 || IS_OPERATOER(calculator_input_str[from_pos - 1])
878 || calculator_input_str[from_pos - 1] == '(') {
879 snprintf(decimal_str, sizeof(decimal_str), "0%c",
881 _calc_entry_text_insert(entry, decimal_str);
882 calculator_state = CALCULATOR_OPERAND_INPUT;
887 if (strcmp(str_num, "p") == 0 || strcmp(str_num, "e") == 0) {
888 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
893 str_num_len = strlen(str_num);
894 if (str_num_len > 0 && str_num[str_num_len - 1] == decimal_ch) {
900 calculator_get_digits_number(str_num, &nDigitCnt, &nPointCnt);
902 if (nDigitCnt >= 15) {
903 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
910 if (IS_OPERATOER(calculator_input_str[calculator_cursor_pos-1])
911 || calculator_input_str[calculator_cursor_pos-1] == '(') {
912 snprintf(decimal_str, sizeof(decimal_str), "0%c", decimal_ch);
914 snprintf(decimal_str, sizeof(decimal_str), "%c", decimal_ch);
916 _calc_entry_text_insert(entry, decimal_str);
917 calculator_state = CALCULATOR_OPERAND_INPUT;
930 static void _calc_btn_backspace_clicked(Evas *e, Evas_Object *entry)
934 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
936 if (calc_select_string_search(selected_str)) {
937 evas_event_feed_key_down(e, "KP_BACKSPACE", "", "", "", 0, NULL);
939 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
940 calculator_cursor_pos = strlen(calculator_input_str);
946 if (calculator_state == CALCULATOR_CALCULATED) {
947 calculator_state = CALCULATOR_OPERATOR_INPUT;
948 if (calculator_cursor_pos > strlen(calculator_input_str)) {
949 calculator_cursor_pos = strlen(calculator_input_str); /* set last position */
952 _calc_entry_backspace(entry);
956 static int __calculator_delete_long_press(void *data)
959 Evas_Object *entry = (Evas_Object *) data;
961 if (calculator_state == CALCULATOR_CALCULATED) {
962 calculator_state = CALCULATOR_OPERATOR_INPUT;
963 if (calculator_cursor_pos > strlen(calculator_input_str)) {
964 calculator_cursor_pos = strlen(calculator_input_str); /* set last position */
967 _calc_entry_backspace(entry);
974 * Process +.-.*.\ these four buttons clicked.
982 __calculator_control_normal_func_clicked(Evas *e,Evas_Object *entry,
987 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
989 if (calc_select_string_search(selected_str)) {
990 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym, op_item->op_sym, op_item->op_sym, 0, NULL);
992 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
993 calculator_cursor_pos = strlen(calculator_input_str);
999 char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1000 strncpy(all_input, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
1002 if (calculator_state == CALCULATOR_CALCULATED) {
1003 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1004 char temp[20] = { 0 };
1006 calc_expr_num_format_result(last_result, temp);
1007 _calc_entry_clear(entry);
1008 //result < 0 or sicience number
1009 if (temp[0] == '-' || strchr(temp, 'E')) {
1010 _calc_entry_text_insert(entry, "(");
1011 _calc_entry_text_insert(entry, temp);
1012 _calc_entry_text_insert(entry, ")");
1014 _calc_entry_text_insert(entry, temp);
1017 _calc_entry_text_insert(entry, op_item->op_sym);
1018 calculator_state = CALCULATOR_OPERATOR_INPUT;
1022 if (!strcmp(op_item->op_sym, "x") ||!strcmp(op_item->op_sym, "/") ||!strcmp(op_item->op_sym, "+")) {
1023 if (!__calculator_string_digit_in(calculator_input_str)) {
1027 int nCntOp = calc_expr_get_operator_num(all_input);
1028 if (nCntOp >= MAX_OPERATOR_NUM) { /* Can't exceed 20 operators */
1029 __calculator_wrong_format_create(CALC_MSG_MAX_OP);
1033 char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1036 __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1037 input_len = strlen(before_cursor);
1039 if (input_len > 0) {
1040 if (before_cursor[input_len - 1] == '(' && !strcmp(op_item->op_sym, "-")) {
1041 _calc_entry_text_insert(entry, op_item->op_sym);
1042 calculator_state = CALCULATOR_OPERATOR_INPUT;
1043 } else if (((input_len > 1) && (before_cursor[input_len - 1] == '-') && (before_cursor[input_len - 2] == '(')) //(-
1044 || /*before_cursor[input_len - 1] == decimal_ch ||*/ before_cursor[input_len - 1] == '(') // . or (
1047 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1049 } else if (IS_OPERATOER(before_cursor[input_len - 1])) {
1050 if ((input_len > 1 || !strcmp(op_item->op_sym, "-"))
1051 || input_len == 1) {
1052 _calc_entry_backspace(entry);
1053 _calc_entry_text_insert(entry, op_item->op_sym);
1054 calculator_state = CALCULATOR_OPERATOR_INPUT;
1056 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1059 } else if (before_cursor[input_len - 1] == ')') //
1061 _calc_entry_text_insert(entry, op_item->op_sym);
1062 calculator_state = CALCULATOR_OPERATOR_INPUT;
1065 if (!IS_DIGITAL(before_cursor[input_len - 1])
1066 && (before_cursor[input_len - 1] != decimal_ch)) {
1067 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1070 _calc_entry_text_insert(entry, op_item->op_sym);
1071 calculator_state = CALCULATOR_OPERATOR_INPUT;
1075 } else { /* before_cursor si empty */
1076 _calc_entry_text_insert(entry, op_item->op_sym);
1077 calculator_state = CALCULATOR_OPERATOR_INPUT;
1090 static void __calculator_symbol_negative_clicked(Evas_Object * entry)
1094 char result[MAX_RESULT_LENGTH] = { 0 };
1096 if (calculator_state == CALCULATOR_CALCULATED) {
1097 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1099 calc_expr_num_format_result(last_result, result);
1100 if (last_result < 0) {
1101 string_remove_at(result, 0, 1); //remove '-'
1103 string_insert(result, 0, "(-"); // add (-xxx)
1104 string_insert(result, strlen(result), ")");
1107 _calc_entry_clear(entry);
1108 _calc_entry_text_insert(entry, result);
1110 calculator_state = CALCULATOR_OPERAND_INPUT;
1111 //use_last_result = 1;
1116 int cursor = calculator_cursor_pos;
1117 int begin = 0, length = 0;
1118 char expr[MAX_EXPRESSION_LENGTH] = { 0 };
1119 strncpy(expr, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
1122 if (expr[cursor] == ')') {
1124 flag = 1; /* before current cursor is ')' */
1128 calc_expr_get_current_num_at_cursor(expr, cursor, &begin,
1130 if (expr[begin] == '-') {
1131 if (begin > 0 && expr[begin - 1] == '('
1132 && expr[begin + length] == ')') {
1133 string_remove_at(expr, begin + length, 1); //remove ')'
1134 string_remove_at(expr, begin - 1, 2); // remove '(-'
1135 calculator_cursor_pos -= flag ? 3 : 2;
1137 string_remove_at(expr, begin, 1);
1138 calculator_cursor_pos -= 1;
1142 if (flag == 1) //not '(-xxx)' but has ')'
1144 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1147 string_insert(expr, begin + length, ")");
1148 string_insert(expr, begin, "(-");
1149 calculator_cursor_pos +=
1150 (((begin + length) ==
1151 calculator_cursor_pos) ? 3 : 2);
1154 strncpy(calculator_input_str, expr, MAX_EXPRESSION_LENGTH - 1);
1156 _calc_entry_text_set(entry, calculator_input_str);
1157 _calc_entry_cursor_set(entry);
1159 calculator_state = CALCULATOR_OPERAND_INPUT;
1162 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1167 /* search the previous operator and value */
1168 static char * __calculator_search_prev_input(char *input_str)
1172 int bracket_number = 0;
1173 char *prev_input = NULL;
1174 for(; i< strlen(input_str); i++) {
1175 if ('(' ==(input_str[i]) ){
1178 if( ')' == input_str[i]){
1181 if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(input_str[i])
1182 || CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(input_str[i])) {
1183 if ( !bracket_number){
1184 prev_input = &input_str[i];
1195 * Deal the event when "=" clicked on the keyboard
1197 * @param[in] entry The input entry
1201 static void __calculator_op_equal(Evas_Object *entry)
1204 if (entry == NULL) {
1207 if (calculator_state == CALCULATOR_CALCULATED) {
1208 /*duplicate previous input operator and value*/
1209 char *p = __calculator_search_prev_input(calculator_input_str);
1213 char prev_input[32] = { 0 };
1214 int len = g_strlcpy(prev_input, p, sizeof(prev_input));
1215 if (len >= sizeof(prev_input)) {
1218 char temp[32] = { 0 };
1219 calc_expr_num_format_result(last_result, temp);
1220 _calc_entry_clear(entry);
1222 if (temp[0] == '-' || strchr(temp, 'E')) {
1223 _calc_entry_text_insert(entry, "(");
1224 _calc_entry_text_insert(entry, temp);
1225 _calc_entry_text_insert(entry, ")");
1227 _calc_entry_text_insert(entry, temp);
1229 _calc_entry_text_insert(entry, prev_input);
1230 calculator_state = CALCULATOR_OPERATOR_INPUT;
1234 char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1235 char result_buf[MAX_RESULT_LENGTH] = { 0 };
1236 char result_format[MAX_RESULT_LENGTH] = { 0 };
1238 char error_msg[MAX_ERROR_MESSAGE_LENGTH] = { 0 };
1239 calc_expr_close_parentheses(calculator_input_str);
1240 _calc_entry_text_set(entry, calculator_input_str);
1241 snprintf(str_buf, sizeof(str_buf), "%s", calculator_input_str);
1242 str_len = strlen(str_buf);
1244 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1248 if (!calculator_calculate(str_buf, &result, error_msg)) {
1249 __calculator_wrong_format_create(error_msg);
1250 calculator_state = CALCULATOR_ERROR_OCCURED;
1253 last_result = result;
1254 memset(result_buf, 0, CALCULATOR_CONTENT_LEN + 1);
1255 calc_expr_num_format_result(result, result_buf);
1258 struct history_item item;
1259 memset(item.expression, 0, sizeof(item.expression));
1260 memset(result_format, 0, sizeof(result_format));
1261 calc_expr_format_expression(calculator_input_str,
1263 item.result = result;
1264 calc_expr_format_expression(result_buf, result_format);
1265 if (result_buf[0] == '-') {
1266 string_replace(result_format, "\xe2\x88\x92", "-");
1269 calc_view_save_history(&item);
1272 calculator_state = CALCULATOR_CALCULATED;
1273 calc_view_show_result(result_format, ad);
1287 static void __calculator_parenthesis_clicked(Evas_Object * entry)
1290 char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1291 snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
1292 if (calculator_state == CALCULATOR_CALCULATED) {
1293 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1295 char temp[MAX_RESULT_LENGTH] = { 0 };
1297 calc_expr_num_format_result(last_result, temp);
1298 _calc_entry_clear(entry);
1300 if (temp[0] == '-' || strchr(temp, 'E') != NULL) //result < 0 or science number
1302 _calc_entry_text_insert(entry, "((");
1303 _calc_entry_text_insert(entry, temp);
1304 _calc_entry_text_insert(entry, ")");
1306 _calc_entry_text_insert(entry, "(");
1307 _calc_entry_text_insert(entry, temp);
1309 calculator_state = CALCULATOR_OPERATOR_INPUT;
1312 char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1314 __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1315 input_len = strlen(before_cursor);
1317 if (input_len == 0) {
1318 _calc_entry_text_insert(entry, "(");
1319 calculator_state = CALCULATOR_OPERATOR_INPUT;
1322 int bracket_num = calculator_get_open_braket(all_input);
1323 if (input_len > 0) {
1324 if (before_cursor[input_len - 1] == decimal_ch) {
1325 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1327 } else if (bracket_num > 0 //'(' is more than ')'
1328 && before_cursor[input_len - 1] != '('
1329 && (before_cursor[input_len - 1] == ')'
1330 || isdigit(before_cursor[input_len - 1])
1332 (__calculator_string_get_char_type
1333 (before_cursor[input_len - 1]) == CHAR_IS_PI
1335 __calculator_string_get_char_type
1336 (before_cursor[input_len - 1]) == CHAR_IS_E))) {
1337 _calc_entry_text_insert(entry, ")");
1339 } else if (bracket_num == 0) {
1340 if (calc_expr_get_left_parentheses_num
1341 (calculator_input_str) < MAX_PARENTHESES_NUM) {
1342 _calc_entry_text_insert(entry, "(");
1345 } else if (before_cursor[input_len - 1] != ')') //'(' is less than ')'!isdigit(before_cursor[input_len-1])&&(
1347 if (calc_expr_get_left_parentheses_num
1348 (calculator_input_str) < MAX_PARENTHESES_NUM) {
1349 _calc_entry_text_insert(entry, "(");
1368 __calculator_control_functions_button_clicked(Evas *e, Evas_Object *entry, op_item_t *op_item)
1373 function_t function = { 0 };
1375 memset(&function, 0x0, sizeof(function_t));
1376 str = op_item->op_name;
1378 char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1380 char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1382 last_char_t last_char_type = 0;
1384 snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
1385 __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1386 input_len = strlen(all_input);
1387 before_len = strlen(before_cursor);
1389 last_char_type = __calculator_string_get_char_type(before_cursor[before_len - 1]);
1392 switch (op_item->op_id) {
1395 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1396 calculator_cursor_pos = strlen(calculator_input_str);
1399 /* if it is calculated state */
1400 if (calculator_state == CALCULATOR_CALCULATED) {
1401 edje_object_signal_emit(_EDJ(ad->edje), "show,input","");
1403 char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1404 double per_result = last_result / 100.0;
1406 calc_expr_num_format_result(per_result, temp);
1407 _calc_entry_clear(entry);
1409 if (strcmp(temp, "0") == 0) {
1410 _calc_entry_text_insert(entry, "0");
1411 } else if (temp[0] == '-') //result < 0
1413 _calc_entry_text_insert(entry, "(");
1414 _calc_entry_text_insert(entry, temp);
1415 _calc_entry_text_insert(entry, ")");
1417 _calc_entry_text_insert(entry, temp);
1419 calculator_state = CALCULATOR_OPERAND_INPUT;
1424 int from_pos, end_pos;
1425 char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
1426 char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1427 double per_result = 0.0;
1429 if (false == __calculator_get_cursor_position_float_string(all_input, str_num, calculator_cursor_pos, &from_pos, &end_pos)) {
1430 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1431 calculator_cursor_pos = strlen(calculator_input_str);
1436 if (strlen(str_num) == 0) {
1437 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1441 if (strcmp(str_num, "0") == 0) {
1445 per_result = atof(str_num);
1446 per_result /= 100.0;
1448 calc_expr_num_format_result(per_result, temp);
1450 _calc_entry_text_remove(entry, from_pos, end_pos);
1451 _calc_entry_text_insert(entry, temp);
1453 calculator_state = CALCULATOR_OPERAND_INPUT;
1460 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1461 calculator_cursor_pos = strlen(calculator_input_str);
1464 if (calculator_state == CALCULATOR_CALCULATED) {
1465 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1467 _calc_entry_clear(entry);
1468 _calc_entry_text_insert(entry, op_item->op_name);
1471 if ((before_len != 0) && (!IS_DIGITAL(before_cursor[before_len - 1]))
1472 && (!IS_OPERATOER(before_cursor[before_len - 1]))
1473 && (before_cursor[before_len - 1] != '(')
1474 && (before_cursor[before_len - 1] != 'P')
1475 && before_cursor[before_len - 1] != 'C') {
1476 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1479 /* input digital after "p", the "x" opeartor will be added automatically */
1480 if(IS_DIGITAL(before_cursor[before_len - 1])){
1481 _calc_entry_text_insert(entry, "x");
1483 _calc_entry_text_insert(entry, op_item->op_name);
1488 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1489 calculator_cursor_pos = strlen(calculator_input_str);
1492 if (calculator_state == CALCULATOR_CALCULATED) {
1493 edje_object_signal_emit(_EDJ(ad->edje), "show,input","");
1494 _calc_entry_clear(entry);
1495 _calc_entry_text_insert(entry, op_item->op_name);
1498 if ((before_len != 0) && (!IS_DIGITAL(before_cursor[before_len - 1]))
1499 && (!IS_OPERATOER(before_cursor[before_len - 1]))
1500 && (before_cursor[before_len - 1] != '(')
1501 && (before_cursor[before_len - 1] != 'P')
1502 && before_cursor[before_len - 1] != 'C') {
1503 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1506 /* input digital after "e", the "x" opeartor will be added automatically */
1507 if(IS_DIGITAL(before_cursor[before_len - 1])){
1508 _calc_entry_text_insert(entry, "x");
1510 _calc_entry_text_insert(entry, op_item->op_name);
1513 case OP_SIN: //sin()
1514 case OP_COS: //cos()
1515 case OP_TAN: //tan()
1516 case OP_LOG: //log()
1517 case OP_ABS: //abs()
1519 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
1521 if (calc_select_string_search(selected_str)) {
1522 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym,
1523 op_item->op_name, op_item->op_sym, 0, NULL);
1525 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1526 calculator_cursor_pos = strlen(calculator_input_str);
1528 SFREE(selected_str);
1532 if (calculator_state == CALCULATOR_CALCULATED) {
1533 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1535 _calc_entry_clear(entry);
1536 _calc_entry_text_insert(entry, op_item->op_name);
1539 if (last_char_type == CHAR_IS_PI || last_char_type == CHAR_IS_E) {
1540 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1544 _calc_entry_text_insert(entry, op_item->op_name);
1549 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
1551 if (calc_select_string_search(selected_str)) {
1552 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym, op_item->op_name,
1553 op_item->op_sym, 0, NULL);
1555 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1556 calculator_cursor_pos = strlen(calculator_input_str);
1558 SFREE(selected_str);
1562 if (calculator_state == CALCULATOR_CALCULATED) {
1563 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1565 _calc_entry_clear(entry);
1566 _calc_entry_text_insert(entry, op_item->op_name);
1569 if (last_char_type == CHAR_IS_PI) {
1570 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1573 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1574 && (before_cursor[before_len - 1] != '-')
1575 && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1576 && (before_cursor[before_len - 1] != '^')
1577 && (before_cursor[before_len - 1] != '(')
1578 && (before_cursor[before_len - 1] != 'C')
1579 && (before_cursor[before_len - 1] != 'P')) {
1580 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1583 _calc_entry_text_insert(entry, op_item->op_name);
1586 case OP_ROOT: //sqrt()
1588 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
1590 if (calc_select_string_search(selected_str)) {
1591 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym, op_item->op_name,
1592 op_item->op_sym, 0, NULL);
1594 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1595 calculator_cursor_pos = strlen(calculator_input_str);
1597 SFREE(selected_str);
1601 if (calculator_state == CALCULATOR_CALCULATED) {
1602 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1605 _calc_entry_clear(entry);
1606 _calc_entry_text_insert(entry, op_item->op_name);
1609 if (last_char_type == CHAR_IS_PI) {
1610 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1613 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1614 && (before_cursor[before_len - 1] != '-')
1615 && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1616 && (before_cursor[before_len - 1] != '^')
1617 && (before_cursor[before_len - 1] != '(')
1618 && (before_cursor[before_len - 1] != 'C')
1619 && (before_cursor[before_len - 1] != 'P')) {
1620 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1623 _calc_entry_text_insert(entry, op_item->op_name);
1627 if (calculator_state == CALCULATOR_CALCULATED) {
1628 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1629 _calc_entry_clear(entry);
1630 _calc_entry_text_insert(entry, op_item->op_name);
1633 if (last_char_type == CHAR_IS_PI) {
1634 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1637 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1638 && (before_cursor[before_len - 1] != '-')
1639 && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1640 && (before_cursor[before_len - 1] != '^')
1641 && (before_cursor[before_len - 1] != '(')
1642 && (before_cursor[before_len - 1] != 'C')
1643 && (before_cursor[before_len - 1] != 'P')) {
1644 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1647 _calc_entry_text_insert(entry, op_item->op_name);
1651 if (calculator_state == CALCULATOR_CALCULATED) {
1652 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1654 char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1655 calc_expr_num_format_result(last_result, temp);
1656 _calc_entry_clear(entry);
1658 if (temp[0] == '-' || strchr(temp, 'E')) //result < 0 or science number
1660 _calc_entry_text_insert(entry, "(");
1661 _calc_entry_text_insert(entry, temp);
1662 _calc_entry_text_insert(entry, ")");
1664 _calc_entry_text_insert(entry, temp);
1666 _calc_entry_text_insert(entry, op_item->op_name);
1667 calculator_state = CALCULATOR_OPERAND_INPUT;
1668 //use_last_result = 1;
1672 if (input_len == 0) {
1673 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
1676 if (last_char_type == CHAR_IS_PI) {
1677 _calc_entry_text_insert(entry, op_item->op_name);
1678 calculator_state = CALCULATOR_OPERAND_INPUT;
1680 } else if ((before_len > 0)
1681 && (!isdigit(before_cursor[before_len - 1]))
1682 && (before_cursor[before_len - 1] != ')')) {
1683 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
1686 _calc_entry_text_insert(entry, op_item->op_name);
1687 calculator_state = CALCULATOR_OPERAND_INPUT;
1690 if (calculator_state == CALCULATOR_CALCULATED) {
1691 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1694 char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1696 calc_expr_num_format_result(last_result, temp);
1697 _calc_entry_clear(entry);
1699 if (temp[0] == '-' || strchr(temp, 'E')) //result < 0 or science number
1701 _calc_entry_text_insert(entry, "(");
1702 _calc_entry_text_insert(entry, temp);
1703 _calc_entry_text_insert(entry, ")");
1705 _calc_entry_text_insert(entry, temp);
1707 _calc_entry_text_insert(entry, op_item->op_name);
1708 calculator_state = CALCULATOR_OPERATOR_INPUT;
1712 if (input_len == 0) {
1713 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
1716 if ((last_char_type == CHAR_IS_PI)
1717 || (last_char_type == CHAR_IS_E)) {
1718 _calc_entry_text_insert(entry, op_item->op_name);
1719 calculator_state = CALCULATOR_OPERATOR_INPUT;
1721 } else if ((before_len > 0)
1722 && !isdigit(before_cursor[before_len - 1])
1723 && (before_cursor[before_len - 1] != ')')) {
1724 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
1727 _calc_entry_text_insert(entry, op_item->op_name);
1728 calculator_state = CALCULATOR_OPERATOR_INPUT;
1733 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1734 calculator_cursor_pos = strlen(calculator_input_str);
1737 if (calculator_state == CALCULATOR_CALCULATED) {
1738 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1741 char temp[MAX_RESULT_LENGTH] = { 0 };
1743 calc_expr_num_format_result(last_result, temp);
1745 if (strchr(temp, decimal_ch) != NULL || strchr(temp, '-') != NULL) //revise by bfl
1747 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1748 calculator_state = CALCULATOR_WAITING_INPUT; //revise by bfl
1752 _calc_entry_clear(entry);
1753 _calc_entry_text_insert(entry, "(");
1754 _calc_entry_text_insert(entry, temp);
1755 _calc_entry_text_insert(entry, "!)");
1757 calculator_state = CALCULATOR_OPERATOR_INPUT;
1761 if (input_len == 0) {
1762 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_FAC);
1765 if ((last_char_type == CHAR_IS_PI)
1766 || (last_char_type == CHAR_IS_E)) {
1767 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1771 /* check if it is natural */
1773 char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1774 int from_pos = 0, end_pos = 0;
1777 __calculator_get_cursor_position_float_string
1778 (all_input, str_buf, calculator_cursor_pos,
1779 &from_pos, &end_pos)) {
1780 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1784 if (strchr(str_buf, decimal_ch) != NULL
1785 || str_buf[0] == '-') {
1786 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1790 _calc_entry_text_remove(entry, from_pos, end_pos);
1791 _calc_entry_text_insert(entry, "(");
1792 _calc_entry_text_insert(entry, str_buf);
1793 _calc_entry_text_insert(entry, "!)");
1794 calculator_state = CALCULATOR_OPERATOR_INPUT;
1798 if (calculator_state == CALCULATOR_CALCULATED) {
1799 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1802 char temp[MAX_RESULT_LENGTH] = { 0 };
1805 calc_expr_num_format_result(last_result, temp);
1806 if (strchr(temp, 'E') != NULL) //science number
1808 temp[strlen(temp)] = ')';
1809 for (i = strlen(temp); i > 0; --i) {
1810 temp[i] = temp[i - 1];
1815 _calc_entry_clear(entry);
1816 if (temp[0] == '-') {
1817 _calc_entry_text_insert(entry, "(-1");
1818 _calc_entry_text_insert(entry, "/");
1820 _calc_entry_text_insert(entry, &temp[1]);
1821 _calc_entry_text_insert(entry, ")");
1823 _calc_entry_text_insert(entry, "(1");
1824 _calc_entry_text_insert(entry, "/");
1826 _calc_entry_text_insert(entry, temp);
1827 _calc_entry_text_insert(entry, ")");
1830 calculator_state = CALCULATOR_OPERATOR_INPUT;
1831 //use_last_result = 1;
1834 if (input_len == 0) {
1835 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
1839 /* check if it is digit */
1841 char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1842 int from_pos = 0, end_pos = 0;
1845 __calculator_get_cursor_position_float_string
1846 (all_input, str_buf, calculator_cursor_pos,
1847 &from_pos, &end_pos)) {
1848 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
1852 if (strcmp(str_buf, "p") && strcmp(str_buf, "e")
1853 && atof(str_buf) == 0) {
1854 __calculator_wrong_format_create(CALC_MSG_DIVIDE_BY_ZERO);
1858 _calc_entry_text_remove(entry, from_pos, end_pos);
1859 if (str_buf[0] == '-') {
1860 _calc_entry_text_insert(entry, "(-1");
1861 _calc_entry_text_insert(entry, "/");
1863 _calc_entry_text_insert(entry, &str_buf[1]);
1864 _calc_entry_text_insert(entry, ")");
1866 _calc_entry_text_insert(entry, "(1");
1867 _calc_entry_text_insert(entry, "/");
1869 _calc_entry_text_insert(entry, str_buf);
1870 _calc_entry_text_insert(entry, ")");
1873 calculator_state = CALCULATOR_OPERATOR_INPUT;
1880 calculator_state = CALCULATOR_SPECIAL_FUNCTION_INPUT;
1885 /////////////////////////// input text finish ////////////////////////////
1896 static int _calculator_get_input_item(Evas_Object * evas_obj, Evas_Object * obj)
1901 if (evas_obj == edje_object_part_object_get(obj, "item_brack")) {
1902 val = OP_PARENTHESIS;
1903 } else if (evas_obj == edje_object_part_object_get(obj, "item_del")) {
1905 } else if (evas_obj == edje_object_part_object_get(obj, "item_c")) {
1907 } else if (evas_obj == edje_object_part_object_get(obj, "item_div")) {
1909 } else if (evas_obj == edje_object_part_object_get(obj, "item_num7")) {
1911 } else if (evas_obj == edje_object_part_object_get(obj, "item_num8")) {
1913 } else if (evas_obj == edje_object_part_object_get(obj, "item_num9")) {
1915 } else if (evas_obj == edje_object_part_object_get(obj, "item_mul")) {
1917 } else if (evas_obj == edje_object_part_object_get(obj, "item_num4")) {
1919 } else if (evas_obj == edje_object_part_object_get(obj, "item_num5")) {
1921 } else if (evas_obj == edje_object_part_object_get(obj, "item_num6")) {
1923 } else if (evas_obj == edje_object_part_object_get(obj, "item_sub")) {
1925 } else if (evas_obj == edje_object_part_object_get(obj, "item_num1")) {
1927 } else if (evas_obj == edje_object_part_object_get(obj, "item_num2")) {
1929 } else if (evas_obj == edje_object_part_object_get(obj, "item_num3")) {
1931 } else if (evas_obj == edje_object_part_object_get(obj, "item_plus")) {
1933 } else if (evas_obj == edje_object_part_object_get(obj, "item_dot")) {
1935 } else if (evas_obj == edje_object_part_object_get(obj, "item_num0")) {
1937 } else if (evas_obj == edje_object_part_object_get(obj, "item_neg")) {
1938 val = OP_PLUS_MINUS;
1939 } else if (evas_obj == edje_object_part_object_get(obj, "item_eq")) {
1941 } else if (evas_obj == edje_object_part_object_get(obj, "item_per")) {
1943 } else if (evas_obj == edje_object_part_object_get(obj, "item_sqr")) {
1945 } else if (evas_obj == edje_object_part_object_get(obj, "item_fac")) {
1947 } else if (evas_obj == edje_object_part_object_get(obj, "item_sin")) {
1949 } else if (evas_obj == edje_object_part_object_get(obj, "item_cos")) {
1951 } else if (evas_obj == edje_object_part_object_get(obj, "item_tan")) {
1953 } else if (evas_obj == edje_object_part_object_get(obj, "item_ln")) {
1955 } else if (evas_obj == edje_object_part_object_get(obj, "item_log")) {
1957 } else if (evas_obj == edje_object_part_object_get(obj, "item_1x")) {
1959 } else if (evas_obj == edje_object_part_object_get(obj, "item_10x")) {
1961 } else if (evas_obj == edje_object_part_object_get(obj, "item_x2")) {
1963 } else if (evas_obj == edje_object_part_object_get(obj, "item_xy")) {
1965 } else if (evas_obj == edje_object_part_object_get(obj, "item_abs")) {
1967 } else if (evas_obj == edje_object_part_object_get(obj, "item_pi")) {
1969 } else if (evas_obj == edje_object_part_object_get(obj, "item_e")) {
1976 /////////////////////////// input text finish ////////////////////////////
1988 static int _calculator_get_input_item_hd(const char *keyname, Evas_Object * obj)
1992 if (0 == strcmp(keyname, "KP_7")) {
1994 } else if (0 == strcmp(keyname, "KP_8")) {
1996 } else if (0 == strcmp(keyname, "KP_9")) {
1998 } else if (0 == strcmp(keyname, "KP_4")) {
2000 } else if (0 == strcmp(keyname, "KP_5")) {
2002 } else if (0 == strcmp(keyname, "KP_6")) {
2004 } else if (0 == strcmp(keyname, "KP_1")) {
2006 } else if (0 == strcmp(keyname, "KP_2")) {
2008 } else if (0 == strcmp(keyname, "KP_3")) {
2010 } else if (0 == strcmp(keyname, "KP_0")) {
2012 }else if (0 == strcmp(keyname, "KP_Decimal")) {
2014 } else if (0 == strcmp(keyname, "Return")) {
2016 } else if (0 == strcmp(keyname, "KP_Add")) {
2018 } else if (0 == strcmp(keyname, "KP_Subtract")) {
2020 } else if (0 == strcmp(keyname, "minus")) {
2022 } else if (0 == strcmp(keyname, "KP_Multiply")) {
2024 } else if (0 == strcmp(keyname, "slash")) {
2026 } else if (0 == strcmp(keyname, "KP_Divide")) {
2028 }else if (0 == strcmp(keyname, "BackSpace")) {
2038 * Interpret all of our different signals, and do things !
2048 _calculator_interp(void *data, Evas * e, Evas_Object * evas_obj, void *event_info)
2055 Evas_Object *obj = (Evas_Object *) data;
2056 val = _calculator_get_input_item(evas_obj, obj);
2057 if (ad->wrong_timer) {
2058 ecore_timer_del(ad->wrong_timer);
2059 ad->wrong_timer = NULL;
2063 _calc_btn_backspace_clicked(e, ad->input_entry);
2064 if (ad->calc_timer) {
2065 ecore_timer_del(ad->calc_timer);
2066 ad->calc_timer = NULL;
2069 ecore_timer_add(0.1, (Ecore_Task_Cb)__calculator_delete_long_press, ad->input_entry);
2072 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
2073 _calc_entry_clear(ad->input_entry);
2074 calculator_state = CALCULATOR_WAITING_INPUT;
2080 __calculator_control_normal_func_clicked(e, ad->input_entry, &calc_op_item[val]);
2083 _calc_btn_dot_clicked(ad->input_entry);
2085 case OP_PARENTHESIS:
2086 __calculator_parenthesis_clicked(ad->input_entry);
2089 __calculator_op_equal(ad->input_entry);
2101 __calculator_control_panel_number_button_clicked(e, ad->input_entry, &calc_op_item[val]);
2104 __calculator_symbol_negative_clicked(ad->input_entry);
2106 case OP_PERCENT...OP_E:
2107 __calculator_control_functions_button_clicked(e, ad->input_entry, &calc_op_item[val]);
2112 if (val == OP_DELETE) {
2113 feedback_play(FEEDBACK_PATTERN_SIP_BACKSPACE);
2115 feedback_play(FEEDBACK_PATTERN_SIP);
2122 static void __calculator_wrong_format_delete(Evas_Object *in_entry)
2124 _calc_entry_text_set(in_entry, calculator_input_str);
2125 if (ad->wrong_timer) {
2126 ecore_timer_del(ad->wrong_timer);
2127 ad->wrong_timer = NULL;
2131 static void __calculator_wrong_text_set(char * wrong_string)
2133 char buf[MAX_EXPRESSION_LENGTH] = { 0 };
2135 memset(buf, 0, sizeof(buf));
2136 snprintf(buf, sizeof(buf),
2137 "<align=right><+ font_size=%d><color=#855B11FF>%s",
2138 fontsize, wrong_string);
2139 elm_entry_editable_set(ad->input_entry, EINA_FALSE);//chx add avoid the word splited
2140 elm_entry_line_wrap_set(ad->input_entry,ELM_WRAP_MIXED);
2141 elm_entry_input_panel_enabled_set(ad->input_entry, EINA_FALSE);
2142 elm_entry_entry_set(ad->input_entry, buf);
2143 elm_entry_cursor_end_set(ad->input_entry);
2144 elm_object_focus_set(ad->input_entry, EINA_TRUE);
2145 calc_view_revise_input_scroller(ad);
2156 static void __calculator_wrong_format_create(char * wrong_string)
2158 __calculator_wrong_text_set(wrong_string);
2159 if (ad->wrong_timer) {
2160 ecore_timer_del(ad->wrong_timer);
2161 ad->wrong_timer = NULL;
2163 ad->wrong_timer = ecore_timer_add(3, (Ecore_Task_Cb)__calculator_wrong_format_delete, ad->input_entry);
2166 /* mouse up for delete button. */
2168 __calculator_delelte_up(void *data, Evas * e, Evas_Object * evas_obj,
2172 if (ad->calc_timer) {
2173 ecore_timer_del(ad->calc_timer);
2174 ad->calc_timer = NULL;
2181 * Register clicked callback of the keys on the keypad.
2183 * @param keypad the keypad
2186 void _calc_view_keypad_cb_register(Evas_Object * keypad)
2189 char *key_name[] = {
2190 "item_per", "item_sqr", "item_fac", "item_c", "item_div",
2191 "item_mul", "item_del",
2192 "item_sin", "item_cos", "item_tan", "item_num7", "item_num8",
2193 "item_num9", "item_sub",
2194 "item_ln", "item_log", "item_1x", "item_num4", "item_num5",
2195 "item_num6", "item_plus",
2196 "item_10x", "item_x2", "item_xy", "item_num1", "item_num2",
2197 "item_num3", "item_brack",
2198 "item_abs", "item_pi", "item_e", "item_num0", "item_dot",
2199 "item_neg", "item_eq",
2202 Evas_Object *item = NULL;
2203 int key_num = sizeof(key_name) / sizeof(key_name[0]);
2206 for (i = 0; i < key_num; ++i) {
2208 (Evas_Object *) edje_object_part_object_get(keypad,
2211 evas_object_event_callback_add(item, EVAS_CALLBACK_MOUSE_DOWN, _calculator_interp, (void *)keypad);
2212 if (0 == strcmp(key_name[i], "item_del")) {
2213 evas_object_event_callback_add(item,
2214 EVAS_CALLBACK_MOUSE_UP,
2215 __calculator_delelte_up,
2226 * The callback of input entry when mouse up.
2228 * @param data unused
2230 * @param entry the input entry
2231 * @param event_info unused
2235 _calc_view_input_entry_mouseup_cb(void *data, Evas * e, Evas_Object * entry,
2237 { if (data == NULL) {
2240 /* if entry is showing warning message, then input operation is unavailable, just return*/
2241 struct appdata *ad = (struct appdata *)data;
2242 if (ad->wrong_timer) {
2245 calculator_cursor_pos = calc_view_cursor_get_position(entry); //for softkey input and mouse move
2249 _calc_view_input_entry_to_str(char *entry_str, char *internal_str, int buf_size)
2252 if (entry_str == NULL) {
2255 strncpy(internal_str, entry_str, buf_size - 1);
2256 /* remove result that behind '='(include '=') */
2257 char *enter = strchr(internal_str, '=');
2258 if (enter != NULL) {
2262 calc_expr_replace_from_special_char(internal_str);
2263 /* remove all ',' and '\n'*/
2266 while (internal_str[j] != '\0'){
2268 if (internal_str[j] == separator_ch || internal_str[j] == '\n'){
2271 internal_str[i++] = internal_str[j++];
2274 internal_str[i] = '\0';
2280 _calc_view_input_entry_keyup_cb(void *data, Evas * e, Evas_Object * entry,
2284 calculator_cursor_pos = calc_view_cursor_get_position(entry); //for hardkey input
2287 Evas_Object *obj = (Evas_Object *) data;
2288 Evas_Event_Key_Up *evt = (Evas_Event_Key_Up *) event_info;
2289 if (0 == strcmp(evt->key, "Return")) {
2290 //calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
2291 __calculator_op_equal(entry);
2294 val = _calculator_get_input_item_hd(evt->key, obj);
2300 __calculator_control_normal_func_clicked(e, ad->input_entry, &calc_op_item[val]);
2303 _calc_btn_dot_clicked(ad->input_entry);
2315 __calculator_control_panel_number_button_clicked(e, ad-> input_entry, &calc_op_item[val]);
2318 calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
2329 _calc_view_input_entry_error_include(char *string)
2332 for(; i < ARRAY_SIZE(error_string); i++)
2334 if(!strcmp(string, _(error_string[i]))){
2343 * The callback of input entry when text changed
2345 * @param[in] data the appdata
2346 * @param[in] obj the input entry
2347 * @param[in] event_info unused
2351 _calc_view_input_entry_changed_cb(void *data, Evas_Object *obj,
2355 if (data == NULL || obj == NULL) {
2358 struct appdata *ad = (struct appdata *)data;
2359 const char *str = (char *)elm_entry_entry_get(obj);
2362 char *entry_tmp = elm_entry_markup_to_utf8(str);
2363 char *entry_expr= elm_entry_markup_to_utf8(entry_tmp);/*because the string format from clipboard is not correct*/
2364 char internal_expr[MAX_EXPRESSION_LENGTH] = { 0 };
2365 char f_number_buf[NUMBER_LENGTH] = { 0 };
2366 char s_number_buf[NUMBER_LENGTH] = { 0 };
2368 _calc_view_input_entry_to_str(entry_expr, internal_expr, MAX_EXPRESSION_LENGTH);
2370 bool char_in =__calculator_string_invalid_char_search(internal_expr, &index);
2371 __calculator_get_cursor_position_float_string(internal_expr, f_number_buf, calculator_cursor_pos, NULL, NULL);
2372 int cur_pos = calc_view_cursor_get_position(ad->input_entry);
2373 __calculator_get_cursor_position_float_string(internal_expr, s_number_buf, cur_pos, NULL, NULL);
2374 int nCntOp = calc_expr_get_operator_num(internal_expr);
2376 if ((strlen(f_number_buf) > MAX_NUM_LENGTH) || (strlen(s_number_buf) > MAX_NUM_LENGTH)) {
2377 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
2378 } else if (nCntOp >= MAX_OPERATOR_NUM) {
2379 __calculator_wrong_format_create(CALC_MSG_MAX_OP);
2382 strncpy(calculator_input_str, internal_expr, index);
2383 calculator_cursor_pos = index;
2385 strncpy(calculator_input_str, internal_expr, sizeof(calculator_input_str) - 1);
2386 calculator_cursor_pos = cur_pos;
2388 _calc_entry_text_set(ad->input_entry, calculator_input_str);
2401 char *entry_expr_s = elm_entry_markup_to_utf8(str);
2402 char internal_expr_s[MAX_EXPRESSION_LENGTH] = { 0 };
2403 _calc_view_input_entry_to_str(entry_expr_s, internal_expr_s, MAX_EXPRESSION_LENGTH);
2404 if(!_calc_view_input_entry_error_include(internal_expr_s)){
2405 /*change calculator_input_str, after cut operation*/
2406 if(calculator_state == CALCULATOR_CALCULATED){
2407 calculator_state = CALCULATOR_OPERAND_INPUT;
2409 strncpy(calculator_input_str, internal_expr_s, MAX_EXPRESSION_LENGTH - 1);
2410 calculator_cursor_pos = calc_view_cursor_get_position(obj);
2412 _calc_entry_text_set(obj, calculator_input_str);
2415 entry_expr_s = NULL;
2420 * Prevent pasting images into entry.
2421 * If a image pasted, "<item absize=... href=...>" will be appended into entry.
2423 if (strstr(str, "item") != NULL) {
2425 char buf[MAX_EXPRESSION_LENGTH] = { 0 };
2427 while (elm_entry_cursor_prev(obj)) {
2429 } /* save cursor position */
2430 pos -= 1; /* correct */
2432 strncpy(buf, str, sizeof(buf));
2433 char *begin = strstr(buf, "<item");
2434 if (begin != NULL) {
2435 char *end = strchr(begin, '>');
2436 string_remove_at(buf, begin - buf, end - begin + 1); /* remove "<item...>" */
2437 elm_entry_entry_set(obj, buf);
2441 elm_entry_cursor_next(obj);
2442 } /* retrieve cursor position */
2444 calc_view_revise_input_scroller(ad);
2450 _calc_view_input_entry_paste_cb(void *data, Evas_Object * obj, void *event_info)
2454 strncpy(calculator_before_paste_str, calculator_input_str,
2455 MAX_EXPRESSION_LENGTH - 1);
2460 _calc_view_input_entry_select_start_cb(void *data, Evas_Object * obj, void *event_info)
2468 _calc_view_input_entry_select_changed_cb(void *data, Evas_Object * obj, void *event_info)
2475 _calc_view_input_entry_select_cleared_cb(void *data, Evas_Object * obj, void *event_info)
2478 select_mode = FALSE;
2485 * Create an entry for inputing expression.
2487 * @param parent the entry's parent
2488 * @param ad the appdata
2489 * @return Evas_Object* the input entry
2491 static Evas_Object *_calc_view_create_input_entry(Evas_Object * parent,
2495 Evas_Object *entry = elm_entry_add(ad->edje);
2496 elm_entry_single_line_set(entry, EINA_FALSE);
2497 elm_entry_editable_set(entry, EINA_TRUE);
2498 elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
2499 if (strlen(calculator_input_str) > 0) {
2500 _calc_entry_text_set(entry, calculator_input_str);
2502 elm_entry_entry_set(entry, "");
2504 elm_entry_cnp_mode_set(entry, ELM_CNP_MODE_NO_IMAGE);
2505 elm_entry_magnifier_disabled_set(entry, EINA_TRUE);
2506 elm_entry_cursor_end_set(entry);
2507 elm_object_focus_set(entry, EINA_TRUE);
2508 elm_object_style_set(entry, "black");
2509 evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND,
2511 evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
2513 evas_object_event_callback_add(entry, EVAS_CALLBACK_MOUSE_UP,
2514 _calc_view_input_entry_mouseup_cb, ad);
2515 evas_object_smart_callback_add(entry, "changed",
2516 _calc_view_input_entry_changed_cb, ad);
2517 evas_object_smart_callback_add(entry, "selection,paste",
2518 _calc_view_input_entry_paste_cb, ad);
2519 evas_object_smart_callback_add(entry, "selection,start",
2520 _calc_view_input_entry_select_start_cb, ad);
2521 evas_object_smart_callback_add(entry, "selection,changed",
2522 _calc_view_input_entry_select_changed_cb, ad);
2523 evas_object_smart_callback_add(entry, "selection,cleared",
2524 _calc_view_input_entry_select_cleared_cb, ad);
2526 evas_object_event_callback_add(entry, EVAS_CALLBACK_KEY_UP,
2527 _calc_view_input_entry_keyup_cb, ad);
2528 evas_object_smart_callback_del (entry, "changed", _calc_view_input_entry_changed_cb);
2530 evas_object_show(entry);
2531 limit_filter_data.max_char_count = 0;
2532 limit_filter_data.max_byte_count = 419 + 20; //19*21+20//result:20
2533 elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size,
2534 &limit_filter_data);
2535 elm_entry_text_style_user_push(entry, "DEFAULT='right_margin=32'");
2542 * Create a input scrooler which around the input entry.
2543 * It can give a input entry a scroller.
2545 * @param parent the parent of input scroller
2546 * @return Evas_Object* the input scroller
2549 static Evas_Object *_calc_view_create_input_scroller(Evas_Object * parent)
2552 Evas_Object *scroller = elm_scroller_add(parent);
2553 elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
2554 evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND,
2556 evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL,
2559 evas_object_show(scroller);
2566 * Create the background
2568 * @param[in] parent background's parent
2569 * @return when success return background, return NULL oppositely
2570 * @retval layout if success, return the background
2571 * @retval NULL if create failed or parent is null, return null
2574 static Evas_Object *__create_bg(Evas_Object *parent)
2577 if (parent == NULL) {
2580 Evas_Object *bg = elm_bg_add(parent);
2584 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2585 elm_win_resize_object_add(parent, bg);
2586 evas_object_show(bg);
2593 * Create the main layout
2595 * @param[in] parent main layout's parent
2596 * @return when success return a layout, return NULL oppositely
2597 * @retval layout if success, return the main layout
2598 * @retval NULL if create failed or parent is null, return null
2601 static Evas_Object *__calc_view_create_layout_main(Evas_Object *parent)
2605 if (parent == NULL) {
2609 Evas_Object *layout = elm_layout_add(parent);
2610 if (layout == NULL) {
2614 elm_layout_theme_set(layout, "layout", "application", "default");
2616 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND,
2618 elm_object_content_set(parent, layout);
2620 edje_object_signal_emit(_EDJ(layout), "elm,state,show,indicator",
2622 evas_object_show(layout);
2629 void _btn_clicked_cb(void *data, Evas_Object * obj, void *event_info)
2632 Evas_Object *win_main = (Evas_Object *) data;
2633 elm_win_lower(win_main);
2639 * Callback function of "Clear" Button on naviframe
2641 * @param data the appdata
2648 __calc_view_clear_clicked_cb(void *data, Evas_Object *obj, void *event_info)
2651 struct appdata *ad = (struct appdata *)data;
2652 if (ad->more_btn_popup) {
2653 evas_object_hide(ad->more_btn_popup);
2654 //ad->more_btn_popup= NULL;
2656 elm_entry_entry_set(ad->hist_area, "");
2657 elm_entry_entry_set(ad->input_entry, "");
2658 _calc_view_clear_histroy(ad->hist_area);
2659 /* Set input entry as initial state */
2660 _calc_entry_clear(ad->input_entry);
2661 calculator_state = CALCULATOR_WAITING_INPUT;
2665 Evas_Object *create_toolbar_more_btn(Evas_Object *parent, Evas_Smart_Cb func, void *data)
2667 Evas_Object *btn = elm_button_add(parent);
2671 elm_object_style_set(btn, "naviframe/more/default");
2673 evas_object_smart_callback_add(btn, "clicked", func, data);
2678 static void __gl_ctxpopup_hide_cb(void *data, Evas_Object *obj, void *event_info)
2680 evas_object_del(obj);
2683 static void __calc_view_create_popup(void *data, Evas_Object *parent)
2688 struct appdata *ad = (struct appdata *)data;
2689 ad->more_btn_popup = elm_ctxpopup_add(parent);
2690 const char *profile = elm_config_profile_get();
2691 if (!strcmp(profile, "mobile")) {
2692 ad->clear_item = elm_ctxpopup_item_append(ad->more_btn_popup,
2693 CALC_MSG_CLEAR_HISTTORY, NULL, __calc_view_clear_clicked_cb, ad);
2694 } else if (!strcmp(profile, "desktop")) {
2695 ad->clear_item = elm_ctxpopup_item_append(ad->more_btn_popup,
2696 CALC_MSG_CLEAR_HISTTORY, NULL, __calc_view_clear_clicked_cb, ad);
2699 Evas_Object *more_btn = NULL;
2700 more_btn = elm_object_item_part_content_get(ad->navi_it, "toolbar_more_btn");
2706 evas_object_geometry_get(more_btn, &x_position, &y_position, &w, &h);
2707 evas_object_move(ad->more_btn_popup, x_position + w/4, y_position+h/2);
2710 evas_object_show(ad->more_btn_popup);
2711 evas_object_smart_callback_add(ad->more_btn_popup, "dismissed", __gl_ctxpopup_hide_cb, data);
2715 void __calc_view_create_nf_more_btn_cb(void *data, Evas_Object * obj, void *event_info)
2717 struct appdata *ad = (struct appdata *)data;
2718 __calc_view_create_popup(data, ad->nf);
2724 * Load the Naviframe.
2726 * @param ad the appdata
2727 * @return naviframe object
2730 static Eina_Bool __calc_view_create_navigation_layout(struct appdata *ad)
2733 Evas_Object *nf = elm_naviframe_add(ad->layout);
2738 if (!ad->back_btn) {
2739 Evas_Object *back_btn = elm_button_add(nf);
2740 elm_object_style_set(back_btn, "naviframe/end_btn/default");
2741 evas_object_smart_callback_add(back_btn, "clicked", _btn_clicked_cb, ad->win);
2742 ad->back_btn = back_btn;
2744 ad->navi_it = elm_naviframe_item_push(nf, NULL, ad->back_btn, NULL, ad->edje, NULL);
2745 elm_naviframe_item_title_visible_set(ad->navi_it, EINA_FALSE);
2746 ad->more_btn = create_toolbar_more_btn(nf, __calc_view_create_nf_more_btn_cb, ad);
2747 elm_object_item_part_content_set(ad->navi_it, "toolbar_more_btn", ad->more_btn);
2748 evas_object_show(nf);
2755 * Load the main view of calculator.
2756 * Create the input entry and keypad.
2758 * @param ad the appdata
2761 void calc_view_load(struct appdata *ad)
2764 if (ad->bg == NULL) {
2765 ad->bg = __create_bg(ad->win);
2767 ad->conform = elm_conformant_add(ad->win);
2768 evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2769 elm_win_resize_object_add(ad->win, ad->conform);
2770 elm_object_style_set(ad->conform, "nokeypad");
2771 evas_object_show(ad->conform);
2772 ad->layout = __calc_view_create_layout_main(ad->conform);
2773 ad->edje = load_edj(ad->layout, LAYOUT_EDJ_NAME, GRP_MAIN);
2774 evas_object_show(ad->edje);
2775 evas_object_name_set(ad->edje, "edje");
2777 if (__calc_view_create_navigation_layout(ad)) {
2778 elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->nf);
2781 /* inititialize environment variable */
2782 locale = localeconv();
2783 decimal = locale->decimal_point;
2784 separator = locale->thousands_sep;
2785 int len_seq = strlen(separator);
2786 decimal_ch = decimal[0];
2787 separator_ch = separator[0];
2788 if (len_seq == 2 || len_seq == 0) {
2793 feedback_initialize();
2796 ad->input_entry = _calc_view_create_input_entry(ad->edje, ad);
2797 ad->input_scroller = _calc_view_create_input_scroller(ad->edje);
2798 elm_object_content_set(ad->input_scroller, ad->input_entry);
2799 edje_object_part_swallow(_EDJ(ad->edje), "input/entry",
2800 ad->input_scroller);
2807 * assign global variable , this will be removed
2813 void calc_xxx(struct appdata *ap)
2818 static Evas_Object* __set_win_icon(struct appdata *ad)
2820 /* set window icon*/
2821 Evas_Object *icon = evas_object_image_add(evas_object_evas_get(ad->win));
2822 evas_object_image_file_set(icon, DESKTOP_MODE_ICON, NULL);
2823 elm_win_icon_object_set(ad->win, icon);
2827 void win_profile_changed_cb(void *data, Evas_Object * obj, void *event_info)
2833 struct appdata *ad = (struct appdata *)data;
2834 const char *profile = elm_config_profile_get();
2835 if (!strcmp(profile, "desktop")) {
2836 /*In destktop mode, Hide indicator & hide back button on the naviframe */
2837 elm_object_item_part_content_set(ad->navi_it, "prev_btn", NULL);
2838 elm_object_item_part_content_set(ad->navi_it , "toolbar_button1", NULL);
2839 elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_HIDE);
2841 /* Show window Icon */
2842 if (!ad->window_icon) {
2843 ad->window_icon = __set_win_icon(ad);
2846 } else if (!strcmp(profile, "mobile")) {
2847 /* In mobile phone mode, show indicator and show back button*/
2848 elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
2849 Evas_Object *back_btn = elm_button_add(ad->nf);
2850 elm_object_style_set(back_btn, "naviframe/end_btn/default");
2851 evas_object_smart_callback_add(back_btn, "clicked", _btn_clicked_cb, ad->win);
2852 ad->back_btn = back_btn;
2853 elm_object_item_part_content_set(ad->navi_it, "prev_btn", ad->back_btn);