diff --git a/app/build.gradle b/app/build.gradle
index 68b2367b..9974f5fa 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -99,6 +99,7 @@ dependencies {
}
compile 'commons-cli:commons-cli:1.2'
compile 'com.squareup:otto:1.3.8'
+ compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.google.dagger:dagger:2.0.2'
apt "com.google.dagger:dagger-compiler:2.0.2"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b16a64d7..4ea3a118 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -76,7 +76,7 @@
android:finishOnTaskLaunch="true"
android:label="@string/calculation_messages_dialog_title"
android:launchMode="singleTask"
- android:theme="@style/Cpp.Theme.Dialog.Material" />
+ android:theme="@style/Cpp.Theme.Material.Dialog" />
+ android:theme="@style/Cpp.Theme.Material.Dialog" />
+ android:theme="@style/Cpp.Theme.Material.Dialog" />
+ android:theme="@style/Cpp.Theme.Material.Dialog" />
+ android:theme="@style/Cpp.Theme.Material.Dialog" />
+ android:theme="@style/Cpp.Theme.Material.Dialog" />
+ android:theme="@style/Cpp.Theme.Material.Dialog">
diff --git a/app/src/main/java/org/solovyev/android/calculator/AppComponent.java b/app/src/main/java/org/solovyev/android/calculator/AppComponent.java
index 24a36253..22fd07d9 100644
--- a/app/src/main/java/org/solovyev/android/calculator/AppComponent.java
+++ b/app/src/main/java/org/solovyev/android/calculator/AppComponent.java
@@ -1,11 +1,12 @@
package org.solovyev.android.calculator;
-import dagger.Component;
import org.solovyev.android.calculator.history.BaseHistoryFragment;
import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService;
import javax.inject.Singleton;
+import dagger.Component;
+
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
@@ -14,4 +15,5 @@ public interface AppComponent {
void inject(BaseUi ui);
void inject(CalculatorOnscreenService service);
void inject(BaseHistoryFragment fragment);
+ void inject(BaseDialogFragment fragment);
}
diff --git a/app/src/main/java/org/solovyev/android/calculator/BaseDialogFragment.java b/app/src/main/java/org/solovyev/android/calculator/BaseDialogFragment.java
new file mode 100644
index 00000000..451515c7
--- /dev/null
+++ b/app/src/main/java/org/solovyev/android/calculator/BaseDialogFragment.java
@@ -0,0 +1,44 @@
+package org.solovyev.android.calculator;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.DialogFragment;
+import android.support.v7.app.AlertDialog;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import javax.inject.Inject;
+
+public abstract class BaseDialogFragment extends DialogFragment {
+
+ @Inject
+ SharedPreferences preferences;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ((CalculatorApplication) getActivity().getApplication()).getComponent().inject(this);
+ }
+
+ @NonNull
+ @Override
+ public AlertDialog onCreateDialog(Bundle savedInstanceState) {
+ final Preferences.Gui.Theme theme = Preferences.Gui.getTheme(preferences);
+ final Context context = getActivity();
+ final LayoutInflater inflater = LayoutInflater.from(context);
+ final View view = onCreateDialogView(context, inflater, savedInstanceState);
+ final int spacing = context.getResources().getDimensionPixelSize(R.dimen.cpp_dialog_spacing);
+ final AlertDialog.Builder b = new AlertDialog.Builder(context, theme.alertDialogTheme);
+ b.setView(view, spacing, spacing, spacing, spacing);
+ onPrepareDialog(b);
+ return b.create();
+ }
+
+ protected abstract void onPrepareDialog(@NonNull AlertDialog.Builder builder);
+
+ @NonNull
+ protected abstract View onCreateDialogView(@NonNull Context context, @NonNull LayoutInflater inflater, @Nullable Bundle savedInstanceState);
+}
diff --git a/app/src/main/java/org/solovyev/android/calculator/DisplayState.java b/app/src/main/java/org/solovyev/android/calculator/DisplayState.java
index 41c86fb7..41a0238f 100644
--- a/app/src/main/java/org/solovyev/android/calculator/DisplayState.java
+++ b/app/src/main/java/org/solovyev/android/calculator/DisplayState.java
@@ -22,6 +22,8 @@
package org.solovyev.android.calculator;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.text.TextUtils;
import org.json.JSONException;
@@ -33,8 +35,19 @@ import javax.annotation.Nullable;
import jscl.math.Generic;
-public class DisplayState {
+public class DisplayState implements Parcelable {
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public DisplayState createFromParcel(Parcel in) {
+ return new DisplayState(in);
+ }
+
+ @Override
+ public DisplayState[] newArray(int size) {
+ return new DisplayState[size];
+ }
+ };
private static final String JSON_TEXT = "t";
@Nonnull
public final String text;
@@ -55,6 +68,12 @@ public class DisplayState {
this(json.optString(JSON_TEXT), true, EditorState.NO_SEQUENCE);
}
+ private DisplayState(Parcel in) {
+ text = in.readString();
+ valid = in.readByte() != 0;
+ sequence = in.readLong();
+ }
+
@Nonnull
public static DisplayState empty() {
return new DisplayState("", true, EditorState.NO_SEQUENCE);
@@ -114,4 +133,16 @@ public class DisplayState {
", operation=" + operation +
'}';
}
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(text);
+ dest.writeByte((byte) (valid ? 1 : 0));
+ dest.writeLong(sequence);
+ }
}
diff --git a/app/src/main/java/org/solovyev/android/calculator/EditorState.java b/app/src/main/java/org/solovyev/android/calculator/EditorState.java
index 40acd7a1..4967dddd 100644
--- a/app/src/main/java/org/solovyev/android/calculator/EditorState.java
+++ b/app/src/main/java/org/solovyev/android/calculator/EditorState.java
@@ -22,6 +22,8 @@
package org.solovyev.android.calculator;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.text.TextUtils;
import org.json.JSONException;
@@ -32,13 +34,23 @@ import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-public class EditorState {
+public class EditorState implements Parcelable {
public static final long NO_SEQUENCE = -1;
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public EditorState createFromParcel(Parcel in) {
+ return new EditorState(in);
+ }
+
+ @Override
+ public EditorState[] newArray(int size) {
+ return new EditorState[size];
+ }
+ };
private static final String JSON_TEXT = "t";
private static final String JSON_SELECTION = "s";
private static AtomicLong counter = new AtomicLong(NO_SEQUENCE + 1);
-
public final long sequence;
@Nonnull
public final CharSequence text;
@@ -60,6 +72,13 @@ public class EditorState {
this(json.optString(JSON_TEXT), json.optInt(JSON_SELECTION));
}
+ private EditorState(Parcel in) {
+ sequence = in.readLong();
+ selection = in.readInt();
+ textString = in.readString();
+ text = textString;
+ }
+
@Nonnull
public static EditorState empty() {
return new EditorState();
@@ -108,4 +127,16 @@ public class EditorState {
json.put(JSON_SELECTION, selection);
return json;
}
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(sequence);
+ dest.writeInt(selection);
+ dest.writeString(textString);
+ }
}
diff --git a/app/src/main/java/org/solovyev/android/calculator/Preferences.java b/app/src/main/java/org/solovyev/android/calculator/Preferences.java
index 8994f66b..26790a1e 100644
--- a/app/src/main/java/org/solovyev/android/calculator/Preferences.java
+++ b/app/src/main/java/org/solovyev/android/calculator/Preferences.java
@@ -31,23 +31,31 @@ import android.support.annotation.LayoutRes;
import android.support.annotation.StyleRes;
import android.util.SparseArray;
import android.view.ContextThemeWrapper;
-import jscl.AngleUnit;
-import jscl.NumeralBase;
+
import org.solovyev.android.Check;
import org.solovyev.android.calculator.language.Languages;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.model.AndroidCalculatorEngine;
import org.solovyev.android.calculator.preferences.PurchaseDialogActivity;
import org.solovyev.android.calculator.wizard.WizardActivity;
-import org.solovyev.android.prefs.*;
+import org.solovyev.android.prefs.BooleanPreference;
+import org.solovyev.android.prefs.IntegerPreference;
+import org.solovyev.android.prefs.LongPreference;
+import org.solovyev.android.prefs.NumberToStringPreference;
+import org.solovyev.android.prefs.Preference;
+import org.solovyev.android.prefs.StringPreference;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import java.text.DecimalFormatSymbols;
import java.util.EnumMap;
import java.util.Locale;
import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import jscl.AngleUnit;
+import jscl.NumeralBase;
+
import static org.solovyev.android.Android.isPhoneModel;
import static org.solovyev.android.DeviceModel.samsung_galaxy_s;
import static org.solovyev.android.DeviceModel.samsung_galaxy_s_2;
@@ -275,11 +283,11 @@ public final class Preferences {
default_theme(R.style.Cpp_Theme_Gray),
violet_theme(R.style.Cpp_Theme_Violet),
light_blue_theme(R.style.Cpp_Theme_Blue),
- metro_blue_theme(R.style.cpp_metro_blue_theme),
- metro_purple_theme(R.style.cpp_metro_purple_theme),
- metro_green_theme(R.style.cpp_metro_green_theme),
+ metro_blue_theme(R.style.Cpp_Theme_Metro_Blue),
+ metro_purple_theme(R.style.Cpp_Theme_Metro_Purple),
+ metro_green_theme(R.style.Cpp_Theme_Metro_Green),
material_theme(R.style.Cpp_Theme_Material),
- material_light_theme(R.style.Cpp_Theme_Material_Light, R.style.Cpp_Theme_Wizard_Light, R.style.Cpp_Theme_Dialog_Material_Light);
+ material_light_theme(R.style.Cpp_Theme_Material_Light, R.style.Cpp_Theme_Wizard_Light, R.style.Cpp_Theme_Material_Light_Dialog, R.style.Cpp_Theme_Material_Light_Dialog_Alert);
private static final SparseArray textColors = new SparseArray<>();
@@ -289,16 +297,19 @@ public final class Preferences {
public final int wizardTheme;
@StyleRes
public final int dialogTheme;
+ @StyleRes
+ public final int alertDialogTheme;
public final boolean light;
Theme(@StyleRes int theme) {
- this(theme, R.style.Cpp_Theme_Wizard, R.style.Cpp_Theme_Dialog_Material);
+ this(theme, R.style.Cpp_Theme_Wizard, R.style.Cpp_Theme_Material_Dialog, R.style.Cpp_Theme_Material_Dialog_Alert);
}
- Theme(@StyleRes int theme, @StyleRes int wizardTheme, @StyleRes int dialogTheme) {
+ Theme(@StyleRes int theme, @StyleRes int wizardTheme, @StyleRes int dialogTheme, @StyleRes int alertDialogTheme) {
this.theme = theme;
this.wizardTheme = wizardTheme;
this.dialogTheme = dialogTheme;
+ this.alertDialogTheme = alertDialogTheme;
this.light = theme == R.style.Cpp_Theme_Material_Light;
}
diff --git a/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java b/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java
index f11bcdff..629eeefb 100644
--- a/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java
+++ b/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java
@@ -30,20 +30,37 @@ import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.ListFragment;
import android.text.ClipboardManager;
-import android.view.*;
-import android.widget.*;
+import android.view.ContextMenu;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
import com.melnykov.fab.FloatingActionButton;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
-import org.solovyev.android.calculator.*;
+
+import org.solovyev.android.calculator.App;
+import org.solovyev.android.calculator.CalculatorActivity;
+import org.solovyev.android.calculator.CalculatorApplication;
+import org.solovyev.android.calculator.CalculatorFragmentType;
+import org.solovyev.android.calculator.FragmentUi;
+import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.text.Strings;
+import java.util.ArrayList;
+import java.util.List;
+
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
-import java.util.ArrayList;
-import java.util.List;
import static android.view.Menu.NONE;
@@ -160,8 +177,7 @@ public abstract class BaseHistoryFragment extends ListFragment {
final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
final HistoryState state = (HistoryState) getListView().getItemAtPosition(info.position);
- // todo serso: fix
- if (true) {
+ if (!isRecentHistory()) {
menu.add(NONE, R.string.c_use, NONE, R.string.c_use);
menu.add(NONE, R.string.c_copy_expression, NONE, R.string.c_copy_expression);
if (shouldHaveCopyResult(state)) {
@@ -206,7 +222,7 @@ public abstract class BaseHistoryFragment extends ListFragment {
}
return true;
case R.string.c_save:
- createEditHistoryDialog(state, context, true);
+ EditHistoryFragment.show(state, getFragmentManager());
return true;
case R.string.c_edit:
createEditHistoryDialog(state, context, false);
diff --git a/app/src/main/java/org/solovyev/android/calculator/history/EditHistoryFragment.java b/app/src/main/java/org/solovyev/android/calculator/history/EditHistoryFragment.java
new file mode 100644
index 00000000..610e8e04
--- /dev/null
+++ b/app/src/main/java/org/solovyev/android/calculator/history/EditHistoryFragment.java
@@ -0,0 +1,61 @@
+package org.solovyev.android.calculator.history;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.FragmentManager;
+import android.support.v7.app.AlertDialog;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import org.solovyev.android.calculator.BaseDialogFragment;
+import org.solovyev.android.calculator.R;
+
+import butterknife.Bind;
+import butterknife.ButterKnife;
+
+public class EditHistoryFragment extends BaseDialogFragment {
+
+ public static final String ARG_STATE = "state";
+
+ @Bind(R.id.history_edit_expression)
+ TextView expressionView;
+
+ @Bind(R.id.history_edit_comment)
+ EditText commentView;
+ private HistoryState state;
+
+ public static void show(@NonNull HistoryState state, @NonNull FragmentManager fm) {
+ final EditHistoryFragment fragment = new EditHistoryFragment();
+ final Bundle args = new Bundle();
+ args.putParcelable(ARG_STATE, state);
+ fragment.setArguments(args);
+ fragment.show(fm, "edit-history-fragment");
+ }
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ state = getArguments().getParcelable(ARG_STATE);
+ }
+
+ @Override
+ protected void onPrepareDialog(@NonNull AlertDialog.Builder builder) {
+
+ }
+
+ @NonNull
+ @Override
+ protected View onCreateDialogView(@NonNull Context context, @NonNull LayoutInflater inflater, @Nullable Bundle savedInstanceState) {
+ final View view = inflater.inflate(R.layout.history_edit, null);
+ ButterKnife.bind(this, view);
+ if (savedInstanceState == null) {
+ expressionView.setText(BaseHistoryFragment.getHistoryText(state));
+ commentView.setText(state.getComment());
+ }
+ return view;
+ }
+}
diff --git a/app/src/main/java/org/solovyev/android/calculator/history/HistoryState.java b/app/src/main/java/org/solovyev/android/calculator/history/HistoryState.java
index 771921ec..a6aeeceb 100644
--- a/app/src/main/java/org/solovyev/android/calculator/history/HistoryState.java
+++ b/app/src/main/java/org/solovyev/android/calculator/history/HistoryState.java
@@ -1,5 +1,9 @@
package org.solovyev.android.calculator.history;
+import android.annotation.SuppressLint;
+import android.os.Parcel;
+import android.os.Parcelable;
+
import org.json.JSONException;
import org.json.JSONObject;
import org.solovyev.android.Check;
@@ -11,13 +15,23 @@ import javax.annotation.Nullable;
import static android.text.TextUtils.isEmpty;
-public class HistoryState {
+public class HistoryState implements Parcelable {
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public HistoryState createFromParcel(Parcel in) {
+ return new HistoryState(in);
+ }
+
+ @Override
+ public HistoryState[] newArray(int size) {
+ return new HistoryState[size];
+ }
+ };
private static final String JSON_EDITOR = "e";
private static final String JSON_DISPLAY = "d";
private static final String JSON_TIME = "t";
private static final String JSON_COMMENT = "c";
-
@Nonnull
public final EditorState editor;
@Nonnull
@@ -37,6 +51,13 @@ public class HistoryState {
this.comment = json.optString(JSON_COMMENT, "");
}
+ private HistoryState(Parcel in) {
+ editor = in.readParcelable(EditorState.class.getClassLoader());
+ display = in.readParcelable(DisplayState.class.getClassLoader());
+ time = in.readLong();
+ comment = in.readString();
+ }
+
@Nonnull
public static Builder newBuilder(@Nonnull EditorState editor, @Nonnull DisplayState display) {
return new Builder(editor, display);
@@ -92,6 +113,20 @@ public class HistoryState {
'}';
}
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(editor, flags);
+ dest.writeParcelable(display, flags);
+ dest.writeLong(time);
+ dest.writeString(comment);
+ }
+
+ @SuppressLint("ParcelCreator")
public static final class Builder extends HistoryState {
private boolean built;
diff --git a/app/src/main/res/layout/history_edit.xml b/app/src/main/res/layout/history_edit.xml
index 8cedbf92..50dfad3d 100644
--- a/app/src/main/res/layout/history_edit.xml
+++ b/app/src/main/res/layout/history_edit.xml
@@ -23,8 +23,8 @@
-->
+ a:layout_width="wrap_content"
+ a:layout_height="wrap_content">
+ a:textStyle="bold" />
+ a:minLines="4"
+ a:inputType="text" />
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 7ce003db..48c42fcb 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -37,4 +37,6 @@
5dp
5dp
1dp
+
+ 20dp
\ No newline at end of file
diff --git a/app/src/main/res/values/theme.xml b/app/src/main/res/values/theme.xml
index de186126..55897b2c 100644
--- a/app/src/main/res/values/theme.xml
+++ b/app/src/main/res/values/theme.xml
@@ -68,6 +68,30 @@
- @color/cpp_text_error
+
+
+
+
-
+
+
-
+
+
-
-
diff --git a/app/src/main/res/values/theme_metro_purple.xml b/app/src/main/res/values/theme_metro_purple.xml
index e3afa8f8..ba4f3b7c 100644
--- a/app/src/main/res/values/theme_metro_purple.xml
+++ b/app/src/main/res/values/theme_metro_purple.xml
@@ -26,7 +26,7 @@
- @drawable/metro_button_purple
-