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"
31 #define CALCULATOR_CHAR_IS_OPERATOR(C) ((C == '+')||(C == '-')||(C == 'x')||(C == '/')) /**<judge if a char is a basic operator*/
32 #define CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(C) ((C == 'x')||(C == '/')) /**<judge if an operator is "*" or "/"*/
33 #define CALCULATOR_CHAR_IS_PLUS_DEDUCT(C) ((C == '+')||(C == '-'))
34 #define CALCULATOR_CHAR_IS_DIGITAL(C)(C >= '0' && C <= '9')
35 #define CALCULATOR_IS_DIGIT_DOT(ch, decimal) (isdigit(ch) || decimal == (ch))
37 static Elm_Entry_Filter_Limit_Size limit_filter_data;
38 extern void _calc_view_show_newest_histroy(Evas_Object * entry);
39 extern void _calc_view_clear_histroy(Evas_Object * entry);
40 extern gboolean __calculator_search_function(char *op, int* len);
41 static void __calculator_wrong_format_create(char * wrong_string);
42 void calc_view_load(struct appdata *ad);
44 static struct appdata *ad; /* will be removed */
45 static calculator_state_t calculator_state = CALCULATOR_WAITING_INPUT;
46 static double last_result = 0.0;
47 int calculator_cursor_pos = 0;
48 char calculator_input_str[MAX_EXPRESSION_LENGTH] = { 0 };
49 char calculator_before_paste_str[MAX_EXPRESSION_LENGTH] = { 0 };
50 bool paste_flag = FALSE;
52 struct lconv *locale = NULL;
54 char *separator = NULL;
56 char separator_ch = 0;
58 int cur_fontsize = 70;
59 int small_fontsize = 58;
60 int default_fontsize = 0;
63 int scientific_result_len = 8;
65 bool select_mode = FALSE;
67 static op_item_t calc_op_item[] = {
68 {OP_INVALID, "", NULL},
71 {OP_PARENTHESIS, "()", NULL},
72 {OP_DELETE, "<-", NULL},
73 {OP_CLEAR, "C", NULL},
74 {OP_DIVIDE, "/", NULL},
76 {OP_NUM_7, "7", NULL},
77 {OP_NUM_8, "8", NULL},
78 {OP_NUM_9, "9", NULL},
79 {OP_MULTIPLY, "x", NULL},
81 {OP_NUM_4, "4", NULL},
82 {OP_NUM_5, "5", NULL},
83 {OP_NUM_6, "6", NULL},
84 {OP_MINUS, "-", NULL},
86 {OP_NUM_1, "1", NULL},
87 {OP_NUM_2, "2", NULL},
88 {OP_NUM_3, "3", NULL},
92 {OP_NUM_0, "0", NULL},
93 {OP_PLUS_MINUS, "+/-", NULL},
94 {OP_EQUAL, "=", NULL},
97 {OP_PERCENT, "%", NULL},
98 {OP_ROOT, "sqrt", "sqrt("},
101 {OP_SIN, "sin", "sin("},
102 {OP_COS, "cos", "cos("},
103 {OP_TAN, "tan", "tan("},
105 {OP_LN, "ln", "ln("},
106 {OP_LOG, "log", "log("},
107 {OP_1X, "1/x", "1/x"},
109 {OP_10X, "10^x", "10^("},
110 {OP_X2, "x^2", "^2"},
111 {OP_XY, "x^y", "^("},
113 {OP_ABS, "abs", "abs("},
117 char *error_string[] = {
118 "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE",
119 "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE",
120 "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE",
121 "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO",
122 "IDS_CCL_POP_NO_NUMBER_ERROR",
124 "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR",
125 "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION",
126 "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION",
127 "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION",
128 "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION",
129 "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION",
130 "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION",
131 "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION",
132 "IDS_CCL_POP_NO_OPERATOR_ERROR",
133 "IDS_CCL_POP_SYNTAX_ERROR",
134 "IDS_CCL_POP_INPUT_ERROR",
137 calculator_state_t calculator_get_state()
139 return calculator_state;
142 void _calc_add_tag(char *string, char *format_string)
148 char buf[MAX_EXPRESSION_LENGTH] = { 0 };
149 char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
151 while (string[i] != '\0') {
152 if (CALCULATOR_CHAR_IS_DIGITAL(string[i])
153 || string[i] == separator_ch || string[i] == decimal_ch
154 ||( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92')) {
155 if ( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92') {
156 memset(buf, 0, sizeof(buf));
157 snprintf(buf, sizeof(buf),
158 "<align=right><font_size=%d><color=#505050FF>(<align=right><font_size=%d><color=#505050FF>-",
159 cur_fontsize, cur_fontsize);
160 strcat(format_string, buf);
165 while (CALCULATOR_CHAR_IS_DIGITAL(string[i])
166 || string[i] == separator_ch
167 || string[i] == decimal_ch) {
171 strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
172 tmp[end - begin + 1] = '\0';
173 memset(buf, 0, sizeof(buf));
174 snprintf(buf, sizeof(buf),
175 "<align=right><font_size=%d><color=#505050FF>%s",
177 strcat(format_string, buf);
181 while (!CALCULATOR_CHAR_IS_DIGITAL(string[i])
182 && string[i] != separator_ch
183 && string[i] != decimal_ch
184 && string[i] != '\0') {
185 if ( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92') {
192 strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
193 tmp[end - begin + 1] = '\0';
194 memset(buf, 0, sizeof(buf));
195 snprintf(buf, sizeof(buf),
196 "<align=right><font_size=%d><color=#505050FF>%s",
198 strcat(format_string, buf);
207 * Change line and font size when it is needed.
208 * Refer to the auto font resizing rules.
209 * @param tag_text The text with tags.
213 void _calc_add_br(char *tag_text)
216 if (tag_text == NULL) {
219 app_device_orientation_e curr = app_get_device_orientation();
220 if (curr == APP_DEVICE_ORIENTATION_270 || curr == APP_DEVICE_ORIENTATION_90) {
223 int line_valid_num = 0;
224 int whole_valid_num = 0;
225 int operator_tag = -1;
226 int operator_location = -1;
227 /* record is there an operator in one line? */
228 bool operator_flag = FALSE;
229 /* when change to small font, we should rescan the tag_text */
230 bool rescan_flag = FALSE;
232 char buf[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
233 strcpy(buf, tag_text);
237 for ( ; tag_text[i] != '\0' && calculator_input_str[j] != '\0'; ) {
238 while (tag_text[i] == '<') {
239 while (tag_text[i++] != '>') {
244 /* if calculator_input_str[j] is "*" or "/", tag_text[i] would be
245 "\xc3\x97" or "\xc3\xb7" */
246 if (tag_text[i] == calculator_input_str[j] || (tag_text[i] == '\xc3') ||
247 ((tag_text[i] == '\xe2') && (tag_text[i+1] == '\x88') && (tag_text[i+2] == '\x92'))) {
249 if ((CALCULATOR_CHAR_IS_OPERATOR(calculator_input_str[j])) &&
250 (!(calculator_input_str[j] == '-' && calculator_input_str[j-1] == '('))) {
251 if (!operator_flag || rescan_flag) {
252 operator_location = j;
254 operator_flag = TRUE;
261 cur_fontsize = default_fontsize;
264 if ((line_valid_num >= min_len) && (!rescan_flag)) {
266 cur_fontsize = small_fontsize;
267 strcpy(tag_text, buf);
268 /* restore to the original state, then scan from the begin */
273 operator_flag = FALSE;
275 operator_location = -1;
276 cur_len = max_len + 1;
280 if (line_valid_num >= cur_len) {
281 if (operator_flag && operator_tag > 0) {
282 string_insert(tag_text, operator_tag, "<br>");
283 line_valid_num = whole_valid_num-operator_location;
284 operator_flag = FALSE;
286 operator_location = -1;
288 string_insert(tag_text, i, "<br>");
316 static void _calc_entry_text_set(Evas_Object * entry, const char *str)
322 char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
323 char tag_text[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
324 char new_font_str[MAX_EXPRESSION_LENGTH] = { 0 };
325 char old_font_str[MAX_EXPRESSION_LENGTH] = { 0 };
327 Eina_Bool status = elm_entry_editable_get(entry);
328 if (EINA_FALSE == status) {
329 elm_entry_editable_set(entry, EINA_TRUE);//chx add recover the old style
330 elm_entry_line_wrap_set(entry,ELM_WRAP_WORD);
331 elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
332 elm_object_style_set(entry, "black");
333 elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data);
334 elm_entry_text_style_user_push(entry, "DEFAULT='right_margin=32'");
341 if (strlen(str) == 0) {
342 elm_entry_entry_set(entry, "");
343 elm_entry_cursor_end_set(entry);
344 elm_object_focus_set(entry, EINA_TRUE);
348 calc_expr_format_expression(str, tmp);
349 CALC_INFO("ASCII :: expr_out = %s", tmp);
350 CALC_INFO("ASCII :: expr_out = %d", tmp);
351 _calc_add_tag(tmp, tag_text);
352 int pre_fontsize = cur_fontsize;
353 _calc_add_br(tag_text);
354 snprintf(old_font_str, sizeof(old_font_str), "=%d", pre_fontsize);
355 snprintf(new_font_str, sizeof(new_font_str), "=%d", cur_fontsize);
356 string_replace(tag_text, old_font_str, new_font_str);
357 CALC_INFO("ASCII :: tag_text = %s", tag_text);
358 CALC_INFO("ASCII :: tag_text = %d", tag_text);
359 elm_entry_entry_set(entry, tag_text);
360 if(calculator_cursor_pos == strlen(calculator_input_str)){
361 elm_entry_cursor_end_set(entry);
362 elm_object_focus_set(entry, EINA_TRUE);
364 calc_view_cursor_set_position(entry, calculator_cursor_pos);
369 void _calc_entry_text_set_rotate(struct appdata *ad)
372 if (calculator_state == CALCULATOR_CALCULATED) {
373 _calc_view_show_newest_histroy(ad->input_entry);
374 elm_entry_cursor_end_set(ad->input_entry);
375 elm_object_focus_set(ad->input_entry, EINA_TRUE);
377 _calc_entry_text_set(ad->input_entry, calculator_input_str);
391 static void _calc_entry_text_insert(Evas_Object * entry, char *str)
394 CALC_INFO("ASCII :: str = %s", str);
395 CALC_INFO("ASCII :: str = %d", str);
396 calc_expr_input_insert(calculator_input_str, &calculator_cursor_pos, str);
397 _calc_entry_text_set(entry, calculator_input_str);
411 static void _calc_entry_text_remove(Evas_Object * entry, const int from_pos,
415 string_remove_at(calculator_input_str, from_pos,
416 end_pos - from_pos + 1);
417 calculator_cursor_pos = from_pos;
418 _calc_entry_text_set(entry, calculator_input_str);
424 * Set correct cursor position in entry.
430 static void _calc_entry_cursor_set(Evas_Object * entry)
433 calc_view_cursor_set_position(entry, calculator_cursor_pos);
445 static void _calc_entry_backspace(Evas_Object * entry)
448 calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
449 _calc_entry_text_set(entry, calculator_input_str);
461 void _calc_entry_clear(Evas_Object * entry)
464 memset(calculator_input_str, 0, sizeof(calculator_input_str));
465 calculator_cursor_pos = 0;
466 _calc_entry_text_set(entry, "");
467 calc_view_cursor_set_position(entry, calculator_cursor_pos);
471 /* END INPUT ENTRY RELATED */
475 * Get the operand start and end location where the cursor in.
476 * 1.2+6.|43 (cursor is before 4), then return begin=4 end=7
477 * Espcially, cursor is after +, it means the operand which follows
478 * the operator, so it return the same result as before.
479 * This is add by on 2012/5/29
481 * @param[in] text The current calculator input string
482 * @param[out] begin The start location of an operand
483 * @param[out] end The end location of an operand
484 * @return Is cursor in an operand
485 * @retval true The cursor is in the operand
486 * @retval false The cursor is not in the operand
490 __calculator_get_float_num_in_cursor_position(char *text, int cur_pos,
491 int *begin, int *end)
497 int pos = cur_pos - 1;
504 if ('p' == text[pos] || 'e' == text[pos]) {
508 } else if (CALCULATOR_IS_DIGIT_DOT(text[pos], decimal_ch)) {
509 for (_begin = pos - 1;
510 CALCULATOR_IS_DIGIT_DOT(text[_begin], decimal_ch)
511 && _begin >= 0; --_begin) {
515 if (_begin > 1 && '-' == text[_begin - 1]
516 && '(' == text[_begin - 2]) {
520 CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
521 && _end < strlen(text); ++_end) {
529 } else if (CALCULATOR_CHAR_IS_OPERATOR(text[pos]) || text[pos] == '(') {
531 CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
532 && _end < strlen(text); ++_end) {
547 * Get the operand start and end location where the cursor in the operand
548 * Actually, it would call "__calculator_get_float_num_in_cursor_position"
549 * function to recognize whether the cursor is in the operand.
551 * @param[in] entry_text The current calcualtor input string
552 * @param[out] str The operand which the cursor in
553 * @param[out] from The operand start location which contain the cursor
554 * @param[out] end The operand end location which contain the cursor
555 * @return Is cursor in an operand
556 * @retval true The cursor is in the operand
557 * @retval false The cursor is not in the operand
561 __calculator_get_cursor_position_float_string(char *entry_text, char *str,
562 int cur_pos, int *from, int *end)
565 if (entry_text == NULL) {
568 int from_pos = cur_pos;
569 int end_pos = cur_pos;
572 __calculator_get_float_num_in_cursor_position(entry_text, cur_pos, &from_pos, &end_pos)) {
576 /* set from&end position */
584 strncpy(str, entry_text + from_pos, end_pos - from_pos + 1);
585 str[end_pos - from_pos + 1] = '\0';
592 * Get the float number in current cursor
600 __calculator_get_before_cursor_float_string(char *entry_text, char *str)
604 int from_pos = calculator_cursor_pos;
605 int end_pos = calculator_cursor_pos;
607 if (false == __calculator_get_float_num_in_cursor_position(entry_text, calculator_cursor_pos, &from_pos, &end_pos)) {
610 snprintf(str, calculator_cursor_pos - from_pos + 1, "%s", entry_text + from_pos);
617 * Get string before cursor in the Entry.
625 __calculator_get_input_from_begin_to_cursor(char *entry_text, char *str)
629 if (calculator_cursor_pos > 0) {
630 strncpy(str, entry_text, calculator_cursor_pos);
631 str[calculator_cursor_pos] = '\0';
641 * judge the type of current input
647 static last_char_t __calculator_string_get_char_type( char ch_in)
659 if (CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(ch_in)) {
660 return CHAR_IS_MULTIPLY_DIVIDE;
663 return CHAR_IS_LEFT_PARENTHESE;
666 return CHAR_IS_RIGHT_PARENTHESE;
668 if (CALCULATOR_CHAR_IS_DIGITAL(ch_in)) {
669 return CHAR_IS_DIGIT;
671 if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(ch_in) ){
672 return CHAR_IS_PLUS_MINUS;
674 if (ch_in == decimal_ch) {
675 return CHAR_IS_POINT;
677 return CHAR_IS_CHARACTER;
681 static bool __calculator_string_digit_in(const char *input)
684 while(input[i]!='\0'){
685 if(IS_DIGITAL(input[i])){/*here ,digit include "p" and "e"*/
695 * search charactor in input string, if have charactor, return True and index of first charactor;
698 static bool __calculator_string_char_search(const char *input, int *index)
704 int len_cp = strlen(input);
709 for(; i < len_cp ; i++){
710 last_char_t cur_char_type = __calculator_string_get_char_type(input[i]);
711 if (CHAR_IS_CHARACTER == cur_char_type) {
721 * search invalid charactor in input string, if have invalid charactor, return True and index of first invalid charactor;
724 static bool __calculator_string_invalid_char_search(char *input, int *index)
728 bool char_in = FALSE;
730 char_in = __calculator_string_char_search(p, &sub_index);
731 if (!char_in) {/*no charactor*/
737 if (!__calculator_search_function(p, &len)) {/*charactor not a function*/
739 } else {/*the first sevaral charactors are function, continue search*/
743 /*Fix bug that paste did not filter invaild word, beacuse here it jump to
744 * the sub_index directly, but the sub_index would change with the string
745 * So, it should recalculate every time*/
746 char_in = __calculator_string_char_search(p, &sub_index);
766 __calculator_control_panel_number_button_clicked(Evas *e, Evas_Object *entry, op_item_t *op_item)
770 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
772 if (calc_select_string_search(selected_str)) {
773 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym,
774 op_item->op_sym, op_item->op_sym, 0, NULL);
776 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
777 calculator_cursor_pos = strlen(calculator_input_str);
783 /* replace special characters */
784 char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
785 snprintf(entry_text, sizeof(entry_text), "%s", calculator_input_str);
786 //Current state is calculated, clear all
787 if (calculator_state == CALCULATOR_CALCULATED) {
788 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
789 _calc_entry_clear(entry);
790 _calc_entry_text_insert(entry, op_item->op_sym);
791 calculator_state = CALCULATOR_OPERAND_INPUT;
795 char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
796 char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
800 __calculator_get_cursor_position_float_string(entry_text, str_buf, calculator_cursor_pos, NULL, NULL);
801 __calculator_get_input_from_begin_to_cursor(entry_text, before_cursor);
802 before_len = strlen(before_cursor);
803 calculator_get_digits_number(str_buf, &nDigitCnt, &nPointCnt);
804 char str_bufa[MAX_EXPRESSION_LENGTH] = { 0 };
805 __calculator_get_before_cursor_float_string(entry_text, str_bufa);
806 if (strcmp(str_bufa, "0") == 0) {
807 _calc_entry_backspace(entry);
810 if (strlen(str_buf) >= MAX_NUM_LENGTH) {
811 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
813 } else if (nPointCnt >= MAX_DECIMAL_NUM && calculator_cursor_pos > nDigitCnt) {
814 __calculator_wrong_format_create(CALC_MSG_MAX_DEC_DIGIT);
816 } else if (before_len > 0
817 && (__calculator_string_get_char_type(before_cursor[before_len - 1]) ==
819 || __calculator_string_get_char_type(before_cursor[before_len - 1]) ==
821 /* input digital after "e" or "p", the "x" opeartor will be added automatically */
822 _calc_entry_text_insert(entry, "x");
823 _calc_entry_text_insert(entry, op_item->op_sym);
824 calculator_state = CALCULATOR_OPERAND_INPUT;
826 } else if (before_len > 0 && ((before_cursor[before_len - 1] == '(') ||CALCULATOR_CHAR_IS_DIGITAL(before_cursor[before_len - 1])
827 || CALCULATOR_CHAR_IS_OPERATOR(before_cursor[before_len - 1]) || (int)before_cursor[before_len - 1] > 120)) //* or/
829 _calc_entry_text_insert(entry, op_item->op_sym);
830 calculator_state = CALCULATOR_OPERAND_INPUT;
832 } else if (before_len > 0 && (before_cursor[before_len - 1] == ')')) {
833 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
836 _calc_entry_text_insert(entry, op_item->op_sym);
837 calculator_state = CALCULATOR_OPERAND_INPUT;
845 * Deal the event when dot clicked on the keyboard
847 * @param[in] entry The input entry
851 static void _calc_btn_dot_clicked(Evas_Object *entry)
857 char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
860 char decimal_str[32] = { 0 };
862 /* replace special characters */
863 char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
864 strncpy(entry_text, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
866 if (calculator_state == CALCULATOR_CALCULATED) {
867 _calc_entry_clear(entry);
868 memset(entry_text,0x00,sizeof(entry_text));
873 if (!__calculator_get_cursor_position_float_string
874 (entry_text, str_num, calculator_cursor_pos, &from_pos, &end_pos)) {
875 if (calculator_cursor_pos == 0
876 || IS_OPERATOER(calculator_input_str[from_pos - 1])
877 || calculator_input_str[from_pos - 1] == '(') {
878 snprintf(decimal_str, sizeof(decimal_str), "0%c",
880 _calc_entry_text_insert(entry, decimal_str);
881 calculator_state = CALCULATOR_OPERAND_INPUT;
886 if (strcmp(str_num, "p") == 0 || strcmp(str_num, "e") == 0) {
887 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
892 str_num_len = strlen(str_num);
893 if (str_num_len > 0 && str_num[str_num_len - 1] == decimal_ch) {
899 calculator_get_digits_number(str_num, &nDigitCnt, &nPointCnt);
901 if (nDigitCnt >= 15) {
902 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
909 if (IS_OPERATOER(calculator_input_str[calculator_cursor_pos-1])
910 || calculator_input_str[calculator_cursor_pos-1] == '(') {
911 snprintf(decimal_str, sizeof(decimal_str), "0%c", decimal_ch);
913 snprintf(decimal_str, sizeof(decimal_str), "%c", decimal_ch);
915 _calc_entry_text_insert(entry, decimal_str);
916 calculator_state = CALCULATOR_OPERAND_INPUT;
929 static void _calc_btn_backspace_clicked(Evas *e, Evas_Object *entry)
933 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
935 if (calc_select_string_search(selected_str)) {
936 evas_event_feed_key_down(e, "KP_BACKSPACE", "", "", "", 0, NULL);
938 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
939 calculator_cursor_pos = strlen(calculator_input_str);
945 if (calculator_state == CALCULATOR_CALCULATED) {
946 calculator_state = CALCULATOR_OPERATOR_INPUT;
947 if (calculator_cursor_pos > strlen(calculator_input_str)) {
948 calculator_cursor_pos = strlen(calculator_input_str); /* set last position */
951 _calc_entry_backspace(entry);
955 static int __calculator_delete_long_press(void *data)
958 Evas_Object *entry = (Evas_Object *) data;
960 if (calculator_state == CALCULATOR_CALCULATED) {
961 calculator_state = CALCULATOR_OPERATOR_INPUT;
962 if (calculator_cursor_pos > strlen(calculator_input_str)) {
963 calculator_cursor_pos = strlen(calculator_input_str); /* set last position */
966 _calc_entry_backspace(entry);
973 * Process +.-.*.\ these four buttons clicked.
981 __calculator_control_normal_func_clicked(Evas *e,Evas_Object *entry,
986 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
988 if (calc_select_string_search(selected_str)) {
989 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym, op_item->op_sym, op_item->op_sym, 0, NULL);
991 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
992 calculator_cursor_pos = strlen(calculator_input_str);
998 char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
999 strncpy(all_input, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
1001 if (calculator_state == CALCULATOR_CALCULATED) {
1002 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1003 char temp[20] = { 0 };
1005 calc_expr_num_format_result(last_result, temp);
1006 _calc_entry_clear(entry);
1007 //result < 0 or sicience number
1008 if (temp[0] == '-' || strchr(temp, 'E')) {
1009 _calc_entry_text_insert(entry, "(");
1010 _calc_entry_text_insert(entry, temp);
1011 _calc_entry_text_insert(entry, ")");
1013 _calc_entry_text_insert(entry, temp);
1016 _calc_entry_text_insert(entry, op_item->op_sym);
1017 calculator_state = CALCULATOR_OPERATOR_INPUT;
1021 if (!strcmp(op_item->op_sym, "x") ||!strcmp(op_item->op_sym, "/") ||!strcmp(op_item->op_sym, "+")) {
1022 if (!__calculator_string_digit_in(calculator_input_str)) {
1026 int nCntOp = calc_expr_get_operator_num(all_input);
1027 if (nCntOp >= MAX_OPERATOR_NUM) { /* Can't exceed 20 operators */
1028 __calculator_wrong_format_create(CALC_MSG_MAX_OP);
1032 char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1035 __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1036 input_len = strlen(before_cursor);
1038 if (input_len > 0) {
1039 if (before_cursor[input_len - 1] == '(' && !strcmp(op_item->op_sym, "-")) {
1040 _calc_entry_text_insert(entry, op_item->op_sym);
1041 calculator_state = CALCULATOR_OPERATOR_INPUT;
1042 } else if (((input_len > 1) && (before_cursor[input_len - 1] == '-') && (before_cursor[input_len - 2] == '(')) //(-
1043 || /*before_cursor[input_len - 1] == decimal_ch ||*/ before_cursor[input_len - 1] == '(') // . or (
1046 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1048 } else if (IS_OPERATOER(before_cursor[input_len - 1])) {
1049 if ((input_len > 1 || !strcmp(op_item->op_sym, "-"))
1050 || input_len == 1) {
1051 _calc_entry_backspace(entry);
1052 _calc_entry_text_insert(entry, op_item->op_sym);
1053 calculator_state = CALCULATOR_OPERATOR_INPUT;
1055 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1058 } else if (before_cursor[input_len - 1] == ')') //
1060 _calc_entry_text_insert(entry, op_item->op_sym);
1061 calculator_state = CALCULATOR_OPERATOR_INPUT;
1064 if (!IS_DIGITAL(before_cursor[input_len - 1])
1065 && (before_cursor[input_len - 1] != decimal_ch)) {
1066 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1069 _calc_entry_text_insert(entry, op_item->op_sym);
1070 calculator_state = CALCULATOR_OPERATOR_INPUT;
1074 } else { /* before_cursor si empty */
1075 _calc_entry_text_insert(entry, op_item->op_sym);
1076 calculator_state = CALCULATOR_OPERATOR_INPUT;
1089 static void __calculator_symbol_negative_clicked(Evas_Object * entry)
1093 char result[MAX_RESULT_LENGTH] = { 0 };
1095 if (calculator_state == CALCULATOR_CALCULATED) {
1096 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1098 calc_expr_num_format_result(last_result, result);
1099 if (last_result < 0) {
1100 string_remove_at(result, 0, 1); //remove '-'
1102 string_insert(result, 0, "(-"); // add (-xxx)
1103 string_insert(result, strlen(result), ")");
1106 _calc_entry_clear(entry);
1107 _calc_entry_text_insert(entry, result);
1109 calculator_state = CALCULATOR_OPERAND_INPUT;
1110 //use_last_result = 1;
1115 int cursor = calculator_cursor_pos;
1116 int begin = 0, length = 0;
1117 char expr[MAX_EXPRESSION_LENGTH] = { 0 };
1118 strncpy(expr, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
1121 if (expr[cursor] == ')') {
1123 flag = 1; /* before current cursor is ')' */
1127 calc_expr_get_current_num_at_cursor(expr, cursor, &begin,
1129 if (expr[begin] == '-') {
1130 if (begin > 0 && expr[begin - 1] == '('
1131 && expr[begin + length] == ')') {
1132 string_remove_at(expr, begin + length, 1); //remove ')'
1133 string_remove_at(expr, begin - 1, 2); // remove '(-'
1134 calculator_cursor_pos -= flag ? 3 : 2;
1136 string_remove_at(expr, begin, 1);
1137 calculator_cursor_pos -= 1;
1141 if (flag == 1) //not '(-xxx)' but has ')'
1143 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1146 string_insert(expr, begin + length, ")");
1147 string_insert(expr, begin, "(-");
1148 calculator_cursor_pos +=
1149 (((begin + length) ==
1150 calculator_cursor_pos) ? 3 : 2);
1153 strncpy(calculator_input_str, expr, MAX_EXPRESSION_LENGTH - 1);
1155 _calc_entry_text_set(entry, calculator_input_str);
1156 _calc_entry_cursor_set(entry);
1158 calculator_state = CALCULATOR_OPERAND_INPUT;
1161 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1166 /* search the previous operator and value */
1167 static char * __calculator_search_prev_input(char *input_str)
1171 int bracket_number = 0;
1172 char *prev_input = NULL;
1173 for(; i< strlen(input_str); i++) {
1174 if ('(' ==(input_str[i]) ){
1177 if( ')' == input_str[i]){
1180 if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(input_str[i])
1181 || CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(input_str[i])) {
1182 if ( !bracket_number){
1183 prev_input = &input_str[i];
1194 * Deal the event when "=" clicked on the keyboard
1196 * @param[in] entry The input entry
1200 static void __calculator_op_equal(Evas_Object *entry)
1203 if (entry == NULL) {
1206 if (calculator_state == CALCULATOR_CALCULATED) {
1207 /*duplicate previous input operator and value*/
1208 char *p = __calculator_search_prev_input(calculator_input_str);
1212 char prev_input[32] = { 0 };
1213 int len = g_strlcpy(prev_input, p, sizeof(prev_input));
1214 if (len >= sizeof(prev_input)) {
1217 char temp[32] = { 0 };
1218 calc_expr_num_format_result(last_result, temp);
1219 _calc_entry_clear(entry);
1221 if (temp[0] == '-' || strchr(temp, 'E')) {
1222 _calc_entry_text_insert(entry, "(");
1223 _calc_entry_text_insert(entry, temp);
1224 _calc_entry_text_insert(entry, ")");
1226 _calc_entry_text_insert(entry, temp);
1228 _calc_entry_text_insert(entry, prev_input);
1229 calculator_state = CALCULATOR_OPERATOR_INPUT;
1233 char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1234 char result_buf[MAX_RESULT_LENGTH] = { 0 };
1235 char result_format[MAX_RESULT_LENGTH] = { 0 };
1237 char error_msg[MAX_ERROR_MESSAGE_LENGTH] = { 0 };
1238 calc_expr_close_parentheses(calculator_input_str);
1239 _calc_entry_text_set(entry, calculator_input_str);
1240 snprintf(str_buf, sizeof(str_buf), "%s", calculator_input_str);
1241 str_len = strlen(str_buf);
1243 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1247 if (!calculator_calculate(str_buf, &result, error_msg)) {
1248 __calculator_wrong_format_create(error_msg);
1249 calculator_state = CALCULATOR_ERROR_OCCURED;
1252 last_result = result;
1253 memset(result_buf, 0, CALCULATOR_CONTENT_LEN + 1);
1254 calc_expr_num_format_result(result, result_buf);
1257 struct history_item item;
1258 memset(item.expression, 0, sizeof(item.expression));
1259 memset(result_format, 0, sizeof(result_format));
1260 calc_expr_format_expression(calculator_input_str,
1262 item.result = result;
1263 calc_expr_format_expression(result_buf, result_format);
1264 if (result_buf[0] == '-') {
1265 string_replace(result_format, "\xe2\x88\x92", "-");
1268 calc_view_save_history(&item);
1271 calculator_state = CALCULATOR_CALCULATED;
1272 calc_view_show_result(result_format, ad);
1286 static void __calculator_parenthesis_clicked(Evas_Object * entry)
1289 char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1290 snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
1291 if (calculator_state == CALCULATOR_CALCULATED) {
1292 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1294 char temp[MAX_RESULT_LENGTH] = { 0 };
1296 calc_expr_num_format_result(last_result, temp);
1297 _calc_entry_clear(entry);
1299 if (temp[0] == '-' || strchr(temp, 'E') != NULL) //result < 0 or science number
1301 _calc_entry_text_insert(entry, "((");
1302 _calc_entry_text_insert(entry, temp);
1303 _calc_entry_text_insert(entry, ")");
1305 _calc_entry_text_insert(entry, "(");
1306 _calc_entry_text_insert(entry, temp);
1308 calculator_state = CALCULATOR_OPERATOR_INPUT;
1311 char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1313 __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1314 input_len = strlen(before_cursor);
1316 if (input_len == 0) {
1317 _calc_entry_text_insert(entry, "(");
1318 calculator_state = CALCULATOR_OPERATOR_INPUT;
1321 int bracket_num = calculator_get_open_braket(all_input);
1322 if (input_len > 0) {
1323 if (before_cursor[input_len - 1] == decimal_ch) {
1324 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1326 } else if (bracket_num > 0 //'(' is more than ')'
1327 && before_cursor[input_len - 1] != '('
1328 && (before_cursor[input_len - 1] == ')'
1329 || isdigit(before_cursor[input_len - 1])
1331 (__calculator_string_get_char_type
1332 (before_cursor[input_len - 1]) == CHAR_IS_PI
1334 __calculator_string_get_char_type
1335 (before_cursor[input_len - 1]) == CHAR_IS_E))) {
1336 _calc_entry_text_insert(entry, ")");
1338 } else if (bracket_num == 0) {
1339 if (calc_expr_get_left_parentheses_num
1340 (calculator_input_str) < MAX_PARENTHESES_NUM) {
1341 _calc_entry_text_insert(entry, "(");
1344 } else if (before_cursor[input_len - 1] != ')') //'(' is less than ')'!isdigit(before_cursor[input_len-1])&&(
1346 if (calc_expr_get_left_parentheses_num
1347 (calculator_input_str) < MAX_PARENTHESES_NUM) {
1348 _calc_entry_text_insert(entry, "(");
1367 __calculator_control_functions_button_clicked(Evas *e, Evas_Object *entry, op_item_t *op_item)
1372 function_t function = { 0 };
1374 memset(&function, 0x0, sizeof(function_t));
1375 str = op_item->op_name;
1377 char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1379 char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1381 last_char_t last_char_type = 0;
1383 snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
1384 __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1385 input_len = strlen(all_input);
1386 before_len = strlen(before_cursor);
1388 last_char_type = __calculator_string_get_char_type(before_cursor[before_len - 1]);
1391 switch (op_item->op_id) {
1394 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1395 calculator_cursor_pos = strlen(calculator_input_str);
1398 /* if it is calculated state */
1399 if (calculator_state == CALCULATOR_CALCULATED) {
1400 edje_object_signal_emit(_EDJ(ad->edje), "show,input","");
1402 char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1403 double per_result = last_result / 100.0;
1405 calc_expr_num_format_result(per_result, temp);
1406 _calc_entry_clear(entry);
1408 if (strcmp(temp, "0") == 0) {
1409 _calc_entry_text_insert(entry, "0");
1410 } else if (temp[0] == '-') //result < 0
1412 _calc_entry_text_insert(entry, "(");
1413 _calc_entry_text_insert(entry, temp);
1414 _calc_entry_text_insert(entry, ")");
1416 _calc_entry_text_insert(entry, temp);
1418 calculator_state = CALCULATOR_OPERAND_INPUT;
1423 int from_pos, end_pos;
1424 char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
1425 char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1426 double per_result = 0.0;
1428 if (false == __calculator_get_cursor_position_float_string(all_input, str_num, calculator_cursor_pos, &from_pos, &end_pos)) {
1429 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1430 calculator_cursor_pos = strlen(calculator_input_str);
1435 if (strlen(str_num) == 0) {
1436 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1440 if (strcmp(str_num, "0") == 0) {
1444 per_result = atof(str_num);
1445 per_result /= 100.0;
1447 calc_expr_num_format_result(per_result, temp);
1449 _calc_entry_text_remove(entry, from_pos, end_pos);
1450 _calc_entry_text_insert(entry, temp);
1452 calculator_state = CALCULATOR_OPERAND_INPUT;
1459 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1460 calculator_cursor_pos = strlen(calculator_input_str);
1463 if (calculator_state == CALCULATOR_CALCULATED) {
1464 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1466 _calc_entry_clear(entry);
1467 _calc_entry_text_insert(entry, op_item->op_name);
1470 if ((before_len != 0) && (!IS_DIGITAL(before_cursor[before_len - 1]))
1471 && (!IS_OPERATOER(before_cursor[before_len - 1]))
1472 && (before_cursor[before_len - 1] != '(')
1473 && (before_cursor[before_len - 1] != 'P')
1474 && before_cursor[before_len - 1] != 'C') {
1475 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1478 /* input digital after "p", the "x" opeartor will be added automatically */
1479 if(IS_DIGITAL(before_cursor[before_len - 1])){
1480 _calc_entry_text_insert(entry, "x");
1482 _calc_entry_text_insert(entry, op_item->op_name);
1487 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1488 calculator_cursor_pos = strlen(calculator_input_str);
1491 if (calculator_state == CALCULATOR_CALCULATED) {
1492 edje_object_signal_emit(_EDJ(ad->edje), "show,input","");
1493 _calc_entry_clear(entry);
1494 _calc_entry_text_insert(entry, op_item->op_name);
1497 if ((before_len != 0) && (!IS_DIGITAL(before_cursor[before_len - 1]))
1498 && (!IS_OPERATOER(before_cursor[before_len - 1]))
1499 && (before_cursor[before_len - 1] != '(')
1500 && (before_cursor[before_len - 1] != 'P')
1501 && before_cursor[before_len - 1] != 'C') {
1502 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1505 /* input digital after "e", the "x" opeartor will be added automatically */
1506 if(IS_DIGITAL(before_cursor[before_len - 1])){
1507 _calc_entry_text_insert(entry, "x");
1509 _calc_entry_text_insert(entry, op_item->op_name);
1512 case OP_SIN: //sin()
1513 case OP_COS: //cos()
1514 case OP_TAN: //tan()
1515 case OP_LOG: //log()
1516 case OP_ABS: //abs()
1518 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
1520 if (calc_select_string_search(selected_str)) {
1521 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym,
1522 op_item->op_name, op_item->op_sym, 0, NULL);
1524 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1525 calculator_cursor_pos = strlen(calculator_input_str);
1527 SFREE(selected_str);
1531 if (calculator_state == CALCULATOR_CALCULATED) {
1532 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1534 _calc_entry_clear(entry);
1535 _calc_entry_text_insert(entry, op_item->op_name);
1538 if (last_char_type == CHAR_IS_PI || last_char_type == CHAR_IS_E) {
1539 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1543 _calc_entry_text_insert(entry, op_item->op_name);
1548 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
1550 if (calc_select_string_search(selected_str)) {
1551 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym, op_item->op_name,
1552 op_item->op_sym, 0, NULL);
1554 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1555 calculator_cursor_pos = strlen(calculator_input_str);
1557 SFREE(selected_str);
1561 if (calculator_state == CALCULATOR_CALCULATED) {
1562 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1564 _calc_entry_clear(entry);
1565 _calc_entry_text_insert(entry, op_item->op_name);
1568 if (last_char_type == CHAR_IS_PI) {
1569 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1572 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1573 && (before_cursor[before_len - 1] != '-')
1574 && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1575 && (before_cursor[before_len - 1] != '^')
1576 && (before_cursor[before_len - 1] != '(')
1577 && (before_cursor[before_len - 1] != 'C')
1578 && (before_cursor[before_len - 1] != 'P')) {
1579 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1582 _calc_entry_text_insert(entry, op_item->op_name);
1585 case OP_ROOT: //sqrt()
1587 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
1589 if (calc_select_string_search(selected_str)) {
1590 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym, op_item->op_name,
1591 op_item->op_sym, 0, NULL);
1593 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1594 calculator_cursor_pos = strlen(calculator_input_str);
1596 SFREE(selected_str);
1600 if (calculator_state == CALCULATOR_CALCULATED) {
1601 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1604 _calc_entry_clear(entry);
1605 _calc_entry_text_insert(entry, op_item->op_name);
1608 if (last_char_type == CHAR_IS_PI) {
1609 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1612 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1613 && (before_cursor[before_len - 1] != '-')
1614 && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1615 && (before_cursor[before_len - 1] != '^')
1616 && (before_cursor[before_len - 1] != '(')
1617 && (before_cursor[before_len - 1] != 'C')
1618 && (before_cursor[before_len - 1] != 'P')) {
1619 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1622 _calc_entry_text_insert(entry, op_item->op_name);
1626 if (calculator_state == CALCULATOR_CALCULATED) {
1627 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1628 _calc_entry_clear(entry);
1629 _calc_entry_text_insert(entry, op_item->op_name);
1632 if (last_char_type == CHAR_IS_PI) {
1633 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1636 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1637 && (before_cursor[before_len - 1] != '-')
1638 && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1639 && (before_cursor[before_len - 1] != '^')
1640 && (before_cursor[before_len - 1] != '(')
1641 && (before_cursor[before_len - 1] != 'C')
1642 && (before_cursor[before_len - 1] != 'P')) {
1643 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1646 _calc_entry_text_insert(entry, op_item->op_name);
1650 if (calculator_state == CALCULATOR_CALCULATED) {
1651 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1653 char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1654 calc_expr_num_format_result(last_result, temp);
1655 _calc_entry_clear(entry);
1657 if (temp[0] == '-' || strchr(temp, 'E')) //result < 0 or science number
1659 _calc_entry_text_insert(entry, "(");
1660 _calc_entry_text_insert(entry, temp);
1661 _calc_entry_text_insert(entry, ")");
1663 _calc_entry_text_insert(entry, temp);
1665 _calc_entry_text_insert(entry, op_item->op_name);
1666 calculator_state = CALCULATOR_OPERAND_INPUT;
1667 //use_last_result = 1;
1671 if (input_len == 0) {
1672 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
1675 if (last_char_type == CHAR_IS_PI) {
1676 _calc_entry_text_insert(entry, op_item->op_name);
1677 calculator_state = CALCULATOR_OPERAND_INPUT;
1679 } else if ((before_len > 0)
1680 && (!isdigit(before_cursor[before_len - 1]))
1681 && (before_cursor[before_len - 1] != ')')) {
1682 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
1685 _calc_entry_text_insert(entry, op_item->op_name);
1686 calculator_state = CALCULATOR_OPERAND_INPUT;
1689 if (calculator_state == CALCULATOR_CALCULATED) {
1690 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1693 char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1695 calc_expr_num_format_result(last_result, temp);
1696 _calc_entry_clear(entry);
1698 if (temp[0] == '-' || strchr(temp, 'E')) //result < 0 or science number
1700 _calc_entry_text_insert(entry, "(");
1701 _calc_entry_text_insert(entry, temp);
1702 _calc_entry_text_insert(entry, ")");
1704 _calc_entry_text_insert(entry, temp);
1706 _calc_entry_text_insert(entry, op_item->op_name);
1707 calculator_state = CALCULATOR_OPERATOR_INPUT;
1711 if (input_len == 0) {
1712 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
1715 if ((last_char_type == CHAR_IS_PI)
1716 || (last_char_type == CHAR_IS_E)) {
1717 _calc_entry_text_insert(entry, op_item->op_name);
1718 calculator_state = CALCULATOR_OPERATOR_INPUT;
1720 } else if ((before_len > 0)
1721 && !isdigit(before_cursor[before_len - 1])
1722 && (before_cursor[before_len - 1] != ')')) {
1723 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
1726 _calc_entry_text_insert(entry, op_item->op_name);
1727 calculator_state = CALCULATOR_OPERATOR_INPUT;
1732 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1733 calculator_cursor_pos = strlen(calculator_input_str);
1736 if (calculator_state == CALCULATOR_CALCULATED) {
1737 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1740 char temp[MAX_RESULT_LENGTH] = { 0 };
1742 calc_expr_num_format_result(last_result, temp);
1744 if (strchr(temp, decimal_ch) != NULL || strchr(temp, '-') != NULL) //revise by bfl
1746 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1747 calculator_state = CALCULATOR_WAITING_INPUT; //revise by bfl
1751 _calc_entry_clear(entry);
1752 _calc_entry_text_insert(entry, "(");
1753 _calc_entry_text_insert(entry, temp);
1754 _calc_entry_text_insert(entry, "!)");
1756 calculator_state = CALCULATOR_OPERATOR_INPUT;
1760 if (input_len == 0) {
1761 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_FAC);
1764 if ((last_char_type == CHAR_IS_PI)
1765 || (last_char_type == CHAR_IS_E)) {
1766 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1770 /* check if it is natural */
1772 char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1773 int from_pos = 0, end_pos = 0;
1776 __calculator_get_cursor_position_float_string
1777 (all_input, str_buf, calculator_cursor_pos,
1778 &from_pos, &end_pos)) {
1779 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1783 if (strchr(str_buf, decimal_ch) != NULL
1784 || str_buf[0] == '-') {
1785 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1789 _calc_entry_text_remove(entry, from_pos, end_pos);
1790 _calc_entry_text_insert(entry, "(");
1791 _calc_entry_text_insert(entry, str_buf);
1792 _calc_entry_text_insert(entry, "!)");
1793 calculator_state = CALCULATOR_OPERATOR_INPUT;
1797 if (calculator_state == CALCULATOR_CALCULATED) {
1798 edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1801 char temp[MAX_RESULT_LENGTH] = { 0 };
1804 calc_expr_num_format_result(last_result, temp);
1805 if (strchr(temp, 'E') != NULL) //science number
1807 temp[strlen(temp)] = ')';
1808 for (i = strlen(temp); i > 0; --i) {
1809 temp[i] = temp[i - 1];
1814 _calc_entry_clear(entry);
1815 if (temp[0] == '-') {
1816 _calc_entry_text_insert(entry, "(-1");
1817 _calc_entry_text_insert(entry, "/");
1819 _calc_entry_text_insert(entry, &temp[1]);
1820 _calc_entry_text_insert(entry, ")");
1822 _calc_entry_text_insert(entry, "(1");
1823 _calc_entry_text_insert(entry, "/");
1825 _calc_entry_text_insert(entry, temp);
1826 _calc_entry_text_insert(entry, ")");
1829 calculator_state = CALCULATOR_OPERATOR_INPUT;
1830 //use_last_result = 1;
1833 if (input_len == 0) {
1834 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
1838 /* check if it is digit */
1840 char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1841 int from_pos = 0, end_pos = 0;
1844 __calculator_get_cursor_position_float_string
1845 (all_input, str_buf, calculator_cursor_pos,
1846 &from_pos, &end_pos)) {
1847 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
1851 if (strcmp(str_buf, "p") && strcmp(str_buf, "e")
1852 && atof(str_buf) == 0) {
1853 __calculator_wrong_format_create(CALC_MSG_DIVIDE_BY_ZERO);
1857 _calc_entry_text_remove(entry, from_pos, end_pos);
1858 if (str_buf[0] == '-') {
1859 _calc_entry_text_insert(entry, "(-1");
1860 _calc_entry_text_insert(entry, "/");
1862 _calc_entry_text_insert(entry, &str_buf[1]);
1863 _calc_entry_text_insert(entry, ")");
1865 _calc_entry_text_insert(entry, "(1");
1866 _calc_entry_text_insert(entry, "/");
1868 _calc_entry_text_insert(entry, str_buf);
1869 _calc_entry_text_insert(entry, ")");
1872 calculator_state = CALCULATOR_OPERATOR_INPUT;
1879 calculator_state = CALCULATOR_SPECIAL_FUNCTION_INPUT;
1884 /////////////////////////// input text finish ////////////////////////////
1895 static int _calculator_get_input_item(Evas_Object * evas_obj, Evas_Object * obj)
1900 if (evas_obj == edje_object_part_object_get(obj, "item_brack")) {
1901 val = OP_PARENTHESIS;
1902 } else if (evas_obj == edje_object_part_object_get(obj, "item_del")) {
1904 } else if (evas_obj == edje_object_part_object_get(obj, "item_c")) {
1906 } else if (evas_obj == edje_object_part_object_get(obj, "item_div")) {
1908 } else if (evas_obj == edje_object_part_object_get(obj, "item_num7")) {
1910 } else if (evas_obj == edje_object_part_object_get(obj, "item_num8")) {
1912 } else if (evas_obj == edje_object_part_object_get(obj, "item_num9")) {
1914 } else if (evas_obj == edje_object_part_object_get(obj, "item_mul")) {
1916 } else if (evas_obj == edje_object_part_object_get(obj, "item_num4")) {
1918 } else if (evas_obj == edje_object_part_object_get(obj, "item_num5")) {
1920 } else if (evas_obj == edje_object_part_object_get(obj, "item_num6")) {
1922 } else if (evas_obj == edje_object_part_object_get(obj, "item_sub")) {
1924 } else if (evas_obj == edje_object_part_object_get(obj, "item_num1")) {
1926 } else if (evas_obj == edje_object_part_object_get(obj, "item_num2")) {
1928 } else if (evas_obj == edje_object_part_object_get(obj, "item_num3")) {
1930 } else if (evas_obj == edje_object_part_object_get(obj, "item_plus")) {
1932 } else if (evas_obj == edje_object_part_object_get(obj, "item_dot")) {
1934 } else if (evas_obj == edje_object_part_object_get(obj, "item_num0")) {
1936 } else if (evas_obj == edje_object_part_object_get(obj, "item_neg")) {
1937 val = OP_PLUS_MINUS;
1938 } else if (evas_obj == edje_object_part_object_get(obj, "item_eq")) {
1940 } else if (evas_obj == edje_object_part_object_get(obj, "item_per")) {
1942 } else if (evas_obj == edje_object_part_object_get(obj, "item_sqr")) {
1944 } else if (evas_obj == edje_object_part_object_get(obj, "item_fac")) {
1946 } else if (evas_obj == edje_object_part_object_get(obj, "item_sin")) {
1948 } else if (evas_obj == edje_object_part_object_get(obj, "item_cos")) {
1950 } else if (evas_obj == edje_object_part_object_get(obj, "item_tan")) {
1952 } else if (evas_obj == edje_object_part_object_get(obj, "item_ln")) {
1954 } else if (evas_obj == edje_object_part_object_get(obj, "item_log")) {
1956 } else if (evas_obj == edje_object_part_object_get(obj, "item_1x")) {
1958 } else if (evas_obj == edje_object_part_object_get(obj, "item_10x")) {
1960 } else if (evas_obj == edje_object_part_object_get(obj, "item_x2")) {
1962 } else if (evas_obj == edje_object_part_object_get(obj, "item_xy")) {
1964 } else if (evas_obj == edje_object_part_object_get(obj, "item_abs")) {
1966 } else if (evas_obj == edje_object_part_object_get(obj, "item_pi")) {
1968 } else if (evas_obj == edje_object_part_object_get(obj, "item_e")) {
1975 /////////////////////////// input text finish ////////////////////////////
1987 static int _calculator_get_input_item_hd(const char *keyname, Evas_Object * obj)
1991 if (0 == strcmp(keyname, "KP_7")) {
1993 } else if (0 == strcmp(keyname, "KP_8")) {
1995 } else if (0 == strcmp(keyname, "KP_9")) {
1997 } else if (0 == strcmp(keyname, "KP_4")) {
1999 } else if (0 == strcmp(keyname, "KP_5")) {
2001 } else if (0 == strcmp(keyname, "KP_6")) {
2003 } else if (0 == strcmp(keyname, "KP_1")) {
2005 } else if (0 == strcmp(keyname, "KP_2")) {
2007 } else if (0 == strcmp(keyname, "KP_3")) {
2009 } else if (0 == strcmp(keyname, "KP_0")) {
2011 }else if (0 == strcmp(keyname, "KP_Decimal")) {
2013 } else if (0 == strcmp(keyname, "Return")) {
2015 } else if (0 == strcmp(keyname, "KP_Add")) {
2017 } else if (0 == strcmp(keyname, "KP_Subtract")) {
2019 } else if (0 == strcmp(keyname, "minus")) {
2021 } else if (0 == strcmp(keyname, "KP_Multiply")) {
2023 } else if (0 == strcmp(keyname, "slash")) {
2025 } else if (0 == strcmp(keyname, "KP_Divide")) {
2027 }else if (0 == strcmp(keyname, "BackSpace")) {
2037 * Interpret all of our different signals, and do things !
2047 _calculator_interp(void *data, Evas * e, Evas_Object * evas_obj, void *event_info)
2054 Evas_Object *obj = (Evas_Object *) data;
2055 val = _calculator_get_input_item(evas_obj, obj);
2056 if (ad->wrong_timer) {
2057 ecore_timer_del(ad->wrong_timer);
2058 ad->wrong_timer = NULL;
2062 _calc_btn_backspace_clicked(e, ad->input_entry);
2063 if (ad->calc_timer) {
2064 ecore_timer_del(ad->calc_timer);
2065 ad->calc_timer = NULL;
2068 ecore_timer_add(0.1, (Ecore_Task_Cb)__calculator_delete_long_press, ad->input_entry);
2071 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
2072 _calc_entry_clear(ad->input_entry);
2073 calculator_state = CALCULATOR_WAITING_INPUT;
2079 __calculator_control_normal_func_clicked(e, ad->input_entry, &calc_op_item[val]);
2082 _calc_btn_dot_clicked(ad->input_entry);
2084 case OP_PARENTHESIS:
2085 __calculator_parenthesis_clicked(ad->input_entry);
2088 __calculator_op_equal(ad->input_entry);
2100 __calculator_control_panel_number_button_clicked(e, ad->input_entry, &calc_op_item[val]);
2103 __calculator_symbol_negative_clicked(ad->input_entry);
2105 case OP_PERCENT...OP_E:
2106 __calculator_control_functions_button_clicked(e, ad->input_entry, &calc_op_item[val]);
2111 if (val == OP_DELETE) {
2112 feedback_play(FEEDBACK_PATTERN_SIP_BACKSPACE);
2114 feedback_play(FEEDBACK_PATTERN_SIP);
2121 static void __calculator_wrong_format_delete(Evas_Object *in_entry)
2123 _calc_entry_text_set(in_entry, calculator_input_str);
2124 if (ad->wrong_timer) {
2125 ecore_timer_del(ad->wrong_timer);
2126 ad->wrong_timer = NULL;
2130 static void __calculator_wrong_text_set(char * wrong_string)
2132 char buf[MAX_EXPRESSION_LENGTH] = { 0 };
2134 memset(buf, 0, sizeof(buf));
2135 snprintf(buf, sizeof(buf),
2136 "<align=right><+ font_size=%d><color=#855B11FF>%s",
2137 fontsize, wrong_string);
2138 elm_entry_editable_set(ad->input_entry, EINA_FALSE);//chx add avoid the word splited
2139 elm_entry_line_wrap_set(ad->input_entry,ELM_WRAP_MIXED);
2140 elm_entry_input_panel_enabled_set(ad->input_entry, EINA_FALSE);
2141 elm_entry_entry_set(ad->input_entry, buf);
2142 elm_entry_cursor_end_set(ad->input_entry);
2143 elm_object_focus_set(ad->input_entry, EINA_TRUE);
2144 calc_view_revise_input_scroller(ad);
2155 static void __calculator_wrong_format_create(char * wrong_string)
2157 __calculator_wrong_text_set(wrong_string);
2158 if (ad->wrong_timer) {
2159 ecore_timer_del(ad->wrong_timer);
2160 ad->wrong_timer = NULL;
2162 ad->wrong_timer = ecore_timer_add(3, (Ecore_Task_Cb)__calculator_wrong_format_delete, ad->input_entry);
2165 /* mouse up for delete button. */
2167 __calculator_delelte_up(void *data, Evas * e, Evas_Object * evas_obj,
2171 if (ad->calc_timer) {
2172 ecore_timer_del(ad->calc_timer);
2173 ad->calc_timer = NULL;
2180 * Register clicked callback of the keys on the keypad.
2182 * @param keypad the keypad
2185 void _calc_view_keypad_cb_register(Evas_Object * keypad)
2188 char *key_name[] = {
2189 "item_per", "item_sqr", "item_fac", "item_c", "item_div",
2190 "item_mul", "item_del",
2191 "item_sin", "item_cos", "item_tan", "item_num7", "item_num8",
2192 "item_num9", "item_sub",
2193 "item_ln", "item_log", "item_1x", "item_num4", "item_num5",
2194 "item_num6", "item_plus",
2195 "item_10x", "item_x2", "item_xy", "item_num1", "item_num2",
2196 "item_num3", "item_brack",
2197 "item_abs", "item_pi", "item_e", "item_num0", "item_dot",
2198 "item_neg", "item_eq",
2201 Evas_Object *item = NULL;
2202 int key_num = sizeof(key_name) / sizeof(key_name[0]);
2205 for (i = 0; i < key_num; ++i) {
2207 (Evas_Object *) edje_object_part_object_get(keypad,
2210 evas_object_event_callback_add(item, EVAS_CALLBACK_MOUSE_DOWN, _calculator_interp, (void *)keypad);
2211 if (0 == strcmp(key_name[i], "item_del")) {
2212 evas_object_event_callback_add(item,
2213 EVAS_CALLBACK_MOUSE_UP,
2214 __calculator_delelte_up,
2225 * The callback of input entry when mouse up.
2227 * @param data unused
2229 * @param entry the input entry
2230 * @param event_info unused
2234 _calc_view_input_entry_mouseup_cb(void *data, Evas * e, Evas_Object * entry,
2236 { if (data == NULL) {
2239 /* if entry is showing warning message, then input operation is unavailable, just return*/
2240 struct appdata *ad = (struct appdata *)data;
2241 if (ad->wrong_timer) {
2244 calculator_cursor_pos = calc_view_cursor_get_position(entry); //for softkey input and mouse move
2248 _calc_view_input_entry_to_str(char *entry_str, char *internal_str, int buf_size)
2251 if (entry_str == NULL) {
2254 strncpy(internal_str, entry_str, buf_size - 1);
2255 /* remove result that behind '='(include '=') */
2256 char *enter = strchr(internal_str, '=');
2257 if (enter != NULL) {
2261 calc_expr_replace_from_special_char(internal_str);
2262 /* remove all ',' and '\n'*/
2265 while (internal_str[j] != '\0'){
2267 if (internal_str[j] == separator_ch || internal_str[j] == '\n'){
2270 internal_str[i++] = internal_str[j++];
2273 internal_str[i] = '\0';
2279 _calc_view_input_entry_keyup_cb(void *data, Evas * e, Evas_Object * entry,
2283 calculator_cursor_pos = calc_view_cursor_get_position(entry); //for hardkey input
2286 Evas_Object *obj = (Evas_Object *) data;
2287 Evas_Event_Key_Up *evt = (Evas_Event_Key_Up *) event_info;
2288 if (0 == strcmp(evt->key, "Return")) {
2289 //calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
2290 __calculator_op_equal(entry);
2293 val = _calculator_get_input_item_hd(evt->key, obj);
2299 __calculator_control_normal_func_clicked(e, ad->input_entry, &calc_op_item[val]);
2302 _calc_btn_dot_clicked(ad->input_entry);
2314 __calculator_control_panel_number_button_clicked(e, ad-> input_entry, &calc_op_item[val]);
2317 calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
2328 _calc_view_input_entry_error_include(char *string)
2331 for(; i < ARRAY_SIZE(error_string); i++)
2333 if(!strcmp(string, _(error_string[i]))){
2342 * The callback of input entry when text changed
2344 * @param[in] data the appdata
2345 * @param[in] obj the input entry
2346 * @param[in] event_info unused
2350 _calc_view_input_entry_changed_cb(void *data, Evas_Object *obj,
2354 if (data == NULL || obj == NULL) {
2357 struct appdata *ad = (struct appdata *)data;
2358 const char *str = (char *)elm_entry_entry_get(obj);
2361 char *entry_tmp = elm_entry_markup_to_utf8(str);
2362 char *entry_expr= elm_entry_markup_to_utf8(entry_tmp);/*because the string format from clipboard is not correct*/
2363 char internal_expr[MAX_EXPRESSION_LENGTH] = { 0 };
2364 char f_number_buf[NUMBER_LENGTH] = { 0 };
2365 char s_number_buf[NUMBER_LENGTH] = { 0 };
2367 _calc_view_input_entry_to_str(entry_expr, internal_expr, MAX_EXPRESSION_LENGTH);
2369 bool char_in =__calculator_string_invalid_char_search(internal_expr, &index);
2370 __calculator_get_cursor_position_float_string(internal_expr, f_number_buf, calculator_cursor_pos, NULL, NULL);
2371 int cur_pos = calc_view_cursor_get_position(ad->input_entry);
2372 __calculator_get_cursor_position_float_string(internal_expr, s_number_buf, cur_pos, NULL, NULL);
2373 int nCntOp = calc_expr_get_operator_num(internal_expr);
2375 if ((strlen(f_number_buf) > MAX_NUM_LENGTH) || (strlen(s_number_buf) > MAX_NUM_LENGTH)) {
2376 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
2377 } else if (nCntOp >= MAX_OPERATOR_NUM) {
2378 __calculator_wrong_format_create(CALC_MSG_MAX_OP);
2381 strncpy(calculator_input_str, internal_expr, index);
2382 calculator_cursor_pos = index;
2384 strncpy(calculator_input_str, internal_expr, sizeof(calculator_input_str) - 1);
2385 calculator_cursor_pos = cur_pos;
2387 _calc_entry_text_set(ad->input_entry, calculator_input_str);
2400 char *entry_expr_s = elm_entry_markup_to_utf8(str);
2401 char internal_expr_s[MAX_EXPRESSION_LENGTH] = { 0 };
2402 _calc_view_input_entry_to_str(entry_expr_s, internal_expr_s, MAX_EXPRESSION_LENGTH);
2403 if(!_calc_view_input_entry_error_include(internal_expr_s)){
2404 /*change calculator_input_str, after cut operation*/
2405 if(calculator_state == CALCULATOR_CALCULATED){
2406 calculator_state = CALCULATOR_OPERAND_INPUT;
2408 strncpy(calculator_input_str, internal_expr_s, MAX_EXPRESSION_LENGTH - 1);
2409 calculator_cursor_pos = calc_view_cursor_get_position(obj);
2411 _calc_entry_text_set(obj, calculator_input_str);
2414 entry_expr_s = NULL;
2419 * Prevent pasting images into entry.
2420 * If a image pasted, "<item absize=... href=...>" will be appended into entry.
2422 if (strstr(str, "item") != NULL) {
2424 char buf[MAX_EXPRESSION_LENGTH] = { 0 };
2426 while (elm_entry_cursor_prev(obj)) {
2428 } /* save cursor position */
2429 pos -= 1; /* correct */
2431 strncpy(buf, str, sizeof(buf));
2432 char *begin = strstr(buf, "<item");
2433 if (begin != NULL) {
2434 char *end = strchr(begin, '>');
2435 string_remove_at(buf, begin - buf, end - begin + 1); /* remove "<item...>" */
2436 elm_entry_entry_set(obj, buf);
2440 elm_entry_cursor_next(obj);
2441 } /* retrieve cursor position */
2443 calc_view_revise_input_scroller(ad);
2449 _calc_view_input_entry_paste_cb(void *data, Evas_Object * obj, void *event_info)
2453 strncpy(calculator_before_paste_str, calculator_input_str,
2454 MAX_EXPRESSION_LENGTH - 1);
2459 _calc_view_input_entry_select_start_cb(void *data, Evas_Object * obj, void *event_info)
2467 _calc_view_input_entry_select_changed_cb(void *data, Evas_Object * obj, void *event_info)
2474 _calc_view_input_entry_select_cleared_cb(void *data, Evas_Object * obj, void *event_info)
2477 select_mode = FALSE;
2484 * Create an entry for inputing expression.
2486 * @param parent the entry's parent
2487 * @param ad the appdata
2488 * @return Evas_Object* the input entry
2490 static Evas_Object *_calc_view_create_input_entry(Evas_Object * parent,
2494 Evas_Object *entry = elm_entry_add(ad->edje);
2495 elm_entry_single_line_set(entry, EINA_FALSE);
2496 elm_entry_editable_set(entry, EINA_TRUE);
2497 elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
2498 if (strlen(calculator_input_str) > 0) {
2499 _calc_entry_text_set(entry, calculator_input_str);
2501 elm_entry_entry_set(entry, "");
2503 elm_entry_cnp_mode_set(entry, ELM_CNP_MODE_NO_IMAGE);
2504 #if (ELM_VERSION_MAJOR == 1) && (ELM_VERSION_MINOR < 8)
2505 elm_entry_magnifier_disabled_set(entry, EINA_TRUE);
2507 elm_config_magnifier_enable_set(EINA_FALSE);
2509 elm_entry_cursor_end_set(entry);
2510 elm_object_focus_set(entry, EINA_TRUE);
2511 elm_object_style_set(entry, "black");
2512 evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND,
2514 evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
2516 evas_object_event_callback_add(entry, EVAS_CALLBACK_MOUSE_UP,
2517 _calc_view_input_entry_mouseup_cb, ad);
2518 evas_object_smart_callback_add(entry, "changed",
2519 _calc_view_input_entry_changed_cb, ad);
2520 evas_object_smart_callback_add(entry, "selection,paste",
2521 _calc_view_input_entry_paste_cb, ad);
2522 evas_object_smart_callback_add(entry, "selection,start",
2523 _calc_view_input_entry_select_start_cb, ad);
2524 evas_object_smart_callback_add(entry, "selection,changed",
2525 _calc_view_input_entry_select_changed_cb, ad);
2526 evas_object_smart_callback_add(entry, "selection,cleared",
2527 _calc_view_input_entry_select_cleared_cb, ad);
2529 evas_object_event_callback_add(entry, EVAS_CALLBACK_KEY_UP,
2530 _calc_view_input_entry_keyup_cb, ad);
2531 evas_object_smart_callback_del (entry, "changed", _calc_view_input_entry_changed_cb);
2533 evas_object_show(entry);
2534 limit_filter_data.max_char_count = 0;
2535 limit_filter_data.max_byte_count = 419 + 20; //19*21+20//result:20
2536 elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size,
2537 &limit_filter_data);
2538 elm_entry_text_style_user_push(entry, "DEFAULT='right_margin=32'");
2545 * Create a input scrooler which around the input entry.
2546 * It can give a input entry a scroller.
2548 * @param parent the parent of input scroller
2549 * @return Evas_Object* the input scroller
2552 static Evas_Object *_calc_view_create_input_scroller(Evas_Object * parent)
2555 Evas_Object *scroller = elm_scroller_add(parent);
2556 elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
2557 evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND,
2559 evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL,
2562 evas_object_show(scroller);
2569 * Create the background
2571 * @param[in] parent background's parent
2572 * @return when success return background, return NULL oppositely
2573 * @retval layout if success, return the background
2574 * @retval NULL if create failed or parent is null, return null
2577 static Evas_Object *__create_bg(Evas_Object *parent)
2580 if (parent == NULL) {
2583 Evas_Object *bg = elm_bg_add(parent);
2587 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2588 elm_win_resize_object_add(parent, bg);
2589 evas_object_show(bg);
2596 * Create the main layout
2598 * @param[in] parent main layout's parent
2599 * @return when success return a layout, return NULL oppositely
2600 * @retval layout if success, return the main layout
2601 * @retval NULL if create failed or parent is null, return null
2604 static Evas_Object *__calc_view_create_layout_main(Evas_Object *parent)
2608 if (parent == NULL) {
2612 Evas_Object *layout = elm_layout_add(parent);
2613 if (layout == NULL) {
2617 elm_layout_theme_set(layout, "layout", "application", "default");
2619 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND,
2621 elm_object_content_set(parent, layout);
2623 edje_object_signal_emit(_EDJ(layout), "elm,state,show,indicator",
2625 evas_object_show(layout);
2632 void _btn_clicked_cb(void *data, Evas_Object * obj, void *event_info)
2635 Evas_Object *win_main = (Evas_Object *) data;
2636 elm_win_lower(win_main);
2642 * Callback function of "Clear" Button on naviframe
2644 * @param data the appdata
2651 __calc_view_clear_clicked_cb(void *data, Evas_Object *obj, void *event_info)
2654 struct appdata *ad = (struct appdata *)data;
2655 if (ad->more_btn_popup) {
2656 evas_object_hide(ad->more_btn_popup);
2657 //ad->more_btn_popup= NULL;
2659 elm_entry_entry_set(ad->hist_area, "");
2660 elm_entry_entry_set(ad->input_entry, "");
2661 _calc_view_clear_histroy(ad->hist_area);
2662 /* Set input entry as initial state */
2663 _calc_entry_clear(ad->input_entry);
2664 calculator_state = CALCULATOR_WAITING_INPUT;
2668 Evas_Object *create_toolbar_more_btn(Evas_Object *parent, Evas_Smart_Cb func, void *data)
2670 Evas_Object *btn = elm_button_add(parent);
2674 elm_object_style_set(btn, "naviframe/more/default");
2676 evas_object_smart_callback_add(btn, "clicked", func, data);
2681 static void __gl_ctxpopup_hide_cb(void *data, Evas_Object *obj, void *event_info)
2683 evas_object_del(obj);
2686 static void __calc_view_create_popup(void *data, Evas_Object *parent)
2691 struct appdata *ad = (struct appdata *)data;
2692 ad->more_btn_popup = elm_ctxpopup_add(parent);
2693 const char *profile = elm_config_profile_get();
2694 if (!strcmp(profile, "mobile")) {
2695 ad->clear_item = elm_ctxpopup_item_append(ad->more_btn_popup,
2696 CALC_MSG_CLEAR_HISTTORY, NULL, __calc_view_clear_clicked_cb, ad);
2697 } else if (!strcmp(profile, "desktop")) {
2698 ad->clear_item = elm_ctxpopup_item_append(ad->more_btn_popup,
2699 CALC_MSG_CLEAR_HISTTORY, NULL, __calc_view_clear_clicked_cb, ad);
2702 Evas_Object *more_btn = NULL;
2703 more_btn = elm_object_item_part_content_get(ad->navi_it, "toolbar_more_btn");
2709 evas_object_geometry_get(more_btn, &x_position, &y_position, &w, &h);
2710 evas_object_move(ad->more_btn_popup, x_position + w/4, y_position+h/2);
2713 evas_object_show(ad->more_btn_popup);
2714 evas_object_smart_callback_add(ad->more_btn_popup, "dismissed", __gl_ctxpopup_hide_cb, data);
2718 void __calc_view_create_nf_more_btn_cb(void *data, Evas_Object * obj, void *event_info)
2720 struct appdata *ad = (struct appdata *)data;
2721 __calc_view_create_popup(data, ad->nf);
2727 * Load the Naviframe.
2729 * @param ad the appdata
2730 * @return naviframe object
2733 static Eina_Bool __calc_view_create_navigation_layout(struct appdata *ad)
2736 Evas_Object *nf = elm_naviframe_add(ad->layout);
2741 if (!ad->back_btn) {
2742 Evas_Object *back_btn = elm_button_add(nf);
2743 elm_object_style_set(back_btn, "naviframe/end_btn/default");
2744 evas_object_smart_callback_add(back_btn, "clicked", _btn_clicked_cb, ad->win);
2745 ad->back_btn = back_btn;
2747 ad->navi_it = elm_naviframe_item_push(nf, NULL, ad->back_btn, NULL, ad->edje, NULL);
2748 elm_naviframe_item_title_visible_set(ad->navi_it, EINA_FALSE);
2749 ad->more_btn = create_toolbar_more_btn(nf, __calc_view_create_nf_more_btn_cb, ad);
2750 elm_object_item_part_content_set(ad->navi_it, "toolbar_more_btn", ad->more_btn);
2751 evas_object_show(nf);
2758 * Load the main view of calculator.
2759 * Create the input entry and keypad.
2761 * @param ad the appdata
2764 void calc_view_load(struct appdata *ad)
2767 if (ad->bg == NULL) {
2768 ad->bg = __create_bg(ad->win);
2770 ad->conform = elm_conformant_add(ad->win);
2771 evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2772 elm_win_resize_object_add(ad->win, ad->conform);
2773 elm_object_style_set(ad->conform, "nokeypad");
2774 evas_object_show(ad->conform);
2775 ad->layout = __calc_view_create_layout_main(ad->conform);
2776 ad->edje = load_edj(ad->layout, LAYOUT_EDJ_NAME, GRP_MAIN);
2777 evas_object_show(ad->edje);
2778 evas_object_name_set(ad->edje, "edje");
2780 if (__calc_view_create_navigation_layout(ad)) {
2781 elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->nf);
2784 /* inititialize environment variable */
2785 locale = localeconv();
2786 decimal = locale->decimal_point;
2787 separator = locale->thousands_sep;
2788 int len_seq = strlen(separator);
2789 decimal_ch = decimal[0];
2790 separator_ch = separator[0];
2791 if (len_seq == 2 || len_seq == 0) {
2796 feedback_initialize();
2799 ad->input_entry = _calc_view_create_input_entry(ad->edje, ad);
2800 ad->input_scroller = _calc_view_create_input_scroller(ad->edje);
2801 elm_object_content_set(ad->input_scroller, ad->input_entry);
2802 edje_object_part_swallow(_EDJ(ad->edje), "input/entry",
2803 ad->input_scroller);
2810 * assign global variable , this will be removed
2816 void calc_xxx(struct appdata *ap)
2821 static Evas_Object* __set_win_icon(struct appdata *ad)
2823 /* set window icon*/
2824 Evas_Object *icon = evas_object_image_add(evas_object_evas_get(ad->win));
2825 evas_object_image_file_set(icon, DESKTOP_MODE_ICON, NULL);
2826 elm_win_icon_object_set(ad->win, icon);
2830 void win_profile_changed_cb(void *data, Evas_Object * obj, void *event_info)
2836 struct appdata *ad = (struct appdata *)data;
2837 const char *profile = elm_config_profile_get();
2838 if (!strcmp(profile, "desktop")) {
2839 /*In destktop mode, Hide indicator & hide back button on the naviframe */
2840 elm_object_item_part_content_set(ad->navi_it, "prev_btn", NULL);
2841 elm_object_item_part_content_set(ad->navi_it , "toolbar_button1", NULL);
2842 elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_HIDE);
2844 /* Show window Icon */
2845 if (!ad->window_icon) {
2846 ad->window_icon = __set_win_icon(ad);
2849 } else if (!strcmp(profile, "mobile")) {
2850 /* In mobile phone mode, show indicator and show back button*/
2851 elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
2852 Evas_Object *back_btn = elm_button_add(ad->nf);
2853 elm_object_style_set(back_btn, "naviframe/end_btn/default");
2854 evas_object_smart_callback_add(back_btn, "clicked", _btn_clicked_cb, ad->win);
2855 ad->back_btn = back_btn;
2856 elm_object_item_part_content_set(ad->navi_it, "prev_btn", ad->back_btn);