diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 797a07ac..0428df4f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -61,7 +61,11 @@
a:label="@string/c_help"
a:configChanges="orientation|keyboardHidden"/>
-
+
+
@@ -69,7 +73,11 @@
a:label="@string/c_operators"
a:configChanges="orientation|keyboardHidden"/>
-
+
+
diff --git a/res/layout/history_tabs.xml b/res/layout/history_tabs.xml
deleted file mode 100644
index d25fabe6..00000000
--- a/res/layout/history_tabs.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/layout/functions.xml b/res/layout/math_entities.xml
similarity index 100%
rename from res/layout/functions.xml
rename to res/layout/math_entities.xml
diff --git a/res/layout/var.xml b/res/layout/math_entity.xml
similarity index 80%
rename from res/layout/var.xml
rename to res/layout/math_entity.xml
index 0a07b948..a9445603 100644
--- a/res/layout/var.xml
+++ b/res/layout/math_entity.xml
@@ -16,18 +16,18 @@
a:layout_width="fill_parent"
a:layout_height="fill_parent">
-
+ style="@style/math_entity_text">
-
+ style="@style/math_entity_description">
\ No newline at end of file
diff --git a/res/layout/operators.xml b/res/layout/operators.xml
deleted file mode 100644
index c0165d13..00000000
--- a/res/layout/operators.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/layout/tabs.xml b/res/layout/tabs.xml
new file mode 100644
index 00000000..9f4c04f3
--- /dev/null
+++ b/res/layout/tabs.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values-hdpi/styles.xml b/res/values-hdpi/styles.xml
index 276197f4..42bdf52f 100644
--- a/res/values-hdpi/styles.xml
+++ b/res/values-hdpi/styles.xml
@@ -30,11 +30,11 @@
- 5dp
-
-
diff --git a/res/values-ldpi/styles.xml b/res/values-ldpi/styles.xml
index 0b4b67f4..235261a5 100644
--- a/res/values-ldpi/styles.xml
+++ b/res/values-ldpi/styles.xml
@@ -30,11 +30,11 @@
- 5dp
-
-
diff --git a/res/values-mdpi/styles.xml b/res/values-mdpi/styles.xml
index d9050a1c..0b1db34f 100644
--- a/res/values-mdpi/styles.xml
+++ b/res/values-mdpi/styles.xml
@@ -30,11 +30,11 @@
- 5dp
-
-
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d013d627..b4514aba 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -321,4 +321,13 @@ Check the \'Round result\' preference in application settings - it should be tur
History was successfully removed!
History was successfully saved!
+
+ Trigonometric
+ Hyperbolic trigonometric
+ Comparison
+ Common
+
+ System
+ My
+
diff --git a/res/values/styles-common-history.xml b/res/values/styles-common-history.xml
index 0ff121d6..f39a28ac 100644
--- a/res/values/styles-common-history.xml
+++ b/res/values/styles-common-history.xml
@@ -6,10 +6,10 @@
-
+
-
-
diff --git a/res/values/styles-common-var.xml b/res/values/styles-common-var.xml
index 195a9db9..ecbc45d1 100644
--- a/res/values/styles-common-var.xml
+++ b/res/values/styles-common-var.xml
@@ -7,7 +7,7 @@
-
-
-
-
diff --git a/src/main/java/org/solovyev/android/calculator/AbstractMathEntityListActivity.java b/src/main/java/org/solovyev/android/calculator/AbstractMathEntityListActivity.java
new file mode 100644
index 00000000..011ad936
--- /dev/null
+++ b/src/main/java/org/solovyev/android/calculator/AbstractMathEntityListActivity.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.android.calculator;
+
+import android.app.Activity;
+import android.app.ListActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.solovyev.android.calculator.model.AndroidMathRegistry;
+import org.solovyev.common.math.MathEntity;
+import org.solovyev.common.utils.EqualsTool;
+import org.solovyev.common.utils.Filter;
+import org.solovyev.common.utils.FilterRule;
+import org.solovyev.common.utils.StringUtils;
+
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * User: serso
+ * Date: 12/21/11
+ * Time: 9:24 PM
+ */
+public abstract class AbstractMathEntityListActivity extends ListActivity {
+
+ public static final String MATH_ENTITY_CATEGORY_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_math_entity_category";
+
+ @NotNull
+ private MathEntityArrayAdapter adapter;
+
+ @Nullable
+ private String category;
+
+ static void createTab(@NotNull Context context,
+ @NotNull TabHost tabHost,
+ @NotNull String tabId,
+ @NotNull String categoryId,
+ int tabCaptionId,
+ @NotNull Class extends Activity> activityClass,
+ @Nullable Intent parentIntent) {
+
+ TabHost.TabSpec spec;
+
+ final Intent intent;
+ if (parentIntent != null) {
+ intent = new Intent(parentIntent);
+ } else {
+ intent = new Intent();
+ }
+ intent.setClass(context, activityClass);
+ intent.putExtra(MATH_ENTITY_CATEGORY_EXTRA_STRING, categoryId);
+
+ // Initialize a TabSpec for each tab and add it to the TabHost
+ spec = tabHost.newTabSpec(tabId).setIndicator(context.getString(tabCaptionId)).setContent(intent);
+
+ tabHost.addTab(spec);
+ }
+
+ protected int getLayoutId() {
+ return R.layout.math_entities;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(getLayoutId());
+
+ final Intent intent = getIntent();
+ if ( intent != null ) {
+ category = intent.getStringExtra(MATH_ENTITY_CATEGORY_EXTRA_STRING);
+ }
+
+ final ListView lv = getListView();
+ lv.setTextFilterEnabled(true);
+
+ lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ public void onItemClick(final AdapterView> parent,
+ final View view,
+ final int position,
+ final long id) {
+
+ CalculatorModel.instance.processDigitButtonAction(((MathEntity) parent.getItemAtPosition(position)).getName(), false);
+
+ AbstractMathEntityListActivity.this.finish();
+ }
+ });
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ adapter = new MathEntityArrayAdapter(getDescriptionGetter(), this, R.layout.math_entity, R.id.math_entity_text, getMathEntitiesByCategory());
+ setListAdapter(adapter);
+
+ sort();
+ }
+
+ @NotNull
+ private List getMathEntitiesByCategory() {
+ final List result = getMathEntities();
+
+ new Filter(new FilterRule() {
+ @Override
+ public boolean isFiltered(T t) {
+ return !isInCategory(t);
+ }
+ }).filter(result.iterator());
+
+ return result;
+ }
+
+ protected boolean isInCategory(@Nullable T t) {
+ return t != null && EqualsTool.areEqual(getMathEntityCategory(t), category);
+ }
+
+ @NotNull
+ protected MathEntityArrayAdapter getAdapter() {
+ return adapter;
+ }
+
+ @NotNull
+ protected abstract MathEntityDescriptionGetter getDescriptionGetter();
+
+ @NotNull
+ protected abstract List getMathEntities();
+
+ @Nullable
+ protected abstract String getMathEntityCategory(@NotNull T t);
+
+ protected void sort() {
+ AbstractMathEntityListActivity.this.adapter.sort(new Comparator() {
+ @Override
+ public int compare(T function1, T function2) {
+ return function1.getName().compareTo(function2.getName());
+ }
+ });
+
+ AbstractMathEntityListActivity.this.adapter.notifyDataSetChanged();
+ }
+
+ protected static class MathEntityArrayAdapter extends ArrayAdapter {
+
+ @NotNull
+ private final MathEntityDescriptionGetter descriptionGetter;
+
+ private MathEntityArrayAdapter(@NotNull MathEntityDescriptionGetter descriptionGetter, @NotNull Context context, int resource, int textViewResourceId, @NotNull List objects) {
+ super(context, resource, textViewResourceId, objects);
+ this.descriptionGetter = descriptionGetter;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final ViewGroup result = (ViewGroup) super.getView(position, convertView, parent);
+
+ final T mathEntity = getItem(position);
+
+ final String mathEntityDescription = descriptionGetter.getDescription(getContext(), mathEntity.getName());
+ if (!StringUtils.isEmpty(mathEntityDescription)) {
+ TextView description = (TextView) result.findViewById(R.id.math_entity_description);
+ if (description == null) {
+ final LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(LAYOUT_INFLATER_SERVICE);
+ final ViewGroup itemView = (ViewGroup) layoutInflater.inflate(R.layout.math_entity, null);
+ description = (TextView) itemView.findViewById(R.id.math_entity_description);
+ itemView.removeView(description);
+ result.addView(description);
+ }
+ description.setText(mathEntityDescription);
+ } else {
+ TextView description = (TextView) result.findViewById(R.id.math_entity_description);
+ if (description != null) {
+ result.removeView(description);
+ }
+ }
+
+
+ return result;
+ }
+ }
+
+ protected static class MathEntityDescriptionGetterImpl implements MathEntityDescriptionGetter {
+
+ @NotNull
+ private final AndroidMathRegistry> mathRegistry;
+
+ public MathEntityDescriptionGetterImpl(@NotNull AndroidMathRegistry> mathRegistry) {
+ this.mathRegistry = mathRegistry;
+ }
+
+ @Override
+ public String getDescription(@NotNull Context context, @NotNull String mathEntityName) {
+ return this.mathRegistry.getDescription(context, mathEntityName);
+ }
+ }
+
+ protected static interface MathEntityDescriptionGetter {
+
+ @Nullable
+ String getDescription(@NotNull Context context, @NotNull String mathEntityName);
+ }
+}
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java b/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java
index a0a66435..fe2bd3ad 100644
--- a/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java
@@ -58,9 +58,9 @@ public class CalculatorActivityLauncher {
if (calculatorModel.getDisplay().isValid() ) {
final String varValue = calculatorModel.getDisplay().getText().toString();
if (!StringUtils.isEmpty(varValue)) {
- if (CalculatorVarsActivity.isValidValue(varValue)) {
+ if (CalculatorVarsTabActivity.isValidValue(varValue)) {
final Intent intent = new Intent(context, CalculatorVarsActivity.class);
- intent.putExtra(CalculatorVarsActivity.CREATE_VAR_EXTRA_STRING, varValue);
+ intent.putExtra(CalculatorVarsTabActivity.CREATE_VAR_EXTRA_STRING, varValue);
context.startActivity(intent);
} else {
Toast.makeText(context, R.string.c_not_valid_result, Toast.LENGTH_SHORT).show();
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsActivity.java
index 819ada86..e971c3dc 100644
--- a/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsActivity.java
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsActivity.java
@@ -6,106 +6,33 @@
package org.solovyev.android.calculator;
-import android.app.ListActivity;
-import android.content.Context;
+import android.app.TabActivity;
import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.*;
-import jscl.math.function.Function;
-import org.jetbrains.annotations.NotNull;
-import org.solovyev.android.calculator.model.CalculatorEngine;
-import org.solovyev.android.calculator.model.Var;
-import org.solovyev.common.utils.StringUtils;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
+import android.widget.TabHost;
+import org.jetbrains.annotations.Nullable;
+import org.solovyev.android.calculator.model.AndroidFunctionsMathRegistry;
+import org.solovyev.android.view.prefs.AndroidUtils;
/**
* User: serso
- * Date: 10/29/11
- * Time: 4:55 PM
+ * Date: 12/21/11
+ * Time: 10:33 PM
*/
-public class CalculatorFunctionsActivity extends ListActivity {
+public class CalculatorFunctionsActivity extends TabActivity {
- @NotNull
- private FunctionsArrayAdapter adapter;
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ setContentView(R.layout.tabs);
- setContentView(R.layout.functions);
+ final TabHost tabHost = getTabHost();
- adapter = new FunctionsArrayAdapter(this, R.layout.var, R.id.var_text, new ArrayList(CalculatorEngine.instance.getFunctionsRegistry().getEntities()));
- setListAdapter(adapter);
-
- final ListView lv = getListView();
- lv.setTextFilterEnabled(true);
-
- lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- public void onItemClick(final AdapterView> parent,
- final View view,
- final int position,
- final long id) {
-
- CalculatorModel.instance.processDigitButtonAction(((Function) parent.getItemAtPosition(position)).getName(), false);
-
- CalculatorFunctionsActivity.this.finish();
- }
- });
-
- sort();
-
- }
-
- private void sort() {
- CalculatorFunctionsActivity.this.adapter.sort(new Comparator() {
- @Override
- public int compare(Function function1, Function function2) {
- return function1.getName().compareTo(function2.getName());
- }
- });
-
- CalculatorFunctionsActivity.this.adapter.notifyDataSetChanged();
- }
-
- private class FunctionsArrayAdapter extends ArrayAdapter {
-
- private FunctionsArrayAdapter(Context context, int resource, int textViewResourceId, List objects) {
- super(context, resource, textViewResourceId, objects);
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final ViewGroup result = (ViewGroup) super.getView(position, convertView, parent);
-
- final Function function = getItem(position);
-
- final String functionDescription = CalculatorEngine.instance.getFunctionsRegistry().getDescription(getContext(), function.getName());
- if (!StringUtils.isEmpty(functionDescription)) {
- TextView description = (TextView) result.findViewById(R.id.var_description);
- if (description == null) {
- final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
- final ViewGroup itemView = (ViewGroup) layoutInflater.inflate(R.layout.var, null);
- description = (TextView) itemView.findViewById(R.id.var_description);
- itemView.removeView(description);
- result.addView(description);
- }
- description.setText(functionDescription);
- } else {
- TextView description = (TextView) result.findViewById(R.id.var_description);
- if (description != null) {
- result.removeView(description);
- }
- }
-
-
- return result;
- }
- }
+ for (AndroidFunctionsMathRegistry.Category category : AndroidFunctionsMathRegistry.Category.getCategoriesByTabOrder()) {
+ AbstractMathEntityListActivity.createTab(this, tabHost, category.name(), category.name(), category.getCaptionId(), CalculatorFunctionsTabActivity.class, null);
+ }
+ AndroidUtils.centerAndWrapTabsFor(tabHost);
+ }
}
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsTabActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsTabActivity.java
new file mode 100644
index 00000000..79dce327
--- /dev/null
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsTabActivity.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.android.calculator;
+
+import jscl.math.function.Function;
+import org.jetbrains.annotations.NotNull;
+import org.solovyev.android.calculator.model.CalculatorEngine;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * User: serso
+ * Date: 10/29/11
+ * Time: 4:55 PM
+ */
+public class CalculatorFunctionsTabActivity extends AbstractMathEntityListActivity {
+
+ @NotNull
+ @Override
+ protected MathEntityDescriptionGetter getDescriptionGetter() {
+ return new MathEntityDescriptionGetterImpl(CalculatorEngine.instance.getFunctionsRegistry());
+ }
+
+ @NotNull
+ @Override
+ protected List getMathEntities() {
+ return new ArrayList(CalculatorEngine.instance.getFunctionsRegistry().getEntities());
+ }
+
+ @Override
+ protected String getMathEntityCategory(@NotNull Function function) {
+ return CalculatorEngine.instance.getFunctionsRegistry().getCategory(function);
+ }
+}
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorOperatorsActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorOperatorsActivity.java
index 0003d497..bcec75c0 100644
--- a/src/main/java/org/solovyev/android/calculator/CalculatorOperatorsActivity.java
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorOperatorsActivity.java
@@ -1,22 +1,12 @@
package org.solovyev.android.calculator;
-import android.app.ListActivity;
import android.content.Context;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
import jscl.math.operator.Operator;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.model.CalculatorEngine;
import org.solovyev.common.utils.StringUtils;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.List;
/**
@@ -25,92 +15,48 @@ import java.util.List;
* Time: 1:53 PM
*/
-public class CalculatorOperatorsActivity extends ListActivity {
+public class CalculatorOperatorsActivity extends AbstractMathEntityListActivity {
- @NotNull
- private OperatorsArrayAdapter adapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.operators);
-
- List elements = new ArrayList();
- elements.addAll(CalculatorEngine.instance.getOperatorsRegistry().getEntities());
- elements.addAll(CalculatorEngine.instance.getPostfixFunctionsRegistry().getEntities());
- adapter = new OperatorsArrayAdapter(this, R.layout.var, R.id.var_text, elements);
- setListAdapter(adapter);
-
- final ListView lv = getListView();
- lv.setTextFilterEnabled(true);
-
- lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- public void onItemClick(final AdapterView> parent,
- final View view,
- final int position,
- final long id) {
-
- CalculatorModel.instance.processDigitButtonAction(((Operator) parent.getItemAtPosition(position)).getName(), false);
-
- CalculatorOperatorsActivity.this.finish();
- }
- });
-
- sort();
-
- }
-
- private void sort() {
- CalculatorOperatorsActivity.this.adapter.sort(new Comparator() {
- @Override
- public int compare(Operator operator1, Operator operator2) {
- return operator1.getName().compareTo(operator2.getName());
- }
- });
-
- CalculatorOperatorsActivity.this.adapter.notifyDataSetChanged();
- }
-
- private class OperatorsArrayAdapter extends ArrayAdapter {
-
- private OperatorsArrayAdapter(Context context, int resource, int textViewResourceId, List objects) {
- super(context, resource, textViewResourceId, objects);
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final ViewGroup result = (ViewGroup) super.getView(position, convertView, parent);
-
- final Operator operator = getItem(position);
-
- String operatorDescription = CalculatorEngine.instance.getOperatorsRegistry().getDescription(getContext(), operator.getName());
- if (StringUtils.isEmpty(operatorDescription)) {
- operatorDescription = CalculatorEngine.instance.getPostfixFunctionsRegistry().getDescription(getContext(), operator.getName());
- }
-
- if (!StringUtils.isEmpty(operatorDescription)) {
- TextView description = (TextView) result.findViewById(R.id.var_description);
- if (description == null) {
- final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
- final ViewGroup itemView = (ViewGroup) layoutInflater.inflate(R.layout.var, null);
- description = (TextView) itemView.findViewById(R.id.var_description);
- itemView.removeView(description);
- result.addView(description);
- }
- description.setText(operatorDescription);
- } else {
- TextView description = (TextView) result.findViewById(R.id.var_description);
- if (description != null) {
- result.removeView(description);
- }
- }
+ @NotNull
+ @Override
+ protected MathEntityDescriptionGetter getDescriptionGetter() {
+ return new OperatorDescriptionGetter();
+ }
- return result;
- }
- }
+ @NotNull
+ @Override
+ protected List getMathEntities() {
+ final List result = new ArrayList();
+ result.addAll(CalculatorEngine.instance.getOperatorsRegistry().getEntities());
+ result.addAll(CalculatorEngine.instance.getPostfixFunctionsRegistry().getEntities());
+
+ return result;
+ }
+
+ @Override
+ protected String getMathEntityCategory(@NotNull Operator operator) {
+ String result = CalculatorEngine.instance.getOperatorsRegistry().getCategory(operator);
+ if (result == null) {
+ result = CalculatorEngine.instance.getPostfixFunctionsRegistry().getCategory(operator);
+ }
+
+ return result;
+ }
+
+ private static class OperatorDescriptionGetter implements MathEntityDescriptionGetter {
+
+ @Override
+ public String getDescription(@NotNull Context context, @NotNull String mathEntityName) {
+ String result = CalculatorEngine.instance.getOperatorsRegistry().getDescription(context, mathEntityName);
+ if (StringUtils.isEmpty(result)) {
+ result = CalculatorEngine.instance.getPostfixFunctionsRegistry().getDescription(context, mathEntityName);
+ }
+
+ return result;
+ }
+ }
}
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java
index 1db14da2..3bfb0a7a 100644
--- a/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java
@@ -6,415 +6,38 @@
package org.solovyev.android.calculator;
-import android.app.AlertDialog;
-import android.app.ListActivity;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
+import android.app.TabActivity;
import android.os.Bundle;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.view.*;
-import android.widget.*;
-import jscl.text.Identifier;
-import jscl.text.MutableInt;
-import jscl.text.ParseException;
-import jscl.text.Parser;
-import org.jetbrains.annotations.NotNull;
+import android.widget.TabHost;
import org.jetbrains.annotations.Nullable;
-import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.model.AndroidVarsRegistry;
-import org.solovyev.android.calculator.model.CalculatorEngine;
-import org.solovyev.android.calculator.model.Var;
-import org.solovyev.common.utils.CollectionsUtils;
-import org.solovyev.common.utils.Finder;
-import org.solovyev.common.utils.StringUtils;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
+import org.solovyev.android.view.prefs.AndroidUtils;
/**
* User: serso
- * Date: 9/28/11
- * Time: 10:55 PM
+ * Date: 12/21/11
+ * Time: 11:05 PM
*/
-public class CalculatorVarsActivity extends ListActivity {
+public class CalculatorVarsActivity extends TabActivity {
- public static final String CREATE_VAR_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_create_var";
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
- private final static List acceptableChars = Arrays.asList(StringUtils.toObject("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_".toCharArray()));
+ setContentView(R.layout.tabs);
- @NotNull
- private VarsArrayAdapter adapter;
+ final TabHost tabHost = getTabHost();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ for (AndroidVarsRegistry.Category category : AndroidVarsRegistry.Category.getCategoriesByTabOrder()) {
+ if (category == AndroidVarsRegistry.Category.my) {
+ AbstractMathEntityListActivity.createTab(this, tabHost, category.name(), category.name(), category.getCaptionId(), CalculatorVarsTabActivity.class, getIntent());
+ } else {
+ AbstractMathEntityListActivity.createTab(this, tabHost, category.name(), category.name(), category.getCaptionId(), CalculatorVarsTabActivity.class, null);
+ }
+ }
- setContentView(R.layout.vars);
+ tabHost.setCurrentTab(0);
+ AndroidUtils.centerAndWrapTabsFor(tabHost);
+ }
- final List vars = new ArrayList(CalculatorEngine.instance.getVarsRegister().getEntities());
- CollectionsUtils.removeAll(vars, new Finder() {
- @Override
- public boolean isFound(@Nullable Var var) {
- return var != null && CollectionsUtils.contains(var.getName(), MathType.INFINITY_JSCL, MathType.NAN);
- }
- });
- adapter = new VarsArrayAdapter(this, R.layout.var, R.id.var_text, vars);
- setListAdapter(adapter);
-
- final ListView lv = getListView();
- lv.setTextFilterEnabled(true);
-
-
- lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
- @Override
- public boolean onItemLongClick(AdapterView> parent, View view, int position, long id) {
- final Var var = (Var) parent.getItemAtPosition(position);
- createEditVariableDialog(var, var.getName(), StringUtils.getNotEmpty(var.getValue(), ""), var.getDescription());
- return true;
- }
- });
-
- lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- public void onItemClick(final AdapterView> parent,
- final View view,
- final int position,
- final long id) {
-
- CalculatorModel.instance.doTextOperation(new CalculatorModel.TextOperation() {
- @Override
- public void doOperation(@NotNull EditText editor) {
- editor.getText().insert(editor.getSelectionStart(), ((Var) parent.getItemAtPosition(position)).getName());
- }
- }, false);
-
- CalculatorVarsActivity.this.finish();
- }
- });
-
- sort();
-
- final Intent intent = getIntent();
- if ( intent != null ) {
- final String varValue = intent.getStringExtra(CREATE_VAR_EXTRA_STRING);
- if (!StringUtils.isEmpty(varValue)) {
- createEditVariableDialog(null, null, varValue, null);
- }
- }
-
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void addVarButtonClickHandler(@NotNull View v) {
- createEditVariableDialog(null, null, null, null);
- }
-
-
- private void createEditVariableDialog(@Nullable final Var var, @Nullable final String name, @Nullable final String value, @Nullable final String description) {
- if (var == null || !var.isSystem()) {
-
- final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
- final View editView = layoutInflater.inflate(R.layout.var_edit, null);
-
- final String errorMsg = CalculatorVarsActivity.this.getString(R.string.c_char_is_not_accepted);
-
- final EditText editName = (EditText) editView.findViewById(R.id.var_edit_name);
- editName.setText(name);
- editName.addTextChangedListener(new TextWatcher() {
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- for ( int i = 0; i < s.length(); i++ ) {
- char c = s.charAt(i);
- if (!acceptableChars.contains(c)) {
- s.delete(i, i+1);
- Toast.makeText(CalculatorVarsActivity.this, String.format(errorMsg, c), Toast.LENGTH_SHORT).show();
- }
- }
- }
- });
-
- final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value);
- if (!StringUtils.isEmpty(value)) {
- editValue.setText(value);
- }
-
- final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description);
- editDescription.setText(description);
-
- final Var.Builder varBuilder;
- if (var != null) {
- varBuilder = new Var.Builder(var);
- } else {
- varBuilder = new Var.Builder();
- }
-
- final AlertDialog.Builder builder = new AlertDialog.Builder(this)
- .setCancelable(true)
- .setNegativeButton(R.string.c_cancel, null)
- .setPositiveButton(R.string.c_save, new VarEditorSaver(varBuilder, var, editView))
- .setView(editView);
-
- if ( var != null ) {
- // EDIT mode
-
- builder.setTitle(R.string.c_var_edit_var);
- builder.setNeutralButton(R.string.c_remove, new VarEditorRemover(var, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- createEditVariableDialog(var, name, value, description);
- }
- }));
- } else {
- // CREATE mode
-
- builder.setTitle(R.string.c_var_create_var);
- }
-
- builder.create().show();
- } else {
- Toast.makeText(this, getString(R.string.c_sys_var_cannot_be_changed), Toast.LENGTH_LONG).show();
- }
- }
-
- private class VarEditorSaver implements DialogInterface.OnClickListener {
-
- @NotNull
- private Var.Builder varBuilder;
-
- @Nullable
- private final Var editedInstance;
-
- @NotNull
- private View editView;
-
- public VarEditorSaver(@NotNull Var.Builder varBuilder, @Nullable Var editedInstance, @NotNull View editView) {
- this.varBuilder = varBuilder;
- this.editedInstance = editedInstance;
- this.editView = editView;
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (which == DialogInterface.BUTTON_POSITIVE) {
- final Integer error;
-
- final EditText editName = (EditText) editView.findViewById(R.id.var_edit_name);
- String name = editName.getText().toString();
-
- final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value);
- String value = editValue.getText().toString();
-
- final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description);
- String description = editDescription.getText().toString();
-
-
- final AndroidVarsRegistry varsRegistry = CalculatorEngine.instance.getVarsRegister();
- if (isValidName(name)) {
-
- boolean canBeSaved = false;
-
- final Var varFromRegister = varsRegistry.get(name);
- if ( varFromRegister == null ) {
- canBeSaved = true;
- } else if ( editedInstance != null && varFromRegister.getId().equals(editedInstance.getId()) ) {
- canBeSaved = true;
- }
-
- if (canBeSaved) {
- final MathType.Result mathType = MathType.getType(name, 0, false);
-
- if (mathType.getMathType() == MathType.text || mathType.getMathType() == MathType.constant) {
-
- if (StringUtils.isEmpty(value)) {
- // value is empty => undefined variable
- varBuilder.setName(name);
- varBuilder.setDescription(description);
- varBuilder.setValue(null);
- error = null;
- } else {
- // value is not empty => must be a number
- boolean valid = isValidValue(value);
-
- if (valid) {
- varBuilder.setName(name);
- varBuilder.setDescription(description);
- varBuilder.setValue(value);
- error = null;
- } else {
- error = R.string.c_value_is_not_a_number;
- }
- }
- } else {
- error = R.string.c_var_name_clashes;
- }
- } else {
- error = R.string.c_var_already_exists;
- }
- } else {
- error = R.string.c_name_is_not_valid;
- }
-
- if (error != null) {
- Toast.makeText(CalculatorVarsActivity.this, getString(error), Toast.LENGTH_LONG).show();
- createEditVariableDialog(editedInstance, name, value, description);
- } else {
- if ( editedInstance == null ) {
- CalculatorVarsActivity.this.adapter.add(varsRegistry.add(varBuilder));
- } else {
- final Var newInstance = varsRegistry.add(varBuilder);
- CalculatorVarsActivity.this.adapter.remove(editedInstance);
- CalculatorVarsActivity.this.adapter.add(newInstance);
- }
-
- varsRegistry.save(CalculatorVarsActivity.this);
-
- sort();
- }
- }
- }
- }
-
- private void sort() {
- CalculatorVarsActivity.this.adapter.sort(new Comparator() {
- @Override
- public int compare(Var var, Var var1) {
- return var.getName().compareTo(var1.getName());
- }
- });
-
- CalculatorVarsActivity.this.adapter.notifyDataSetChanged();
- }
-
- private static boolean isValidName(@Nullable String name) {
- boolean result = false;
-
- if (!StringUtils.isEmpty(name)) {
- try {
- Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorEngine.instance.getEngine()), null);
- result = true;
- } catch (ParseException e) {
- // not valid name;
- }
- }
-
- return result;
- }
-
- public static boolean isValidValue(@NotNull String value) {
- // now every string might be constant
- return true;
- }
-
- private class VarsArrayAdapter extends ArrayAdapter {
-
- private VarsArrayAdapter(Context context, int resource, int textViewResourceId, List objects) {
- super(context, resource, textViewResourceId, objects);
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final ViewGroup result = (ViewGroup) super.getView(position, convertView, parent);
-
- final Var var = getItem(position);
-
- if (!StringUtils.isEmpty(var.getDescription())) {
- TextView description = (TextView) result.findViewById(R.id.var_description);
- if (description == null) {
- final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
- final ViewGroup itemView = (ViewGroup) layoutInflater.inflate(R.layout.var, null);
- description = (TextView) itemView.findViewById(R.id.var_description);
- itemView.removeView(description);
- result.addView(description);
- }
- description.setText(var.getDescription());
- } else {
- TextView description = (TextView) result.findViewById(R.id.var_description);
- if (description != null) {
- result.removeView(description);
- }
- }
-
-
- return result;
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- final MenuInflater menuInflater = getMenuInflater();
- menuInflater.inflate(R.menu.var_menu, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- boolean result;
-
- switch (item.getItemId()) {
- case R.id.var_menu_add_var:
- createEditVariableDialog(null, null, null, null);
- result = true;
- break;
- default:
- result = super.onOptionsItemSelected(item);
- }
-
- return result;
- }
-
- private class VarEditorRemover implements DialogInterface.OnClickListener {
-
- @NotNull
- private final Var var;
-
- @Nullable
- private final DialogInterface.OnClickListener callbackOnCancel;
-
- private final boolean confirmed;
-
- public VarEditorRemover(@NotNull Var var, @Nullable DialogInterface.OnClickListener callbackOnCancel) {
- this(var, callbackOnCancel, false);
- }
-
- public VarEditorRemover(@NotNull Var var, @Nullable DialogInterface.OnClickListener callbackOnCancel, boolean confirmed) {
- this.var = var;
- this.callbackOnCancel = callbackOnCancel;
- this.confirmed = confirmed;
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (!confirmed) {
- final TextView question = new TextView(CalculatorVarsActivity.this);
- question.setText(String.format(getString(R.string.c_var_removal_confirmation_question), var.getName()));
- question.setPadding(6, 6, 6, 6);
- final AlertDialog.Builder builder = new AlertDialog.Builder(CalculatorVarsActivity.this)
- .setCancelable(true)
- .setView(question)
- .setTitle(R.string.c_var_removal_confirmation)
- .setNegativeButton(R.string.c_no, callbackOnCancel)
- .setPositiveButton(R.string.c_yes, new VarEditorRemover(var, callbackOnCancel, true));
-
- builder.create().show();
- } else {
- adapter.remove(var);
- final AndroidVarsRegistry varsRegistry = CalculatorEngine.instance.getVarsRegister();
- varsRegistry.remove(var);
- varsRegistry.save(CalculatorVarsActivity.this);
- CalculatorVarsActivity.this.adapter.notifyDataSetChanged();
- }
- }
- }
}
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorVarsTabActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorVarsTabActivity.java
new file mode 100644
index 00000000..185bce95
--- /dev/null
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorVarsTabActivity.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.android.calculator;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.*;
+import android.widget.AdapterView;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+import jscl.text.Identifier;
+import jscl.text.MutableInt;
+import jscl.text.ParseException;
+import jscl.text.Parser;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.solovyev.android.calculator.math.MathType;
+import org.solovyev.android.calculator.model.AndroidVarsRegistry;
+import org.solovyev.android.calculator.model.CalculatorEngine;
+import org.solovyev.android.calculator.model.Var;
+import org.solovyev.common.utils.CollectionsUtils;
+import org.solovyev.common.utils.Finder;
+import org.solovyev.common.utils.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * User: serso
+ * Date: 9/28/11
+ * Time: 10:55 PM
+ */
+public class CalculatorVarsTabActivity extends AbstractMathEntityListActivity {
+
+ public static final String CREATE_VAR_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_create_var";
+
+ private final static List acceptableChars = Arrays.asList(StringUtils.toObject("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_".toCharArray()));
+
+ @Override
+ protected int getLayoutId() {
+ return R.layout.vars;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view, int position, long id) {
+ final Var var = (Var) parent.getItemAtPosition(position);
+ createEditVariableDialog(var, var.getName(), StringUtils.getNotEmpty(var.getValue(), ""), var.getDescription());
+ return true;
+ }
+ });
+
+ final Intent intent = getIntent();
+ if ( intent != null ) {
+ final String varValue = intent.getStringExtra(CREATE_VAR_EXTRA_STRING);
+ if (!StringUtils.isEmpty(varValue)) {
+ createEditVariableDialog(null, null, varValue, null);
+
+ // in order to stop intent for other tabs
+ intent.removeExtra(CREATE_VAR_EXTRA_STRING);
+ }
+ }
+ }
+
+ @NotNull
+ @Override
+ protected MathEntityDescriptionGetter getDescriptionGetter() {
+ return new MathEntityDescriptionGetterImpl(CalculatorEngine.instance.getVarsRegister());
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void addVarButtonClickHandler(@NotNull View v) {
+ createEditVariableDialog(null, null, null, null);
+ }
+
+ @NotNull
+ @Override
+ protected List getMathEntities() {
+ final List result = new ArrayList(CalculatorEngine.instance.getVarsRegister().getEntities());
+
+ CollectionsUtils.removeAll(result, new Finder() {
+ @Override
+ public boolean isFound(@Nullable Var var) {
+ return var != null && CollectionsUtils.contains(var.getName(), MathType.INFINITY_JSCL, MathType.NAN);
+ }
+ });
+
+ return result;
+ }
+
+ @Override
+ protected String getMathEntityCategory(@NotNull Var var) {
+ return CalculatorEngine.instance.getVarsRegister().getCategory(var);
+ }
+
+ private void createEditVariableDialog(@Nullable final Var var, @Nullable final String name, @Nullable final String value, @Nullable final String description) {
+ if (var == null || !var.isSystem()) {
+
+ final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
+ final View editView = layoutInflater.inflate(R.layout.var_edit, null);
+
+ final String errorMsg = CalculatorVarsTabActivity.this.getString(R.string.c_char_is_not_accepted);
+
+ final EditText editName = (EditText) editView.findViewById(R.id.var_edit_name);
+ editName.setText(name);
+ editName.addTextChangedListener(new TextWatcher() {
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ for ( int i = 0; i < s.length(); i++ ) {
+ char c = s.charAt(i);
+ if (!acceptableChars.contains(c)) {
+ s.delete(i, i+1);
+ Toast.makeText(CalculatorVarsTabActivity.this, String.format(errorMsg, c), Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+ });
+
+ final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value);
+ if (!StringUtils.isEmpty(value)) {
+ editValue.setText(value);
+ }
+
+ final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description);
+ editDescription.setText(description);
+
+ final Var.Builder varBuilder;
+ if (var != null) {
+ varBuilder = new Var.Builder(var);
+ } else {
+ varBuilder = new Var.Builder();
+ }
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder(this)
+ .setCancelable(true)
+ .setNegativeButton(R.string.c_cancel, null)
+ .setPositiveButton(R.string.c_save, new VarEditorSaver(varBuilder, var, editView))
+ .setView(editView);
+
+ if ( var != null ) {
+ // EDIT mode
+
+ builder.setTitle(R.string.c_var_edit_var);
+ builder.setNeutralButton(R.string.c_remove, new VarEditorRemover(var, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ createEditVariableDialog(var, name, value, description);
+ }
+ }));
+ } else {
+ // CREATE mode
+
+ builder.setTitle(R.string.c_var_create_var);
+ }
+
+ builder.create().show();
+ } else {
+ Toast.makeText(this, getString(R.string.c_sys_var_cannot_be_changed), Toast.LENGTH_LONG).show();
+ }
+ }
+
+ private class VarEditorSaver implements DialogInterface.OnClickListener {
+
+ @NotNull
+ private Var.Builder varBuilder;
+
+ @Nullable
+ private final Var editedInstance;
+
+ @NotNull
+ private View editView;
+
+ public VarEditorSaver(@NotNull Var.Builder varBuilder, @Nullable Var editedInstance, @NotNull View editView) {
+ this.varBuilder = varBuilder;
+ this.editedInstance = editedInstance;
+ this.editView = editView;
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == DialogInterface.BUTTON_POSITIVE) {
+ final Integer error;
+
+ final EditText editName = (EditText) editView.findViewById(R.id.var_edit_name);
+ String name = editName.getText().toString();
+
+ final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value);
+ String value = editValue.getText().toString();
+
+ final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description);
+ String description = editDescription.getText().toString();
+
+
+ final AndroidVarsRegistry varsRegistry = CalculatorEngine.instance.getVarsRegister();
+ if (isValidName(name)) {
+
+ boolean canBeSaved = false;
+
+ final Var varFromRegister = varsRegistry.get(name);
+ if ( varFromRegister == null ) {
+ canBeSaved = true;
+ } else if ( editedInstance != null && varFromRegister.getId().equals(editedInstance.getId()) ) {
+ canBeSaved = true;
+ }
+
+ if (canBeSaved) {
+ final MathType.Result mathType = MathType.getType(name, 0, false);
+
+ if (mathType.getMathType() == MathType.text || mathType.getMathType() == MathType.constant) {
+
+ if (StringUtils.isEmpty(value)) {
+ // value is empty => undefined variable
+ varBuilder.setName(name);
+ varBuilder.setDescription(description);
+ varBuilder.setValue(null);
+ error = null;
+ } else {
+ // value is not empty => must be a number
+ boolean valid = isValidValue(value);
+
+ if (valid) {
+ varBuilder.setName(name);
+ varBuilder.setDescription(description);
+ varBuilder.setValue(value);
+ error = null;
+ } else {
+ error = R.string.c_value_is_not_a_number;
+ }
+ }
+ } else {
+ error = R.string.c_var_name_clashes;
+ }
+ } else {
+ error = R.string.c_var_already_exists;
+ }
+ } else {
+ error = R.string.c_name_is_not_valid;
+ }
+
+ if (error != null) {
+ Toast.makeText(CalculatorVarsTabActivity.this, getString(error), Toast.LENGTH_LONG).show();
+ createEditVariableDialog(editedInstance, name, value, description);
+ } else {
+ final Var addedVar = varsRegistry.add(varBuilder);
+ if (isInCategory(addedVar)) {
+ if ( editedInstance != null ) {
+ CalculatorVarsTabActivity.this.getAdapter().remove(editedInstance);
+ }
+ CalculatorVarsTabActivity.this.getAdapter().add(addedVar);
+ }
+
+ varsRegistry.save(CalculatorVarsTabActivity.this);
+
+ if (isInCategory(addedVar)) {
+ sort();
+ }
+ }
+ }
+ }
+ }
+
+ private static boolean isValidName(@Nullable String name) {
+ boolean result = false;
+
+ if (!StringUtils.isEmpty(name)) {
+ try {
+ Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorEngine.instance.getEngine()), null);
+ result = true;
+ } catch (ParseException e) {
+ // not valid name;
+ }
+ }
+
+ return result;
+ }
+
+ public static boolean isValidValue(@NotNull String value) {
+ // now every string might be constant
+ return true;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ final MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.var_menu, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ boolean result;
+
+ switch (item.getItemId()) {
+ case R.id.var_menu_add_var:
+ createEditVariableDialog(null, null, null, null);
+ result = true;
+ break;
+ default:
+ result = super.onOptionsItemSelected(item);
+ }
+
+ return result;
+ }
+
+ private class VarEditorRemover implements DialogInterface.OnClickListener {
+
+ @NotNull
+ private final Var var;
+
+ @Nullable
+ private final DialogInterface.OnClickListener callbackOnCancel;
+
+ private final boolean confirmed;
+
+ public VarEditorRemover(@NotNull Var var, @Nullable DialogInterface.OnClickListener callbackOnCancel) {
+ this(var, callbackOnCancel, false);
+ }
+
+ public VarEditorRemover(@NotNull Var var, @Nullable DialogInterface.OnClickListener callbackOnCancel, boolean confirmed) {
+ this.var = var;
+ this.callbackOnCancel = callbackOnCancel;
+ this.confirmed = confirmed;
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (!confirmed) {
+ final TextView question = new TextView(CalculatorVarsTabActivity.this);
+ question.setText(String.format(getString(R.string.c_var_removal_confirmation_question), var.getName()));
+ question.setPadding(6, 6, 6, 6);
+ final AlertDialog.Builder builder = new AlertDialog.Builder(CalculatorVarsTabActivity.this)
+ .setCancelable(true)
+ .setView(question)
+ .setTitle(R.string.c_var_removal_confirmation)
+ .setNegativeButton(R.string.c_no, callbackOnCancel)
+ .setPositiveButton(R.string.c_yes, new VarEditorRemover(var, callbackOnCancel, true));
+
+ builder.create().show();
+ } else {
+ if (isInCategory(var)) {
+ getAdapter().remove(var);
+ }
+ final AndroidVarsRegistry varsRegistry = CalculatorEngine.instance.getVarsRegister();
+ varsRegistry.remove(var);
+ varsRegistry.save(CalculatorVarsTabActivity.this);
+ if (isInCategory(var)) {
+ CalculatorVarsTabActivity.this.getAdapter().notifyDataSetChanged();
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryActivity.java b/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryActivity.java
index 7772417f..d1065b39 100644
--- a/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryActivity.java
+++ b/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryActivity.java
@@ -14,6 +14,7 @@ import android.widget.TabHost;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.R;
+import org.solovyev.android.view.prefs.AndroidUtils;
/**
* User: serso
@@ -26,7 +27,7 @@ public class CalculatorHistoryActivity extends TabActivity {
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.history_tabs);
+ setContentView(R.layout.tabs);
final TabHost tabHost = getTabHost();
@@ -34,6 +35,8 @@ public class CalculatorHistoryActivity extends TabActivity {
createTab(tabHost, "history", R.string.c_history, HistoryActivityTab.class);
tabHost.setCurrentTab(0);
+
+ AndroidUtils.centerAndWrapTabsFor(tabHost);
}
private void createTab(@NotNull TabHost tabHost,
@@ -46,7 +49,7 @@ public class CalculatorHistoryActivity extends TabActivity {
final Intent intent = new Intent().setClass(this, activityClass);
// Initialize a TabSpec for each tab and add it to the TabHost
- spec = tabHost.newTabSpec(tabId).setIndicator(getString(tabCaptionId)).setContent(intent);
+ spec = tabHost.newTabSpec(tabId).setIndicator(this.getString(tabCaptionId)).setContent(intent);
tabHost.addTab(spec);
}
diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidFunctionsMathRegistry.java b/src/main/java/org/solovyev/android/calculator/model/AndroidFunctionsMathRegistry.java
index 8d25d821..c5204baa 100644
--- a/src/main/java/org/solovyev/android/calculator/model/AndroidFunctionsMathRegistry.java
+++ b/src/main/java/org/solovyev/android/calculator/model/AndroidFunctionsMathRegistry.java
@@ -6,11 +6,16 @@
package org.solovyev.android.calculator.model;
+import jscl.math.function.ArcTrigonometric;
+import jscl.math.function.Comparison;
+import jscl.math.function.Function;
+import jscl.math.function.Trigonometric;
import org.jetbrains.annotations.NotNull;
+import org.solovyev.android.calculator.R;
import org.solovyev.common.math.MathRegistry;
+import org.solovyev.common.utils.CollectionsUtils;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
/**
* User: serso
@@ -19,6 +24,77 @@ import java.util.Map;
*/
public class AndroidFunctionsMathRegistry extends AndroidMathRegistryImpl {
+ public static enum Category {
+
+ trigonometric(R.string.c_fun_category_trig, 100){
+ @Override
+ boolean isInCategory(@NotNull Function function) {
+ return (function instanceof Trigonometric || function instanceof ArcTrigonometric) && !hyperbolic_trigonometric.isInCategory(function);
+ }
+ },
+
+ hyperbolic_trigonometric(R.string.c_fun_category_hyper_trig, 300) {
+
+ private final List names = Arrays.asList("sinh", "cosh", "tanh", "coth", "asinh", "acosh", "atanh", "acoth");
+
+ @Override
+ boolean isInCategory(@NotNull Function function) {
+ return names.contains(function.getName());
+ }
+ },
+
+ comparison(R.string.c_fun_category_comparison, 200) {
+ @Override
+ boolean isInCategory(@NotNull Function function) {
+ return function instanceof Comparison;
+ }
+ },
+
+ common(R.string.c_fun_category_common, 0) {
+ @Override
+ boolean isInCategory(@NotNull Function function) {
+ for (Category category : values()) {
+ if ( category != this ) {
+ if ( category.isInCategory(function) ) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+ };
+
+ private final int captionId;
+
+ private final int tabOrder;
+
+ Category(int captionId, int tabOrder) {
+ this.captionId = captionId;
+ this.tabOrder = tabOrder;
+ }
+
+ public int getCaptionId() {
+ return captionId;
+ }
+
+ abstract boolean isInCategory(@NotNull Function function);
+
+ @NotNull
+ public static List getCategoriesByTabOrder() {
+ final List result = CollectionsUtils.asList(Category.values());
+
+ Collections.sort(result, new Comparator() {
+ @Override
+ public int compare(Category category, Category category1) {
+ return category.tabOrder - category1.tabOrder;
+ }
+ });
+
+ return result;
+ }
+ }
+
@NotNull
private static final Map substitutes = new HashMap();
static {
@@ -37,4 +113,15 @@ public class AndroidFunctionsMathRegistry extends AndroidMathRegistryImpl getSubstitutes() {
return substitutes;
}
+
+ @Override
+ public String getCategory(@NotNull Function function) {
+ for (Category category : Category.values()) {
+ if ( category.isInCategory(function) ) {
+ return category.name();
+ }
+ }
+
+ return null;
+ }
}
diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistry.java b/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistry.java
index 70e762c5..8d898582 100644
--- a/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistry.java
+++ b/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistry.java
@@ -7,7 +7,6 @@
package org.solovyev.android.calculator.model;
import android.content.Context;
-import jscl.math.function.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.common.math.MathEntity;
@@ -21,5 +20,8 @@ import org.solovyev.common.math.MathRegistry;
public interface AndroidMathRegistry extends MathRegistry {
@Nullable
- String getDescription(@NotNull Context context, @NotNull String functionName);
+ String getDescription(@NotNull Context context, @NotNull String mathEntityName);
+
+ @Nullable
+ String getCategory(@NotNull T mathEntity);
}
diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistryImpl.java b/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistryImpl.java
index cdca7963..ae7135e6 100644
--- a/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistryImpl.java
+++ b/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistryImpl.java
@@ -40,13 +40,13 @@ public abstract class AndroidMathRegistryImpl implements A
@Nullable
@Override
- public String getDescription(@NotNull Context context, @NotNull String name) {
+ public String getDescription(@NotNull Context context, @NotNull String mathEntityName) {
final String stringName;
final Map substitutes = getSubstitutes();
- final String substitute = substitutes.get(name);
+ final String substitute = substitutes.get(mathEntityName);
if (substitute == null) {
- stringName = prefix + name;
+ stringName = prefix + mathEntityName;
} else {
stringName = prefix + substitute;
}
diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidOperatorsMathRegistry.java b/src/main/java/org/solovyev/android/calculator/model/AndroidOperatorsMathRegistry.java
index 261b61de..79b37cf2 100644
--- a/src/main/java/org/solovyev/android/calculator/model/AndroidOperatorsMathRegistry.java
+++ b/src/main/java/org/solovyev/android/calculator/model/AndroidOperatorsMathRegistry.java
@@ -43,4 +43,9 @@ public class AndroidOperatorsMathRegistry extends AndroidMathRegistryImpl getSubstitutes() {
return substitutes;
}
+
+ @Override
+ public String getCategory(@NotNull Operator mathEntity) {
+ return null;
+ }
}
diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidPostfixFunctionsRegistry.java b/src/main/java/org/solovyev/android/calculator/model/AndroidPostfixFunctionsRegistry.java
index 58c0277a..58075907 100644
--- a/src/main/java/org/solovyev/android/calculator/model/AndroidPostfixFunctionsRegistry.java
+++ b/src/main/java/org/solovyev/android/calculator/model/AndroidPostfixFunctionsRegistry.java
@@ -42,4 +42,9 @@ public class AndroidPostfixFunctionsRegistry extends AndroidMathRegistryImpl getSubstitutes() {
return substitutes;
}
+
+ @Override
+ public String getCategory(@NotNull Operator mathEntity) {
+ return null;
+ }
}
diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistry.java b/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistry.java
index 156d3c0a..80b2b85e 100644
--- a/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistry.java
+++ b/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistry.java
@@ -10,14 +10,65 @@ import android.content.Context;
import android.content.SharedPreferences;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.solovyev.common.math.MathRegistry;
+import org.solovyev.android.calculator.R;
+import org.solovyev.common.utils.CollectionsUtils;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
/**
* User: serso
* Date: 10/6/11
* Time: 9:31 PM
*/
-public interface AndroidVarsRegistry extends MathRegistry{
+public interface AndroidVarsRegistry extends AndroidMathRegistry{
+
+ public static enum Category {
+
+ system(R.string.c_var_system, 100){
+ @Override
+ boolean isInCategory(@NotNull Var var) {
+ return var.isSystem();
+ }
+ },
+
+ my(R.string.c_var_my, 0) {
+ @Override
+ boolean isInCategory(@NotNull Var var) {
+ return !var.isSystem();
+ }
+ };
+
+ private final int captionId;
+
+ private final int tabOrder;
+
+ Category(int captionId, int tabOrder) {
+ this.captionId = captionId;
+ this.tabOrder = tabOrder;
+ }
+
+ public int getCaptionId() {
+ return captionId;
+ }
+
+ abstract boolean isInCategory(@NotNull Var var);
+
+ @NotNull
+ public static List getCategoriesByTabOrder() {
+ final List result = CollectionsUtils.asList(Category.values());
+
+ Collections.sort(result, new Comparator() {
+ @Override
+ public int compare(Category category, Category category1) {
+ return category.tabOrder - category1.tabOrder;
+ }
+ });
+
+ return result;
+ }
+ }
void load(@Nullable Context context, @Nullable SharedPreferences preferences);
diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistryImpl.java b/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistryImpl.java
index 89b901cb..c6267e4c 100644
--- a/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistryImpl.java
+++ b/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistryImpl.java
@@ -234,4 +234,25 @@ class AndroidVarsRegistryImpl implements AndroidVarsRegistry {
return null;
}
}
+
+ @Override
+ public String getDescription(@NotNull Context context, @NotNull String mathEntityName) {
+ final Var var = get(mathEntityName);
+ if (var != null) {
+ return var.getDescription();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public String getCategory(@NotNull Var var) {
+ for (Category category : Category.values()) {
+ if ( category.isInCategory(var) ) {
+ return category.name();
+ }
+ }
+
+ return null;
+ }
}
diff --git a/src/main/java/org/solovyev/android/view/prefs/AndroidUtils.java b/src/main/java/org/solovyev/android/view/prefs/AndroidUtils.java
new file mode 100644
index 00000000..2d369309
--- /dev/null
+++ b/src/main/java/org/solovyev/android/view/prefs/AndroidUtils.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.android.view.prefs;
+
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TabHost;
+import android.widget.TextView;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: serso
+ * Date: 12/21/11
+ * Time: 11:54 PM
+ */
+public final class AndroidUtils {
+
+ // not intended for instantiation
+ private AndroidUtils() {
+ throw new AssertionError();
+ }
+
+ public static void centerAndWrapTabsFor(@NotNull TabHost tabHost) {
+ int tabCount = tabHost.getTabWidget().getTabCount();
+ for (int i = 0; i < tabCount; i++) {
+ final View view = tabHost.getTabWidget().getChildTabViewAt(i);
+ if ( view != null ) {
+ if (view.getLayoutParams().height > 0) {
+ // reduce height of the tab
+ view.getLayoutParams().height *= 0.8;
+ }
+
+ // get title text view
+ final View textView = view.findViewById(android.R.id.title);
+ if ( textView instanceof TextView) {
+ // just in case check the type
+
+ // center text
+ ((TextView) textView).setGravity(Gravity.CENTER);
+ // wrap text
+ ((TextView) textView).setSingleLine(false);
+
+ // explicitly set layout parameters
+ textView.getLayoutParams().height = ViewGroup.LayoutParams.FILL_PARENT;
+ textView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
+ }
+ }
+ }
+ }
+}