2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
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"
30 #define CALCULATOR_CHAR_IS_OPERATOR(C) ((C == '+')||(C == '-')||(C == 'x')||(C == '/')) /**<judge if a char is a basic operator*/
31 #define CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(C) ((C == 'x')||(C == '/')) /**<judge if an operator is "*" or "/"*/
32 #define CALCULATOR_CHAR_IS_PLUS_DEDUCT(C) ((C == '+')||(C == '-'))
33 #define CALCULATOR_CHAR_IS_DIGITAL(C)(C >= '0' && C <= '9')
34 #define CALCULATOR_IS_DIGIT_DOT(ch, decimal) (isdigit(ch) || decimal == (ch))
36 static Elm_Entry_Filter_Limit_Size limit_filter_data;
38 extern int get_max_fontsize();
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 extern gboolean __calculator_search_function(char *op, int* len);
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;
49 int calculator_cursor_pos = 0;
50 char calculator_input_str[MAX_EXPRESSION_LENGTH] = { 0 };
51 char calculator_before_paste_str[MAX_EXPRESSION_LENGTH] = { 0 };
53 bool paste_flag = FALSE;
55 struct lconv *locale = NULL;
57 char *separator = NULL;
59 char separator_ch = 0;
61 static op_item_t calc_op_item[] = {
62 {OP_INVALID, "", NULL},
65 {OP_PARENTHESIS, "()", NULL},
66 {OP_DELETE, "<-", NULL},
67 {OP_CLEAR, "C", NULL},
68 {OP_DIVIDE, "/", NULL},
70 {OP_NUM_7, "7", NULL},
71 {OP_NUM_8, "8", NULL},
72 {OP_NUM_9, "9", NULL},
73 {OP_MULTIPLY, "x", NULL},
75 {OP_NUM_4, "4", NULL},
76 {OP_NUM_5, "5", NULL},
77 {OP_NUM_6, "6", NULL},
78 {OP_MINUS, "-", NULL},
80 {OP_NUM_1, "1", NULL},
81 {OP_NUM_2, "2", NULL},
82 {OP_NUM_3, "3", NULL},
86 {OP_NUM_0, "0", NULL},
87 {OP_PLUS_MINUS, "+/-", NULL},
88 {OP_EQUAL, "=", NULL},
91 {OP_PERCENT, "%", NULL},
92 {OP_ROOT, "sqrt", "sqrt("},
95 {OP_SIN, "sin", "sin("},
96 {OP_COS, "cos", "cos("},
97 {OP_TAN, "tan", "tan("},
100 {OP_LOG, "log", "log("},
101 {OP_1X, "1/x", "1/x"},
103 {OP_EX, "e^x", "e^("},
104 {OP_X2, "x^2", "^2"},
105 {OP_XY, "x^y", "^("},
107 {OP_ABS, "abs", "abs("},
111 char *error_string[] = {
112 "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE",
113 "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE",
114 "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE",
115 "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO",
116 "IDS_CCL_POP_NO_NUMBER_ERROR",
118 "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR",
119 "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION",
120 "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION",
121 "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION",
122 "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION",
123 "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION",
124 "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION",
125 "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION",
126 "IDS_CCL_POP_NO_OPERATOR_ERROR",
127 "IDS_CCL_POP_SYNTAX_ERROR",
131 calculator_state_t calculator_get_state()
133 return calculator_state;
136 void _calc_add_tag(char *string, char *format_string)
142 char buf[MAX_EXPRESSION_LENGTH] = { 0 };
143 char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
145 while (string[i] != '\0') {
146 if (CALCULATOR_CHAR_IS_DIGITAL(string[i])
147 || string[i] == separator_ch || string[i] == decimal_ch) {
150 while (CALCULATOR_CHAR_IS_DIGITAL(string[i])
151 || string[i] == separator_ch
152 || string[i] == decimal_ch) {
156 strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
157 tmp[end - begin + 1] = '\0';
158 memset(buf, 0, sizeof(buf));
159 snprintf(buf, sizeof(buf),
160 "<align=right><+ font_size=%d><color=#000000ff>%s",
161 get_max_fontsize(), tmp);
162 strcat(format_string, buf);
166 while (!CALCULATOR_CHAR_IS_DIGITAL(string[i])
167 && string[i] != separator_ch
168 && string[i] != decimal_ch
169 && string[i] != '\0') {
173 strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
174 tmp[end - begin + 1] = '\0';
175 memset(buf, 0, sizeof(buf));
176 snprintf(buf, sizeof(buf),
177 "<align=right><+ font_size=%d><color=#855B11FF>%s",
178 get_max_fontsize(), tmp);
179 strcat(format_string, buf);
183 PLOG("Expression with tag : %s\n", format_string);
187 /* BEGIN INPUT ENTRY RELATED */
198 static void _calc_entry_text_set(Evas_Object * entry, const char *str)
201 char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
202 char tag_text[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
208 if (strlen(str) == 0) {
209 elm_entry_entry_set(entry, "");
210 calc_view_cursor_set_position(entry, calculator_cursor_pos);
213 calc_expr_format_expression(str, tmp);
214 _calc_add_tag(tmp, tag_text);
215 elm_entry_entry_set(entry, tag_text);
217 calc_view_cursor_set_position(entry, calculator_cursor_pos);
218 calc_view_revise_input_scroller(ad);
223 void _calc_entry_text_set_rotate(struct appdata *ad)
225 if (calculator_state == CALCULATOR_CALCULATED) {
226 _calc_view_show_newest_histroy(ad->input_entry);
227 elm_entry_cursor_end_set(ad->input_entry);
229 _calc_entry_text_set(ad->input_entry, calculator_input_str);
242 static void _calc_entry_text_insert(Evas_Object * entry, char *str)
245 calc_expr_input_insert(calculator_input_str, &calculator_cursor_pos,
247 printf("calculator_input_str=%s, str=%s, calculator_cursor_pos=%d\n", calculator_input_str, str, calculator_cursor_pos);
248 _calc_entry_text_set(entry, calculator_input_str);
262 static void _calc_entry_text_remove(Evas_Object * entry, const int from_pos,
266 string_remove_at(calculator_input_str, from_pos,
267 end_pos - from_pos + 1);
268 calculator_cursor_pos = from_pos;
269 _calc_entry_text_set(entry, calculator_input_str);
275 * Set correct cursor position in entry.
281 static void _calc_entry_cursor_set(Evas_Object * entry)
284 calc_view_cursor_set_position(entry, calculator_cursor_pos);
296 static void _calc_entry_backspace(Evas_Object * entry)
299 calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
300 _calc_entry_text_set(entry, calculator_input_str);
312 void _calc_entry_clear(Evas_Object * entry)
314 memset(calculator_input_str, 0, sizeof(calculator_input_str));
315 calculator_cursor_pos = 0;
316 _calc_entry_text_set(entry, "");
317 calc_view_cursor_set_position(entry, calculator_cursor_pos);
320 /* END INPUT ENTRY RELATED */
333 __calculator_get_float_num_in_cursor_position(char *text, int cur_pos,
334 int *begin, int *end)
338 int pos = cur_pos - 1;
346 if ('p' == text[pos] || 'e' == text[pos]) {
350 } else if (CALCULATOR_IS_DIGIT_DOT(text[pos], decimal_ch)) {
351 for (_begin = pos - 1;
352 CALCULATOR_IS_DIGIT_DOT(text[_begin], decimal_ch)
353 && _begin >= 0; --_begin) {
357 if (_begin > 1 && '-' == text[_begin - 1]
358 && '(' == text[_begin - 2]) {
362 CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
363 && _end < strlen(text); ++_end) {
389 __calculator_get_cursor_position_float_string(char *entry_text, char *str,
390 int cur_pos, int *from, int *end)
394 int from_pos = cur_pos;
395 int end_pos = cur_pos;
398 __calculator_get_float_num_in_cursor_position(entry_text, cur_pos,
404 /* set from&end position */
412 strncpy(str, entry_text + from_pos, end_pos - from_pos + 1);
413 str[end_pos - from_pos + 1] = '\0';
420 * Get the float number in current cursor
428 __calculator_get_before_cursor_float_string(char *entry_text, char *str)
432 int from_pos = calculator_cursor_pos;
433 int end_pos = calculator_cursor_pos;
436 __calculator_get_float_num_in_cursor_position(entry_text,
437 calculator_cursor_pos,
442 snprintf(str, calculator_cursor_pos - from_pos + 1, "%s",
443 entry_text + from_pos);
450 * Get string before cursor in the Entry.
458 __calculator_get_input_from_begin_to_cursor(char *entry_text, char *str)
462 if (calculator_cursor_pos > 0) {
463 strncpy(str, entry_text, calculator_cursor_pos);
464 str[calculator_cursor_pos] = '\0';
474 * judge the type of current input
480 static last_char_t __calculator_string_get_char_type( char ch_in)
492 if (CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(ch_in)) {
493 return CHAR_IS_MULTIPLY_DIVIDE;
496 return CHAR_IS_LEFT_PARENTHESE;
499 return CHAR_IS_RIGHT_PARENTHESE;
501 if (CALCULATOR_CHAR_IS_DIGITAL(ch_in)) {
502 return CHAR_IS_DIGIT;
504 if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(ch_in) ){
505 return CHAR_IS_PLUS_MINUS;
507 if (ch_in == decimal_ch) {
508 return CHAR_IS_POINT;
510 return CHAR_IS_CHARACTER;
514 static bool __calculator_string_digit_in(const char *input)
517 while(input[i]!='\0'){
518 if(CALCULATOR_CHAR_IS_DIGITAL(input[i])){
528 * search charactor in input string, if have charactor, return True and index of first charactor;
531 static bool __calculator_string_char_search(const char *input, int *index)
534 int len_cp = strlen(input);
539 for(; i < len_cp ; i++){
540 last_char_t cur_char_type = __calculator_string_get_char_type(input[i]);
541 if (CHAR_IS_CHARACTER == cur_char_type) {
551 * search invalid charactor in input string, if have invalid charactor, return True and index of first invalid charactor;
554 static bool __calculator_string_invalid_char_search(char *input, int *index)
558 bool char_in = FALSE;
560 char_in = __calculator_string_char_search(p, &sub_index);
561 if(!char_in){/*no charactor*/
565 /* charactor present*/
568 if(!__calculator_search_function(p, &len)){/*charactor not a function*/
570 }else{/*the first sevaral charactors are function, continue search*/
587 __calculator_control_panel_number_button_clicked(Evas_Object * entry,
592 /* replace special characters */
593 char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
594 snprintf(entry_text, sizeof(entry_text), "%s", calculator_input_str);
596 //Current state is calculated, clear all
597 if (calculator_state == CALCULATOR_CALCULATED) {
598 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
599 _calc_entry_clear(entry);
600 _calc_entry_text_insert(entry, op_item->op_sym);
601 calculator_state = CALCULATOR_OPERAND_INPUT;
605 char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
606 char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
610 __calculator_get_cursor_position_float_string(entry_text, str_buf,
611 calculator_cursor_pos,
613 __calculator_get_input_from_begin_to_cursor(entry_text, before_cursor);
614 before_len = strlen(before_cursor);
615 calculator_get_digits_number(str_buf, &nDigitCnt, &nPointCnt);
617 char str_bufa[MAX_EXPRESSION_LENGTH] = { 0 };
618 __calculator_get_before_cursor_float_string(entry_text, str_bufa);
619 if (strcmp(str_bufa, "0") == 0) {
620 _calc_entry_backspace(entry);
623 if (strlen(str_buf) >= MAX_NUM_LENGTH) {
624 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
626 } else if (nPointCnt >= MAX_DECIMAL_NUM
627 && calculator_cursor_pos > nDigitCnt) {
628 __calculator_wrong_format_create(CALC_MSG_MAX_DEC_DIGIT);
630 } else if (before_len > 0
631 && (__calculator_string_get_char_type(before_cursor[before_len - 1]) ==
633 || __calculator_string_get_char_type(before_cursor[before_len - 1]) ==
635 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
637 } else if (before_len > 0
638 && ((before_cursor[before_len - 1] == '(')
640 CALCULATOR_CHAR_IS_DIGITAL(before_cursor[before_len - 1])
641 || CALCULATOR_CHAR_IS_OPERATOR(before_cursor[before_len - 1]) || (int)before_cursor[before_len - 1] > 120)) //* or/
643 _calc_entry_text_insert(entry, op_item->op_sym);
644 calculator_state = CALCULATOR_OPERAND_INPUT;
646 } else if (before_len > 0 && (before_cursor[before_len - 1] == ')')) {
647 _calc_entry_text_insert(entry, op_item->op_sym);
650 _calc_entry_text_insert(entry, op_item->op_sym);
651 calculator_state = CALCULATOR_OPERAND_INPUT;
665 static void _calc_btn_dot_clicked(Evas_Object * entry)
668 char temp[MAX_RESULT_LENGTH] = { 0 };
669 char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
672 char decimal_str[32] = { 0 };
674 /* replace special characters */
675 char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
676 strncpy(entry_text, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
678 if (calculator_state == CALCULATOR_CALCULATED) {
679 calc_expr_num_format_result(last_result, temp);
680 if (strchr(temp, 'E') != NULL) {
684 _calc_entry_clear(entry);
685 _calc_entry_text_insert(entry, temp);
690 if (!__calculator_get_cursor_position_float_string
691 (entry_text, str_num, calculator_cursor_pos, &from_pos, &end_pos)) {
692 if (calculator_cursor_pos == 0
693 || IS_OPERATOER(calculator_input_str[from_pos - 1])) {
694 snprintf(decimal_str, sizeof(decimal_str), "0%c",
696 _calc_entry_text_insert(entry, decimal_str);
697 calculator_state = CALCULATOR_OPERAND_INPUT;
700 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
704 if (strcmp(str_num, "p") == 0 || strcmp(str_num, "e") == 0) {
705 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
710 str_num_len = strlen(str_num);
711 if (str_num_len > 0 && str_num[str_num_len - 1] == decimal_ch) {
712 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
718 calculator_get_digits_number(str_num, &nDigitCnt, &nPointCnt);
720 if (nDigitCnt >= 15) {
721 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
726 __calculator_wrong_format_create(CALC_MSG_ENTRY_LIMIT);
729 snprintf(decimal_str, sizeof(decimal_str), "%c", decimal_ch);
730 _calc_entry_text_insert(entry, decimal_str);
731 calculator_state = CALCULATOR_OPERAND_INPUT;
744 static void _calc_btn_backspace_clicked(Evas_Object * entry)
748 if (calculator_state == CALCULATOR_CALCULATED) {
749 calculator_state = CALCULATOR_OPERATOR_INPUT;
750 if (calculator_cursor_pos > strlen(calculator_input_str)) {
751 calculator_cursor_pos = strlen(calculator_input_str); /* set last position */
754 _calc_entry_backspace(entry);
758 static int __calculator_delete_long_press(void *data)
761 Evas_Object *entry = (Evas_Object *) data;
762 _calc_btn_backspace_clicked(entry);
769 * Process +.-.*.\ these four buttons clicked.
777 __calculator_control_normal_func_clicked(Evas_Object * entry,
781 char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
782 strncpy(all_input, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
784 if (calculator_state == CALCULATOR_CALCULATED) {
785 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
786 char temp[20] = { 0 };
788 calc_expr_num_format_result(last_result, temp);
789 _calc_entry_clear(entry);
791 if (temp[0] == '-' || strchr(temp, 'E')) //result < 0 or sicience number
793 _calc_entry_text_insert(entry, "(");
794 _calc_entry_text_insert(entry, temp);
795 _calc_entry_text_insert(entry, ")");
797 _calc_entry_text_insert(entry, temp);
800 _calc_entry_text_insert(entry, op_item->op_sym);
801 calculator_state = CALCULATOR_OPERATOR_INPUT;
805 if(!strcmp(op_item->op_sym, "x") || !strcmp(op_item->op_sym, "/") || !strcmp(op_item->op_sym, "+")){
806 if(!__calculator_string_digit_in(calculator_input_str)){ return; }
808 int nCntOp = calc_expr_get_operator_num(all_input);
809 if (nCntOp >= MAX_OPERATOR_NUM) { /* Can't exceed 20 operators */
810 __calculator_wrong_format_create(CALC_MSG_MAX_OP);
814 char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
817 __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
818 input_len = strlen(before_cursor);
821 if (before_cursor[input_len - 1] == '('
822 && !strcmp(op_item->op_sym, "-")) {
823 _calc_entry_text_insert(entry, op_item->op_sym);
824 calculator_state = CALCULATOR_OPERATOR_INPUT;
825 } else if (((input_len > 1) && (before_cursor[input_len - 1] == '-') && (before_cursor[input_len - 2] == '(')) //(-
826 || before_cursor[input_len - 1] == decimal_ch || before_cursor[input_len - 1] == '(') // . or (
829 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
831 } else if (IS_OPERATOER(before_cursor[input_len - 1])) {
832 if ((input_len > 1 || !strcmp(op_item->op_sym, "-"))
834 _calc_entry_backspace(entry);
835 _calc_entry_text_insert(entry, op_item->op_sym);
836 calculator_state = CALCULATOR_OPERATOR_INPUT;
838 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
841 } else if (before_cursor[input_len - 1] == ')') //
843 _calc_entry_text_insert(entry, op_item->op_sym);
844 calculator_state = CALCULATOR_OPERATOR_INPUT;
847 if (!IS_DIGITAL(before_cursor[input_len - 1])) {
848 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
851 _calc_entry_text_insert(entry, op_item->op_sym);
852 calculator_state = CALCULATOR_OPERATOR_INPUT;
856 } else { /* before_cursor si empty */
858 _calc_entry_text_insert(entry, op_item->op_sym);
859 calculator_state = CALCULATOR_OPERATOR_INPUT;
872 static void __calculator_symbol_negative_clicked(Evas_Object * entry)
876 char result[MAX_RESULT_LENGTH] = { 0 };
878 if (calculator_state == CALCULATOR_CALCULATED) {
879 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
881 calc_expr_num_format_result(last_result, result);
882 if (last_result < 0) {
883 string_remove_at(result, 0, 1); //remove '-'
885 string_insert(result, 0, "(-"); // add (-xxx)
886 string_insert(result, strlen(result), ")");
889 _calc_entry_clear(entry);
890 _calc_entry_text_insert(entry, result);
892 calculator_state = CALCULATOR_OPERAND_INPUT;
893 //use_last_result = 1;
898 int cursor = calculator_cursor_pos;
899 int begin = 0, length = 0;
900 char expr[MAX_EXPRESSION_LENGTH] = { 0 };
901 strncpy(expr, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
905 if (expr[cursor] == ')') {
907 flag = 1; /* before current cursor is ')' */
911 calc_expr_get_current_num_at_cursor(expr, cursor, &begin,
913 if (expr[begin] == '-') {
914 if (begin > 0 && expr[begin - 1] == '('
915 && expr[begin + length] == ')') {
916 string_remove_at(expr, begin + length, 1); //remove ')'
917 string_remove_at(expr, begin - 1, 2); // remove '(-'
918 calculator_cursor_pos -= flag ? 3 : 2;
920 string_remove_at(expr, begin, 1);
921 calculator_cursor_pos -= 1;
925 if (flag == 1) //not '(-xxx)' but has ')'
927 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
930 string_insert(expr, begin + length, ")");
931 string_insert(expr, begin, "(-");
932 calculator_cursor_pos +=
933 (((begin + length) ==
934 calculator_cursor_pos) ? 3 : 2);
937 strncpy(calculator_input_str, expr, MAX_EXPRESSION_LENGTH - 1);
939 _calc_entry_text_set(entry, calculator_input_str);
940 _calc_entry_cursor_set(entry);
942 calculator_state = CALCULATOR_OPERAND_INPUT;
945 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
950 /* search the previous operator and value */
951 static char * __calculator_search_prev_input(char *input_str)
953 int i = strlen(input_str) - 1;
954 int rightbracket = 0;
955 char *prev_input = NULL;
957 if (input_str[i] == ')') {
959 } else if (input_str[i] == '(') {
962 if ((CALCULATOR_CHAR_IS_PLUS_DEDUCT(input_str[i])
963 ||CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(input_str[i])) && (rightbracket == 0)){
964 prev_input = &input_str[i];
979 static void __calculator_op_equal(Evas_Object * entry)
982 if (calculator_state == CALCULATOR_CALCULATED) {
983 /*duplicate previous input operator and value*/
984 char *p = __calculator_search_prev_input(calculator_input_str);
988 char prev_input[32] = { 0 };
989 int len = g_strlcpy(prev_input, p, sizeof(prev_input));
990 if(len >= sizeof(prev_input)){
993 char temp[32] = { 0 };
994 calc_expr_num_format_result(last_result, temp);
995 _calc_entry_clear(entry);
997 if (temp[0] == '-' || strchr(temp, 'E')) {
998 _calc_entry_text_insert(entry, "(");
999 _calc_entry_text_insert(entry, temp);
1000 _calc_entry_text_insert(entry, ")");
1002 _calc_entry_text_insert(entry, temp);
1004 _calc_entry_text_insert(entry, prev_input);
1005 calculator_state = CALCULATOR_OPERATOR_INPUT;
1009 char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1010 char result_buf[MAX_RESULT_LENGTH] = { 0 };
1012 char error_msg[MAX_ERROR_MESSAGE_LENGTH] = { 0 };
1013 calc_expr_close_parentheses(calculator_input_str);
1014 _calc_entry_text_set(entry, calculator_input_str);
1015 snprintf(str_buf, sizeof(str_buf), "%s", calculator_input_str);
1016 str_len = strlen(str_buf);
1018 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1022 PLOG("calculate :%s\n", str_buf);
1023 if (!calculator_calculate(str_buf, &result, error_msg)) {
1024 PLOG("error : %s\n", error_msg);
1025 __calculator_wrong_format_create(error_msg);
1026 calculator_state = CALCULATOR_ERROR_OCCURED;
1029 last_result = result;
1030 memset(result_buf, 0, CALCULATOR_CONTENT_LEN + 1);
1031 calc_expr_num_format_result(result, result_buf);
1034 struct history_item item;
1035 memset(item.expression, 0, sizeof(item.expression));
1036 memset(item.result, 0, sizeof(item.result));
1037 calc_expr_format_expression(calculator_input_str,
1039 calc_expr_format_expression(result_buf, item.result);
1041 calc_view_save_history(item);
1045 calculator_state = CALCULATOR_CALCULATED;
1046 calc_view_show_result(item.result, ad);
1060 static void __calculator_parenthesis_clicked(Evas_Object * entry)
1063 char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1064 snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
1065 if (calculator_state == CALCULATOR_CALCULATED) {
1066 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1068 char temp[MAX_RESULT_LENGTH] = { 0 };
1070 calc_expr_num_format_result(last_result, temp);
1071 _calc_entry_clear(entry);
1073 if (temp[0] == '-' || strchr(temp, 'E') != NULL) //result < 0 or science number
1075 _calc_entry_text_insert(entry, "((");
1076 _calc_entry_text_insert(entry, temp);
1077 _calc_entry_text_insert(entry, ")");
1079 _calc_entry_text_insert(entry, "(");
1080 _calc_entry_text_insert(entry, temp);
1082 calculator_state = CALCULATOR_OPERATOR_INPUT;
1085 char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1087 __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1088 input_len = strlen(before_cursor);
1090 if (input_len == 0) {
1091 _calc_entry_text_insert(entry, "(");
1092 calculator_state = CALCULATOR_OPERATOR_INPUT;
1095 int bracket_num = calculator_get_open_braket(all_input);
1096 if (input_len > 0) {
1097 if (before_cursor[input_len - 1] == decimal_ch) {
1098 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1100 } else if (bracket_num > 0 //'(' is more than ')'
1101 && before_cursor[input_len - 1] != '('
1102 && (before_cursor[input_len - 1] == ')'
1103 || isdigit(before_cursor[input_len - 1])
1105 (__calculator_string_get_char_type
1106 (before_cursor[input_len - 1]) == CHAR_IS_PI
1108 __calculator_string_get_char_type
1109 (before_cursor[input_len - 1]) == CHAR_IS_E))) {
1110 _calc_entry_text_insert(entry, ")");
1112 } else if (bracket_num == 0) {
1113 if (calc_expr_get_left_parentheses_num
1114 (calculator_input_str) < MAX_PARENTHESES_NUM) {
1115 _calc_entry_text_insert(entry, "(");
1118 } else if (before_cursor[input_len - 1] != ')') //'(' is less than ')'!isdigit(before_cursor[input_len-1])&&(
1120 if (calc_expr_get_left_parentheses_num
1121 (calculator_input_str) < MAX_PARENTHESES_NUM) {
1122 _calc_entry_text_insert(entry, "(");
1141 __calculator_control_functions_button_clicked(Evas_Object * entry,
1142 op_item_t * op_item)
1147 function_t function = { 0 };
1149 memset(&function, 0x0, sizeof(function_t));
1150 str = op_item->op_name;
1152 char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1154 char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1156 last_char_t last_char_type = 0;
1158 snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
1159 __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1160 input_len = strlen(all_input);
1161 before_len = strlen(before_cursor);
1163 last_char_type = __calculator_string_get_char_type(before_cursor[before_len - 1]);
1166 switch (op_item->op_id) {
1168 /* if it is calculated state */
1169 if (calculator_state == CALCULATOR_CALCULATED) {
1170 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1173 char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1174 double per_result = last_result / 100.0;
1176 calc_expr_num_format_result(per_result, temp);
1177 _calc_entry_clear(entry);
1179 if (strcmp(temp, "0") == 0) {
1180 _calc_entry_text_insert(entry, "0");
1181 } else if (temp[0] == '-') //result < 0
1183 _calc_entry_text_insert(entry, "(");
1184 _calc_entry_text_insert(entry, temp);
1185 _calc_entry_text_insert(entry, ")");
1187 _calc_entry_text_insert(entry, temp);
1189 calculator_state = CALCULATOR_OPERAND_INPUT;
1194 int from_pos, end_pos;
1195 char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
1196 char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1197 double per_result = 0.0;
1200 __calculator_get_cursor_position_float_string
1201 (all_input, str_num, calculator_cursor_pos,
1202 &from_pos, &end_pos)) {
1203 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1208 if (strlen(str_num) == 0) {
1209 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1213 if (strcmp(str_num, "0") == 0) {
1217 per_result = atof(str_num);
1218 per_result /= 100.0;
1220 calc_expr_num_format_result(per_result, temp);
1222 _calc_entry_text_remove(entry, from_pos,
1224 _calc_entry_text_insert(entry, temp);
1226 calculator_state = CALCULATOR_OPERAND_INPUT;
1232 if (calculator_state == CALCULATOR_CALCULATED) {
1233 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1235 _calc_entry_clear(entry);
1236 _calc_entry_text_insert(entry, "p");
1239 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1240 && (before_cursor[before_len - 1] != '-')
1241 && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1242 && (before_cursor[before_len - 1] != '^')
1243 && (before_cursor[before_len - 1] != '(')
1244 && (before_cursor[before_len - 1] != 'P')
1245 && before_cursor[before_len - 1] != 'C') {
1246 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1249 _calc_entry_text_insert(entry, "p");
1253 if (calculator_state == CALCULATOR_CALCULATED) {
1254 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1257 _calc_entry_clear(entry);
1258 _calc_entry_text_insert(entry, op_item->op_name);
1261 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1262 && (before_cursor[before_len - 1] != '-')
1263 && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1264 && (before_cursor[before_len - 1] != '^')
1265 && (before_cursor[before_len - 1] != '(')
1266 && (before_cursor[before_len - 1] != 'P')
1267 && before_cursor[before_len - 1] != 'C') {
1268 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1271 _calc_entry_text_insert(entry, op_item->op_name);
1274 case OP_SIN: //sin()
1275 case OP_COS: //cos()
1276 case OP_TAN: //tan()
1277 case OP_LOG: //log()
1278 case OP_ABS: //abs()
1279 if (calculator_state == CALCULATOR_CALCULATED) {
1280 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1283 _calc_entry_clear(entry);
1284 _calc_entry_text_insert(entry, op_item->op_name);
1287 if (last_char_type == CHAR_IS_PI || last_char_type == CHAR_IS_E) {
1288 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1292 _calc_entry_text_insert(entry, op_item->op_name);
1296 if (calculator_state == CALCULATOR_CALCULATED) {
1297 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1299 _calc_entry_clear(entry);
1300 _calc_entry_text_insert(entry, op_item->op_name);
1303 if (last_char_type == CHAR_IS_PI) {
1304 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1307 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1308 && (before_cursor[before_len - 1] != '-')
1309 && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1310 && (before_cursor[before_len - 1] != '^')
1311 && (before_cursor[before_len - 1] != '(')
1312 && (before_cursor[before_len - 1] != 'C')
1313 && (before_cursor[before_len - 1] != 'P')) {
1314 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1317 _calc_entry_text_insert(entry, op_item->op_name);
1320 case OP_ROOT: //sqrt()
1321 if (calculator_state == CALCULATOR_CALCULATED) {
1322 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1325 _calc_entry_clear(entry);
1326 _calc_entry_text_insert(entry, op_item->op_name);
1329 if (last_char_type == CHAR_IS_PI) {
1330 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1333 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1334 && (before_cursor[before_len - 1] != '-')
1335 && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1336 && (before_cursor[before_len - 1] != '^')
1337 && (before_cursor[before_len - 1] != '(')
1338 && (before_cursor[before_len - 1] != 'C')
1339 && (before_cursor[before_len - 1] != 'P')) {
1340 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1343 _calc_entry_text_insert(entry, op_item->op_name);
1347 if (calculator_state == CALCULATOR_CALCULATED) {
1348 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1350 _calc_entry_clear(entry);
1351 _calc_entry_text_insert(entry, op_item->op_name);
1354 if (last_char_type == CHAR_IS_PI) {
1355 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1358 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1359 && (before_cursor[before_len - 1] != '-')
1360 && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1361 && (before_cursor[before_len - 1] != '^')
1362 && (before_cursor[before_len - 1] != '(')
1363 && (before_cursor[before_len - 1] != 'C')
1364 && (before_cursor[before_len - 1] != 'P')) {
1365 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1368 _calc_entry_text_insert(entry, op_item->op_name);
1372 if (calculator_state == CALCULATOR_CALCULATED) {
1373 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1376 char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1377 calc_expr_num_format_result(last_result, temp);
1378 _calc_entry_clear(entry);
1380 if (temp[0] == '-' || strchr(temp, 'E')) //result < 0 or science number
1382 _calc_entry_text_insert(entry, "(");
1383 _calc_entry_text_insert(entry, temp);
1384 _calc_entry_text_insert(entry, ")");
1386 _calc_entry_text_insert(entry, temp);
1388 _calc_entry_text_insert(entry, op_item->op_name);
1389 calculator_state = CALCULATOR_OPERAND_INPUT;
1390 //use_last_result = 1;
1394 if (input_len == 0) {
1395 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
1398 if (last_char_type == CHAR_IS_PI) {
1399 _calc_entry_text_insert(entry, op_item->op_name);
1400 calculator_state = CALCULATOR_OPERAND_INPUT;
1402 } else if ((before_len > 0)
1403 && (!isdigit(before_cursor[before_len - 1]))
1404 && (before_cursor[before_len - 1] != ')')) {
1405 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
1408 _calc_entry_text_insert(entry, op_item->op_name);
1409 calculator_state = CALCULATOR_OPERAND_INPUT;
1412 if (calculator_state == CALCULATOR_CALCULATED) {
1413 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1416 char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1418 calc_expr_num_format_result(last_result, temp);
1419 _calc_entry_clear(entry);
1421 if (temp[0] == '-' || strchr(temp, 'E')) //result < 0 or science number
1423 _calc_entry_text_insert(entry, "(");
1424 _calc_entry_text_insert(entry, temp);
1425 _calc_entry_text_insert(entry, ")");
1427 _calc_entry_text_insert(entry, temp);
1429 _calc_entry_text_insert(entry, op_item->op_name);
1430 calculator_state = CALCULATOR_OPERATOR_INPUT;
1434 if (input_len == 0) {
1435 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
1438 if ((last_char_type == CHAR_IS_PI)
1439 || (last_char_type == CHAR_IS_E)) {
1440 _calc_entry_text_insert(entry, op_item->op_name);
1441 calculator_state = CALCULATOR_OPERATOR_INPUT;
1443 } else if ((before_len > 0)
1444 && !isdigit(before_cursor[before_len - 1])
1445 && (before_cursor[before_len - 1] != ')')) {
1446 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
1449 _calc_entry_text_insert(entry, op_item->op_name);
1450 calculator_state = CALCULATOR_OPERATOR_INPUT;
1454 if (calculator_state == CALCULATOR_CALCULATED) {
1455 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1458 char temp[MAX_RESULT_LENGTH] = { 0 };
1460 calc_expr_num_format_result(last_result, temp);
1462 if (strchr(temp, decimal_ch) != NULL || strchr(temp, '-') != NULL) //revise by bfl
1464 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1465 calculator_state = CALCULATOR_WAITING_INPUT; //revise by bfl
1469 _calc_entry_clear(entry);
1470 _calc_entry_text_insert(entry, "(");
1471 _calc_entry_text_insert(entry, temp);
1472 _calc_entry_text_insert(entry, "!)");
1474 calculator_state = CALCULATOR_OPERATOR_INPUT;
1478 if (input_len == 0) {
1479 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_FAC);
1482 if ((last_char_type == CHAR_IS_PI)
1483 || (last_char_type == CHAR_IS_E)) {
1484 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1488 /* check if it is natural */
1490 char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1491 int from_pos = 0, end_pos = 0;
1494 __calculator_get_cursor_position_float_string
1495 (all_input, str_buf, calculator_cursor_pos,
1496 &from_pos, &end_pos)) {
1497 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1501 if (strchr(str_buf, decimal_ch) != NULL
1502 || str_buf[0] == '-') {
1503 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1507 _calc_entry_text_remove(entry, from_pos, end_pos);
1508 _calc_entry_text_insert(entry, "(");
1509 _calc_entry_text_insert(entry, str_buf);
1510 _calc_entry_text_insert(entry, "!)");
1511 calculator_state = CALCULATOR_OPERATOR_INPUT;
1515 This is redundant comment.
1516 Its only use is for Klocwork testing.
1517 The comment rete should passed 25%.
1518 But we have only one day to do this work.
1519 So, sorry, I will delete this comment and add useful comment later.
1522 if (calculator_state == CALCULATOR_CALCULATED) {
1523 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1526 char temp[MAX_RESULT_LENGTH] = { 0 };
1529 calc_expr_num_format_result(last_result, temp);
1530 if (strchr(temp, 'E') != NULL) //science number
1532 temp[strlen(temp)] = ')';
1533 for (i = strlen(temp); i > 0; --i) {
1534 temp[i] = temp[i - 1];
1539 _calc_entry_clear(entry);
1540 if (temp[0] == '-') {
1541 _calc_entry_text_insert(entry, "(-1");
1542 _calc_entry_text_insert(entry, "/");
1544 _calc_entry_text_insert(entry, &temp[1]);
1545 _calc_entry_text_insert(entry, ")");
1547 _calc_entry_text_insert(entry, "(1");
1548 _calc_entry_text_insert(entry, "/");
1550 _calc_entry_text_insert(entry, temp);
1551 _calc_entry_text_insert(entry, ")");
1554 calculator_state = CALCULATOR_OPERATOR_INPUT;
1555 //use_last_result = 1;
1559 This is redundant comment.
1560 Its only use is for Klocwork testing.
1561 The comment rete should passed 25%.
1562 But we have only one day to do this work.
1563 So, sorry, I will delete this comment and add useful comment later.
1565 if (input_len == 0) {
1566 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
1570 /* check if it is digit */
1572 char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1573 int from_pos = 0, end_pos = 0;
1576 __calculator_get_cursor_position_float_string
1577 (all_input, str_buf, calculator_cursor_pos,
1578 &from_pos, &end_pos)) {
1579 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
1583 if (strcmp(str_buf, "p") && strcmp(str_buf, "e")
1584 && atof(str_buf) == 0) {
1585 __calculator_wrong_format_create(CALC_MSG_DIVIDE_BY_ZERO);
1589 _calc_entry_text_remove(entry, from_pos, end_pos);
1590 if (str_buf[0] == '-') {
1591 _calc_entry_text_insert(entry, "(-1");
1592 _calc_entry_text_insert(entry, "/");
1594 _calc_entry_text_insert(entry, &str_buf[1]);
1595 _calc_entry_text_insert(entry, ")");
1597 _calc_entry_text_insert(entry, "(1");
1598 _calc_entry_text_insert(entry, "/");
1600 _calc_entry_text_insert(entry, str_buf);
1601 _calc_entry_text_insert(entry, ")");
1604 calculator_state = CALCULATOR_OPERATOR_INPUT;
1611 calculator_state = CALCULATOR_SPECIAL_FUNCTION_INPUT;
1616 /////////////////////////// input text finish ////////////////////////////
1627 static int _calculator_get_input_item(Evas_Object * evas_obj, Evas_Object * obj)
1632 if (evas_obj == edje_object_part_object_get(obj, "item_brack")) {
1633 val = OP_PARENTHESIS;
1634 } else if (evas_obj == edje_object_part_object_get(obj, "item_del")) {
1636 } else if (evas_obj == edje_object_part_object_get(obj, "item_c")) {
1638 } else if (evas_obj == edje_object_part_object_get(obj, "item_div")) {
1640 } else if (evas_obj == edje_object_part_object_get(obj, "item_num7")) {
1642 } else if (evas_obj == edje_object_part_object_get(obj, "item_num8")) {
1644 } else if (evas_obj == edje_object_part_object_get(obj, "item_num9")) {
1646 } else if (evas_obj == edje_object_part_object_get(obj, "item_mul")) {
1648 } else if (evas_obj == edje_object_part_object_get(obj, "item_num4")) {
1650 } else if (evas_obj == edje_object_part_object_get(obj, "item_num5")) {
1652 } else if (evas_obj == edje_object_part_object_get(obj, "item_num6")) {
1654 } else if (evas_obj == edje_object_part_object_get(obj, "item_sub")) {
1656 } else if (evas_obj == edje_object_part_object_get(obj, "item_num1")) {
1658 } else if (evas_obj == edje_object_part_object_get(obj, "item_num2")) {
1660 } else if (evas_obj == edje_object_part_object_get(obj, "item_num3")) {
1662 } else if (evas_obj == edje_object_part_object_get(obj, "item_plus")) {
1664 } else if (evas_obj == edje_object_part_object_get(obj, "item_dot")) {
1666 } else if (evas_obj == edje_object_part_object_get(obj, "item_num0")) {
1668 } else if (evas_obj == edje_object_part_object_get(obj, "item_neg")) {
1669 val = OP_PLUS_MINUS;
1670 } else if (evas_obj == edje_object_part_object_get(obj, "item_eq")) {
1672 } else if (evas_obj == edje_object_part_object_get(obj, "item_per")) {
1674 } else if (evas_obj == edje_object_part_object_get(obj, "item_sqr")) {
1676 } else if (evas_obj == edje_object_part_object_get(obj, "item_fac")) {
1678 } else if (evas_obj == edje_object_part_object_get(obj, "item_sin")) {
1680 } else if (evas_obj == edje_object_part_object_get(obj, "item_cos")) {
1682 } else if (evas_obj == edje_object_part_object_get(obj, "item_tan")) {
1684 } else if (evas_obj == edje_object_part_object_get(obj, "item_ln")) {
1686 } else if (evas_obj == edje_object_part_object_get(obj, "item_log")) {
1688 } else if (evas_obj == edje_object_part_object_get(obj, "item_1x")) {
1690 } else if (evas_obj == edje_object_part_object_get(obj, "item_ex")) {
1692 } else if (evas_obj == edje_object_part_object_get(obj, "item_x2")) {
1694 } else if (evas_obj == edje_object_part_object_get(obj, "item_xy")) {
1696 } else if (evas_obj == edje_object_part_object_get(obj, "item_abs")) {
1698 } else if (evas_obj == edje_object_part_object_get(obj, "item_pi")) {
1700 } else if (evas_obj == edje_object_part_object_get(obj, "item_e")) {
1709 * Interpret all of our different signals, and do things !
1719 _calculator_interp(void *data, Evas * e, Evas_Object * evas_obj,
1725 if (data && ad->popup == NULL) {
1726 Evas_Object *obj = (Evas_Object *) data;
1727 val = _calculator_get_input_item(evas_obj, obj);
1728 if (ad->wrong_timer) {
1729 ecore_timer_del(ad->wrong_timer);
1730 ad->wrong_timer = NULL;
1732 _calc_entry_text_set(ad->input_entry, calculator_input_str);
1735 _calc_btn_backspace_clicked(ad->input_entry);
1736 if (ad->calc_timer) {
1737 ecore_timer_del(ad->calc_timer);
1738 ad->calc_timer = NULL;
1741 ecore_timer_add(0.1,
1743 __calculator_delete_long_press,
1747 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1749 _calc_entry_clear(ad->input_entry);
1750 calculator_state = CALCULATOR_WAITING_INPUT;
1756 __calculator_control_normal_func_clicked(ad->
1762 __calculator_op_equal(ad->input_entry);
1765 _calc_btn_dot_clicked(ad->input_entry);
1767 case OP_PARENTHESIS:
1768 __calculator_parenthesis_clicked(ad->input_entry);
1780 __calculator_control_panel_number_button_clicked(ad->
1786 __calculator_symbol_negative_clicked(ad->input_entry);
1788 case OP_PERCENT...OP_E:
1789 __calculator_control_functions_button_clicked(ad->
1797 if (ad->svi_handle) {
1798 svi_play_sound(ad->svi_handle, SVI_SND_TOUCH_SIP);
1799 svi_play_vib(ad->svi_handle, SVI_VIB_TOUCH_SIP);
1806 static void __calculator_wrong_format_delete(Evas_Object *in_entry)
1808 _calc_entry_text_set(in_entry, calculator_input_str);
1809 if (ad->wrong_timer) {
1810 ecore_timer_del(ad->wrong_timer);
1811 ad->wrong_timer = NULL;
1815 static void __calculator_wrong_text_set(char * wrong_string)
1817 char buf[MAX_EXPRESSION_LENGTH] = { 0 };
1818 memset(buf, 0, sizeof(buf));
1819 snprintf(buf, sizeof(buf),
1820 "<align=right><+ font_size=%d><color=#855B11FF>%s",
1821 get_max_fontsize(), wrong_string);
1822 elm_entry_entry_set(ad->input_entry, buf);
1823 elm_entry_cursor_end_set(ad->input_entry);
1824 calc_view_revise_input_scroller(ad);
1835 static void __calculator_wrong_format_create(char * wrong_string)
1837 __calculator_wrong_text_set(wrong_string);
1838 if (ad->wrong_timer) {
1839 ecore_timer_del(ad->wrong_timer);
1840 ad->wrong_timer = NULL;
1845 __calculator_wrong_format_delete,
1849 /* mouse up for delete button. */
1851 __calculator_delelte_up(void *data, Evas * e, Evas_Object * evas_obj,
1854 if (ad->calc_timer) {
1855 ecore_timer_del(ad->calc_timer);
1856 ad->calc_timer = NULL;
1862 * Register clicked callback of the keys on the keypad.
1864 * @param keypad the keypad
1867 static void _calc_view_keypad_cb_register(Evas_Object * keypad)
1869 char *key_name[] = {
1870 "item_per", "item_sqr", "item_fac", "item_c", "item_div",
1871 "item_mul", "item_del",
1872 "item_sin", "item_cos", "item_tan", "item_num7", "item_num8",
1873 "item_num9", "item_sub",
1874 "item_ln", "item_log", "item_1x", "item_num4", "item_num5",
1875 "item_num6", "item_plus",
1876 "item_ex", "item_x2", "item_xy", "item_num1", "item_num2",
1877 "item_num3", "item_brack",
1878 "item_abs", "item_pi", "item_e", "item_num0", "item_dot",
1879 "item_neg", "item_eq",
1882 Evas_Object *item = NULL;
1883 int key_num = sizeof(key_name) / sizeof(key_name[0]);
1886 for (i = 0; i < key_num; ++i) {
1888 (Evas_Object *) edje_object_part_object_get(keypad,
1891 evas_object_event_callback_add(item,
1892 EVAS_CALLBACK_MOUSE_DOWN,
1895 if (0 == strcmp(key_name[i], "item_del")) {
1896 evas_object_event_callback_add(item,
1897 EVAS_CALLBACK_MOUSE_UP,
1898 __calculator_delelte_up,
1908 * The callback of input entry when mouse up.
1910 * @param data unused
1912 * @param entry the input entry
1913 * @param event_info unused
1917 _calc_view_input_entry_mouseup_cb(void *data, Evas * e, Evas_Object * entry,
1920 calculator_cursor_pos = calc_view_cursor_get_position(entry); //for softkey input and mouse move
1924 _calc_view_input_entry_to_str(char *entry_str, char *internal_str, int buf_size)
1926 strncpy(internal_str, entry_str, buf_size - 1);
1927 /* remove result that behind '='(include '=') */
1928 char *enter = strchr(internal_str, '=');
1929 if (enter != NULL) {
1933 calc_expr_replace_from_special_char(internal_str);
1934 /* remove all ',' and '\n'*/
1937 while (internal_str[j] != '\0'){
1939 if (internal_str[j] == separator_ch || internal_str[j] == '\n'){
1942 internal_str[i++] = internal_str[j++];
1945 internal_str[i] = '\0';
1951 _calc_view_input_entry_keyup_cb(void *data, Evas * e, Evas_Object * entry,
1954 calculator_cursor_pos = calc_view_cursor_get_position(entry); //for hardkey input
1956 Evas_Event_Key_Up *evt = (Evas_Event_Key_Up *) event_info;
1957 printf("keyname: %s\n", (char *)evt->keyname);
1958 if ((0 == strcmp(evt->keyname, "XF86Phone"))||
1959 (0 == strcmp(evt->keyname, "XF86PowerOff"))||
1960 (0 == strcmp(evt->keyname, "XF86AudioRaiseVolume"))||
1961 (0 == strcmp(evt->keyname, "XF86AudioLowerVolume"))){
1964 _calc_entry_backspace(ad->input_entry);
1969 _calc_view_input_entry_error_include(char *string)
1972 for(; i < ARRAY_SIZE(error_string); i++)
1974 if(!strcmp(string, _(error_string[i]))){
1983 * The callback of input entry when text changed.
1985 * @param data the appdata
1986 * @param [in]obj the input entry
1987 * @param event_info unused
1991 _calc_view_input_entry_changed_cb(void *data, Evas_Object * obj,
1994 struct appdata *ad = (struct appdata *)data;
1995 PLOG("Input entry test changed\n"); /* Don't remove the log. It can guard against recursion. */
1996 const char *str = (char *)elm_entry_entry_get(obj);
1999 char *entry_tmp = elm_entry_markup_to_utf8(str);
2000 char *entry_expr= elm_entry_markup_to_utf8(entry_tmp);/*because the string format from clipboard is not correct*/
2001 char internal_expr[MAX_EXPRESSION_LENGTH] = { 0 };
2002 char f_number_buf[NUMBER_LENGTH] = { 0 };
2003 char s_number_buf[NUMBER_LENGTH] = { 0 };
2005 _calc_view_input_entry_to_str(entry_expr, internal_expr,
2006 MAX_EXPRESSION_LENGTH);
2008 bool char_in =__calculator_string_invalid_char_search(internal_expr, &index);
2009 __calculator_get_cursor_position_float_string(internal_expr,
2011 calculator_cursor_pos,
2013 int cur_pos = calc_view_cursor_get_position(ad->input_entry);
2014 __calculator_get_cursor_position_float_string(internal_expr,
2018 int nCntOp = calc_expr_get_operator_num(internal_expr);
2020 if ((strlen(f_number_buf) > MAX_NUM_LENGTH)
2021 || (strlen(s_number_buf) > MAX_NUM_LENGTH)) {
2022 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
2023 } else if (nCntOp >= MAX_OPERATOR_NUM) {
2024 __calculator_wrong_format_create(CALC_MSG_MAX_OP);
2027 strncpy(calculator_input_str, internal_expr,
2029 calculator_cursor_pos = index;
2031 strncpy(calculator_input_str, internal_expr,
2032 sizeof(calculator_input_str) - 1);
2033 calculator_cursor_pos = cur_pos;
2035 _calc_entry_text_set(ad->input_entry, calculator_input_str);
2042 char *entry_expr_s = elm_entry_markup_to_utf8(str);
2043 char internal_expr_s[MAX_EXPRESSION_LENGTH] = { 0 };
2044 _calc_view_input_entry_to_str(entry_expr_s, internal_expr_s,
2045 MAX_EXPRESSION_LENGTH);
2046 if(!_calc_view_input_entry_error_include(internal_expr_s)){
2047 /*change calculator_input_str, after cut operation*/
2048 strncpy(calculator_input_str, internal_expr_s,
2049 MAX_EXPRESSION_LENGTH - 1);
2053 * Prevent pasting images into entry.
2054 * If a image pasted, "<item absize=... href=...>" will be appended into entry.
2056 if (strstr(str, "item") != NULL) {
2058 char buf[MAX_EXPRESSION_LENGTH] = { 0 };
2060 while (elm_entry_cursor_prev(obj)) {
2062 } /* save cursor position */
2063 pos -= 1; /* correct */
2065 strncpy(buf, str, sizeof(buf));
2066 char *begin = strstr(buf, "<item");
2067 char *end = strchr(begin, '>');
2068 string_remove_at(buf, begin - buf, end - begin + 1); /* remove "<item...>" */
2069 elm_entry_entry_set(obj, buf);
2072 elm_entry_cursor_next(obj);
2073 } /* retrieve cursor position */
2075 calc_view_revise_input_scroller(ad);
2081 _calc_view_input_entry_paste_cb(void *data, Evas_Object * obj, void *event_info)
2085 strncpy(calculator_before_paste_str, calculator_input_str,
2086 MAX_EXPRESSION_LENGTH - 1);
2087 printf("line = %d\n", __LINE__);
2092 __conv_view_clear_clicked_cb(void *data, Evas_Object * obj, const char *emission, const char *source)
2097 struct appdata *ad = (struct appdata *)data;
2098 elm_entry_entry_set(ad->hist_area, "");
2099 elm_entry_entry_set(ad->input_entry, "");
2100 _calc_view_clear_histroy(ad->hist_area);
2107 * Create an entry for inputing expression.
2109 * @param parent the entry's parent
2110 * @param ad the appdata
2111 * @return Evas_Object* the input entry
2113 static Evas_Object *_calc_view_create_input_entry(Evas_Object * parent,
2117 Evas_Object *entry = elm_entry_add(ad->edje);
2118 elm_entry_single_line_set(entry, EINA_FALSE);
2119 elm_entry_line_wrap_set(entry, ELM_WRAP_WORD);
2120 elm_entry_editable_set(entry, EINA_TRUE);
2121 elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
2122 elm_entry_entry_set(entry, "");
2123 elm_entry_cnp_mode_set(entry, ELM_CNP_MODE_NO_IMAGE);
2124 elm_entry_magnifier_disabled_set(entry, EINA_TRUE);
2125 elm_entry_cursor_end_set(entry);
2126 elm_object_style_set(entry, "black");
2127 evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND,
2129 evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
2131 evas_object_event_callback_add(entry, EVAS_CALLBACK_MOUSE_UP,
2132 _calc_view_input_entry_mouseup_cb, ad);
2133 evas_object_smart_callback_add(entry, "changed",
2134 _calc_view_input_entry_changed_cb, ad);
2135 evas_object_smart_callback_add(entry, "selection,paste",
2136 _calc_view_input_entry_paste_cb, ad);
2138 evas_object_event_callback_add(entry, EVAS_CALLBACK_KEY_UP,
2139 _calc_view_input_entry_keyup_cb, ad);
2141 evas_object_show(entry);
2142 limit_filter_data.max_char_count = 0;
2143 limit_filter_data.max_byte_count = 419 + 20; //19*21+20//result:20
2144 elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size,
2145 &limit_filter_data);
2152 * Create a input scrooler which around the input entry.
2153 * It can give a input entry a scroller.
2155 * @param parent the parent of input scroller
2156 * @return Evas_Object* the input scroller
2159 static Evas_Object *_calc_view_create_input_scroller(Evas_Object * parent)
2162 Evas_Object *scroller = elm_scroller_add(parent);
2163 elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
2164 evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND,
2166 evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL,
2169 evas_object_show(scroller);
2178 * Create the main layout.
2180 * @param parent main layout's parent
2181 * @return Evas_Object* when success return a layout, return NULL oppositely.
2183 static Evas_Object *_calc_view_create_layout_main(Evas_Object * parent)
2187 if (parent == NULL) {
2191 Evas_Object *layout = elm_layout_add(parent);
2192 if (layout == NULL) {
2196 elm_layout_theme_set(layout, "standard", "window", "integration");
2197 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND,
2199 elm_win_resize_object_add(parent, layout);
2201 edje_object_signal_emit(_EDJ(layout), "elm,state,show,content", "elm");
2202 edje_object_signal_emit(_EDJ(layout), "elm,state,show,indicator",
2204 evas_object_show(layout);
2213 * Load the main view of calculator.
2214 * Create the input entry and keypad.
2216 * @param ad the appdata
2219 void calc_view_load(struct appdata *ad)
2223 ad->layout = _calc_view_create_layout_main(ad->win);
2224 ad->edje = load_edj(ad->win, LAYOUT_EDJ_NAME, GRP_MAIN);
2225 evas_object_show(ad->edje);
2226 evas_object_name_set(ad->edje, "edje");
2227 elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->edje);
2229 /* inititialize environment variable */
2230 locale = localeconv();
2231 decimal = locale->decimal_point;
2232 separator = locale->thousands_sep;
2233 int len_seq = strlen(separator);
2234 decimal_ch = decimal[0];
2235 separator_ch = separator[0];
2236 if (len_seq == 2 || len_seq == 0) {
2240 svi_init(&ad->svi_handle);
2243 ad->input_entry = _calc_view_create_input_entry(ad->edje, ad);
2244 ad->input_scroller = _calc_view_create_input_scroller(ad->edje);
2245 elm_object_content_set(ad->input_scroller, ad->input_entry);
2246 edje_object_part_swallow(_EDJ(ad->edje), "input/entry",
2247 ad->input_scroller);
2248 edje_object_signal_callback_add(_EDJ(ad->edje), "clicked", "",
2249 __conv_view_clear_clicked_cb, ad);
2252 ad->por_pannel = load_edj(ad->edje, LAYOUT_EDJ_NAME, GRP_POR_PANNEL);
2253 edje_object_part_swallow(_EDJ(ad->edje), "por_pannel/rect",
2255 edje_object_signal_emit(_EDJ(ad->edje), "portrait", "");
2256 _calc_view_keypad_cb_register(_EDJ(ad->por_pannel));
2264 * assign global variable , this will be removed
2270 void calc_xxx(struct appdata *ap)