184614957604253d51296e06c97daced699a0a9deHans Boehm/* 284614957604253d51296e06c97daced699a0a9deHans Boehm * Copyright (C) 2015 The Android Open Source Project 384614957604253d51296e06c97daced699a0a9deHans Boehm * 484614957604253d51296e06c97daced699a0a9deHans Boehm * Licensed under the Apache License, Version 2.0 (the "License"); 584614957604253d51296e06c97daced699a0a9deHans Boehm * you may not use this file except in compliance with the License. 684614957604253d51296e06c97daced699a0a9deHans Boehm * You may obtain a copy of the License at 784614957604253d51296e06c97daced699a0a9deHans Boehm * 884614957604253d51296e06c97daced699a0a9deHans Boehm * http://www.apache.org/licenses/LICENSE-2.0 984614957604253d51296e06c97daced699a0a9deHans Boehm * 1084614957604253d51296e06c97daced699a0a9deHans Boehm * Unless required by applicable law or agreed to in writing, software 1184614957604253d51296e06c97daced699a0a9deHans Boehm * distributed under the License is distributed on an "AS IS" BASIS, 1284614957604253d51296e06c97daced699a0a9deHans Boehm * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1384614957604253d51296e06c97daced699a0a9deHans Boehm * See the License for the specific language governing permissions and 1484614957604253d51296e06c97daced699a0a9deHans Boehm * limitations under the License. 1584614957604253d51296e06c97daced699a0a9deHans Boehm */ 1684614957604253d51296e06c97daced699a0a9deHans Boehm 1784614957604253d51296e06c97daced699a0a9deHans Boehmpackage com.android.calculator2; 1884614957604253d51296e06c97daced699a0a9deHans Boehm 1984614957604253d51296e06c97daced699a0a9deHans Boehmimport android.content.res.Resources; 2084614957604253d51296e06c97daced699a0a9deHans Boehmimport android.content.Context; 214a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehmimport android.app.Activity; 224a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehmimport android.util.Log; 2384614957604253d51296e06c97daced699a0a9deHans Boehmimport android.view.View; 244a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehmimport android.widget.Button; 254a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm 2684614957604253d51296e06c97daced699a0a9deHans Boehmimport java.text.DecimalFormatSymbols; 274a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehmimport java.util.HashMap; 284a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehmimport java.util.Locale; 2984614957604253d51296e06c97daced699a0a9deHans Boehm 300b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm/** 310b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Collection of mapping functions between key ids, characters, internationalized 32e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen * and non-internationalized characters, etc. 330b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * <p> 340b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * KeyMap instances are not meaningful; everything here is static. 350b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * All functions are either pure, or are assumed to be called only from a single UI thread. 360b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 3784614957604253d51296e06c97daced699a0a9deHans Boehmpublic class KeyMaps { 380b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 390b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Map key id to corresponding (internationalized) display string. 400b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Pure function. 410b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 42e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen public static String toString(Context context, int id) { 4384614957604253d51296e06c97daced699a0a9deHans Boehm switch(id) { 440b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.const_pi: 45e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.const_pi); 460b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.const_e: 47e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.const_e); 480b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.op_sqrt: 49e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.op_sqrt); 500b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.op_fact: 51e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.op_fact); 52e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen case R.id.op_pct: 53e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.op_pct); 540b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.fun_sin: 55e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.fun_sin) + context.getString(R.string.lparen); 560b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.fun_cos: 57e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.fun_cos) + context.getString(R.string.lparen); 580b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.fun_tan: 59e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.fun_tan) + context.getString(R.string.lparen); 600b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.fun_arcsin: 61e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.fun_arcsin) + context.getString(R.string.lparen); 620b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.fun_arccos: 63e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.fun_arccos) + context.getString(R.string.lparen); 640b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.fun_arctan: 65e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.fun_arctan) + context.getString(R.string.lparen); 660b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.fun_ln: 67e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.fun_ln) + context.getString(R.string.lparen); 680b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.fun_log: 69e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.fun_log) + context.getString(R.string.lparen); 704db31b490443e4454d98a5ae2bc44b87149accfeHans Boehm case R.id.fun_exp: 714db31b490443e4454d98a5ae2bc44b87149accfeHans Boehm // Button label doesn't work. 724db31b490443e4454d98a5ae2bc44b87149accfeHans Boehm return context.getString(R.string.exponential) + context.getString(R.string.lparen); 730b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.lparen: 74e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.lparen); 750b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.rparen: 76e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.rparen); 770b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.op_pow: 78e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.op_pow); 790b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.op_mul: 80e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.op_mul); 810b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.op_div: 82e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.op_div); 830b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.op_add: 84e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.op_add); 854db31b490443e4454d98a5ae2bc44b87149accfeHans Boehm case R.id.op_sqr: 864db31b490443e4454d98a5ae2bc44b87149accfeHans Boehm // Button label doesn't work. 874db31b490443e4454d98a5ae2bc44b87149accfeHans Boehm return context.getString(R.string.squared); 880b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.op_sub: 89e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.op_sub); 900b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.dec_point: 91e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.dec_point); 920b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.digit_0: 93e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.digit_0); 940b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.digit_1: 95e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.digit_1); 960b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.digit_2: 97e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.digit_2); 980b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.digit_3: 99e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.digit_3); 1000b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.digit_4: 101e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.digit_4); 1020b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.digit_5: 103e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.digit_5); 1040b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.digit_6: 105e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.digit_6); 1060b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.digit_7: 107e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.digit_7); 1080b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.digit_8: 109e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.digit_8); 1100b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.digit_9: 111e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return context.getString(R.string.digit_9); 1120b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm default: 113e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return ""; 11484614957604253d51296e06c97daced699a0a9deHans Boehm } 11584614957604253d51296e06c97daced699a0a9deHans Boehm } 11684614957604253d51296e06c97daced699a0a9deHans Boehm 1170b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 1188a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm * Map key id to corresponding (internationalized) descriptive string that can be used 1198a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm * to correctly read back a formula. 1208a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm * Only used for operators and individual characters; not used inside constants. 1218a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm * Returns null when we don't need a descriptive string. 1228a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm * Pure function. 1238a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm */ 1248a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm public static String toDescriptiveString(Context context, int id) { 1258a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm switch(id) { 1268a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.op_fact: 1278a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_op_fact); 1288a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.fun_sin: 1298a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_fun_sin) 1308a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm + " " + context.getString(R.string.desc_lparen); 1318a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.fun_cos: 1328a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_fun_cos) 1338a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm + " " + context.getString(R.string.desc_lparen); 1348a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.fun_tan: 1358a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_fun_tan) 1368a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm + " " + context.getString(R.string.desc_lparen); 1378a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.fun_arcsin: 1388a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_fun_arcsin) 1398a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm + " " + context.getString(R.string.desc_lparen); 1408a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.fun_arccos: 1418a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_fun_arccos) 1428a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm + " " + context.getString(R.string.desc_lparen); 1438a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.fun_arctan: 1448a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_fun_arctan) 1458a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm + " " + context.getString(R.string.desc_lparen); 1468a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.fun_ln: 1478a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_fun_ln) 1488a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm + " " + context.getString(R.string.desc_lparen); 1498a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.fun_log: 1508a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_fun_log) 1518a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm + " " + context.getString(R.string.desc_lparen); 1528a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.fun_exp: 1538a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_fun_exp) 1548a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm + " " + context.getString(R.string.desc_lparen); 1558a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.lparen: 1568a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_lparen); 1578a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.rparen: 1588a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_rparen); 1598a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.op_pow: 1608a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_op_pow); 1618a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm case R.id.dec_point: 1628a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return context.getString(R.string.desc_dec_point); 1638a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm default: 1648a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm return null; 1658a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm } 1668a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm } 1678a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm 1688a4f81c5b30edd4e62d222a17f4e0e2140bfd99dHans Boehm /** 1690b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Does a button id correspond to a binary operator? 1700b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Pure function. 1710b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 17284614957604253d51296e06c97daced699a0a9deHans Boehm public static boolean isBinary(int id) { 17384614957604253d51296e06c97daced699a0a9deHans Boehm switch(id) { 1740b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.op_pow: 1750b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.op_mul: 1760b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.op_div: 1770b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.op_add: 1780b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case R.id.op_sub: 179017de9893efd33e179db10bc71189e150bc3486dHans Boehm return true; 180017de9893efd33e179db10bc71189e150bc3486dHans Boehm default: 181017de9893efd33e179db10bc71189e150bc3486dHans Boehm return false; 182017de9893efd33e179db10bc71189e150bc3486dHans Boehm } 183017de9893efd33e179db10bc71189e150bc3486dHans Boehm } 184017de9893efd33e179db10bc71189e150bc3486dHans Boehm 185017de9893efd33e179db10bc71189e150bc3486dHans Boehm /** 186017de9893efd33e179db10bc71189e150bc3486dHans Boehm * Does a button id correspond to a function that introduces an implicit lparen? 187017de9893efd33e179db10bc71189e150bc3486dHans Boehm * Pure function. 188017de9893efd33e179db10bc71189e150bc3486dHans Boehm */ 189017de9893efd33e179db10bc71189e150bc3486dHans Boehm public static boolean isFunc(int id) { 190017de9893efd33e179db10bc71189e150bc3486dHans Boehm switch(id) { 191017de9893efd33e179db10bc71189e150bc3486dHans Boehm case R.id.fun_sin: 192017de9893efd33e179db10bc71189e150bc3486dHans Boehm case R.id.fun_cos: 193017de9893efd33e179db10bc71189e150bc3486dHans Boehm case R.id.fun_tan: 194017de9893efd33e179db10bc71189e150bc3486dHans Boehm case R.id.fun_arcsin: 195017de9893efd33e179db10bc71189e150bc3486dHans Boehm case R.id.fun_arccos: 196017de9893efd33e179db10bc71189e150bc3486dHans Boehm case R.id.fun_arctan: 197017de9893efd33e179db10bc71189e150bc3486dHans Boehm case R.id.fun_ln: 198017de9893efd33e179db10bc71189e150bc3486dHans Boehm case R.id.fun_log: 199017de9893efd33e179db10bc71189e150bc3486dHans Boehm case R.id.fun_exp: 200017de9893efd33e179db10bc71189e150bc3486dHans Boehm return true; 201017de9893efd33e179db10bc71189e150bc3486dHans Boehm default: 202017de9893efd33e179db10bc71189e150bc3486dHans Boehm return false; 203017de9893efd33e179db10bc71189e150bc3486dHans Boehm } 204017de9893efd33e179db10bc71189e150bc3486dHans Boehm } 205017de9893efd33e179db10bc71189e150bc3486dHans Boehm 206017de9893efd33e179db10bc71189e150bc3486dHans Boehm /** 207017de9893efd33e179db10bc71189e150bc3486dHans Boehm * Does a button id correspond to a prefix operator? 208017de9893efd33e179db10bc71189e150bc3486dHans Boehm * Pure function. 209017de9893efd33e179db10bc71189e150bc3486dHans Boehm */ 210017de9893efd33e179db10bc71189e150bc3486dHans Boehm public static boolean isPrefix(int id) { 211017de9893efd33e179db10bc71189e150bc3486dHans Boehm switch(id) { 212017de9893efd33e179db10bc71189e150bc3486dHans Boehm case R.id.op_sqrt: 213017de9893efd33e179db10bc71189e150bc3486dHans Boehm case R.id.op_sub: 2140b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return true; 2150b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm default: 2160b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return false; 21784614957604253d51296e06c97daced699a0a9deHans Boehm } 21884614957604253d51296e06c97daced699a0a9deHans Boehm } 21984614957604253d51296e06c97daced699a0a9deHans Boehm 2200b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 2210b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Does a button id correspond to a suffix operator? 2220b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 22384614957604253d51296e06c97daced699a0a9deHans Boehm public static boolean isSuffix(int id) { 224e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen switch (id) { 225e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen case R.id.op_fact: 226e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen case R.id.op_pct: 2274db31b490443e4454d98a5ae2bc44b87149accfeHans Boehm case R.id.op_sqr: 228e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return true; 229e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen default: 230e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return false; 231e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen } 23284614957604253d51296e06c97daced699a0a9deHans Boehm } 23384614957604253d51296e06c97daced699a0a9deHans Boehm 23484614957604253d51296e06c97daced699a0a9deHans Boehm public static final int NOT_DIGIT = 10; 23584614957604253d51296e06c97daced699a0a9deHans Boehm 23608e8f322b0d93e06aaa2a15acc869dfd70791461Hans Boehm public static final String ELLIPSIS = "\u2026"; 23708e8f322b0d93e06aaa2a15acc869dfd70791461Hans Boehm 2380b9806f624f25e7e0302da4cf55eda21f8c28163Hans Boehm public static final char MINUS_SIGN = '\u2212'; 2390b9806f624f25e7e0302da4cf55eda21f8c28163Hans Boehm 2400b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 2410b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Map key id to digit or NOT_DIGIT 2420b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Pure function. 2430b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 24484614957604253d51296e06c97daced699a0a9deHans Boehm public static int digVal(int id) { 24584614957604253d51296e06c97daced699a0a9deHans Boehm switch (id) { 24684614957604253d51296e06c97daced699a0a9deHans Boehm case R.id.digit_0: 24784614957604253d51296e06c97daced699a0a9deHans Boehm return 0; 24884614957604253d51296e06c97daced699a0a9deHans Boehm case R.id.digit_1: 24984614957604253d51296e06c97daced699a0a9deHans Boehm return 1; 25084614957604253d51296e06c97daced699a0a9deHans Boehm case R.id.digit_2: 25184614957604253d51296e06c97daced699a0a9deHans Boehm return 2; 25284614957604253d51296e06c97daced699a0a9deHans Boehm case R.id.digit_3: 25384614957604253d51296e06c97daced699a0a9deHans Boehm return 3; 25484614957604253d51296e06c97daced699a0a9deHans Boehm case R.id.digit_4: 25584614957604253d51296e06c97daced699a0a9deHans Boehm return 4; 25684614957604253d51296e06c97daced699a0a9deHans Boehm case R.id.digit_5: 25784614957604253d51296e06c97daced699a0a9deHans Boehm return 5; 25884614957604253d51296e06c97daced699a0a9deHans Boehm case R.id.digit_6: 25984614957604253d51296e06c97daced699a0a9deHans Boehm return 6; 26084614957604253d51296e06c97daced699a0a9deHans Boehm case R.id.digit_7: 26184614957604253d51296e06c97daced699a0a9deHans Boehm return 7; 26284614957604253d51296e06c97daced699a0a9deHans Boehm case R.id.digit_8: 26384614957604253d51296e06c97daced699a0a9deHans Boehm return 8; 26484614957604253d51296e06c97daced699a0a9deHans Boehm case R.id.digit_9: 26584614957604253d51296e06c97daced699a0a9deHans Boehm return 9; 26684614957604253d51296e06c97daced699a0a9deHans Boehm default: 26784614957604253d51296e06c97daced699a0a9deHans Boehm return NOT_DIGIT; 26884614957604253d51296e06c97daced699a0a9deHans Boehm } 26984614957604253d51296e06c97daced699a0a9deHans Boehm } 27084614957604253d51296e06c97daced699a0a9deHans Boehm 2710b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 2720b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Map digit to corresponding key. Inverse of above. 2730b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Pure function. 2740b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 27584614957604253d51296e06c97daced699a0a9deHans Boehm public static int keyForDigVal(int v) { 27684614957604253d51296e06c97daced699a0a9deHans Boehm switch(v) { 27784614957604253d51296e06c97daced699a0a9deHans Boehm case 0: 27884614957604253d51296e06c97daced699a0a9deHans Boehm return R.id.digit_0; 27984614957604253d51296e06c97daced699a0a9deHans Boehm case 1: 28084614957604253d51296e06c97daced699a0a9deHans Boehm return R.id.digit_1; 28184614957604253d51296e06c97daced699a0a9deHans Boehm case 2: 28284614957604253d51296e06c97daced699a0a9deHans Boehm return R.id.digit_2; 28384614957604253d51296e06c97daced699a0a9deHans Boehm case 3: 28484614957604253d51296e06c97daced699a0a9deHans Boehm return R.id.digit_3; 28584614957604253d51296e06c97daced699a0a9deHans Boehm case 4: 28684614957604253d51296e06c97daced699a0a9deHans Boehm return R.id.digit_4; 28784614957604253d51296e06c97daced699a0a9deHans Boehm case 5: 28884614957604253d51296e06c97daced699a0a9deHans Boehm return R.id.digit_5; 28984614957604253d51296e06c97daced699a0a9deHans Boehm case 6: 29084614957604253d51296e06c97daced699a0a9deHans Boehm return R.id.digit_6; 29184614957604253d51296e06c97daced699a0a9deHans Boehm case 7: 29284614957604253d51296e06c97daced699a0a9deHans Boehm return R.id.digit_7; 29384614957604253d51296e06c97daced699a0a9deHans Boehm case 8: 29484614957604253d51296e06c97daced699a0a9deHans Boehm return R.id.digit_8; 29584614957604253d51296e06c97daced699a0a9deHans Boehm case 9: 29684614957604253d51296e06c97daced699a0a9deHans Boehm return R.id.digit_9; 29784614957604253d51296e06c97daced699a0a9deHans Boehm default: 29884614957604253d51296e06c97daced699a0a9deHans Boehm return View.NO_ID; 29984614957604253d51296e06c97daced699a0a9deHans Boehm } 30084614957604253d51296e06c97daced699a0a9deHans Boehm } 30184614957604253d51296e06c97daced699a0a9deHans Boehm 302425ed0a15c7c755a94701457b671b8b86765dc59Hans Boehm // The following two are only used for recognizing additional 303425ed0a15c7c755a94701457b671b8b86765dc59Hans Boehm // input characters from a physical keyboard. They are not used 304425ed0a15c7c755a94701457b671b8b86765dc59Hans Boehm // for output internationalization. 305425ed0a15c7c755a94701457b671b8b86765dc59Hans Boehm private static char mDecimalPt; 306ffda52845ca6cca5f72795706988a11f6bcf5b03Hans Boehm 307ffda52845ca6cca5f72795706988a11f6bcf5b03Hans Boehm private static char mPiChar; 30884614957604253d51296e06c97daced699a0a9deHans Boehm 309ffda52845ca6cca5f72795706988a11f6bcf5b03Hans Boehm /** 3100b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Character used as a placeholder for digits that are currently unknown in a result that 3110b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * is being computed. We initially generate blanks, and then use this as a replacement 3120b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * during final translation. 313ffda52845ca6cca5f72795706988a11f6bcf5b03Hans Boehm * <p/> 314ffda52845ca6cca5f72795706988a11f6bcf5b03Hans Boehm * Note: the character must correspond closely to the width of a digit, 315ffda52845ca6cca5f72795706988a11f6bcf5b03Hans Boehm * otherwise the UI will visibly shift once the computation is finished. 316ffda52845ca6cca5f72795706988a11f6bcf5b03Hans Boehm */ 317ffda52845ca6cca5f72795706988a11f6bcf5b03Hans Boehm private static final char CHAR_DIGIT_UNKNOWN = '\u2007'; 3184a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm 3190b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 3200b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Map typed function name strings to corresponding button ids. 3210b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * We (now redundantly?) include both localized and English names. 3220b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 323ffda52845ca6cca5f72795706988a11f6bcf5b03Hans Boehm private static HashMap<String, Integer> sKeyValForFun; 3244a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm 3250b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 3260b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Result string corresponding to a character in the calculator result. 3270b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * The string values in the map are expected to be one character long. 3280b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 329ffda52845ca6cca5f72795706988a11f6bcf5b03Hans Boehm private static HashMap<Character, String> sOutputForResultChar; 330013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm 3310b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 3320b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Locale string corresponding to preceding map and character constants. 3330b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * We recompute the map if this is not the current locale. 3340b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 335ffda52845ca6cca5f72795706988a11f6bcf5b03Hans Boehm private static String sLocaleForMaps = "none"; 3364a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm 3370b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 3380b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Activity to use for looking up buttons. 3390b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 3400b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm private static Activity mActivity; 341013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm 3420b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 3430b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Set acttivity used for looking up button labels. 3440b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Call only from UI thread. 3450b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 346013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm public static void setActivity(Activity a) { 347013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm mActivity = a; 348013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm } 349013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm 3500b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 3510b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Return the button id corresponding to the supplied character or return NO_ID. 3520b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Called only by UI thread. 3530b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 354013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm public static int keyForChar(char c) { 355013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm validateMaps(); 35684614957604253d51296e06c97daced699a0a9deHans Boehm if (Character.isDigit(c)) { 35784614957604253d51296e06c97daced699a0a9deHans Boehm int i = Character.digit(c, 10); 35884614957604253d51296e06c97daced699a0a9deHans Boehm return KeyMaps.keyForDigVal(i); 35984614957604253d51296e06c97daced699a0a9deHans Boehm } 36084614957604253d51296e06c97daced699a0a9deHans Boehm switch (c) { 3610b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case '.': 3620b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case ',': 3630b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return R.id.dec_point; 3640b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case '-': 3650b9806f624f25e7e0302da4cf55eda21f8c28163Hans Boehm case MINUS_SIGN: 3660b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return R.id.op_sub; 3670b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case '+': 3680b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return R.id.op_add; 3690b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case '*': 3700b9806f624f25e7e0302da4cf55eda21f8c28163Hans Boehm case '\u00D7': // MULTIPLICATION SIGN 3710b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return R.id.op_mul; 3720b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case '/': 3730b9806f624f25e7e0302da4cf55eda21f8c28163Hans Boehm case '\u00F7': // DIVISION SIGN 3740b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return R.id.op_div; 3750b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm // We no longer localize function names, so they can't start with an 'e' or 'p'. 3760b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case 'e': 3770b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case 'E': 3780b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return R.id.const_e; 3790b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case 'p': 3800b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case 'P': 3810b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return R.id.const_pi; 3820b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case '^': 3830b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return R.id.op_pow; 3840b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case '!': 3850b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return R.id.op_fact; 386e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen case '%': 387e2711cbb1569ab6c7a7c4506505ec403286d5ab4Justin Klaassen return R.id.op_pct; 3880b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case '(': 3890b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return R.id.lparen; 3900b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm case ')': 3910b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return R.id.rparen; 3920b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm default: 3930b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm if (c == mDecimalPt) return R.id.dec_point; 3940b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm if (c == mPiChar) return R.id.const_pi; 3950b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm // pi is not translated, but it might be typable on a Greek keyboard, 3960b9806f624f25e7e0302da4cf55eda21f8c28163Hans Boehm // or pasted in, so we check ... 3970b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm return View.NO_ID; 39884614957604253d51296e06c97daced699a0a9deHans Boehm } 39984614957604253d51296e06c97daced699a0a9deHans Boehm } 4004a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm 4010b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 4020b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Add information corresponding to the given button id to sKeyValForFun, to be used 4030b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * when mapping keyboard input to button ids. 4040b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 405013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm static void addButtonToFunMap(int button_id) { 406013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm Button button = (Button)mActivity.findViewById(button_id); 4074a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put(button.getText().toString(), button_id); 4084a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm } 4094a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm 4100b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 4110b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Add information corresponding to the given button to sOutputForResultChar, to be used 4120b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * when translating numbers on output. 4130b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 414013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm static void addButtonToOutputMap(char c, int button_id) { 415013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm Button button = (Button)mActivity.findViewById(button_id); 416013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm sOutputForResultChar.put(c, button.getText().toString()); 417013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm } 418013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm 4194a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm // Ensure that the preceding map and character constants are 4204a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm // initialized and correspond to the current locale. 4214a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm // Called only by a single thread, namely the UI thread. 422013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm static void validateMaps() { 4234a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm Locale locale = Locale.getDefault(); 4244a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm String lname = locale.toString(); 425013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm if (lname != sLocaleForMaps) { 4264a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm Log.v ("Calculator", "Setting local to: " + lname); 4274a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun = new HashMap<String, Integer>(); 4284a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put("sin", R.id.fun_sin); 4294a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put("cos", R.id.fun_cos); 4304a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put("tan", R.id.fun_tan); 4314a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put("arcsin", R.id.fun_arcsin); 4324a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put("arccos", R.id.fun_arccos); 4334a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put("arctan", R.id.fun_arctan); 4344a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put("asin", R.id.fun_arcsin); 4354a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put("acos", R.id.fun_arccos); 4364a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put("atan", R.id.fun_arctan); 4374a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put("ln", R.id.fun_ln); 4384a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put("log", R.id.fun_log); 4394a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm sKeyValForFun.put("sqrt", R.id.op_sqrt); // special treatment 440013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm addButtonToFunMap(R.id.fun_sin); 441013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm addButtonToFunMap(R.id.fun_cos); 442013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm addButtonToFunMap(R.id.fun_tan); 443013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm addButtonToFunMap(R.id.fun_arcsin); 444013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm addButtonToFunMap(R.id.fun_arccos); 445013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm addButtonToFunMap(R.id.fun_arctan); 446013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm addButtonToFunMap(R.id.fun_ln); 447013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm addButtonToFunMap(R.id.fun_log); 4484a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm 4494a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm // Set locale-dependent character "constants" 450013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm mDecimalPt = 4514a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm DecimalFormatSymbols.getInstance().getDecimalSeparator(); 452425ed0a15c7c755a94701457b671b8b86765dc59Hans Boehm // We recognize this in keyboard input, even if we use 453425ed0a15c7c755a94701457b671b8b86765dc59Hans Boehm // a different character. 454013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm Resources res = mActivity.getResources(); 455425ed0a15c7c755a94701457b671b8b86765dc59Hans Boehm mPiChar = 0; 4564a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm String piString = res.getString(R.string.const_pi); 4570b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm if (piString.length() == 1) { 4580b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm mPiChar = piString.charAt(0); 4590b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm } 4604a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm 461013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm sOutputForResultChar = new HashMap<Character, String>(); 462013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm sOutputForResultChar.put('e', "E"); 463013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm sOutputForResultChar.put('E', "E"); 464ffda52845ca6cca5f72795706988a11f6bcf5b03Hans Boehm sOutputForResultChar.put(' ', String.valueOf(CHAR_DIGIT_UNKNOWN)); 46508e8f322b0d93e06aaa2a15acc869dfd70791461Hans Boehm sOutputForResultChar.put(ELLIPSIS.charAt(0), ELLIPSIS); 466013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm sOutputForResultChar.put('/', "/"); 467013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm // Translate numbers for fraction display, but not 468013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm // the separating slash, which appears to be 469013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm // universal. 470013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm addButtonToOutputMap('-', R.id.op_sub); 471425ed0a15c7c755a94701457b671b8b86765dc59Hans Boehm addButtonToOutputMap('.', R.id.dec_point); 472013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm for (int i = 0; i <= 9; ++i) { 473013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm addButtonToOutputMap((char)('0' + i), keyForDigVal(i)); 474013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm } 475013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm 476013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm sLocaleForMaps = lname; 477013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm 4784a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm } 4794a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm } 4804a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm 4810b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 4820b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Return function button id for the substring of s starting at pos and ending with 4830b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * the next "(". Return NO_ID if there is none. 4840b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * We currently check for both (possibly localized) button labels, and standard 4850b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * English names. (They should currently be the same, and hence this is currently redundant.) 4860b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Callable only from UI thread. 4870b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 488013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm public static int funForString(String s, int pos) { 489013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm validateMaps(); 4904a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm int parenPos = s.indexOf('(', pos); 4914a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm if (parenPos != -1) { 4924a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm String funString = s.substring(pos, parenPos); 4934a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm Integer keyValue = sKeyValForFun.get(funString); 4944a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm if (keyValue == null) return View.NO_ID; 4954a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm return keyValue; 4964a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm } 4974a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm return View.NO_ID; 4984a6b7cb235c305761af5d7f40e74d4704e5058c8Hans Boehm } 499013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm 5000b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm /** 5010b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Return the localization of the string s representing a numeric answer. 5020b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm * Callable only from UI thread. 5030b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm */ 504013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm public static String translateResult(String s) { 505013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm StringBuilder result = new StringBuilder(); 506013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm int len = s.length(); 507013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm validateMaps(); 508013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm for (int i = 0; i < len; ++i) { 509013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm char c = s.charAt(i); 510013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm String translation = sOutputForResultChar.get(c); 511013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm if (translation == null) { 5120b3a9fd4405fd023e4343d4ff6c8da5ffb1346f4Hans Boehm // Should not get here. Report if we do. 513013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm Log.v("Calculator", "Bad character:" + c); 514013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm result.append(String.valueOf(c)); 515013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm } else { 516013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm result.append(translation); 517013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm } 518013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm } 519013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm return result.toString(); 520013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm } 521013969e98ce9e3eb4f87ec6159b06a74d07b2592Hans Boehm 52284614957604253d51296e06c97daced699a0a9deHans Boehm} 523