Variables refactor

This commit is contained in:
serso 2016-01-30 22:27:25 +01:00
parent a52bc5f5e4
commit 51ced42d8e
21 changed files with 310 additions and 664 deletions

View File

@ -478,50 +478,53 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
} }
private void updateAnsVariable(@NonNull String value) { private void updateAnsVariable(@NonNull String value) {
final EntitiesRegistry<IConstant> varsRegistry = Locator.getInstance().getEngine().getVariablesRegistry(); final VariablesRegistry variablesRegistry = Locator.getInstance().getEngine().getVariablesRegistry();
final IConstant variable = varsRegistry.get(VariablesRegistry.ANS); final IConstant variable = variablesRegistry.get(VariablesRegistry.ANS);
final CppVariable.Builder b = variable != null ? CppVariable.builder(variable) : CppVariable.builder(VariablesRegistry.ANS); final CppVariable.Builder b = variable != null ? CppVariable.builder(variable) : CppVariable.builder(VariablesRegistry.ANS);
b.withValue(value); b.withValue(value);
b.withSystem(true); b.withSystem(true);
b.withDescription(CalculatorMessages.getBundle().getString(CalculatorMessages.ans_description)); b.withDescription(CalculatorMessages.getBundle().getString(CalculatorMessages.ans_description));
VariablesRegistry.add(varsRegistry, b.build().toJsclBuilder(), variable, this); variablesRegistry.add(b.build().toJsclBuilder(), variable);
} }
@Subscribe @Subscribe
public void onFunctionAdded(@Nonnull FunctionsRegistry.AddedEvent event) { public void onFunctionAdded(@Nonnull FunctionsRegistry.AddedEvent event) {
evaluate(); evaluate();
} }
@Subscribe @Subscribe
public void onFunctionsChanged(@Nonnull FunctionsRegistry.ChangedEvent event) { public void onFunctionsChanged(@Nonnull FunctionsRegistry.ChangedEvent event) {
evaluate(); evaluate();
} }
@Subscribe @Subscribe
public void onFunctionsRemoved(@Nonnull FunctionsRegistry.RemovedEvent event) { public void onFunctionsRemoved(@Nonnull FunctionsRegistry.RemovedEvent event) {
evaluate(); evaluate();
} }
@Subscribe
public void onVariableRemoved(@NonNull VariablesRegistry.RemovedEvent e) {
evaluate();
}
@Subscribe
public void onVariableAdded(@NonNull VariablesRegistry.AddedEvent e) {
evaluate();
}
@Subscribe
public void onVariableChanged(@NonNull VariablesRegistry.ChangedEvent e) {
if (!e.newVariable.getName().equals(VariablesRegistry.ANS)) {
evaluate();
}
}
@Override @Override
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
switch (calculatorEventType) { switch (calculatorEventType) {
case constant_changed:
final IConstant newConstant = ((Change<IConstant>) data).getNewValue();
if (!newConstant.getName().equals(VariablesRegistry.ANS)) {
evaluate();
}
break;
case constant_added:
case constant_removed:
evaluate();
break;
case use_constant:
final IConstant constant = (IConstant) data;
Locator.getInstance().getKeyboard().buttonPressed(constant.getName());
break;
case use_operator: case use_operator:
final Operator operator = (Operator) data; final Operator operator = (Operator) data;
Locator.getInstance().getKeyboard().buttonPressed(operator.getName()); Locator.getInstance().getKeyboard().buttonPressed(operator.getName());
@ -535,8 +538,4 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
return App.getEditor(); return App.getEditor();
} }
@Nonnull
private Display getDisplay() {
return App.getDisplay();
}
} }

View File

@ -29,6 +29,7 @@ import jscl.JsclMathEngine;
import jscl.MathEngine; import jscl.MathEngine;
import jscl.NumeralBase; import jscl.NumeralBase;
import jscl.math.operator.Operator; import jscl.math.operator.Operator;
import jscl.text.*;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.calculator.functions.FunctionsRegistry; import org.solovyev.android.calculator.functions.FunctionsRegistry;
import org.solovyev.android.prefs.BooleanPreference; import org.solovyev.android.prefs.BooleanPreference;
@ -40,6 +41,7 @@ import org.solovyev.common.text.NumberMapper;
import org.solovyev.common.text.Strings; import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import java.util.ArrayList; import java.util.ArrayList;
@ -102,6 +104,19 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene
editor.putString(preference.getKey(), preferences.getString(oldKey, null)); editor.putString(preference.getKey(), preferences.getString(oldKey, null));
} }
public static boolean isValidName(@Nullable String name) {
if (!Strings.isEmpty(name)) {
try {
Identifier.parser.parse(Parser.Parameters.get(name), null);
return true;
} catch (jscl.text.ParseException e) {
// not valid name;
}
}
return false;
}
@Nonnull @Nonnull
public VariablesRegistry getVariablesRegistry() { public VariablesRegistry getVariablesRegistry() {
return variablesRegistry; return variablesRegistry;

View File

@ -39,7 +39,6 @@ import org.solovyev.android.calculator.variables.OldVars;
import org.solovyev.android.calculator.variables.VariableCategory; import org.solovyev.android.calculator.variables.VariableCategory;
import org.solovyev.android.io.FileSaver; import org.solovyev.android.io.FileSaver;
import org.solovyev.common.JBuilder; import org.solovyev.common.JBuilder;
import org.solovyev.common.math.MathEntity;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -72,19 +71,21 @@ public class VariablesRegistry extends BaseEntitiesRegistry<IConstant> {
super(mathEngine.getConstantsRegistry(), "c_var_description_"); super(mathEngine.getConstantsRegistry(), "c_var_description_");
} }
public static <T extends MathEntity> void add(@Nonnull EntitiesRegistry<T> registry, public void add(@NonNull JBuilder<? extends IConstant> builder, @Nullable IConstant oldVariable) {
@Nonnull JBuilder<? extends T> builder, final IConstant variable = add(builder);
@Nullable T editedInstance, if (oldVariable == null) {
@Nonnull Object source) { bus.post(new AddedEvent(variable));
final T addedVar = registry.add(builder);
if (editedInstance == null) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.constant_added, addedVar, source);
} else { } else {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.constant_changed, ChangeImpl.newInstance(editedInstance, addedVar), source); bus.post(new ChangedEvent(oldVariable, variable));
} }
} }
@Override
public void remove(@Nonnull IConstant variable) {
super.remove(variable);
bus.post(new RemovedEvent(variable));
}
@Nonnull @Nonnull
@Override @Override
protected Map<String, String> getSubstitutes() { protected Map<String, String> getSubstitutes() {
@ -97,14 +98,14 @@ public class VariablesRegistry extends BaseEntitiesRegistry<IConstant> {
try { try {
migrateOldVariables(); migrateOldVariables();
for (CppVariable variable : loadEntities(CppVariable.JSON_CREATOR)) {
addSafely(variable.toJsclBuilder());
}
addSafely("x"); addSafely("x");
addSafely("y"); addSafely("y");
addSafely("t"); addSafely("t");
addSafely("j"); addSafely("j");
for (CppVariable variable : loadEntities(CppVariable.JSON_CREATOR)) {
addSafely(variable.toJsclBuilder());
}
} finally { } finally {
setInitialized(); setInitialized();
} }
@ -148,9 +149,9 @@ public class VariablesRegistry extends BaseEntitiesRegistry<IConstant> {
@Override @Override
public String getDescription(@Nonnull String name) { public String getDescription(@Nonnull String name) {
final IConstant var = get(name); final IConstant variable = get(name);
if (var != null && !var.isSystem()) { if (variable != null && !variable.isSystem()) {
return var.getDescription(); return variable.getDescription();
} else { } else {
return super.getDescription(name); return super.getDescription(name);
} }
@ -160,4 +161,34 @@ public class VariablesRegistry extends BaseEntitiesRegistry<IConstant> {
public Category getCategory(@Nonnull IConstant variable) { public Category getCategory(@Nonnull IConstant variable) {
return Entities.getCategory(variable, VariableCategory.values()); return Entities.getCategory(variable, VariableCategory.values());
} }
public static final class AddedEvent {
@NonNull
public final IConstant variable;
public AddedEvent(@NonNull IConstant variable) {
this.variable = variable;
}
}
public static final class ChangedEvent {
@NonNull
public final IConstant oldVariable;
@NonNull
public final IConstant newVariable;
public ChangedEvent(@NonNull IConstant oldVariable, @NonNull IConstant newVariable) {
this.oldVariable = oldVariable;
this.newVariable = newVariable;
}
}
public static final class RemovedEvent {
@NonNull
public final IConstant variable;
public RemovedEvent(@NonNull IConstant variable) {
this.variable = variable;
}
}
} }

View File

@ -1,37 +1,45 @@
package org.solovyev.android.calculator.functions; package org.solovyev.android.calculator.entities;
import android.app.Activity; import android.app.Activity;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.support.annotation.StringRes;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class FunctionRemovalDialog { public class EntityRemovalDialog {
@Nonnull @Nonnull
private final Activity activity; private final Activity activity;
@Nonnull @Nonnull
private final String functionName; private final String name;
@Nonnull @Nonnull
private final DialogInterface.OnClickListener listener; private final DialogInterface.OnClickListener listener;
@StringRes
private final int message;
private FunctionRemovalDialog(@Nonnull Activity activity, @Nonnull String functionName, @Nonnull DialogInterface.OnClickListener listener) { private EntityRemovalDialog(@Nonnull Activity activity, @Nonnull String name, @Nonnull DialogInterface.OnClickListener listener, int message) {
this.activity = activity; this.activity = activity;
this.functionName = functionName; this.name = name;
this.listener = listener; this.listener = listener;
this.message = message;
} }
public static void show(@Nonnull Activity activity, @Nonnull String functionName, @Nonnull DialogInterface.OnClickListener listener) { public static void showForFunction(@Nonnull Activity activity, @Nonnull String name, @Nonnull DialogInterface.OnClickListener listener) {
new FunctionRemovalDialog(activity, functionName, listener).show(); new EntityRemovalDialog(activity, name, listener, R.string.function_removal_confirmation_question).show();
} }
public void show() { public static void showForVariable(@Nonnull Activity activity, @Nonnull String name, @Nonnull DialogInterface.OnClickListener listener) {
new EntityRemovalDialog(activity, name, listener, R.string.c_var_removal_confirmation_question).show();
}
private void show() {
new AlertDialog.Builder(activity, App.getTheme().alertDialogTheme) new AlertDialog.Builder(activity, App.getTheme().alertDialogTheme)
.setCancelable(true) .setCancelable(true)
.setTitle(R.string.removal_confirmation) .setTitle(R.string.removal_confirmation)
.setMessage(activity.getString(R.string.function_removal_confirmation_question, functionName)) .setMessage(activity.getString(message, name))
.setNegativeButton(R.string.c_no, null) .setNegativeButton(R.string.c_no, null)
.setPositiveButton(R.string.c_yes, new DialogInterface.OnClickListener() { .setPositiveButton(R.string.c_yes, new DialogInterface.OnClickListener() {
@Override @Override

View File

@ -4,7 +4,9 @@ import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import jscl.math.function.CustomFunction;
import jscl.math.function.Function;
import jscl.math.function.IFunction;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -14,16 +16,11 @@ import org.solovyev.android.calculator.json.Jsonable;
import org.solovyev.common.JBuilder; import org.solovyev.common.JBuilder;
import org.solovyev.common.text.Strings; import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import javax.annotation.Nonnull;
import jscl.math.function.CustomFunction;
import jscl.math.function.Function;
import jscl.math.function.IFunction;
public class CppFunction implements Jsonable, Parcelable { public class CppFunction implements Jsonable, Parcelable {
public static final Json.Creator<CppFunction> JSON_CREATOR = new Json.Creator<CppFunction>() { public static final Json.Creator<CppFunction> JSON_CREATOR = new Json.Creator<CppFunction>() {
@ -192,6 +189,15 @@ public class CppFunction implements Jsonable, Parcelable {
return builder; return builder;
} }
@Override
public String toString() {
if (id == NO_ID) {
return name + parameters.toString() + "{" + body + "}";
} else {
return name + "[#" + id + "]" + parameters.toString() + "{" + body + "}";
}
}
public static final class Builder { public static final class Builder {
@NonNull @NonNull

View File

@ -45,8 +45,8 @@ import jscl.math.function.Function;
import org.solovyev.android.Activities; import org.solovyev.android.Activities;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.entities.EntityRemovalDialog;
import org.solovyev.android.calculator.keyboard.FloatingKeyboardWindow; import org.solovyev.android.calculator.keyboard.FloatingKeyboardWindow;
import org.solovyev.android.calculator.math.edit.VarEditorSaver;
import org.solovyev.android.calculator.view.EditTextCompat; import org.solovyev.android.calculator.view.EditTextCompat;
import org.solovyev.common.math.MathRegistry; import org.solovyev.common.math.MathRegistry;
@ -185,7 +185,7 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
} }
private void showRemovalDialog(@NonNull final CppFunction function) { private void showRemovalDialog(@NonNull final CppFunction function) {
FunctionRemovalDialog.show(getActivity(), function.name, new DialogInterface.OnClickListener() { EntityRemovalDialog.showForFunction(getActivity(), function.name, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
Check.isTrue(which == DialogInterface.BUTTON_POSITIVE); Check.isTrue(which == DialogInterface.BUTTON_POSITIVE);
@ -292,7 +292,7 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
private boolean validateName() { private boolean validateName() {
final String name = nameView.getText().toString(); final String name = nameView.getText().toString();
if (!VarEditorSaver.isValidName(name)) { if (!Engine.isValidName(name)) {
setError(nameLabel, getString(R.string.function_name_is_not_valid)); setError(nameLabel, getString(R.string.function_name_is_not_valid));
return false; return false;
} }
@ -344,7 +344,7 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
final TextInputLayout paramLabel = paramsView.getParamLabel(i); final TextInputLayout paramLabel = paramsView.getParamLabel(i);
if (TextUtils.isEmpty(parameter)) { if (TextUtils.isEmpty(parameter)) {
clearError(paramLabel); clearError(paramLabel);
} else if (!VarEditorSaver.isValidName(parameter)) { } else if (!Engine.isValidName(parameter)) {
valid = false; valid = false;
setError(paramLabel, getString(R.string.invalid_name)); setError(paramLabel, getString(R.string.invalid_name));
} else if (usedParameters.contains(parameter)) { } else if (usedParameters.contains(parameter)) {

View File

@ -15,6 +15,7 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.EditText; import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import org.solovyev.android.Check;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
public class FloatingKeyboardWindow { public class FloatingKeyboardWindow {
@ -43,8 +44,13 @@ public class FloatingKeyboardWindow {
if (!isShown()) { if (!isShown()) {
return; return;
} }
moveDialog(Gravity.CENTER); Check.isNotNull(window);
window.dismiss(); window.dismiss();
onDismissed();
}
private void onDismissed() {
moveDialog(Gravity.CENTER);
window = null; window = null;
dialog = null; dialog = null;
} }
@ -73,7 +79,7 @@ public class FloatingKeyboardWindow {
window.setOnDismissListener(new PopupWindow.OnDismissListener() { window.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override @Override
public void onDismiss() { public void onDismiss() {
window = null; onDismissed();
if (dismissListener != null) { if (dismissListener != null) {
dismissListener.onDismiss(); dismissListener.onDismiss();
} }
@ -109,7 +115,7 @@ public class FloatingKeyboardWindow {
return (V) window.getContentView(); return (V) window.getContentView();
} }
public void moveDialog(int gravity) { private void moveDialog(int gravity) {
if (dialog == null) { if (dialog == null) {
return; return;
} }

View File

@ -280,6 +280,19 @@ public enum MathType {
} }
if (s.length() > 1) { if (s.length() > 1) {
if (mathType == function) {
final int nextToken = i + s.length();
if (nextToken < text.length()) {
// function must have an open group symbol after its name
if (MathType.open_group_symbol.getTokens().contains(text.substring(nextToken, nextToken + 1))) {
return result.set(function, s);
}
} else if (nextToken == text.length()) {
// or its name should finish the expression
return result.set(function, s);
}
continue;
}
return result.set(mathType, s); return result.set(mathType, s);
} }

View File

@ -34,6 +34,7 @@ import jscl.math.function.IFunction;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.entities.Category; import org.solovyev.android.calculator.entities.Category;
import org.solovyev.android.calculator.entities.EntityRemovalDialog;
import org.solovyev.android.calculator.functions.*; import org.solovyev.android.calculator.functions.*;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -67,13 +68,6 @@ public class FunctionsFragment extends BaseEntitiesFragment<Function> {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = super.onCreateView(inflater, container, savedInstanceState); final View view = super.onCreateView(inflater, container, savedInstanceState);
bus.register(this); bus.register(this);
return view;
}
@Override
public void onViewCreated(View root, Bundle savedInstanceState) {
super.onViewCreated(root, savedInstanceState);
fab.setVisibility(View.VISIBLE); fab.setVisibility(View.VISIBLE);
fab.attachToRecyclerView(recyclerView); fab.attachToRecyclerView(recyclerView);
fab.setOnClickListener(new View.OnClickListener() { fab.setOnClickListener(new View.OnClickListener() {
@ -82,6 +76,7 @@ public class FunctionsFragment extends BaseEntitiesFragment<Function> {
EditFunctionFragment.showDialog(getActivity()); EditFunctionFragment.showDialog(getActivity());
} }
}); });
return view;
} }
@Override @Override
@ -115,7 +110,7 @@ public class FunctionsFragment extends BaseEntitiesFragment<Function> {
} }
return true; return true;
case R.string.c_remove: case R.string.c_remove:
FunctionRemovalDialog.show(getActivity(), function.getName(), new DialogInterface.OnClickListener() { EntityRemovalDialog.showForFunction(getActivity(), function.getName(), new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
Check.isTrue(which == DialogInterface.BUTTON_POSITIVE); Check.isTrue(which == DialogInterface.BUTTON_POSITIVE);

View File

@ -1,150 +0,0 @@
/*
* Copyright 2013 serso aka se.solovyev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Contact details
*
* Email: se.solovyev@gmail.com
* Site: http://se.solovyev.org
*/
package org.solovyev.android.calculator.math.edit;
import android.view.View;
import android.widget.EditText;
import jscl.text.Identifier;
import jscl.text.ParseException;
import jscl.text.Parser;
import org.solovyev.android.calculator.EntitiesRegistry;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.VariablesRegistry;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.model.MathEntityBuilder;
import org.solovyev.android.calculator.variables.VariablesFragment;
import org.solovyev.common.math.MathEntity;
import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class VarEditorSaver<T extends MathEntity> implements View.OnClickListener {
@Nonnull
private final MathEntityBuilder<? extends T> varBuilder;
@Nullable
private final T editedInstance;
@Nonnull
private final EntitiesRegistry<T> mathRegistry;
@Nonnull
private final Object source;
@Nonnull
private View editView;
public VarEditorSaver(@Nonnull MathEntityBuilder<? extends T> varBuilder,
@Nullable T editedInstance,
@Nonnull View editView,
@Nonnull EntitiesRegistry<T> mathRegistry,
@Nonnull Object source) {
this.varBuilder = varBuilder;
this.editedInstance = editedInstance;
this.editView = editView;
this.mathRegistry = mathRegistry;
this.source = source;
}
public static boolean isValidName(@Nullable String name) {
if (!Strings.isEmpty(name)) {
try {
Identifier.parser.parse(Parser.Parameters.get(name), null);
return true;
} catch (ParseException e) {
// not valid name;
}
}
return false;
}
@Override
public void onClick(View v) {
final Integer error;
final EditText editName = (EditText) editView.findViewById(R.id.variable_name);
String name = editName.getText().toString();
final EditText editValue = (EditText) editView.findViewById(R.id.variable_value);
String value = editValue.getText().toString();
final EditText editDescription = (EditText) editView.findViewById(R.id.variable_description);
String description = editDescription.getText().toString();
if (isValidName(name)) {
boolean canBeSaved = false;
final T entityFromRegistry = mathRegistry.get(name);
if (entityFromRegistry == null) {
canBeSaved = true;
} else if (editedInstance != null && entityFromRegistry.getId().equals(editedInstance.getId())) {
canBeSaved = true;
}
if (canBeSaved) {
final MathType.Result mathType = MathType.getType(name, 0, false);
if (mathType.type == MathType.text || mathType.type == MathType.constant) {
if (Strings.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 = VariablesFragment.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) {
Locator.getInstance().getNotifier().showMessage(error, MessageType.error);
} else {
VariablesRegistry.add(mathRegistry, varBuilder, editedInstance, source);
}
}
}

View File

@ -37,10 +37,11 @@ public class CppVariable implements Jsonable, Parcelable {
return new CppVariable[size]; return new CppVariable[size];
} }
}; };
public static final int NO_ID = CppFunction.NO_ID;
private static final String JSON_NAME = "n"; private static final String JSON_NAME = "n";
private static final String JSON_VALUE = "v"; private static final String JSON_VALUE = "v";
private static final String JSON_DESCRIPTION = "d"; private static final String JSON_DESCRIPTION = "d";
protected int id = CppFunction.NO_ID; protected int id = NO_ID;
@Nonnull @Nonnull
protected String name; protected String name;
@Nonnull @Nonnull
@ -62,7 +63,7 @@ public class CppVariable implements Jsonable, Parcelable {
} }
protected CppVariable(@NonNull IConstant that) { protected CppVariable(@NonNull IConstant that) {
id = that.isIdDefined() ? that.getId() : CppFunction.NO_ID; id = that.isIdDefined() ? that.getId() : NO_ID;
name = that.getName(); name = that.getName();
value = nullToEmpty(that.getValue()); value = nullToEmpty(that.getValue());
description = nullToEmpty(that.getDescription()); description = nullToEmpty(that.getDescription());
@ -71,7 +72,7 @@ public class CppVariable implements Jsonable, Parcelable {
private CppVariable(@NonNull JSONObject json) throws JSONException { private CppVariable(@NonNull JSONObject json) throws JSONException {
this.name = json.getString(JSON_NAME); this.name = json.getString(JSON_NAME);
this.value = json.optString(JSON_DESCRIPTION); this.value = json.optString(JSON_VALUE);
this.description = json.optString(JSON_DESCRIPTION); this.description = json.optString(JSON_DESCRIPTION);
} }
@ -88,6 +89,11 @@ public class CppVariable implements Jsonable, Parcelable {
return new Builder(name); return new Builder(name);
} }
@NonNull
public static CppVariable.Builder builder(@NonNull String name, double value) {
return new Builder(name).withValue(value);
}
@NonNull @NonNull
public static Builder builder(@NonNull IConstant constant) { public static Builder builder(@NonNull IConstant constant) {
return new Builder(constant); return new Builder(constant);
@ -152,6 +158,15 @@ public class CppVariable implements Jsonable, Parcelable {
dest.writeByte((byte) (system ? 1 : 0)); dest.writeByte((byte) (system ? 1 : 0));
} }
@Override
public String toString() {
if (id == NO_ID) {
return name + "=" + value;
} else {
return name + "[#" + id + "]=" + value;
}
}
public static class Builder { public static class Builder {
@NonNull @NonNull
private final CppVariable variable; private final CppVariable variable;
@ -179,6 +194,12 @@ public class CppVariable implements Jsonable, Parcelable {
return this; return this;
} }
@Nonnull
public Builder withValue(double value) {
Check.isTrue(!built);
return withValue(Double.toString(value));
}
@Nonnull @Nonnull
public Builder withSystem(boolean system) { public Builder withSystem(boolean system) {
Check.isTrue(!built); Check.isTrue(!built);

View File

@ -22,7 +22,9 @@
package org.solovyev.android.calculator.variables; package org.solovyev.android.calculator.variables;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
@ -45,11 +47,11 @@ import jscl.math.function.IConstant;
import org.solovyev.android.Activities; import org.solovyev.android.Activities;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.entities.EntityRemovalDialog;
import org.solovyev.android.calculator.functions.FunctionsRegistry; import org.solovyev.android.calculator.functions.FunctionsRegistry;
import org.solovyev.android.calculator.keyboard.FloatingKeyboard; import org.solovyev.android.calculator.keyboard.FloatingKeyboard;
import org.solovyev.android.calculator.keyboard.FloatingKeyboardWindow; import org.solovyev.android.calculator.keyboard.FloatingKeyboardWindow;
import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.math.edit.VarEditorSaver;
import org.solovyev.android.calculator.view.EditTextCompat; import org.solovyev.android.calculator.view.EditTextCompat;
import org.solovyev.common.text.Strings; import org.solovyev.common.text.Strings;
@ -59,25 +61,25 @@ import javax.inject.Inject;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.solovyev.android.calculator.functions.CppFunction.NO_ID; import static org.solovyev.android.calculator.variables.CppVariable.NO_ID;
public class EditVariableFragment extends BaseDialogFragment implements CalculatorEventListener, View.OnFocusChangeListener, View.OnKeyListener, View.OnClickListener { public class EditVariableFragment extends BaseDialogFragment implements View.OnFocusChangeListener, View.OnKeyListener, View.OnClickListener {
private static final String ARG_VARIABLE = "variable"; private static final String ARG_VARIABLE = "variable";
private final static List<Character> ACCEPTABLE_CHARACTERS = Arrays.asList(Strings.toObjects(("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_" + GreekFloatingKeyboard.ALPHABET).toCharArray())); private final static List<Character> ACCEPTABLE_CHARACTERS = Arrays.asList(Strings.toObjects(("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_" + GreekFloatingKeyboard.ALPHABET).toCharArray()));
@NonNull @NonNull
private final KeyboardUser keyboardUser = new KeyboardUser();
@Bind(R.id.variable_name_label)
TextInputLayout nameLabel;
@Bind(R.id.variable_name)
EditTextCompat nameView;
@NonNull
private final FloatingKeyboardWindow keyboardWindow = new FloatingKeyboardWindow(new PopupWindow.OnDismissListener() { private final FloatingKeyboardWindow keyboardWindow = new FloatingKeyboardWindow(new PopupWindow.OnDismissListener() {
@Override @Override
public void onDismiss() { public void onDismiss() {
nameView.setShowSoftInputOnFocusCompat(true); nameView.setShowSoftInputOnFocusCompat(true);
} }
}); });
@NonNull
private final KeyboardUser keyboardUser = new KeyboardUser();
@Bind(R.id.variable_name_label)
TextInputLayout nameLabel;
@Bind(R.id.variable_name)
EditTextCompat nameView;
@Bind(R.id.variable_keyboard_button) @Bind(R.id.variable_keyboard_button)
Button keyboardButton; Button keyboardButton;
@Bind(R.id.variable_value_label) @Bind(R.id.variable_value_label)
@ -188,13 +190,23 @@ public class EditVariableFragment extends BaseDialogFragment implements Calculat
neutral.setOnClickListener(new View.OnClickListener() { neutral.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
// FIXME: 2016-01-30 removal dialog showRemovalDialog(variable);
// showRemovalDialog(function);
} }
}); });
} }
} }
private void showRemovalDialog(@NonNull final CppVariable variable) {
EntityRemovalDialog.showForVariable(getActivity(), variable.name, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Check.isTrue(which == DialogInterface.BUTTON_POSITIVE);
variablesRegistry.remove(variable.toJsclBuilder().create());
dismiss();
}
});
}
private void tryClose() { private void tryClose() {
if (validate() && applyData()) { if (validate() && applyData()) {
dismiss(); dismiss();
@ -202,6 +214,17 @@ public class EditVariableFragment extends BaseDialogFragment implements Calculat
} }
private boolean applyData() { private boolean applyData() {
try {
final CppVariable newVariable = CppVariable.builder(nameView.getText().toString())
.withId(isNewVariable() ? NO_ID : variable.id)
.withValue(valueView.getText().toString())
.withDescription(descriptionView.getText().toString()).build();
final IConstant oldVariable = isNewVariable() ? null : variablesRegistry.getById(variable.id);
variablesRegistry.add(newVariable.toJsclBuilder(), oldVariable);
return true;
} catch (RuntimeException e) {
setError(valueLabel, e.getLocalizedMessage());
}
return false; return false;
} }
@ -225,7 +248,7 @@ public class EditVariableFragment extends BaseDialogFragment implements Calculat
private boolean validateName() { private boolean validateName() {
final String name = nameView.getText().toString(); final String name = nameView.getText().toString();
if (!VarEditorSaver.isValidName(name)) { if (!Engine.isValidName(name)) {
setError(nameLabel, getString(R.string.c_name_is_not_valid)); setError(nameLabel, getString(R.string.c_name_is_not_valid));
return false; return false;
} }
@ -266,34 +289,7 @@ public class EditVariableFragment extends BaseDialogFragment implements Calculat
return true; return true;
} }
@Override @SuppressLint("InflateParams")
public void onResume() {
super.onResume();
Locator.getInstance().getCalculator().addCalculatorEventListener(this);
}
@Override
public void onPause() {
Locator.getInstance().getCalculator().removeCalculatorEventListener(this);
super.onPause();
}
@Override
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
switch (calculatorEventType) {
case constant_removed:
case constant_added:
case constant_changed:
if (calculatorEventData.getSource() == this) {
dismiss();
}
break;
}
}
@NonNull @NonNull
@Override @Override
protected View onCreateDialogView(@NonNull Context context, @NonNull LayoutInflater inflater, @android.support.annotation.Nullable Bundle savedInstanceState) { protected View onCreateDialogView(@NonNull Context context, @NonNull LayoutInflater inflater, @android.support.annotation.Nullable Bundle savedInstanceState) {

View File

@ -9,20 +9,22 @@ import org.solovyev.common.math.MathEntity;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
class JsclConstant extends CppVariable implements IConstant { class JsclConstant implements IConstant {
@Nonnull
private final CppVariable variable;
private Double doubleValue; private Double doubleValue;
private Constant constant; private Constant constant;
JsclConstant(@Nonnull CppVariable variable) { JsclConstant(@Nonnull CppVariable variable) {
super(variable); this.variable = variable;
} }
@Nonnull @Nonnull
@Override @Override
public Constant getConstant() { public Constant getConstant() {
if (constant == null) { if (constant == null) {
constant = new Constant(name); constant = new Constant(variable.name);
} }
return constant; return constant;
} }
@ -30,18 +32,18 @@ class JsclConstant extends CppVariable implements IConstant {
@Nullable @Nullable
@Override @Override
public String getDescription() { public String getDescription() {
return description; return variable.description;
} }
@Override @Override
public boolean isDefined() { public boolean isDefined() {
return !Strings.isNullOrEmpty(value); return !Strings.isNullOrEmpty(variable.value);
} }
@Nullable @Nullable
@Override @Override
public String getValue() { public String getValue() {
return value; return variable.value;
} }
@Nullable @Nullable
@ -50,9 +52,9 @@ class JsclConstant extends CppVariable implements IConstant {
if (doubleValue != null) { if (doubleValue != null) {
return doubleValue; return doubleValue;
} }
if (!Strings.isNullOrEmpty(value)) { if (!Strings.isNullOrEmpty(variable.value)) {
try { try {
doubleValue = Double.valueOf(value); doubleValue = Double.valueOf(variable.value);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
// do nothing - string is not a double // do nothing - string is not a double
} }
@ -63,34 +65,34 @@ class JsclConstant extends CppVariable implements IConstant {
@Nonnull @Nonnull
@Override @Override
public String toJava() { public String toJava() {
return Strings.nullToEmpty(value); return Strings.nullToEmpty(variable.value);
} }
@Nonnull @Nonnull
@Override @Override
public String getName() { public String getName() {
return name; return variable.name;
} }
@Override @Override
public boolean isSystem() { public boolean isSystem() {
return system; return variable.system;
} }
@Nonnull @Nonnull
@Override @Override
public Integer getId() { public Integer getId() {
return id == CppFunction.NO_ID ? null : id; return variable.id == CppVariable.NO_ID ? null : variable.id;
} }
@Override @Override
public void setId(@Nonnull Integer id) { public void setId(@Nonnull Integer id) {
this.id = id; variable.id = id;
} }
@Override @Override
public boolean isIdDefined() { public boolean isIdDefined() {
return id != CppFunction.NO_ID; return variable.id != CppVariable.NO_ID;
} }
@Override @Override
@ -99,14 +101,14 @@ class JsclConstant extends CppVariable implements IConstant {
throw new IllegalArgumentException("Trying to make a copy of unsupported type: " + o.getClass()); throw new IllegalArgumentException("Trying to make a copy of unsupported type: " + o.getClass());
} }
final IConstant that = ((IConstant) o); final IConstant that = ((IConstant) o);
this.name = that.getName(); variable.name = that.getName();
this.value = that.getValue(); variable.value = Strings.nullToEmpty(that.getValue());
this.description = that.getDescription(); variable.description = Strings.nullToEmpty(that.getDescription());
this.system = that.isSystem(); variable.system = that.isSystem();
if (that.isIdDefined()) { if (that.isIdDefined()) {
this.id = that.getId(); variable.id = that.getId();
} else { } else {
this.id = CppFunction.NO_ID; variable.id = CppVariable.NO_ID;
} }
this.doubleValue = null; this.doubleValue = null;
this.constant = null; this.constant = null;

View File

@ -24,243 +24,25 @@ package org.solovyev.android.calculator.variables;
import org.simpleframework.xml.Element; import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root; import org.simpleframework.xml.Root;
import org.simpleframework.xml.Transient;
import org.solovyev.android.calculator.model.MathEntityBuilder;
import org.solovyev.common.JBuilder;
import org.solovyev.common.math.MathEntity;
import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import jscl.math.function.Constant;
import jscl.math.function.ExtendedConstant;
import jscl.math.function.IConstant;
@Root(name = "var") @Root(name = "var")
public class OldVar implements IConstant { public class OldVar {
@Transient
private Integer id;
@Element @Element
@Nonnull @Nonnull
private String name; String name;
@Element(required = false) @Element(required = false)
@Nullable @Nullable
private String value; String value;
@Element @Element
private boolean system; boolean system;
@Element(required = false) @Element(required = false)
@Nullable @Nullable
private String description; String description;
@Transient
private Constant constant;
private OldVar() {
}
private OldVar(@Nonnull Integer id) {
this.id = id;
}
public void copy(@Nonnull MathEntity o) {
if (o instanceof IConstant) {
final IConstant that = ((IConstant) o);
this.name = that.getName();
this.value = that.getValue();
this.description = that.getDescription();
this.system = that.isSystem();
if (that.isIdDefined()) {
this.id = that.getId();
}
} else {
throw new IllegalArgumentException("Trying to make a copy of unsupported type: " + o.getClass());
}
}
@Nullable
public Double getDoubleValue() {
Double result = null;
if (value != null) {
try {
result = Double.valueOf(value);
} catch (NumberFormatException e) {
// do nothing - string is not a double
}
}
return result;
}
@Nullable
public String getValue() {
return value;
}
@Nonnull
@Override
public String toJava() {
return String.valueOf(value);
}
public boolean isSystem() {
return system;
}
@Nonnull
@Override
public Integer getId() {
return this.id;
}
@Override
public void setId(@Nonnull Integer id) {
this.id = id;
}
@Override
public boolean isIdDefined() {
return this.id != null;
}
@Nonnull
public String getName() {
return name;
}
@Nonnull
@Override
public Constant getConstant() {
if (constant == null) {
constant = new Constant(this.name);
}
return constant;
}
@Nullable
public String getDescription() {
return description;
}
@Override
public boolean isDefined() {
return !Strings.isEmpty(value);
}
@Override
public String toString() {
return ExtendedConstant.toString(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OldVar var = (OldVar) o;
if (!name.equals(var.name)) return false;
return true;
}
@Override
public int hashCode() {
return name.hashCode();
}
public static class Builder implements JBuilder<OldVar>, MathEntityBuilder<OldVar> {
@Nonnull
private String name;
@Nullable
private String value;
private boolean system = false;
@Nullable
private String description;
@Nullable
private Integer id;
public Builder() {
}
public Builder(@Nonnull OldVar var) {
this.name = var.name;
this.value = var.value;
this.system = var.system;
this.description = var.description;
this.id = var.id;
}
public Builder(@Nonnull IConstant iConstant) {
this.name = iConstant.getName();
this.value = iConstant.getValue();
this.system = iConstant.isSystem();
this.description = iConstant.getDescription();
if (iConstant.isIdDefined()) {
this.id = iConstant.getId();
}
}
public Builder(@Nonnull String name, @Nonnull Double value) {
this(name, String.valueOf(value));
}
public Builder(@Nonnull String name, @Nullable String value) {
this.name = name;
this.value = value;
}
@Nonnull
public Builder setName(@Nonnull String name) {
this.name = name;
return this;
}
@Nonnull
public Builder setValue(@Nullable String value) {
this.value = value;
return this;
}
public Builder setSystem(boolean system) {
this.system = system;
return this;
}
@Nonnull
public Builder setDescription(@Nullable String description) {
this.description = description;
return this;
}
@Nonnull
public OldVar create() {
final OldVar result;
if (id != null) {
result = new OldVar(id);
} else {
result = new OldVar();
}
result.name = name;
result.value = value;
result.system = system;
result.description = description;
return result;
}
}
} }

View File

@ -23,15 +23,13 @@
package org.solovyev.android.calculator.variables; package org.solovyev.android.calculator.variables;
import android.text.TextUtils; import android.text.TextUtils;
import org.simpleframework.xml.ElementList; import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root; import org.simpleframework.xml.Root;
import javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.annotation.Nonnull;
import static com.google.common.base.Strings.nullToEmpty; import static com.google.common.base.Strings.nullToEmpty;
@Root(name = "vars") @Root(name = "vars")
@ -49,13 +47,13 @@ public class OldVars {
public static List<CppVariable> toCppVariables(@Nonnull OldVars oldVariables) { public static List<CppVariable> toCppVariables(@Nonnull OldVars oldVariables) {
final List<CppVariable> variables = new ArrayList<>(); final List<CppVariable> variables = new ArrayList<>();
for (OldVar oldVar : oldVariables.list) { for (OldVar oldVar : oldVariables.list) {
final String name = oldVar.getName(); final String name = oldVar.name;
if (TextUtils.isEmpty(name)) { if (TextUtils.isEmpty(name)) {
continue; continue;
} }
variables.add(CppVariable.builder(name) variables.add(CppVariable.builder(name)
.withValue(nullToEmpty(oldVar.getValue())) .withValue(nullToEmpty(oldVar.value))
.withDescription(nullToEmpty(oldVar.getDescription())).build()); .withDescription(nullToEmpty(oldVar.description)).build());
} }
return variables; return variables;
} }

View File

@ -24,12 +24,14 @@ package org.solovyev.android.calculator.variables;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.BaseActivity;
import org.solovyev.android.calculator.CalculatorFragmentType;
import org.solovyev.android.calculator.R;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class VariablesActivity extends BaseActivity implements CalculatorEventListener { public class VariablesActivity extends BaseActivity {
public static final String EXTRA_VARIABLE = "variable"; public static final String EXTRA_VARIABLE = "variable";
private static final CalculatorFragmentType FRAGMENT_TYPE = CalculatorFragmentType.variables; private static final CalculatorFragmentType FRAGMENT_TYPE = CalculatorFragmentType.variables;
@ -62,13 +64,4 @@ public class VariablesActivity extends BaseActivity implements CalculatorEventLi
final Class<? extends Fragment> fragmentClass = FRAGMENT_TYPE.getFragmentClass(); final Class<? extends Fragment> fragmentClass = FRAGMENT_TYPE.getFragmentClass();
ui.addTab(this, fragmentTag, fragmentClass, arguments, category.title(), R.id.main_layout); ui.addTab(this, fragmentTag, fragmentClass, arguments, category.title(), R.id.main_layout);
} }
@Override
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
switch (calculatorEventType) {
case use_constant:
this.finish();
break;
}
}
} }

View File

@ -22,19 +22,20 @@
package org.solovyev.android.calculator.variables; package org.solovyev.android.calculator.variables;
import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.view.ContextMenu; import android.view.*;
import android.view.MenuItem;
import android.view.View;
import com.squareup.otto.Bus; import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import jscl.math.function.IConstant; import jscl.math.function.IConstant;
import org.solovyev.android.Check;
import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.entities.Category; import org.solovyev.android.calculator.entities.Category;
import org.solovyev.android.calculator.entities.EntityRemovalDialog;
import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.math.edit.BaseEntitiesFragment; import org.solovyev.android.calculator.math.edit.BaseEntitiesFragment;
import org.solovyev.android.calculator.math.edit.MathEntityRemover;
import org.solovyev.common.JPredicate; import org.solovyev.common.JPredicate;
import org.solovyev.common.collections.Collections; import org.solovyev.common.collections.Collections;
import org.solovyev.common.text.Strings; import org.solovyev.common.text.Strings;
@ -45,7 +46,7 @@ import javax.inject.Inject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class VariablesFragment extends BaseEntitiesFragment<IConstant> implements CalculatorEventListener { public class VariablesFragment extends BaseEntitiesFragment<IConstant> {
@Inject @Inject
VariablesRegistry registry; VariablesRegistry registry;
@ -77,9 +78,9 @@ public class VariablesFragment extends BaseEntitiesFragment<IConstant> implement
} }
@Override @Override
public void onViewCreated(View root, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onViewCreated(root, savedInstanceState); final View view = super.onCreateView(inflater, container, savedInstanceState);
bus.register(this);
fab.setVisibility(View.VISIBLE); fab.setVisibility(View.VISIBLE);
fab.attachToRecyclerView(recyclerView); fab.attachToRecyclerView(recyclerView);
fab.setOnClickListener(new View.OnClickListener() { fab.setOnClickListener(new View.OnClickListener() {
@ -88,11 +89,22 @@ public class VariablesFragment extends BaseEntitiesFragment<IConstant> implement
EditVariableFragment.showDialog(null, getFragmentManager()); EditVariableFragment.showDialog(null, getFragmentManager());
} }
}); });
return view;
}
@Override
public void onDestroyView() {
bus.unregister(this);
super.onDestroyView();
} }
@Override @Override
protected void onClick(@NonNull IConstant constant) { protected void onClick(@NonNull IConstant constant) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.use_constant, constant); keyboard.buttonPressed(constant.getName());
final FragmentActivity activity = getActivity();
if (activity instanceof VariablesActivity) {
activity.finish();
}
} }
@Nonnull @Nonnull
@ -115,23 +127,6 @@ public class VariablesFragment extends BaseEntitiesFragment<IConstant> implement
return registry.getCategory(var); return registry.getCategory(var);
} }
@Override
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
switch (calculatorEventType) {
case constant_added:
processConstantAdded((IConstant) data);
break;
case constant_changed:
processConstantChanged((Change<IConstant>) data);
break;
case constant_removed:
processConstantRemoved((IConstant) data);
break;
}
}
@Override @Override
protected void onCreateContextMenu(@Nonnull ContextMenu menu, @Nonnull IConstant constant, @Nonnull MenuItem.OnMenuItemClickListener listener) { protected void onCreateContextMenu(@Nonnull ContextMenu menu, @Nonnull IConstant constant, @Nonnull MenuItem.OnMenuItemClickListener listener) {
addMenu(menu, R.string.c_use, listener); addMenu(menu, R.string.c_use, listener);
@ -146,17 +141,23 @@ public class VariablesFragment extends BaseEntitiesFragment<IConstant> implement
} }
@Override @Override
protected boolean onMenuItemClicked(@Nonnull MenuItem item, @Nonnull IConstant constant) { protected boolean onMenuItemClicked(@Nonnull MenuItem item, @Nonnull final IConstant constant) {
FragmentActivity activity = getActivity(); FragmentActivity activity = getActivity();
switch (item.getItemId()) { switch (item.getItemId()) {
case R.string.c_use: case R.string.c_use:
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.use_constant, constant); onClick(constant);
return true; return true;
case R.string.c_edit: case R.string.c_edit:
EditVariableFragment.showDialog(CppVariable.builder(constant).build(), activity); EditVariableFragment.showDialog(CppVariable.builder(constant).build(), activity);
return true; return true;
case R.string.c_remove: case R.string.c_remove:
MathEntityRemover.newConstantRemover(constant, null, activity, activity).showConfirmationDialog(); EntityRemovalDialog.showForVariable(getActivity(), constant.getName(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Check.isTrue(which == DialogInterface.BUTTON_POSITIVE);
registry.remove(constant);
}
});
return true; return true;
case R.string.c_copy_value: case R.string.c_copy_value:
final String value = constant.getValue(); final String value = constant.getValue();
@ -168,45 +169,19 @@ public class VariablesFragment extends BaseEntitiesFragment<IConstant> implement
return false; return false;
} }
private void processConstantRemoved(@Nonnull final IConstant constant) { @Subscribe
if (this.isInCategory(constant)) { public void onVariableRemoved(@NonNull VariablesRegistry.RemovedEvent e) {
getUiHandler().post(new Runnable() { onEntityRemoved(e.variable);
@Override
public void run() {
final EntitiesAdapter adapter = getAdapter();
adapter.remove(constant);
adapter.notifyDataSetChanged();
}
});
}
} }
private void processConstantChanged(@Nonnull final Change<IConstant> change) { @Subscribe
final IConstant newConstant = change.getNewValue(); public void onVariableAdded(@NonNull VariablesRegistry.AddedEvent e) {
if (this.isInCategory(newConstant)) { onEntityAdded(e.variable);
getUiHandler().post(new Runnable() {
@Override
public void run() {
final EntitiesAdapter adapter = getAdapter();
adapter.remove(change.getOldValue());
adapter.add(newConstant);
adapter.sort();
}
});
}
} }
private void processConstantAdded(@Nonnull final IConstant constant) { @Subscribe
if (this.isInCategory(constant)) { public void onVariableChanged(@NonNull VariablesRegistry.ChangedEvent e) {
getUiHandler().post(new Runnable() { onEntityChanged(e.newVariable);
@Override
public void run() {
final EntitiesAdapter adapter = getAdapter();
adapter.add(constant);
adapter.sort();
}
});
}
} }
@Nullable @Nullable

View File

@ -25,8 +25,8 @@ package org.solovyev.android.calculator;
import org.junit.Assert; import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.solovyev.android.calculator.variables.OldVar;
import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor; import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor;
import org.solovyev.android.calculator.variables.CppVariable;
import java.text.DecimalFormatSymbols; import java.text.DecimalFormatSymbols;
@ -57,15 +57,15 @@ public class FromJsclSimplifyTextProcessorTest extends AbstractCalculatorTest {
//Assert.assertEquals("e", tp.process("2.718281828459045")); //Assert.assertEquals("e", tp.process("2.718281828459045"));
//Assert.assertEquals("tee", tp.process("t2.718281828459045*2.718281828459045")); //Assert.assertEquals("tee", tp.process("t2.718281828459045*2.718281828459045"));
Locator.getInstance().getEngine().getVariablesRegistry().add(new OldVar.Builder("t2.718281828459045", "2")); Locator.getInstance().getEngine().getVariablesRegistry().add(CppVariable.builder("t2.718281828459045", 2).build().toJsclBuilder());
Locator.getInstance().getEngine().getVariablesRegistry().add(new OldVar.Builder("t", (String) null)); Locator.getInstance().getEngine().getVariablesRegistry().add(CppVariable.builder("t").build().toJsclBuilder());
//Assert.assertEquals("t2.718281828459045e", tp.process("t2.718281828459045*2.718281828459045")); //Assert.assertEquals("t2.718281828459045e", tp.process("t2.718281828459045*2.718281828459045"));
//Assert.assertEquals("ee", tp.process("2.718281828459045*2.718281828459045")); //Assert.assertEquals("ee", tp.process("2.718281828459045*2.718281828459045"));
Assert.assertEquals("t×", tp.process("t*")); Assert.assertEquals("t×", tp.process("t*"));
Assert.assertEquals("×t", tp.process("*t")); Assert.assertEquals("×t", tp.process("*t"));
Assert.assertEquals("t2", tp.process("t*2")); Assert.assertEquals("t2", tp.process("t*2"));
Assert.assertEquals("2t", tp.process("2*t")); Assert.assertEquals("2t", tp.process("2*t"));
Locator.getInstance().getEngine().getVariablesRegistry().add(new OldVar.Builder("t", (String) null)); Locator.getInstance().getEngine().getVariablesRegistry().add(CppVariable.builder("t").build().toJsclBuilder());
Assert.assertEquals("t×", tp.process("t*")); Assert.assertEquals("t×", tp.process("t*"));
Assert.assertEquals("×t", tp.process("*t")); Assert.assertEquals("×t", tp.process("*t"));
@ -78,7 +78,7 @@ public class FromJsclSimplifyTextProcessorTest extends AbstractCalculatorTest {
Assert.assertEquals("t^[2×2t]", tp.process("t^[2*2*t]")); Assert.assertEquals("t^[2×2t]", tp.process("t^[2*2*t]"));
Assert.assertEquals("2t^2[2t]", tp.process("2*t^2[2*t]")); Assert.assertEquals("2t^2[2t]", tp.process("2*t^2[2*t]"));
Locator.getInstance().getEngine().getVariablesRegistry().add(new OldVar.Builder("k", (String) null)); Locator.getInstance().getEngine().getVariablesRegistry().add(CppVariable.builder("k").build().toJsclBuilder());
Assert.assertEquals("(t+2k)[k+2t]", tp.process("(t+2*k)*[k+2*t]")); Assert.assertEquals("(t+2k)[k+2t]", tp.process("(t+2*k)*[k+2*t]"));
Assert.assertEquals("(te+2k)e[k+2te]", tp.process("(t*e+2*k)*e*[k+2*t*e]")); Assert.assertEquals("(te+2k)e[k+2te]", tp.process("(t*e+2*k)*e*[k+2*t*e]"));

View File

@ -22,20 +22,6 @@
package org.solovyev.android.calculator.model; package org.solovyev.android.calculator.model;
import junit.framework.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.AbstractCalculatorTest;
import org.solovyev.android.calculator.CalculatorEvalException;
import org.solovyev.android.calculator.CalculatorTestUtils;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.calculator.variables.OldVar;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import jscl.AngleUnit; import jscl.AngleUnit;
import jscl.JsclMathEngine; import jscl.JsclMathEngine;
import jscl.MathEngine; import jscl.MathEngine;
@ -43,6 +29,18 @@ import jscl.NumeralBase;
import jscl.math.Expression; import jscl.math.Expression;
import jscl.math.function.CustomFunction; import jscl.math.function.CustomFunction;
import jscl.text.ParseException; import jscl.text.ParseException;
import junit.framework.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.AbstractCalculatorTest;
import org.solovyev.android.calculator.CalculatorEvalException;
import org.solovyev.android.calculator.CalculatorTestUtils;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.calculator.variables.CppVariable;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
@ -140,7 +138,7 @@ public class AndroidEngineTest extends AbstractCalculatorTest {
cm.setAngleUnits(defaultAngleUnit); cm.setAngleUnits(defaultAngleUnit);
} }
Locator.getInstance().getEngine().getVariablesRegistry().add(new OldVar.Builder("si", 5d)); Locator.getInstance().getEngine().getVariablesRegistry().add(CppVariable.builder("si").withValue(5d).build().toJsclBuilder());
CalculatorTestUtils.assertEval("5", cm.evaluate("si")); CalculatorTestUtils.assertEval("5", cm.evaluate("si"));
CalculatorTestUtils.assertError("sin"); CalculatorTestUtils.assertError("sin");

View File

@ -22,20 +22,19 @@
package org.solovyev.android.calculator.model; package org.solovyev.android.calculator.model;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.AbstractCalculatorTest;
import org.solovyev.android.calculator.CalculatorTestUtils;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.calculator.variables.OldVar;
import jscl.AngleUnit; import jscl.AngleUnit;
import jscl.MathEngine; import jscl.MathEngine;
import jscl.NumeralBase; import jscl.NumeralBase;
import jscl.math.Expression; import jscl.math.Expression;
import jscl.math.Generic; import jscl.math.Generic;
import jscl.math.function.Constant; import jscl.math.function.Constant;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.AbstractCalculatorTest;
import org.solovyev.android.calculator.CalculatorTestUtils;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.calculator.variables.CppVariable;
/** /**
@ -117,7 +116,7 @@ public class EvaluateTest extends AbstractCalculatorTest {
CalculatorTestUtils.assertError("(-1)i!"); CalculatorTestUtils.assertError("(-1)i!");
CalculatorTestUtils.assertEval("24i", "4!i"); CalculatorTestUtils.assertEval("24i", "4!i");
Locator.getInstance().getEngine().getVariablesRegistry().add(new OldVar.Builder("si", 5d)); Locator.getInstance().getEngine().getVariablesRegistry().add(CppVariable.builder("si", 5d).build().toJsclBuilder());
try { try {
cm.setAngleUnits(AngleUnit.rad); cm.setAngleUnits(AngleUnit.rad);
@ -131,14 +130,14 @@ public class EvaluateTest extends AbstractCalculatorTest {
cm.setAngleUnits(defaultAngleUnit); cm.setAngleUnits(defaultAngleUnit);
} }
Locator.getInstance().getEngine().getVariablesRegistry().add(new OldVar.Builder("s", 1d)); Locator.getInstance().getEngine().getVariablesRegistry().add(CppVariable.builder("s", 1d).build().toJsclBuilder());
CalculatorTestUtils.assertEval("5", cm.evaluate("si")); CalculatorTestUtils.assertEval("5", cm.evaluate("si"));
Locator.getInstance().getEngine().getVariablesRegistry().add(new OldVar.Builder("k", 3.5d)); Locator.getInstance().getEngine().getVariablesRegistry().add(CppVariable.builder("k", 3.5d).build().toJsclBuilder());
Locator.getInstance().getEngine().getVariablesRegistry().add(new OldVar.Builder("k1", 4d)); Locator.getInstance().getEngine().getVariablesRegistry().add(CppVariable.builder("k1", 4d).build().toJsclBuilder());
CalculatorTestUtils.assertEval("4", "k11"); CalculatorTestUtils.assertEval("4", "k11");
Locator.getInstance().getEngine().getVariablesRegistry().add(new OldVar.Builder("t", (String) null)); Locator.getInstance().getEngine().getVariablesRegistry().add(CppVariable.builder("t").build().toJsclBuilder());
CalculatorTestUtils.assertEval("11t", "t11"); CalculatorTestUtils.assertEval("11t", "t11");
CalculatorTestUtils.assertEval("11et", "t11e"); CalculatorTestUtils.assertEval("11et", "t11e");
CalculatorTestUtils.assertEval("", ""); CalculatorTestUtils.assertEval("", "");
@ -184,10 +183,10 @@ public class EvaluateTest extends AbstractCalculatorTest {
cm.setTimeout(3000); cm.setTimeout(3000);
}*/ }*/
Locator.getInstance().getEngine().getVariablesRegistry().add(new OldVar.Builder("t", (String) null)); Locator.getInstance().getEngine().getVariablesRegistry().add(CppVariable.builder("t").build().toJsclBuilder());
CalculatorTestUtils.assertEval("2t", "∂(t^2,t)", JsclOperation.simplify); CalculatorTestUtils.assertEval("2t", "∂(t^2,t)", JsclOperation.simplify);
CalculatorTestUtils.assertEval("2t", "∂(t^2,t)"); CalculatorTestUtils.assertEval("2t", "∂(t^2,t)");
Locator.getInstance().getEngine().getVariablesRegistry().add(new OldVar.Builder("t", "2")); Locator.getInstance().getEngine().getVariablesRegistry().add(CppVariable.builder("t", 2d).build().toJsclBuilder());
CalculatorTestUtils.assertEval("2t", "∂(t^2,t)", JsclOperation.simplify); CalculatorTestUtils.assertEval("2t", "∂(t^2,t)", JsclOperation.simplify);
CalculatorTestUtils.assertEval("4", "∂(t^2,t)"); CalculatorTestUtils.assertEval("4", "∂(t^2,t)");

View File

@ -22,18 +22,6 @@
package org.solovyev.android.calculator.model; package org.solovyev.android.calculator.model;
import org.junit.Test;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import org.solovyev.android.calculator.variables.OldVar;
import org.solovyev.android.calculator.variables.OldVars;
import java.io.StringWriter;
import jscl.math.function.IConstant;
import static org.junit.Assert.assertEquals;
/** /**
* User: serso * User: serso
* Date: 11/7/11 * Date: 11/7/11
@ -56,33 +44,4 @@ public class OldVarTest {
" </var>\n" + " </var>\n" +
" </vars>\n" + " </vars>\n" +
"</vars>"; "</vars>";
@Test
public void testXml() throws Exception {
final OldVars vars = new OldVars();
OldVar first = new OldVar.Builder("e", Math.E).setDescription("description").setSystem(true).create();
vars.list.add(first);
OldVar second = new OldVar.Builder(";", 3d).setSystem(true).create();
vars.list.add(second);
final StringWriter sw = new StringWriter();
final Serializer serializer = new Persister();
serializer.write(vars, sw);
assertEquals(xml, sw.toString());
final OldVars result = serializer.read(OldVars.class, xml);
final IConstant actualFirst = result.list.get(0);
final IConstant actualSecond = result.list.get(1);
areEqual(first, actualFirst);
areEqual(second, actualSecond);
}
private void areEqual(IConstant expected, IConstant actual) {
assertEquals(expected.getName(), actual.getName());
assertEquals(expected.getDescription(), actual.getDescription());
assertEquals(expected.getValue(), actual.getValue());
}
} }