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 -