EditFunctionFragment changes

This commit is contained in:
serso 2016-01-21 11:20:43 +01:00
parent 3a879b0de8
commit 2a8c559a01
19 changed files with 555 additions and 728 deletions

View File

@ -60,6 +60,7 @@ dependencies {
compile 'org.solovyev:common-core:1.0.7'
compile 'org.solovyev:common-text:1.0.7'
compile 'org.solovyev:common-security:1.0.7'
compile 'org.solovyev:common-msg:1.0.7'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
@ -73,7 +74,7 @@ dependencies {
compile 'org.solovyev.android:android-common-views:1.1.18@aar'
compile 'org.solovyev.android:android-common-menus:1.1.18@aar'
compile 'org.solovyev.android:android-common-preferences:1.1.18@aar'
compile('org.solovyev:jscl:1.0.8') {
compile('org.solovyev:jscl:1.0.12') {
exclude(module: 'xercesImpl')
}
compile 'org.solovyev.android:checkout:0.7.2@aar'

Binary file not shown.

View File

@ -1,7 +1,9 @@
package org.solovyev.android.calculator;
import org.solovyev.android.calculator.function.EditFunctionFragment;
import org.solovyev.android.calculator.history.BaseHistoryFragment;
import org.solovyev.android.calculator.history.EditHistoryFragment;
import org.solovyev.android.calculator.math.edit.FunctionsFragment;
import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService;
import javax.inject.Singleton;
@ -17,5 +19,7 @@ public interface AppComponent {
void inject(CalculatorOnscreenService service);
void inject(BaseHistoryFragment fragment);
void inject(BaseDialogFragment fragment);
void inject(EditFunctionFragment fragment);
void inject(EditHistoryFragment fragment);
void inject(FunctionsFragment fragment);
}

View File

@ -33,12 +33,17 @@ import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import jscl.math.Generic;
import org.solovyev.android.Activities;
import org.solovyev.android.calculator.about.CalculatorAboutActivity;
import org.solovyev.android.calculator.function.CppFunction;
import org.solovyev.android.calculator.function.EditFunctionFragment;
import org.solovyev.android.calculator.history.CalculatorHistoryActivity;
import org.solovyev.android.calculator.math.edit.*;
import org.solovyev.android.calculator.math.edit.CalculatorFunctionsActivity;
import org.solovyev.android.calculator.math.edit.CalculatorOperatorsActivity;
import org.solovyev.android.calculator.math.edit.CalculatorVarsActivity;
import org.solovyev.android.calculator.math.edit.VarEditDialogFragment;
import org.solovyev.android.calculator.math.edit.VarsFragment;
import org.solovyev.android.calculator.matrix.CalculatorMatrixActivity;
import org.solovyev.android.calculator.plot.CalculatorPlotActivity;
import org.solovyev.android.calculator.plot.CalculatorPlotter;
@ -47,9 +52,14 @@ import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.Strings;
import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import jscl.math.Generic;
import jscl.math.function.Constant;
/**
* User: serso
@ -159,9 +169,17 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
final DisplayState viewState = display.getState();
if (viewState.valid) {
final String functionValue = viewState.text;
if (!Strings.isEmpty(functionValue)) {
EditFunctionFragment.showDialog(EditFunctionFragment.Input.newFromDisplay(viewState), context);
final String functionBody = viewState.text;
if (!Strings.isEmpty(functionBody)) {
final CppFunction.Builder builder = CppFunction.builder("", functionBody);
final Generic generic = viewState.getResult();
if (generic != null) {
final Set<Constant> constants = CalculatorUtils.getNotSystemConstants(generic);
for (Constant constant : constants) {
builder.withParameter(constant.getName());
}
}
EditFunctionFragment.showDialog(builder.build(), context);
} else {
getNotifier().showMessage(R.string.empty_function_error, MessageType.error);
}

View File

@ -81,9 +81,6 @@ public enum CalculatorEventType {
// @Nonnull IConstant
use_constant,
// @Nonnull Function
use_function,
// @Nonnull Operator
use_operator,
@ -100,12 +97,6 @@ public enum CalculatorEventType {
// @Nonnull Function
function_removed,
// @Nonnull Function
function_added,
// @Nonnull Change<IFunction>
function_changed,
/*
**********************************************************************
*

View File

@ -54,7 +54,6 @@ import jscl.MathEngine;
import jscl.NumeralBase;
import jscl.NumeralBaseException;
import jscl.math.Generic;
import jscl.math.function.Function;
import jscl.math.function.IConstant;
import jscl.math.operator.Operator;
import jscl.text.ParseInterruptedException;
@ -489,6 +488,15 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
VarsRegistry.saveVariable(varsRegistry, builder, ansVar, this, false);
}
@Subscribe
public void onFunctionAdded(@Nonnull FunctionsRegistry.AddedEvent event) {
evaluate();
}
@Subscribe
public void onFunctionsChanged(@Nonnull FunctionsRegistry.ChangedEvent event) {
evaluate();
}
@Override
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
@ -502,8 +510,6 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
case constant_added:
case constant_removed:
case function_added:
case function_changed:
case function_removed:
evaluate();
break;
@ -517,11 +523,6 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
Locator.getInstance().getKeyboard().buttonPressed(operator.getName());
break;
case use_function:
final Function function = (Function) data;
Locator.getInstance().getKeyboard().buttonPressed(function.getName());
break;
}
}

View File

@ -23,13 +23,10 @@
package org.solovyev.android.calculator;
import android.content.SharedPreferences;
import com.squareup.otto.Bus;
import jscl.AngleUnit;
import jscl.JsclMathEngine;
import jscl.MathEngine;
import jscl.NumeralBase;
import jscl.math.function.IConstant;
import jscl.math.operator.Operator;
import org.solovyev.android.Check;
import org.solovyev.android.calculator.model.EntityDao;
import org.solovyev.android.calculator.model.Vars;
import org.solovyev.android.prefs.BooleanPreference;
@ -40,14 +37,22 @@ import org.solovyev.common.text.EnumMapper;
import org.solovyev.common.text.NumberMapper;
import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Singleton;
import jscl.AngleUnit;
import jscl.JsclMathEngine;
import jscl.MathEngine;
import jscl.NumeralBase;
import jscl.math.function.IConstant;
import jscl.math.operator.Operator;
@Singleton
public class Engine implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -131,6 +136,7 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene
}
public void init(@Nonnull Executor initThread) {
Check.isMainThread();
checkPreferences();
preferences.registerOnSharedPreferenceChangeListener(this);
applyPreferences();
@ -183,6 +189,7 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene
}
private void applyPreferences() {
Check.isMainThread();
mathEngine.setAngleUnits(Preferences.angleUnit.getPreference(preferences));
mathEngine.setNumeralBase(Preferences.numeralBase.getPreference(preferences));
setMultiplicationSign(Preferences.multiplicationSign.getPreference(preferences));

View File

@ -26,17 +26,15 @@ import android.app.Application;
import android.content.SharedPreferences;
import android.os.Handler;
import android.support.annotation.NonNull;
import jscl.JsclMathEngine;
import jscl.math.function.CustomFunction;
import jscl.math.function.Function;
import jscl.math.function.IFunction;
import com.squareup.otto.Bus;
import org.json.JSONArray;
import org.json.JSONException;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import org.solovyev.android.Check;
import org.solovyev.android.calculator.function.CppFunction;
import org.solovyev.android.calculator.function.FunctionBuilderAdapter;
import org.solovyev.android.calculator.json.Json;
import org.solovyev.android.calculator.model.OldFunction;
import org.solovyev.android.calculator.model.OldFunctions;
@ -44,15 +42,25 @@ import org.solovyev.android.io.FileSaver;
import org.solovyev.common.JBuilder;
import org.solovyev.common.text.Strings;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.Executor;
import jscl.JsclMathEngine;
import jscl.math.function.CustomFunction;
import jscl.math.function.Function;
import static android.text.TextUtils.isEmpty;
@ -83,19 +91,20 @@ public class FunctionsRegistry extends BaseEntitiesRegistry<Function, OldFunctio
SharedPreferences preferences;
@Inject
Application application;
@Inject
Bus bus;
@Inject
public FunctionsRegistry(@Nonnull JsclMathEngine mathEngine) {
super(mathEngine.getFunctionsRegistry(), FUNCTION_DESCRIPTION_PREFIX, null);
}
public void add(@NonNull FunctionBuilderAdapter builder, @Nullable IFunction editedInstance, Object source) {
public void add(@NonNull JBuilder<? extends Function> builder, @Nullable Function oldFunction) {
final Function function = add(builder);
save();
if (editedInstance == null) {
calculator.fireCalculatorEvent(CalculatorEventType.function_added, function, source);
if (oldFunction == null) {
bus.post(new AddedEvent(function));
} else {
calculator.fireCalculatorEvent(CalculatorEventType.function_changed, ChangeImpl.newInstance(editedInstance, function), source);
bus.post(new ChangedEvent(oldFunction, function));
}
}
@ -112,12 +121,25 @@ public class FunctionsRegistry extends BaseEntitiesRegistry<Function, OldFunctio
add(new CustomFunction.Builder(true, "im", Collections.singletonList("x"), "(x-conjugate(x))/(2*i)"));
for (CppFunction function : loadFunctions()) {
final CustomFunction.Builder builder = new CustomFunction.Builder(function.getName(), function.getParameters(), function.getBody());
builder.setDescription(function.getDescription());
add(builder);
add(function.toCustomFunctionBuilder());
}
}
@Override
public void remove(@Nonnull Function function) {
super.remove(function);
bus.post(new RemovedEvent(function));
save();
}
@Override
public Function add(@Nonnull JBuilder<? extends Function> result) {
final Function function = super.add(result);
// todo serso: don't save while we're initializing
save();
return function;
}
@NonNull
private List<CppFunction> loadFunctions() {
try {
@ -194,7 +216,7 @@ public class FunctionsRegistry extends BaseEntitiesRegistry<Function, OldFunctio
@Nonnull
@Override
protected JBuilder<? extends Function> createBuilder(@Nonnull OldFunction function) {
return new FunctionBuilderAdapter(new OldFunction.Builder(function));
throw new UnsupportedOperationException();
}
@Override
@ -239,4 +261,34 @@ public class FunctionsRegistry extends BaseEntitiesRegistry<Function, OldFunctio
});
}
}
public static final class RemovedEvent {
@NonNull
public final Function function;
public RemovedEvent(@NonNull Function function) {
this.function = function;
}
}
public static final class AddedEvent {
@NonNull
public final Function function;
public AddedEvent(@NonNull Function function) {
this.function = function;
}
}
public static final class ChangedEvent {
@NonNull
public final Function oldFunction;
@NonNull
public final Function newFunction;
public ChangedEvent(@NonNull Function oldFunction, @NonNull Function newFunction) {
this.oldFunction = oldFunction;
this.newFunction = newFunction;
}
}
}

View File

@ -1,8 +1,10 @@
package org.solovyev.android.calculator.function;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import jscl.math.function.IFunction;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -11,12 +13,16 @@ import org.solovyev.android.calculator.json.Json;
import org.solovyev.android.calculator.json.Jsonable;
import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class CppFunction implements Jsonable {
import javax.annotation.Nonnull;
import jscl.math.function.CustomFunction;
import jscl.math.function.IFunction;
public class CppFunction implements Jsonable, Parcelable {
public static final Json.Creator<CppFunction> JSON_CREATOR = new Json.Creator<CppFunction>() {
@NonNull
@ -25,10 +31,23 @@ public class CppFunction implements Jsonable {
return new CppFunction(json);
}
};
public static final Creator<CppFunction> CREATOR = new Creator<CppFunction>() {
@Override
public CppFunction createFromParcel(Parcel in) {
return new CppFunction(in);
}
@Override
public CppFunction[] newArray(int size) {
return new CppFunction[size];
}
};
public static final int NO_ID = -1;
private static final String JSON_NAME = "n";
private static final String JSON_BODY = "b";
private static final String JSON_PARAMETERS = "ps";
private static final String JSON_DESCRIPTION = "d";
protected final int id;
@Nonnull
protected final List<String> parameters = new ArrayList<>();
@Nonnull
@ -41,13 +60,13 @@ public class CppFunction implements Jsonable {
private CppFunction(@Nonnull String name, @Nonnull String body) {
Check.isNotEmpty(name);
Check.isNotEmpty(body);
this.id = NO_ID;
this.name = name;
this.body = body;
}
private CppFunction(@NonNull JSONObject json) throws JSONException {
name = json.getString(JSON_NAME);
body = json.getString(JSON_BODY);
id = NO_ID;
final JSONArray array = json.optJSONArray(JSON_PARAMETERS);
if (array != null) {
for (int i = 0; i < array.length(); i++) {
@ -57,21 +76,33 @@ public class CppFunction implements Jsonable {
}
}
}
name = json.getString(JSON_NAME);
body = json.getString(JSON_BODY);
description = json.optString(JSON_DESCRIPTION, "");
}
private CppFunction(@NonNull CppFunction that) {
id = that.id;
parameters.addAll(that.parameters);
name = that.name;
body = that.body;
description = that.description;
parameters.addAll(that.parameters);
}
private CppFunction(@NonNull IFunction that) {
id = that.isIdDefined() ? that.getId() : NO_ID;
parameters.addAll(that.getParameterNames());
name = that.getName();
body = that.getContent();
description = Strings.getNotEmpty(that.getDescription(), "");
parameters.addAll(that.getParameterNames());
}
protected CppFunction(Parcel in) {
id = in.readInt();
parameters.addAll(in.createStringArrayList());
name = in.readString();
body = in.readString();
description = in.readString();
}
@Nonnull
@ -93,8 +124,6 @@ public class CppFunction implements Jsonable {
@Override
public JSONObject toJson() throws JSONException {
final JSONObject json = new JSONObject();
json.put(JSON_NAME, name);
json.put(JSON_BODY, body);
if (!parameters.isEmpty()) {
final JSONArray array = new JSONArray();
int j = 0;
@ -106,12 +135,18 @@ public class CppFunction implements Jsonable {
}
json.put(JSON_PARAMETERS, array);
}
json.put(JSON_NAME, name);
json.put(JSON_BODY, body);
if (!TextUtils.isEmpty(description)) {
json.put(JSON_DESCRIPTION, description);
}
return json;
}
public int getId() {
return id;
}
@Nonnull
public String getBody() {
return body;
@ -132,56 +167,73 @@ public class CppFunction implements Jsonable {
return name;
}
public static final class Builder extends CppFunction {
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeStringList(parameters);
dest.writeString(name);
dest.writeString(body);
dest.writeString(description);
}
@Nonnull
public CustomFunction.Builder toCustomFunctionBuilder() {
final CustomFunction.Builder builder = new CustomFunction.Builder(name, parameters, body);
builder.setDescription(description);
if (id != NO_ID) {
builder.setId(id);
}
return builder;
}
public static final class Builder {
@NonNull
private final CppFunction function;
private boolean built;
private Builder(@Nonnull String name, @Nonnull String body) {
super(name, body);
function = new CppFunction(name, body);
}
public Builder(@NonNull CppFunction function) {
super(function);
public Builder(@NonNull CppFunction that) {
function = new CppFunction(that);
}
public Builder(@NonNull IFunction function) {
super(function);
public Builder(@NonNull IFunction that) {
function = new CppFunction(that);
}
@Nonnull
public Builder withDescription(@Nonnull String description) {
Check.isTrue(!built);
this.description = description;
function.description = description;
return this;
}
@Nonnull
public Builder withParameters(@Nonnull Collection<? extends String> parameters) {
Check.isTrue(!built);
this.parameters.addAll(parameters);
function.parameters.addAll(parameters);
return this;
}
@Nonnull
public Builder withParameter(@Nonnull String parameter) {
Check.isTrue(!built);
parameters.add(parameter);
function.parameters.add(parameter);
return this;
}
@Nonnull
public CppFunction build() {
built = true;
return this;
}
public void withValuesFrom(@Nonnull IFunction that) {
Check.isTrue(!built);
name = that.getName();
body = that.getContent();
description = Strings.getNotEmpty(that.getDescription(), "");
parameters.clear();
parameters.addAll(that.getParameterNames());
return function;
}
}
}

View File

@ -28,40 +28,56 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.view.*;
import android.text.TextUtils;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import butterknife.Bind;
import butterknife.ButterKnife;
import jscl.math.Generic;
import jscl.math.function.*;
import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.AppComponent;
import org.solovyev.android.calculator.BaseDialogFragment;
import org.solovyev.android.calculator.Calculator;
import org.solovyev.android.calculator.CalculatorEventType;
import org.solovyev.android.calculator.FunctionsRegistry;
import org.solovyev.android.calculator.KeyboardUi;
import org.solovyev.android.calculator.KeyboardWindow;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.math.edit.CalculatorFunctionsActivity;
import org.solovyev.android.calculator.math.edit.FunctionsFragment;
import org.solovyev.android.calculator.math.edit.MathEntityRemover;
import org.solovyev.android.calculator.math.edit.VarEditorSaver;
import org.solovyev.android.calculator.model.OldFunction;
import org.solovyev.common.math.MathRegistry;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
public class EditFunctionFragment extends BaseDialogFragment implements CalculatorEventListener, View.OnClickListener, View.OnFocusChangeListener, View.OnKeyListener {
import butterknife.Bind;
import butterknife.ButterKnife;
import jscl.math.function.CustomFunction;
import jscl.math.function.Function;
import jscl.math.function.IConstant;
private static final String ARG_INPUT = "input";
public class EditFunctionFragment extends BaseDialogFragment implements View.OnClickListener, View.OnFocusChangeListener, View.OnKeyListener {
private static final String ARG_FUNCTION = "function";
private static final int MENU_FUNCTION = Menu.FIRST;
private static final int MENU_CONSTANT = Menu.FIRST + 1;
@ -79,48 +95,65 @@ public class EditFunctionFragment extends BaseDialogFragment implements Calculat
TextInputLayout nameLabel;
@Bind(R.id.function_name)
EditText nameView;
@Bind(R.id.function_body_label)
TextInputLayout bodyLabel;
@Bind(R.id.function_body)
EditText bodyView;
@Bind(R.id.function_description)
EditText descriptionView;
private Input input;
private CppFunction function;
@Inject
Calculator calculator;
@Inject
FunctionsRegistry registry;
@Nonnull
public static EditFunctionFragment create(@Nonnull Input input) {
private static EditFunctionFragment create(@Nullable CppFunction function) {
final EditFunctionFragment fragment = new EditFunctionFragment();
fragment.input = input;
final Bundle args = new Bundle();
args.putParcelable("input", input);
fragment.setArguments(args);
if (function != null) {
final Bundle args = new Bundle();
args.putParcelable(ARG_FUNCTION, function);
fragment.setArguments(args);
}
return fragment;
}
public static void showDialog(@Nonnull Input input, @Nonnull Context context) {
if (context instanceof AppCompatActivity) {
EditFunctionFragment.showDialog(input, ((AppCompatActivity) context).getSupportFragmentManager());
} else {
public static void showDialog(@Nonnull FragmentActivity activity) {
EditFunctionFragment.showDialog(null, activity.getSupportFragmentManager());
}
public static void showDialog(@Nonnull CppFunction function, @Nonnull Context context) {
if (!(context instanceof CalculatorFunctionsActivity)) {
final Intent intent = new Intent(context, CalculatorFunctionsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(FunctionsFragment.EXTRA_FUNCTION, input);
intent.putExtra(FunctionsFragment.EXTRA_FUNCTION, function);
context.startActivity(intent);
} else {
EditFunctionFragment.showDialog(function, ((AppCompatActivity) context).getSupportFragmentManager());
}
}
public static void showDialog(@Nonnull Input input, @Nonnull FragmentManager fm) {
public static void showDialog(@Nullable CppFunction input, @Nonnull FragmentManager fm) {
App.showDialog(create(input), "function-editor", fm);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
input = getArguments().getParcelable(ARG_INPUT);
function = getArguments().getParcelable(ARG_FUNCTION);
}
@Override
protected void inject(@NonNull AppComponent component) {
super.inject(component);
component.inject(this);
}
@Override
protected void onPrepareDialog(@NonNull AlertDialog.Builder builder) {
builder.setNegativeButton(R.string.c_cancel, null);
builder.setPositiveButton(R.string.ok, null);
final OldFunction function = input.getFunction();
builder.setTitle(function == null ? R.string.function_create_function : R.string.function_edit_function);
if (function != null) {
builder.setNeutralButton(R.string.c_remove, null);
@ -145,17 +178,46 @@ public class EditFunctionFragment extends BaseDialogFragment implements Calculat
tryClose();
}
});
final OldFunction function = input.getFunction();
if (function != null) {
final Function customFunction = new CustomFunction.Builder(function).create();
final Button neutral = dialog.getButton(AlertDialog.BUTTON_NEUTRAL);
neutral.setOnClickListener(MathEntityRemover.newFunctionRemover(customFunction, null, getActivity(), EditFunctionFragment.this));
neutral.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tryRemoveFunction(function, false);
}
});
}
}
});
return dialog;
}
private void tryRemoveFunction(@NonNull CppFunction function, boolean confirmed) {
if (!confirmed) {
showRemovalDialog(function);
return;
}
final CustomFunction entity = function.toCustomFunctionBuilder().create();
registry.remove(entity);
calculator.fireCalculatorEvent(CalculatorEventType.function_removed, entity, this);
dismiss();
}
private void showRemovalDialog(@NonNull final CppFunction function) {
new AlertDialog.Builder(getActivity(), App.getTheme().alertDialogTheme)
.setCancelable(true)
.setTitle(R.string.removal_confirmation)
.setMessage(R.string.function_removal_confirmation_question)
.setNegativeButton(R.string.c_no, null)
.setPositiveButton(R.string.c_yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
tryRemoveFunction(function, true);
}
})
.create().show();
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (v.getId() == R.id.function_body) {
@ -166,6 +228,7 @@ public class EditFunctionFragment extends BaseDialogFragment implements Calculat
}
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.function_body) {
@ -199,9 +262,30 @@ public class EditFunctionFragment extends BaseDialogFragment implements Calculat
if (!validateName()) {
return false;
}
if (!validateParameters()) {
return false;
}
if (!validateBody()) {
return false;
}
final CppFunction newFunction = CppFunction.builder(nameView.getText().toString(), bodyView.getText().toString())
.withParameters(paramsView.getParams())
.withDescription(descriptionView.getText().toString()).build();
final Function oldFunction = function.id == CppFunction.NO_ID ? null : registry.getById(function.id);
registry.add(newFunction.toCustomFunctionBuilder(), oldFunction);
return true;
}
private boolean validateParameters(@Nonnull List<String> parameterNames) {
for (String parameterName : parameterNames) {
if (!VarEditorSaver.isValidName(parameterName)) {
return false;
}
}
// error = R.string.function_param_not_empty;
return true;
}
@ -211,11 +295,32 @@ public class EditFunctionFragment extends BaseDialogFragment implements Calculat
setError(nameLabel, getString(R.string.function_name_is_not_valid));
return false;
}
final Function existingFunction = registry.get(name);
if (existingFunction != null && (!existingFunction.isIdDefined() || !existingFunction.getId().equals(function.getId()))) {
setError(nameLabel, getString(R.string.function_already_exists));
return false;
}
clearError(nameLabel);
return true;
}
private boolean validateBody() {
final String body = bodyView.getText().toString();
if (TextUtils.isEmpty(body)) {
setError(bodyLabel, getString(R.string.function_is_empty));
return false;
}
clearError(bodyLabel);
return true;
}
private boolean validateParameters() {
final List<String> parameters = paramsView.getParams();
/*if (TextUtils.isEmpty(body)) {
setError(bodyLabel, getString(R.string.function_is_empty));
return false;
}*/
//clearError(bodyLabel);
return true;
}
@ -227,14 +332,10 @@ public class EditFunctionFragment extends BaseDialogFragment implements Calculat
ButterKnife.bind(this, view);
if (savedInstanceState == null) {
final List<String> parameterNames = input.getParameterNames();
if (parameterNames != null) {
paramsView.addParams(parameterNames);
}
nameView.setText(input.getName());
descriptionView.setText(input.getDescription());
bodyView.setText(input.getContent());
paramsView.addParams(function.getParameters());
nameView.setText(function.getName());
descriptionView.setText(function.getDescription());
bodyView.setText(function.getBody());
}
bodyView.setOnClickListener(this);
bodyView.setOnFocusChangeListener(this);
@ -243,177 +344,6 @@ public class EditFunctionFragment extends BaseDialogFragment implements Calculat
return view;
}
@Override
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 function_removed:
case function_added:
case function_changed:
if (calculatorEventData.getSource() == EditFunctionFragment.this) {
dismiss();
}
break;
}
}
public static class Input implements Parcelable {
private static final Parcelable.Creator<String> STRING_CREATOR = new Creator<String>() {
@Override
public String createFromParcel(@Nonnull Parcel in) {
return in.readString();
}
@Override
public String[] newArray(int size) {
return new String[size];
}
};
@Nullable
private OldFunction function;
@Nullable
private String name;
@Nullable
private String content;
@Nullable
private String description;
@Nullable
private List<String> parameterNames;
public static final Parcelable.Creator<Input> CREATOR = new Creator<Input>() {
@Override
public Input createFromParcel(@Nonnull Parcel in) {
return Input.fromParcel(in);
}
@Override
public Input[] newArray(int size) {
return new Input[size];
}
};
private Input() {
}
@Nonnull
private static Input fromParcel(@Nonnull Parcel in) {
final Input result = new Input();
result.name = in.readString();
result.content = in.readString();
result.description = in.readString();
final List<String> parameterNames = new ArrayList<>();
in.readTypedList(parameterNames, STRING_CREATOR);
result.parameterNames = parameterNames;
result.function = (OldFunction) in.readSerializable();
return result;
}
@Nonnull
public static Input newInstance() {
return new Input();
}
@Nonnull
public static Input newFromFunction(@Nonnull IFunction function) {
final Input result = new Input();
result.function = OldFunction.fromIFunction(function);
return result;
}
@Nonnull
public static Input newInstance(@Nullable IFunction function,
@Nullable String name,
@Nullable String value,
@Nullable String description,
@Nonnull List<String> parameterNames) {
final Input result = new Input();
if (function != null) {
result.function = OldFunction.fromIFunction(function);
}
result.name = name;
result.content = value;
result.description = description;
result.parameterNames = new ArrayList<>(parameterNames);
return result;
}
@Nonnull
public static Input newFromDisplay(@Nonnull DisplayState viewState) {
final Input result = new Input();
result.content = viewState.text;
final Generic generic = viewState.getResult();
if (generic != null) {
final Set<Constant> constants = CalculatorUtils.getNotSystemConstants(generic);
final List<String> parameterNames = new ArrayList<>(constants.size());
for (Constant constant : constants) {
parameterNames.add(constant.getName());
}
result.parameterNames = parameterNames;
}
return result;
}
@Nullable
public OldFunction getFunction() {
return function;
}
@Nullable
public String getName() {
return name == null ? (function == null ? null : function.getName()) : name;
}
@Nullable
public String getContent() {
return content == null ? (function == null ? null : function.getContent()) : content;
}
@Nullable
public String getDescription() {
return description == null ? (function == null ? null : function.getDescription()) : description;
}
@Nullable
public List<String> getParameterNames() {
return parameterNames == null ? (function == null ? null : function.getParameterNames()) : parameterNames;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@Nonnull Parcel out, int flags) {
out.writeString(name);
out.writeString(content);
out.writeString(description);
out.writeList(parameterNames);
out.writeSerializable(function);
}
}
private class KeyboardUser implements KeyboardUi.User, MenuItem.OnMenuItemClickListener {
@NonNull
@Override

View File

@ -1,75 +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.function;
import jscl.CustomFunctionCalculationException;
import jscl.math.function.CustomFunction;
import jscl.math.function.Function;
import org.solovyev.android.calculator.model.MathEntityBuilder;
import org.solovyev.android.calculator.model.OldFunction;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* User: serso
* Date: 1/20/13
* Time: 12:21 PM
*/
public final class FunctionBuilderAdapter implements MathEntityBuilder<Function> {
@Nonnull
private final OldFunction.Builder nestedBuilder;
public FunctionBuilderAdapter(@Nonnull OldFunction.Builder nestedBuilder) {
this.nestedBuilder = nestedBuilder;
}
@Nonnull
@Override
public MathEntityBuilder<Function> setName(@Nonnull String name) {
nestedBuilder.setName(name);
return this;
}
@Nonnull
@Override
public MathEntityBuilder<Function> setDescription(@Nullable String description) {
nestedBuilder.setDescription(description);
return this;
}
@Nonnull
@Override
public MathEntityBuilder<Function> setValue(@Nullable String value) {
nestedBuilder.setValue(value);
return this;
}
@Nonnull
@Override
public Function create() throws CustomFunctionCalculationException, OldFunction.Builder.CreationException {
final OldFunction function = nestedBuilder.create();
return new CustomFunction.Builder(function).create();
}
}

View File

@ -1,159 +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.function;
import android.view.View;
import android.widget.EditText;
import jscl.CustomFunctionCalculationException;
import jscl.math.function.Function;
import jscl.math.function.IFunction;
import org.solovyev.android.calculator.EntitiesRegistry;
import org.solovyev.android.calculator.FunctionsRegistry;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.math.edit.VarEditorSaver;
import org.solovyev.android.calculator.model.OldFunction;
import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
public class FunctionEditorSaver implements View.OnClickListener {
@Nonnull
private final Object source;
@Nonnull
private final OldFunction.Builder builder;
@Nullable
private final IFunction editedInstance;
@Nonnull
private final View view;
public FunctionEditorSaver(@Nonnull OldFunction.Builder builder,
@Nullable IFunction editedInstance,
@Nonnull View view,
@Nonnull EntitiesRegistry<Function> registry,
@Nonnull Object source) {
this.builder = builder;
this.editedInstance = editedInstance;
this.view = view;
this.source = source;
}
@Nonnull
public static EditFunctionFragment.Input readInput(@Nullable IFunction function, @Nonnull View root) {
final EditText editName = (EditText) root.findViewById(R.id.function_name);
String name = editName.getText().toString();
final EditText editValue = (EditText) root.findViewById(R.id.function_body);
String content = editValue.getText().toString();
final EditText editDescription = (EditText) root.findViewById(R.id.function_description);
String description = editDescription.getText().toString();
final FunctionParamsView editParams = (FunctionParamsView) root.findViewById(R.id.function_params);
List<String> parameterNames = editParams.getParams();
return EditFunctionFragment.Input.newInstance(function, name, content, description, parameterNames);
}
@Override
public void onClick(View v) {
final Integer error;
final EditFunctionFragment.Input input = readInput(null, view);
final String name = input.getName();
final String content = input.getContent();
final String description = input.getDescription();
List<String> parameterNames = input.getParameterNames();
if (parameterNames == null) {
parameterNames = Collections.emptyList();
}
final FunctionsRegistry registry = Locator.getInstance().getEngine().getFunctionsRegistry();
if (VarEditorSaver.isValidName(name)) {
boolean canBeSaved = false;
final Function entityFromRegistry = registry.get(name);
if (entityFromRegistry == null) {
canBeSaved = true;
} else if (editedInstance != null && entityFromRegistry.getId().equals(editedInstance.getId())) {
canBeSaved = true;
}
if (canBeSaved) {
if (validateParameters(parameterNames)) {
if (!Strings.isEmpty(content)) {
builder.setParameterNames(parameterNames);
builder.setName(name);
builder.setDescription(description);
builder.setValue(content);
error = null;
} else {
error = R.string.function_is_empty;
}
} else {
error = R.string.function_param_not_empty;
}
} else {
error = R.string.function_already_exists;
}
} else {
error = R.string.function_name_is_not_valid;
}
if (error != null) {
Locator.getInstance().getNotifier().showMessage(error, MessageType.error);
} else {
try {
registry.add(new FunctionBuilderAdapter(builder), editedInstance, source);
} catch (CustomFunctionCalculationException e) {
Locator.getInstance().getNotifier().showMessage(e);
} catch (OldFunction.Builder.CreationException e) {
Locator.getInstance().getNotifier().showMessage(e);
}
}
}
private boolean validateParameters(@Nonnull List<String> parameterNames) {
for (String parameterName : parameterNames) {
if (!VarEditorSaver.isValidName(parameterName)) {
return false;
}
}
return true;
}
}

View File

@ -1,9 +1,9 @@
package org.solovyev.android.calculator.history;
import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import org.json.JSONException;
import org.json.JSONObject;
import org.solovyev.android.Check;
@ -173,17 +173,18 @@ public class HistoryState implements Parcelable, Jsonable {
dest.writeString(comment);
}
@SuppressLint("ParcelCreator")
public static final class Builder extends HistoryState {
public static final class Builder {
@NonNull
private final HistoryState state;
private boolean built;
private Builder(@Nonnull EditorState editor, @Nonnull DisplayState display) {
super(editor, display);
this.state = new HistoryState(editor, display);
}
private Builder(@Nonnull HistoryState state, boolean newState) {
super(state, newState);
this.state = new HistoryState(state, newState);
if (newState) {
withTime(now());
}
@ -192,21 +193,21 @@ public class HistoryState implements Parcelable, Jsonable {
@Nonnull
public Builder withTime(long time) {
Check.isTrue(!built);
this.time = time;
state.time = time;
return this;
}
@Nonnull
public Builder withComment(@Nullable String comment) {
Check.isTrue(!built);
this.comment = comment == null ? "" : comment;
state.comment = comment == null ? "" : comment;
return this;
}
@Nonnull
public HistoryState build() {
built = true;
return this;
return state;
}
}
}

View File

@ -31,26 +31,44 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.ClipboardManager;
import android.text.TextUtils;
import android.view.*;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import butterknife.Bind;
import butterknife.ButterKnife;
import com.melnykov.fab.FloatingActionButton;
import org.solovyev.android.Check;
import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.BaseFragment;
import org.solovyev.android.calculator.CalculatorFragmentType;
import org.solovyev.android.calculator.R;
import org.solovyev.android.views.llm.DividerItemDecoration;
import org.solovyev.common.math.MathEntity;
import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseEntitiesFragment<E extends MathEntity> extends BaseFragment implements CalculatorEventListener {
import butterknife.Bind;
import butterknife.ButterKnife;
public abstract class BaseEntitiesFragment<E extends MathEntity> extends BaseFragment {
public static final String EXTRA_CATEGORY = "category";
private static final Comparator<MathEntity> COMPARATOR = new Comparator<MathEntity>() {
@Override
public int compare(MathEntity l, MathEntity r) {
return l.getName().compareTo(r.getName());
}
};
@Nonnull
private final Handler uiHandler = new Handler();
@ -58,7 +76,6 @@ public abstract class BaseEntitiesFragment<E extends MathEntity> extends BaseFra
FloatingActionButton fab;
@Bind(R.id.entities_recyclerview)
RecyclerView recyclerView;
@Nullable
private EntitiesAdapter adapter;
@Nullable
private String category;
@ -132,40 +149,6 @@ public abstract class BaseEntitiesFragment<E extends MathEntity> extends BaseFra
@Nullable
abstract String getCategory(@Nonnull E e);
protected void sort() {
/*
final EntitiesAdapter localAdapter = adapter;
if (localAdapter != null) {
localAdapter.sort(new Comparator<E>() {
@Override
public int compare(E function1, E function2) {
return function1.getName().compareTo(function2.getName());
}
});
localAdapter.notifyDataSetChanged();
}*/
}
public void addToAdapter(@Nonnull E mathEntity) {
if (this.adapter != null) {
//this.adapter.add(mathEntity);
}
}
public void removeFromAdapter(@Nonnull E mathEntity) {
if (this.adapter != null) {
//this.adapter.remove(mathEntity);
}
}
public void notifyAdapter() {
if (this.adapter != null) {
this.adapter.notifyDataSetChanged();
}
}
@Nullable
protected EntitiesAdapter getAdapter() {
return adapter;
}
@ -175,10 +158,22 @@ public abstract class BaseEntitiesFragment<E extends MathEntity> extends BaseFra
return uiHandler;
}
@Override
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
@SuppressWarnings("deprecation")
protected final void copyDescription(@Nonnull E entity) {
final String description = getDescription(entity);
if (!Strings.isEmpty(description)) {
final ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Activity.CLIPBOARD_SERVICE);
clipboard.setText(description);
}
}
@Nullable
protected abstract String getDescription(@NonNull E entity);
protected abstract void onCreateContextMenu(@Nonnull ContextMenu menu, @Nonnull E entity, @Nonnull MenuItem.OnMenuItemClickListener listener);
protected abstract boolean onMenuItemClicked(@Nonnull MenuItem item, @Nonnull E entity);
public class EntityViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener {
@Bind(R.id.entity_text)
TextView textView;
@ -226,20 +221,6 @@ public abstract class BaseEntitiesFragment<E extends MathEntity> extends BaseFra
}
}
@SuppressWarnings("deprecation")
protected final void copyDescription(@Nonnull E entity) {
final String description = getDescription(entity);
if (!Strings.isEmpty(description)) {
final ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Activity.CLIPBOARD_SERVICE);
clipboard.setText(description);
}
}
@Nullable
protected abstract String getDescription(@NonNull E entity);
protected abstract void onCreateContextMenu(@Nonnull ContextMenu menu, @Nonnull E entity, @Nonnull MenuItem.OnMenuItemClickListener listener);
protected abstract boolean onMenuItemClicked(@Nonnull MenuItem item, @Nonnull E entity);
public class EntitiesAdapter extends RecyclerView.Adapter<EntityViewHolder> {
@Nonnull
private final LayoutInflater inflater;
@ -271,5 +252,22 @@ public abstract class BaseEntitiesFragment<E extends MathEntity> extends BaseFra
public E getItem(int position) {
return list.get(position);
}
public void set(int position, @Nonnull E function) {
list.set(position, function);
}
public void sort() {
Collections.sort(list, COMPARATOR);
notifyDataSetChanged();
}
public void add(@Nonnull E entity) {
list.add(entity);
}
public void remove(@Nonnull E function) {
list.remove(function);
}
}
}

View File

@ -24,12 +24,16 @@ package org.solovyev.android.calculator.math.edit;
import android.os.Bundle;
import android.util.Log;
import org.solovyev.android.calculator.*;
import javax.annotation.Nonnull;
import org.solovyev.android.calculator.AndroidFunctionCategory;
import org.solovyev.android.calculator.BaseActivity;
import org.solovyev.android.calculator.CalculatorFragmentType;
import org.solovyev.android.calculator.FunctionCategory;
import org.solovyev.android.calculator.R;
import javax.annotation.Nullable;
public class CalculatorFunctionsActivity extends BaseActivity implements CalculatorEventListener {
public class CalculatorFunctionsActivity extends BaseActivity {
public CalculatorFunctionsActivity() {
super(R.layout.main_empty, CalculatorFunctionsActivity.class.getSimpleName());
@ -62,13 +66,4 @@ public class CalculatorFunctionsActivity extends BaseActivity implements Calcula
}
}
}
@Override
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
switch (calculatorEventType) {
case use_function:
this.finish();
break;
}
}
}

View File

@ -26,24 +26,46 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import jscl.math.function.Function;
import jscl.math.function.IFunction;
import org.solovyev.android.calculator.*;
import android.view.ViewGroup;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import org.solovyev.android.calculator.AppComponent;
import org.solovyev.android.calculator.Calculator;
import org.solovyev.android.calculator.CalculatorFragmentType;
import org.solovyev.android.calculator.EntitiesRegistry;
import org.solovyev.android.calculator.FunctionsRegistry;
import org.solovyev.android.calculator.Keyboard;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.function.CppFunction;
import org.solovyev.android.calculator.function.EditFunctionFragment;
import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import jscl.math.function.Function;
import jscl.math.function.IFunction;
public class FunctionsFragment extends BaseEntitiesFragment<Function> {
public static final String EXTRA_FUNCTION = "function";
@NonNull
private final EntitiesRegistry<Function> registry = Locator.getInstance().getEngine().getFunctionsRegistry();
@Inject
FunctionsRegistry registry;
@Inject
Calculator calculator;
@Inject
Keyboard keyboard;
@Inject
Bus bus;
public FunctionsFragment() {
super(CalculatorFragmentType.functions);
@ -55,15 +77,28 @@ public class FunctionsFragment extends BaseEntitiesFragment<Function> {
final Bundle bundle = getArguments();
if (bundle != null) {
final EditFunctionFragment.Input input = bundle.getParcelable(EXTRA_FUNCTION);
if (input != null) {
EditFunctionFragment.showDialog(input, getFragmentManager());
final CppFunction function = bundle.getParcelable(EXTRA_FUNCTION);
if (function != null) {
EditFunctionFragment.showDialog(function, getFragmentManager());
// in order to stop intent for other tabs
bundle.remove(EXTRA_FUNCTION);
}
}
}
@Override
protected void inject(@Nonnull AppComponent component) {
super.inject(component);
component.inject(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = super.onCreateView(inflater, container, savedInstanceState);
bus.register(this);
return view;
}
@Override
public void onViewCreated(View root, Bundle savedInstanceState) {
super.onViewCreated(root, savedInstanceState);
@ -73,14 +108,18 @@ public class FunctionsFragment extends BaseEntitiesFragment<Function> {
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EditFunctionFragment.showDialog(EditFunctionFragment.Input.newInstance(), getFragmentManager());
EditFunctionFragment.showDialog(getActivity());
}
});
}
@Override
protected void onClick(@NonNull @Nonnull Function function) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.use_function, function);
protected void onClick(@Nonnull Function function) {
keyboard.buttonPressed(function.getName());
final FragmentActivity activity = getActivity();
if (activity instanceof CalculatorFunctionsActivity) {
activity.finish();
}
}
@Override
@ -102,15 +141,15 @@ public class FunctionsFragment extends BaseEntitiesFragment<Function> {
final FragmentActivity activity = getActivity();
switch (item.getItemId()) {
case R.string.c_use:
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.use_function, function);
onClick(function);
return true;
case R.string.c_edit:
if (function instanceof IFunction) {
EditFunctionFragment.showDialog(EditFunctionFragment.Input.newFromFunction((IFunction) function), activity.getSupportFragmentManager());
EditFunctionFragment.showDialog(CppFunction.builder((IFunction) function).build(), activity.getSupportFragmentManager());
}
return true;
case R.string.c_remove:
MathEntityRemover.newFunctionRemover(function, null, activity, activity).showConfirmationDialog();
// todo serso:
return true;
case R.string.c_copy_description:
copyDescription(function);
@ -131,22 +170,48 @@ public class FunctionsFragment extends BaseEntitiesFragment<Function> {
}
@Override
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
super.onCalculatorEvent(calculatorEventData, calculatorEventType, data);
public void onDestroyView() {
bus.unregister(this);
super.onDestroyView();
}
switch (calculatorEventType) {
case function_added:
processFunctionAdded((Function) data);
break;
case function_changed:
processFunctionChanged((Change<IFunction>) data);
break;
case function_removed:
processFunctionRemoved((Function) data);
break;
@Subscribe
public void onFunctionAdded(@NonNull final FunctionsRegistry.AddedEvent event) {
if (!isInCategory(event.function)) {
return;
}
final EntitiesAdapter adapter = getAdapter();
adapter.add(event.function);
adapter.sort();
}
@Subscribe
public void onFunctionChanged(@NonNull final FunctionsRegistry.ChangedEvent event) {
if (!isInCategory(event.newFunction)) {
return;
}
if (!event.oldFunction.isIdDefined()) {
return;
}
final EntitiesAdapter adapter = getAdapter();
if (adapter == null) {
return;
}
for (int i = 0; i < adapter.getItemCount(); i++) {
final Function adapterFunction = adapter.getItem(i);
if (adapterFunction.isIdDefined() && event.oldFunction.getId().equals(adapterFunction.getId())) {
adapter.set(i, adapterFunction);
break;
}
}
adapter.sort();
}
@Subscribe
public void onFunctionRemoved(@NonNull final FunctionsRegistry.RemovedEvent event) {
final EntitiesAdapter adapter = getAdapter();
adapter.remove(event.function);
adapter.notifyDataSetChanged();
}
@Nullable
@ -154,64 +219,4 @@ public class FunctionsFragment extends BaseEntitiesFragment<Function> {
protected String getDescription(@NonNull Function function) {
return registry.getDescription(function.getName());
}
private void processFunctionRemoved(@Nonnull final Function function) {
if (this.isInCategory(function)) {
getUiHandler().post(new Runnable() {
@Override
public void run() {
removeFromAdapter(function);
notifyAdapter();
}
});
}
}
private void processFunctionChanged(@Nonnull final Change<IFunction> change) {
final IFunction newFunction = change.getNewValue();
if (newFunction instanceof Function) {
if (this.isInCategory((Function) newFunction)) {
getUiHandler().post(new Runnable() {
@Override
public void run() {
IFunction oldValue = change.getOldValue();
if (oldValue.isIdDefined()) {
final EntitiesAdapter adapter = getAdapter();
if (adapter != null) {
for (int i = 0; i < adapter.getItemCount(); i++) {
final Function functionFromAdapter = adapter.getItem(i);
if (functionFromAdapter.isIdDefined() && oldValue.getId().equals(functionFromAdapter.getId())) {
//adapter.remove(functionFromAdapter);
break;
}
}
}
}
addToAdapter((Function) newFunction);
sort();
}
});
}
} else {
throw new IllegalArgumentException("Function must be instance of jscl.math.function.Function class!");
}
}
private void processFunctionAdded(@Nonnull final Function function) {
if (this.isInCategory(function)) {
getUiHandler().post(new Runnable() {
@Override
public void run() {
addToAdapter(function);
sort();
}
});
}
}
}

View File

@ -37,7 +37,6 @@ import org.solovyev.common.math.MathEntity;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import jscl.math.function.Function;
import jscl.math.function.IConstant;
/**
@ -95,14 +94,7 @@ public class MathEntityRemover<T extends MathEntity> implements View.OnClickList
return new MathEntityRemover<IConstant>(constant, callbackOnCancel, false, Locator.getInstance().getEngine().getVarsRegistry(), context, source, Params.newConstantInstance());
}
public static MathEntityRemover<Function> newFunctionRemover(@Nonnull Function function,
@Nullable DialogInterface.OnClickListener callbackOnCancel,
@Nonnull Context context,
@Nonnull Object source) {
return new MathEntityRemover<Function>(function, callbackOnCancel, false, Locator.getInstance().getEngine().getFunctionsRegistry(), context, source, Params.newFunctionInstance());
}
/*
/*
**********************************************************************
*
* METHODS
@ -169,14 +161,6 @@ public class MathEntityRemover<T extends MathEntity> implements View.OnClickList
return result;
}
private static <T extends MathEntity> Params newFunctionInstance() {
final Params result = new Params();
result.removalConfirmationTitleResId = R.string.removal_confirmation;
result.removalConfirmationQuestionResId = R.string.function_removal_confirmation_question;
result.calculatorEventType = CalculatorEventType.function_removed;
return result;
}
public int getRemovalConfirmationTitleResId() {
return removalConfirmationTitleResId;
}

View File

@ -26,14 +26,21 @@ import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.view.ContextMenu;
import android.view.MenuItem;
import jscl.math.operator.Operator;
import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.CalculatorEventType;
import org.solovyev.android.calculator.CalculatorFragmentType;
import org.solovyev.android.calculator.EntitiesRegistry;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.R;
import org.solovyev.common.text.Strings;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import jscl.math.operator.Operator;
public class OperatorsFragment extends BaseEntitiesFragment<Operator> {

View File

@ -28,20 +28,34 @@ import android.support.v4.app.FragmentActivity;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import com.melnykov.fab.FloatingActionButton;
import jscl.math.function.IConstant;
import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.CalculatorEventData;
import org.solovyev.android.calculator.CalculatorEventListener;
import org.solovyev.android.calculator.CalculatorEventType;
import org.solovyev.android.calculator.CalculatorFragmentType;
import org.solovyev.android.calculator.CalculatorParseException;
import org.solovyev.android.calculator.Change;
import org.solovyev.android.calculator.EntitiesRegistry;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.PreparedExpression;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.ToJsclTextProcessor;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.common.JPredicate;
import org.solovyev.common.collections.Collections;
import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class VarsFragment extends BaseEntitiesFragment<IConstant> {
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import jscl.math.function.IConstant;
public class VarsFragment extends BaseEntitiesFragment<IConstant>implements CalculatorEventListener {
public static final String CREATE_VAR_EXTRA_STRING = "create_var";
@NonNull
@ -128,8 +142,6 @@ public class VarsFragment extends BaseEntitiesFragment<IConstant> {
@Override
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
super.onCalculatorEvent(calculatorEventData, calculatorEventType, data);
switch (calculatorEventType) {
case constant_added:
processConstantAdded((IConstant) data);
@ -196,8 +208,9 @@ public class VarsFragment extends BaseEntitiesFragment<IConstant> {
getUiHandler().post(new Runnable() {
@Override
public void run() {
removeFromAdapter(constant);
notifyAdapter();
final EntitiesAdapter adapter = getAdapter();
adapter.remove(constant);
adapter.notifyDataSetChanged();
}
});
}
@ -209,9 +222,10 @@ public class VarsFragment extends BaseEntitiesFragment<IConstant> {
getUiHandler().post(new Runnable() {
@Override
public void run() {
removeFromAdapter(change.getOldValue());
addToAdapter(newConstant);
sort();
final EntitiesAdapter adapter = getAdapter();
adapter.remove(change.getOldValue());
adapter.add(newConstant);
adapter.sort();
}
});
}
@ -222,8 +236,9 @@ public class VarsFragment extends BaseEntitiesFragment<IConstant> {
getUiHandler().post(new Runnable() {
@Override
public void run() {
addToAdapter(constant);
sort();
final EntitiesAdapter adapter = getAdapter();
adapter.add(constant);
adapter.sort();
}
});
}