From af43970d9b8f08aecaffa58c19ca8a0020ba75da Mon Sep 17 00:00:00 2001 From: serso Date: Sun, 31 Jan 2016 20:46:47 +0100 Subject: [PATCH] FixableErrorsActivity --- app/src/main/AndroidManifest.xml | 5 +- .../calculator/AbstractFixableError.java | 44 --- .../android/calculator/AndroidCalculator.java | 15 +- .../AndroidCalculatorPreferenceService.java | 115 -------- .../android/calculator/AppComponent.java | 5 + .../android/calculator/BaseActivity.java | 7 +- .../calculator/BaseDialogFragment.java | 12 +- .../calculator/CalculatorActivity.java | 26 +- .../CalculatorActivityLauncher.java | 15 +- .../calculator/CalculatorApplication.java | 5 +- .../android/calculator/CalculatorButtons.java | 4 +- .../calculator/CalculatorDisplayFragment.java | 2 +- .../calculator/CalculatorEditorFragment.java | 2 +- .../android/calculator/CalculatorImpl.java | 3 +- .../CalculatorKeyboardFragment.java | 2 +- .../android/calculator/CalculatorLocator.java | 4 +- .../calculator/CalculatorMessages.java | 2 +- .../CalculatorPreferenceService.java | 46 --- .../android/calculator/DisplayView.java | 2 +- .../android/calculator/FixableError.java | 40 --- .../android/calculator/FixableMessage.java | 109 ------- .../calculator/FixableMessagesDialog.java | 275 ------------------ .../solovyev/android/calculator/Locator.java | 10 +- .../android/calculator/Preferences.java | 41 +-- .../calculator/PreferredPreferences.java | 117 ++++++++ .../calculator/errors/FixableError.java | 87 ++++++ .../errors/FixableErrorFragment.java | 98 +++++++ .../FixableErrorType.java} | 39 +-- .../errors/FixableErrorsActivity.java | 118 ++++++++ .../functions/EditFunctionFragment.java | 12 +- .../functions/FunctionsActivity.java | 2 +- .../functions/FunctionsFragment.java | 4 +- .../calculator/wizard/CalculatorLayout.java | 2 +- .../calculator/wizard/CalculatorMode.java | 4 +- app/src/main/res/values/styles.xml | 6 +- app/src/main/res/values/text_strings.xml | 1 + app/src/main/res/values/theme.xml | 9 + .../main/res/xml/preferences_appearance.xml | 11 - .../main/res/xml/preferences_calculations.xml | 5 - .../calculator/AbstractCalculatorTest.java | 2 +- .../calculator/CalculatorTestUtils.java | 4 +- 41 files changed, 539 insertions(+), 773 deletions(-) delete mode 100644 app/src/main/java/org/solovyev/android/calculator/AbstractFixableError.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorPreferenceService.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/CalculatorPreferenceService.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/FixableError.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/FixableMessage.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/FixableMessagesDialog.java create mode 100644 app/src/main/java/org/solovyev/android/calculator/PreferredPreferences.java create mode 100644 app/src/main/java/org/solovyev/android/calculator/errors/FixableError.java create mode 100644 app/src/main/java/org/solovyev/android/calculator/errors/FixableErrorFragment.java rename app/src/main/java/org/solovyev/android/calculator/{CalculatorFixableError.java => errors/FixableErrorType.java} (61%) create mode 100644 app/src/main/java/org/solovyev/android/calculator/errors/FixableErrorsActivity.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2a09e020..05a7c740 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -71,12 +71,11 @@ android:label="@string/c_history" /> + android:theme="@style/Cpp.Theme.Translucent" /> ) data); + FixableErrorsActivity.show(App.getApplication(), (List) data); break; case show_history: CalculatorActivityLauncher.showHistory(App.getApplication()); diff --git a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorPreferenceService.java b/app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorPreferenceService.java deleted file mode 100644 index 7497cdf1..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorPreferenceService.java +++ /dev/null @@ -1,115 +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; - -import android.app.Application; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import jscl.AngleUnit; -import jscl.NumeralBase; -import org.solovyev.android.msg.AndroidMessage; -import org.solovyev.common.msg.MessageType; - -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.List; - -/** - * User: serso - * Date: 11/17/12 - * Time: 7:46 PM - */ -public class AndroidCalculatorPreferenceService implements CalculatorPreferenceService { - - // one hour - private static final Long PREFERRED_PREFS_INTERVAL_TIME = 1000L * 60L * 60L; - - @Nonnull - private final Application application; - - public AndroidCalculatorPreferenceService(@Nonnull Application application) { - this.application = application; - } - - @Override - public void checkPreferredPreferences(boolean force) { - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(application); - - final Long currentTime = System.currentTimeMillis(); - - if (force || (Preferences.Calculations.showCalculationMessagesDialog.getPreference(prefs) && isTimeForCheck(currentTime, prefs))) { - final NumeralBase preferredNumeralBase = Preferences.Calculations.preferredNumeralBase.getPreference(prefs); - final NumeralBase numeralBase = Engine.Preferences.numeralBase.getPreference(prefs); - - final AngleUnit preferredAngleUnits = Preferences.Calculations.preferredAngleUnits.getPreference(prefs); - final AngleUnit angleUnits = Engine.Preferences.angleUnit.getPreference(prefs); - - final List messages = new ArrayList(2); - if (numeralBase != preferredNumeralBase) { - messages.add(new FixableMessage(application.getString(R.string.preferred_numeral_base_message, preferredNumeralBase.name(), numeralBase.name()), MessageType.warning, CalculatorFixableError.preferred_numeral_base)); - } - - if (angleUnits != preferredAngleUnits) { - messages.add(new FixableMessage(application.getString(R.string.preferred_angle_units_message, preferredAngleUnits.name(), angleUnits.name()), MessageType.warning, CalculatorFixableError.preferred_angle_units)); - } - - FixableMessagesDialog.showDialog(messages, application, true); - - Preferences.Calculations.lastPreferredPreferencesCheck.putPreference(prefs, currentTime); - } - } - - private boolean isTimeForCheck(@Nonnull Long currentTime, @Nonnull SharedPreferences preferences) { - final Long lastPreferredPreferencesCheckTime = Preferences.Calculations.lastPreferredPreferencesCheck.getPreference(preferences); - - return currentTime - lastPreferredPreferencesCheckTime > PREFERRED_PREFS_INTERVAL_TIME; - } - - @Override - public void setPreferredAngleUnits() { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(application); - setAngleUnits(Preferences.Calculations.preferredAngleUnits.getPreference(preferences)); - } - - @Override - public void setAngleUnits(@Nonnull AngleUnit angleUnit) { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(application); - Engine.Preferences.angleUnit.putPreference(preferences, angleUnit); - - Locator.getInstance().getNotifier().showMessage(new AndroidMessage(R.string.c_angle_units_changed_to, MessageType.info, application, angleUnit.name())); - } - - @Override - public void setPreferredNumeralBase() { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(application); - setNumeralBase(Preferences.Calculations.preferredNumeralBase.getPreference(preferences)); - } - - @Override - public void setNumeralBase(@Nonnull NumeralBase numeralBase) { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(application); - Engine.Preferences.numeralBase.putPreference(preferences, numeralBase); - - Locator.getInstance().getNotifier().showMessage(new AndroidMessage(R.string.c_numeral_base_changed_to, MessageType.info, application, numeralBase.name())); - } -} 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 48811740..5b0fc552 100644 --- a/app/src/main/java/org/solovyev/android/calculator/AppComponent.java +++ b/app/src/main/java/org/solovyev/android/calculator/AppComponent.java @@ -1,6 +1,8 @@ package org.solovyev.android.calculator; import dagger.Component; +import org.solovyev.android.calculator.errors.FixableErrorFragment; +import org.solovyev.android.calculator.errors.FixableErrorsActivity; import org.solovyev.android.calculator.functions.EditFunctionFragment; import org.solovyev.android.calculator.functions.FunctionsFragment; import org.solovyev.android.calculator.history.BaseHistoryFragment; @@ -21,10 +23,13 @@ public interface AppComponent { void inject(CalculatorOnscreenService service); void inject(BaseHistoryFragment fragment); void inject(BaseDialogFragment fragment); + void inject(FixableErrorFragment fragment); void inject(EditFunctionFragment fragment); void inject(EditVariableFragment fragment); void inject(EditHistoryFragment fragment); void inject(FunctionsFragment fragment); void inject(VariablesFragment fragment); void inject(OperatorsFragment fragment); + void inject(CalculatorActivity activity); + void inject(FixableErrorsActivity activity); } diff --git a/app/src/main/java/org/solovyev/android/calculator/BaseActivity.java b/app/src/main/java/org/solovyev/android/calculator/BaseActivity.java index 47b7ef85..50c18e88 100644 --- a/app/src/main/java/org/solovyev/android/calculator/BaseActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/BaseActivity.java @@ -6,8 +6,8 @@ import android.support.v4.app.Fragment; import android.support.v7.app.AppCompatActivity; import android.view.KeyEvent; import android.view.MenuItem; -import org.solovyev.android.calculator.entities.Category; import org.solovyev.android.calculator.entities.BaseEntitiesFragment; +import org.solovyev.android.calculator.entities.Category; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -38,9 +38,13 @@ public class BaseActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { ui.onPreCreate(this); super.onCreate(savedInstanceState); + inject(((CalculatorApplication) getApplication()).getComponent()); ui.onCreate(this); } + protected void inject(@Nonnull AppComponent component) { + } + @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -80,7 +84,6 @@ public class BaseActivity extends AppCompatActivity { super.onPause(); } - @Override protected void onDestroy() { super.onDestroy(); diff --git a/app/src/main/java/org/solovyev/android/calculator/BaseDialogFragment.java b/app/src/main/java/org/solovyev/android/calculator/BaseDialogFragment.java index 9651553b..cb39cf76 100644 --- a/app/src/main/java/org/solovyev/android/calculator/BaseDialogFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/BaseDialogFragment.java @@ -20,7 +20,7 @@ import javax.inject.Inject; public abstract class BaseDialogFragment extends DialogFragment { @Inject - SharedPreferences preferences; + protected SharedPreferences preferences; @Override public void onCreate(@Nullable Bundle savedInstanceState) { @@ -38,10 +38,12 @@ public abstract class BaseDialogFragment extends DialogFragment { 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); + final View view = onCreateDialogView(context, inflater, savedInstanceState); + if (view != null) { + final int spacing = context.getResources().getDimensionPixelSize(R.dimen.cpp_dialog_spacing); + b.setView(view, spacing, spacing, spacing, spacing); + } onPrepareDialog(b); final AlertDialog dialog = b.create(); dialog.setOnShowListener(new DialogInterface.OnShowListener() { @@ -58,7 +60,7 @@ public abstract class BaseDialogFragment extends DialogFragment { protected abstract void onPrepareDialog(@NonNull AlertDialog.Builder builder); - @NonNull + @Nullable protected abstract View onCreateDialogView(@NonNull Context context, @NonNull LayoutInflater inflater, @Nullable Bundle savedInstanceState); protected void setError(@NonNull TextInputLayout textInput, @StringRes int error, Object... errorArgs) { diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java index b5f21f93..85a11bda 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java @@ -70,6 +70,11 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference public static final String TAG = CalculatorActivity.class.getSimpleName(); private boolean useBackAsPrev; + + @Inject + PreferredPreferences preferredPreferences; + @Inject + Keyboard keyboard; public CalculatorActivity() { super(0, TAG); @@ -154,7 +159,7 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference public void onCreate(@Nullable Bundle savedInstanceState) { final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); final Preferences.Gui.Layout layout = Preferences.Gui.layout.getPreferenceNoError(preferences); - ui.setLayoutId(layout.getLayoutId()); + ui.setLayoutId(layout.layoutId); super.onCreate(savedInstanceState); @@ -188,15 +193,21 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference preferences.registerOnSharedPreferenceChangeListener(this); - Locator.getInstance().getPreferenceService().checkPreferredPreferences(false); + preferredPreferences.check(this, false); if (App.isMonkeyRunner(this)) { - Locator.getInstance().getKeyboard().buttonPressed("123"); - Locator.getInstance().getKeyboard().buttonPressed("+"); - Locator.getInstance().getKeyboard().buttonPressed("321"); + keyboard.buttonPressed("123"); + keyboard.buttonPressed("+"); + keyboard.buttonPressed("321"); } } + @Override + protected void inject(@Nonnull AppComponent component) { + super.inject(component); + component.inject(this); + } + @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) private boolean hasPermanentMenuKey() { return ViewConfiguration.get(this).hasPermanentMenuKey(); @@ -206,11 +217,6 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference return findViewById(R.id.main_second_pane) != null; } - @Nonnull - private AndroidCalculator getCalculator() { - return ((AndroidCalculator) Locator.getInstance().getCalculator()); - } - @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java index 807a0503..54d22b4c 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java @@ -36,12 +36,14 @@ import jscl.math.Generic; import jscl.math.function.Constant; import org.solovyev.android.Activities; import org.solovyev.android.calculator.about.CalculatorAboutActivity; +import org.solovyev.android.calculator.errors.FixableError; +import org.solovyev.android.calculator.errors.FixableErrorsActivity; import org.solovyev.android.calculator.functions.CppFunction; import org.solovyev.android.calculator.functions.EditFunctionFragment; import org.solovyev.android.calculator.functions.FunctionsActivity; import org.solovyev.android.calculator.history.CalculatorHistoryActivity; -import org.solovyev.android.calculator.operators.OperatorsActivity; import org.solovyev.android.calculator.matrix.CalculatorMatrixActivity; +import org.solovyev.android.calculator.operators.OperatorsActivity; import org.solovyev.android.calculator.plot.CalculatorPlotActivity; import org.solovyev.android.calculator.plot.CalculatorPlotter; import org.solovyev.android.calculator.preferences.PreferencesActivity; @@ -55,6 +57,7 @@ import org.solovyev.common.text.Strings; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -169,7 +172,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener builder.withParameter(constant.getName()); } } - EditFunctionFragment.showDialog(builder.build(), context); + EditFunctionFragment.show(builder.build(), context); } else { getNotifier().showMessage(R.string.empty_function_error, MessageType.error); } @@ -217,14 +220,6 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener context.startActivity(intent); } - public static void showCalculationMessagesDialog(@Nonnull Context context, @Nonnull List messages) { - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - - if (Preferences.Calculations.showCalculationMessagesDialog.getPreference(prefs)) { - FixableMessagesDialog.showDialogForMessages(messages, context, true); - } - } - public static void showEvaluationError(@Nonnull Context context, @Nonnull final String errorMessage) { final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java index 669193c0..b6b3e201 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java @@ -94,6 +94,9 @@ public class CalculatorApplication extends android.app.Application implements Sh @Inject ErrorReporter errorReporter; + @Inject + PreferredPreferences preferredPreferences; + @Override public void onCreate() { final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); @@ -123,7 +126,7 @@ public class CalculatorApplication extends android.app.Application implements Sh engine, new AndroidCalculatorNotifier(this), errorReporter, - new AndroidCalculatorPreferenceService(this), + preferredPreferences, keyboard, new AndroidCalculatorPlotter(this, new CalculatorPlotterImpl(calculator)) ); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java index 70732357..8e52db33 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java @@ -55,7 +55,7 @@ public final class CalculatorButtons { public static void fixButtonsTextSize(@Nonnull Preferences.Gui.Theme theme, @Nonnull Preferences.Gui.Layout layout, @Nonnull View root) { - if (!layout.isOptimized()) { + if (!layout.optimized) { final ScreenMetrics metrics = App.getScreenMetrics(); final boolean portrait = metrics.isInPortraitMode(); @@ -85,7 +85,7 @@ public final class CalculatorButtons { @Nonnull Activity activity) { preferences = preferences == null ? PreferenceManager.getDefaultSharedPreferences(activity) : preferences; - final boolean large = App.isLargeScreen() && Preferences.Gui.getLayout(preferences).isOptimized(); + final boolean large = App.isLargeScreen() && Preferences.Gui.getLayout(preferences).optimized; if (!large) { if (Views.getScreenOrientation(activity) == Configuration.ORIENTATION_PORTRAIT diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java index d9d08612..6a39ae8c 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java @@ -50,7 +50,7 @@ public class CalculatorDisplayFragment extends Fragment { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.getActivity()); final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(prefs); - if (!layout.isOptimized()) { + if (!layout.optimized) { fragmentUi = new FragmentUi(R.layout.cpp_app_display_mobile, R.string.result); } else { fragmentUi = new FragmentUi(R.layout.cpp_app_display, R.string.result); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java index 10f907e4..dcea4e87 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java @@ -80,7 +80,7 @@ public class CalculatorEditorFragment extends Fragment { ((CalculatorApplication) getActivity().getApplication()).getComponent().inject(this); final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(preferences); - if (!layout.isOptimized()) { + if (!layout.optimized) { fragmentUi = new FragmentUi(R.layout.cpp_app_editor_mobile, R.string.editor); } else { fragmentUi = new FragmentUi(R.layout.cpp_app_editor, R.string.editor); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java index db30c858..530aa1d3 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java @@ -78,7 +78,6 @@ public class CalculatorImpl implements Calculator { private volatile long lastPreferenceCheck = 0L; - public CalculatorImpl(@Nonnull Bus bus, @Nonnull Executor eventExecutor) { this.eventExecutor = eventExecutor; bus.register(this); @@ -287,7 +286,7 @@ public class CalculatorImpl implements Calculator { if (currentTime - lastPreferenceCheck > PREFERENCE_CHECK_INTERVAL) { lastPreferenceCheck = currentTime; - Locator.getInstance().getPreferenceService().checkPreferredPreferences(false); + Locator.getInstance().getPreferenceService().check(false); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardFragment.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardFragment.java index 3fd5bf63..f488f33d 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardFragment.java @@ -54,7 +54,7 @@ public class CalculatorKeyboardFragment extends Fragment implements SharedPrefer final SharedPreferences preferences = App.getPreferences(); final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(preferences); - if (!layout.isOptimized()) { + if (!layout.optimized) { ui = new FragmentUi(R.layout.cpp_app_keyboard_mobile); } else { ui = new FragmentUi(R.layout.cpp_app_keyboard); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java index 9694d8b9..aa00afac 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java @@ -32,7 +32,7 @@ public interface CalculatorLocator { @Nonnull Engine engine, @Nonnull CalculatorNotifier notifier, @Nonnull ErrorReporter errorReporter, - @Nonnull CalculatorPreferenceService preferenceService, + @Nonnull PreferredPreferences preferenceService, @Nonnull Keyboard keyboard, @Nonnull CalculatorPlotter plotter); @@ -55,5 +55,5 @@ public interface CalculatorLocator { CalculatorPlotter getPlotter(); @Nonnull - CalculatorPreferenceService getPreferenceService(); + PreferredPreferences getPreferenceService(); } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorMessages.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorMessages.java index b5169a46..a811979e 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorMessages.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorMessages.java @@ -84,7 +84,7 @@ public final class CalculatorMessages { } @Nonnull - static MessageType toMessageType(int messageLevel) { + public static MessageType toMessageType(int messageLevel) { if (messageLevel < info.getMessageLevel()) { return info; } else if (messageLevel < warning.getMessageLevel()) { diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorPreferenceService.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorPreferenceService.java deleted file mode 100644 index 996390e6..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorPreferenceService.java +++ /dev/null @@ -1,46 +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; - -import javax.annotation.Nonnull; - -import jscl.AngleUnit; -import jscl.NumeralBase; - -/** - * User: serso - * Date: 11/17/12 - * Time: 7:45 PM - */ -public interface CalculatorPreferenceService { - - void setPreferredAngleUnits(); - - void setAngleUnits(@Nonnull AngleUnit angleUnit); - - void setPreferredNumeralBase(); - - void setNumeralBase(@Nonnull NumeralBase numeralBase); - - void checkPreferredPreferences(boolean force); -} diff --git a/app/src/main/java/org/solovyev/android/calculator/DisplayView.java b/app/src/main/java/org/solovyev/android/calculator/DisplayView.java index 27bf758b..3377bdbb 100644 --- a/app/src/main/java/org/solovyev/android/calculator/DisplayView.java +++ b/app/src/main/java/org/solovyev/android/calculator/DisplayView.java @@ -67,7 +67,7 @@ public class DisplayView extends AutoResizeTextView { return; } final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(App.getPreferences()); - if (!layout.isOptimized()) { + if (!layout.optimized) { setTextSize(TypedValue.COMPLEX_UNIT_SP, getResources().getDimension(R.dimen.cpp_display_text_size_mobile)); } setOnClickListener(new CalculatorDisplayOnClickListener((FragmentActivity) context)); diff --git a/app/src/main/java/org/solovyev/android/calculator/FixableError.java b/app/src/main/java/org/solovyev/android/calculator/FixableError.java deleted file mode 100644 index a73ce899..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/FixableError.java +++ /dev/null @@ -1,40 +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; - -import java.io.Serializable; - -import javax.annotation.Nullable; - -/** - * User: serso - * Date: 12/2/12 - * Time: 10:21 PM - */ -public interface FixableError extends Serializable { - - @Nullable - CharSequence getFixCaption(); - - void fix(); -} diff --git a/app/src/main/java/org/solovyev/android/calculator/FixableMessage.java b/app/src/main/java/org/solovyev/android/calculator/FixableMessage.java deleted file mode 100644 index 83a2a4bc..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/FixableMessage.java +++ /dev/null @@ -1,109 +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; - -import android.os.Parcel; -import android.os.Parcelable; - -import org.solovyev.common.msg.Message; -import org.solovyev.common.msg.MessageType; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -/** - * User: serso - * Date: 11/17/12 - * Time: 6:54 PM - */ -public class FixableMessage implements Parcelable { - - public static final Creator CREATOR = new Creator() { - @Override - public FixableMessage createFromParcel(@Nonnull Parcel in) { - return FixableMessage.fromParcel(in); - } - - @Override - public FixableMessage[] newArray(int size) { - return new FixableMessage[size]; - } - }; - @Nonnull - private final String message; - @Nonnull - private final MessageType messageType; - @Nullable - private final FixableError fixableError; - - public FixableMessage(@Nonnull Message message) { - this.message = message.getLocalizedMessage(); - final int messageLevel = message.getMessageLevel().getMessageLevel(); - this.messageType = CalculatorMessages.toMessageType(messageLevel); - this.fixableError = CalculatorFixableError.getErrorByMessageCode(message.getMessageCode()); - } - - public FixableMessage(@Nonnull String message, - @Nonnull MessageType messageType, - @Nullable FixableError fixableError) { - this.message = message; - this.messageType = messageType; - this.fixableError = fixableError; - } - - @Nonnull - private static FixableMessage fromParcel(@Nonnull Parcel in) { - final String message = in.readString(); - final MessageType messageType = (MessageType) in.readSerializable(); - final FixableError fixableError = (FixableError) in.readSerializable(); - - return new FixableMessage(message, messageType, fixableError); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@Nonnull Parcel out, int flags) { - out.writeString(message); - out.writeSerializable(messageType); - out.writeSerializable(fixableError); - } - - @Nonnull - public String getMessage() { - return message; - } - - @Nonnull - public MessageType getMessageType() { - return messageType; - } - - @Nullable - public FixableError getFixableError() { - return fixableError; - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/FixableMessagesDialog.java b/app/src/main/java/org/solovyev/android/calculator/FixableMessagesDialog.java deleted file mode 100644 index c41668f5..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/FixableMessagesDialog.java +++ /dev/null @@ -1,275 +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; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.preference.PreferenceManager; -import android.support.v7.app.ActionBarActivity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.TextView; - -import org.solovyev.common.msg.Message; -import org.solovyev.common.text.Strings; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.annotation.Nonnull; - -/** - * User: serso - * Date: 11/17/12 - * Time: 3:37 PM - */ -public class FixableMessagesDialog extends ActionBarActivity { - - private static final String INPUT = "input"; - - @Nonnull - private Input input = new Input(Collections.emptyList(), false); - - public FixableMessagesDialog() { - } - - public static void showDialogForMessages(@Nonnull List messages, - @Nonnull Context context, - boolean showCheckbox) { - if (!messages.isEmpty()) { - final Intent intent = new Intent(context, FixableMessagesDialog.class); - - intent.putExtra(INPUT, Input.fromMessages(messages, showCheckbox)); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - - context.startActivity(intent); - } - } - - public static void showDialog(@Nonnull List messages, - @Nonnull Context context, - boolean showCheckbox) { - if (!messages.isEmpty()) { - final Intent intent = new Intent(context, FixableMessagesDialog.class); - - intent.putExtra(INPUT, new Input(messages, showCheckbox)); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - - context.startActivity(intent); - } - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.cpp_fixable_messages_dialog); - - final Intent intent = getIntent(); - if (intent != null) { - parseIntent(intent); - } - - final CheckBox doNotShowCalculationMessagesCheckbox = (CheckBox) findViewById(R.id.cpp_do_not_show_fixable_messages_checkbox); - if (input.isShowCheckbox()) { - doNotShowCalculationMessagesCheckbox.setVisibility(View.VISIBLE); - } else { - doNotShowCalculationMessagesCheckbox.setVisibility(View.GONE); - } - - final Button closeButton = (Button) findViewById(R.id.close_button); - closeButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (doNotShowCalculationMessagesCheckbox.isChecked()) { - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(FixableMessagesDialog.this); - Preferences.Calculations.showCalculationMessagesDialog.putPreference(prefs, false); - } - - FixableMessagesDialog.this.finish(); - } - }); - } - - private void parseIntent(@Nonnull Intent intent) { - final Input input = intent.getParcelableExtra(INPUT); - if (input != null) { - this.input = input; - onInputChanged(); - } - } - - /* - ********************************************************************** - * - * STATIC - * - ********************************************************************** - */ - - private void onInputChanged() { - final ViewGroup viewGroup = (ViewGroup) findViewById(R.id.cpp_fixable_messages_container); - viewGroup.removeAllViews(); - - final LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - final List messages = input.getMessages(); - for (final FixableMessage message : messages) { - final View view = layoutInflater.inflate(R.layout.cpp_fixable_messages_dialog_message, null); - - final TextView calculationMessagesTextView = (TextView) view.findViewById(R.id.cpp_fixable_messages_text_view); - calculationMessagesTextView.setText(message.getMessage()); - - final Button fixButton = (Button) view.findViewById(R.id.cpp_fix_button); - final FixableError fixableError = message.getFixableError(); - if (fixableError == null) { - fixButton.setVisibility(View.GONE); - fixButton.setOnClickListener(null); - } else { - fixButton.setVisibility(View.VISIBLE); - fixButton.setOnClickListener(new FixErrorOnClickListener(messages, message)); - - final CharSequence fixCaption = fixableError.getFixCaption(); - if (!Strings.isEmpty(fixCaption)) { - fixButton.setText(fixCaption); - } - } - - - viewGroup.addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); - } - - } - - @Override - protected void onNewIntent(@Nonnull Intent intent) { - super.onNewIntent(intent); - parseIntent(intent); - } - - private static final class Input implements Parcelable { - - public static final Creator CREATOR = new Creator() { - @Override - public Input createFromParcel(@Nonnull Parcel in) { - return Input.fromParcel(in); - } - - @Override - public Input[] newArray(int size) { - return new Input[size]; - } - }; - @Nonnull - private List messages = new ArrayList(); - private boolean showCheckbox; - - private Input(@Nonnull List messages, boolean showCheckbox) { - this.messages = messages; - this.showCheckbox = showCheckbox; - } - - @Nonnull - private static Input fromParcel(@Nonnull Parcel in) { - final List messages = new ArrayList(); - boolean showCheckbox = in.readInt() == 1; - in.readTypedList(messages, FixableMessage.CREATOR); - return new Input(messages, showCheckbox); - } - - @Nonnull - public static Input fromMessages(@Nonnull List messages, boolean showCheckbox) { - final List stringMessages = new ArrayList(messages.size()); - for (Message message : messages) { - stringMessages.add(new FixableMessage(message)); - } - - return new Input(stringMessages, showCheckbox); - } - - @Nonnull - public List getMessages() { - return messages; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@Nonnull Parcel out, int flags) { - out.writeInt(showCheckbox ? 1 : 0); - out.writeTypedList(messages); - } - - public boolean isShowCheckbox() { - return showCheckbox; - } - } - - private class FixErrorOnClickListener implements View.OnClickListener { - - @Nonnull - private final List messages; - - @Nonnull - private final FixableMessage currentMessage; - - public FixErrorOnClickListener(@Nonnull List messages, - @Nonnull FixableMessage message) { - this.messages = messages; - this.currentMessage = message; - } - - @Override - public void onClick(View v) { - final List filteredMessages = new ArrayList(messages.size() - 1); - for (FixableMessage message : messages) { - if (message.getFixableError() == null) { - filteredMessages.add(message); - } else if (message.getFixableError() != currentMessage.getFixableError()) { - filteredMessages.add(message); - } - } - - currentMessage.getFixableError().fix(); - - if (!filteredMessages.isEmpty()) { - FixableMessagesDialog.this.input = new Input(filteredMessages, FixableMessagesDialog.this.input.showCheckbox); - onInputChanged(); - } else { - FixableMessagesDialog.this.finish(); - } - } - } -} - diff --git a/app/src/main/java/org/solovyev/android/calculator/Locator.java b/app/src/main/java/org/solovyev/android/calculator/Locator.java index dd9753c4..042b1062 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Locator.java +++ b/app/src/main/java/org/solovyev/android/calculator/Locator.java @@ -41,7 +41,7 @@ public class Locator implements CalculatorLocator { @Nonnull private ErrorReporter errorReporter = new SystemErrorReporter(); @Nonnull - private CalculatorPreferenceService calculatorPreferenceService; + private PreferredPreferences preferredPreferences; @Nonnull private CalculatorPlotter calculatorPlotter; @@ -59,7 +59,7 @@ public class Locator implements CalculatorLocator { @Nonnull Engine engine, @Nonnull CalculatorNotifier notifier, @Nonnull ErrorReporter errorReporter, - @Nonnull CalculatorPreferenceService preferenceService, + @Nonnull PreferredPreferences preferenceService, @Nonnull Keyboard keyboard, @Nonnull CalculatorPlotter plotter) { @@ -67,7 +67,7 @@ public class Locator implements CalculatorLocator { this.engine = engine; this.calculatorNotifier = notifier; this.errorReporter = errorReporter; - this.calculatorPreferenceService = preferenceService; + this.preferredPreferences = preferenceService; this.calculatorPlotter = plotter; this.keyboard = keyboard; @@ -115,7 +115,7 @@ public class Locator implements CalculatorLocator { @Nonnull @Override - public CalculatorPreferenceService getPreferenceService() { - return this.calculatorPreferenceService; + public PreferredPreferences getPreferenceService() { + return this.preferredPreferences; } } 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 91b458b1..bec5d51a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Preferences.java +++ b/app/src/main/java/org/solovyev/android/calculator/Preferences.java @@ -60,6 +60,9 @@ public final class Preferences { } static void setDefaultValues(@Nonnull SharedPreferences preferences) { + // renew value after each application start + Gui.showFixableErrorDialog.putDefault(preferences); + Gui.lastPreferredPreferencesCheck.putDefault(preferences); if (!Engine.Preferences.groupingSeparator.isSet(preferences)) { final Locale locale = Locale.getDefault(); @@ -116,10 +119,6 @@ public final class Preferences { applyDefaultPreference(preferences, Onscreen.theme); applyDefaultPreference(preferences, Widget.theme); - - // renew value after each application start - Calculations.showCalculationMessagesDialog.putDefault(preferences); - Calculations.lastPreferredPreferencesCheck.putDefault(preferences); } private static void applyDefaultPreference(@Nonnull SharedPreferences preferences, @Nonnull Preference preference) { @@ -236,11 +235,9 @@ public final class Preferences { public static class Calculations { public static final Preference calculateOnFly = BooleanPreference.of("calculations_calculate_on_fly", true); - public static final Preference showCalculationMessagesDialog = BooleanPreference.of("show_calculation_messages_dialog", true); public static final Preference preferredNumeralBase = StringPreference.ofEnum("preferred_numeral_base", Engine.Preferences.numeralBase.getDefaultValue(), NumeralBase.class); public static final Preference preferredAngleUnits = StringPreference.ofEnum("preferred_angle_units", Engine.Preferences.angleUnit.getDefaultValue(), AngleUnit.class); - public static final Preference lastPreferredPreferencesCheck = LongPreference.of("preferred_preferences_check_time", 0L); } @@ -258,6 +255,8 @@ public final class Preferences { public static final Preference preventScreenFromFading = BooleanPreference.of("preventScreenFromFading", true); public static final Preference colorDisplay = BooleanPreference.of("org.solovyev.android.calculator.CalculatorModel_color_display", true); public static final Preference hapticFeedback = NumberToStringPreference.of("hapticFeedback", 60L, Long.class); + public static final Preference showFixableErrorDialog = BooleanPreference.of("gui.showFixableErrorDialog", true); + public static final Preference lastPreferredPreferencesCheck = LongPreference.of("gui.lastPreferredPreferencesCheck", 0L); @Nonnull public static Theme getTheme(@Nonnull SharedPreferences preferences) { @@ -332,37 +331,23 @@ public final class Preferences { } public enum Layout { - main_calculator(R.layout.main_calculator, R.string.p_layout_calculator, true), - main_calculator_mobile(R.layout.main_calculator_mobile, R.string.p_layout_calculator_mobile, false), + main_calculator(R.layout.main_calculator, true), + main_calculator_mobile(R.layout.main_calculator_mobile, false), // not used anymore @Deprecated - main_cellphone(R.layout.main_calculator, 0, true), + main_cellphone(R.layout.main_calculator, true), - simple(R.layout.main_calculator, R.string.p_layout_simple, true), - simple_mobile(R.layout.main_calculator_mobile, R.string.p_layout_simple_mobile, false); + simple(R.layout.main_calculator, true), + simple_mobile(R.layout.main_calculator_mobile, false); - private final int layoutId; - private final int nameResId; - private final boolean optimized; + public final int layoutId; + public final boolean optimized; - Layout(int layoutId, int nameResId, boolean optimized) { + Layout(int layoutId, boolean optimized) { this.layoutId = layoutId; - this.nameResId = nameResId; this.optimized = optimized; } - - public int getLayoutId() { - return layoutId; - } - - public int getNameResId() { - return nameResId; - } - - public boolean isOptimized() { - return optimized; - } } public static final class TextColor { diff --git a/app/src/main/java/org/solovyev/android/calculator/PreferredPreferences.java b/app/src/main/java/org/solovyev/android/calculator/PreferredPreferences.java new file mode 100644 index 00000000..8cfa27f3 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/PreferredPreferences.java @@ -0,0 +1,117 @@ +/* + * 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; + +import android.app.Application; +import android.content.Context; +import android.content.SharedPreferences; +import jscl.AngleUnit; +import jscl.NumeralBase; +import org.solovyev.android.calculator.errors.FixableError; +import org.solovyev.android.calculator.errors.FixableErrorType; +import org.solovyev.android.calculator.errors.FixableErrorsActivity; +import org.solovyev.android.msg.AndroidMessage; +import org.solovyev.common.msg.MessageType; + +import javax.annotation.Nonnull; +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.ArrayList; + +import static org.solovyev.android.calculator.Preferences.Gui.lastPreferredPreferencesCheck; + +@Singleton +public class PreferredPreferences { + + // one hour + private static final Long PREFERRED_PREFS_INTERVAL_TIME = 1000L * 60L * 60L; + + @Inject + Application application; + @Inject + SharedPreferences preferences; + + @Inject + public PreferredPreferences() { + } + + public void check(boolean force) { + check(application, force); + } + + public void check(@Nonnull Context context, boolean force) { + final long now = System.currentTimeMillis(); + + if (!force) { + if (!Preferences.Gui.showFixableErrorDialog.getPreference(preferences)) { + // user has disabled calculation message dialogs until the next session + return; + } + if (!shouldCheck(now)) { + return; + } + } + + final NumeralBase preferredNumeralBase = Preferences.Calculations.preferredNumeralBase.getPreference(preferences); + final NumeralBase numeralBase = Engine.Preferences.numeralBase.getPreference(preferences); + + final AngleUnit preferredAngleUnits = Preferences.Calculations.preferredAngleUnits.getPreference(preferences); + final AngleUnit angleUnits = Engine.Preferences.angleUnit.getPreference(preferences); + + final ArrayList messages = new ArrayList<>(2); + if (numeralBase != preferredNumeralBase) { + messages.add(new FixableError(application.getString(R.string.preferred_numeral_base_message, preferredNumeralBase.name(), numeralBase.name()), MessageType.warning, FixableErrorType.preferred_numeral_base)); + } + + if (angleUnits != preferredAngleUnits) { + messages.add(new FixableError(application.getString(R.string.preferred_angle_units_message, preferredAngleUnits.name(), angleUnits.name()), MessageType.warning, FixableErrorType.preferred_angle_units)); + } + + FixableErrorsActivity.show(context, messages); + + lastPreferredPreferencesCheck.putPreference(preferences, now); + } + + private boolean shouldCheck(long now) { + final long lastCheckTime = lastPreferredPreferencesCheck.getPreference(preferences); + return now - lastCheckTime > PREFERRED_PREFS_INTERVAL_TIME; + } + + public void setPreferredAngleUnits() { + setAngleUnits(Preferences.Calculations.preferredAngleUnits.getPreference(preferences)); + } + + public void setAngleUnits(@Nonnull AngleUnit angleUnit) { + Engine.Preferences.angleUnit.putPreference(preferences, angleUnit); + Locator.getInstance().getNotifier().showMessage(new AndroidMessage(R.string.c_angle_units_changed_to, MessageType.info, application, angleUnit.name())); + } + + public void setPreferredNumeralBase() { + setNumeralBase(Preferences.Calculations.preferredNumeralBase.getPreference(preferences)); + } + + public void setNumeralBase(@Nonnull NumeralBase numeralBase) { + Engine.Preferences.numeralBase.putPreference(preferences, numeralBase); + Locator.getInstance().getNotifier().showMessage(new AndroidMessage(R.string.c_numeral_base_changed_to, MessageType.info, application, numeralBase.name())); + } +} diff --git a/app/src/main/java/org/solovyev/android/calculator/errors/FixableError.java b/app/src/main/java/org/solovyev/android/calculator/errors/FixableError.java new file mode 100644 index 00000000..9e62097f --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/errors/FixableError.java @@ -0,0 +1,87 @@ +/* + * 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.errors; + +import android.os.Parcel; +import android.os.Parcelable; +import org.solovyev.android.calculator.CalculatorMessages; +import org.solovyev.common.msg.Message; +import org.solovyev.common.msg.MessageType; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class FixableError implements Parcelable { + + public static final Creator CREATOR = new Creator() { + @Override + public FixableError createFromParcel(@Nonnull Parcel in) { + return new FixableError(in); + } + + @Override + public FixableError[] newArray(int size) { + return new FixableError[size]; + } + }; + @Nonnull + public final String message; + @Nonnull + public final MessageType messageType; + @Nullable + public final FixableErrorType error; + + private FixableError(@Nonnull Parcel in) { + message = in.readString(); + messageType = MessageType.values()[in.readInt()]; + final int errorOrdinal = in.readInt(); + error = errorOrdinal == -1 ? null : FixableErrorType.values()[errorOrdinal]; + } + + public FixableError(@Nonnull Message message) { + this.message = message.getLocalizedMessage(); + final int messageLevel = message.getMessageLevel().getMessageLevel(); + this.messageType = CalculatorMessages.toMessageType(messageLevel); + this.error = FixableErrorType.getErrorByCode(message.getMessageCode()); + } + + public FixableError(@Nonnull String message, + @Nonnull MessageType messageType, + @Nullable FixableErrorType error) { + this.message = message; + this.messageType = messageType; + this.error = error; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@Nonnull Parcel out, int flags) { + out.writeString(message); + out.writeInt(messageType.ordinal()); + out.writeInt(error == null ? -1 : error.ordinal()); + } +} diff --git a/app/src/main/java/org/solovyev/android/calculator/errors/FixableErrorFragment.java b/app/src/main/java/org/solovyev/android/calculator/errors/FixableErrorFragment.java new file mode 100644 index 00000000..46edbde4 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/errors/FixableErrorFragment.java @@ -0,0 +1,98 @@ +package org.solovyev.android.calculator.errors; + +import android.app.Activity; +import android.content.Context; +import android.content.DialogInterface; +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 org.solovyev.android.Check; +import org.solovyev.android.calculator.*; + +import javax.annotation.Nonnull; +import javax.inject.Inject; + +public class FixableErrorFragment extends BaseDialogFragment { + + static final String FRAGMENT_TAG = "fixable-error"; + @Nonnull + private static final String ARG_ERROR = "error"; + @Inject + PreferredPreferences preferredPreferences; + private FixableError error; + @Nullable + private FixableErrorsActivity activity; + + @Nonnull + private static FixableErrorFragment create(@Nonnull FixableError error) { + final FixableErrorFragment fragment = new FixableErrorFragment(); + final Bundle args = new Bundle(1); + args.putParcelable(ARG_ERROR, error); + fragment.setArguments(args); + return fragment; + } + + public static void show(@Nonnull FixableError error, @Nonnull FragmentManager fm) { + App.showDialog(create(error), FRAGMENT_TAG, fm); + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + this.activity = (FixableErrorsActivity) activity; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + error = getArguments().getParcelable(ARG_ERROR); + Check.isNotNull(error); + } + + @Override + protected void inject(@NonNull AppComponent component) { + super.inject(component); + component.inject(this); + } + + @Override + protected void onPrepareDialog(@NonNull AlertDialog.Builder builder) { + builder.setMessage(error.message); + builder.setNeutralButton(R.string.cpp_dont_show_again, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Preferences.Gui.showFixableErrorDialog.putPreference(preferences, false); + dismiss(); + } + }); + builder.setNegativeButton(R.string.close, null); + if (error.error != null) { + builder.setPositiveButton(R.string.fix, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + error.error.fix(preferredPreferences); + dismiss(); + } + }); + } + } + + @Override + public void onDismiss(DialogInterface dialog) { + super.onDismiss(dialog); + if (activity != null) { + activity.onDialogClosed(); + activity = null; + } + } + + @Nullable + @Override + protected View onCreateDialogView(@NonNull Context context, @NonNull LayoutInflater inflater, @Nullable Bundle savedInstanceState) { + return null; + } +} diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorFixableError.java b/app/src/main/java/org/solovyev/android/calculator/errors/FixableErrorType.java similarity index 61% rename from app/src/main/java/org/solovyev/android/calculator/CalculatorFixableError.java rename to app/src/main/java/org/solovyev/android/calculator/errors/FixableErrorType.java index 89dfd8ee..2396c12e 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorFixableError.java +++ b/app/src/main/java/org/solovyev/android/calculator/errors/FixableErrorType.java @@ -20,65 +20,56 @@ * Site: http://se.solovyev.org */ -package org.solovyev.android.calculator; +package org.solovyev.android.calculator.errors; import jscl.AngleUnit; import jscl.text.msg.Messages; +import org.solovyev.android.calculator.PreferredPreferences; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Arrays; import java.util.List; -/** - * User: serso - * Date: 11/17/12 - * Time: 7:30 PM - */ -public enum CalculatorFixableError implements FixableError { +public enum FixableErrorType { must_be_rad(Messages.msg_23, Messages.msg_24, Messages.msg_25) { @Override - public void fix() { - Locator.getInstance().getPreferenceService().setAngleUnits(AngleUnit.rad); + public void fix(@Nonnull PreferredPreferences preferences) { + preferences.setAngleUnits(AngleUnit.rad); } }, preferred_numeral_base() { @Override - public void fix() { - Locator.getInstance().getPreferenceService().setPreferredNumeralBase(); + public void fix(@Nonnull PreferredPreferences preferences) { + preferences.setPreferredNumeralBase(); } }, preferred_angle_units() { @Override - public void fix() { - Locator.getInstance().getPreferenceService().setPreferredAngleUnits(); + public void fix(@Nonnull PreferredPreferences preferences) { + preferences.setPreferredAngleUnits(); } }; @Nonnull private final List messageCodes; - CalculatorFixableError(@Nullable String... messageCodes) { + FixableErrorType(@Nullable String... messageCodes) { this.messageCodes = messageCodes == null || messageCodes.length == 0 ? java.util.Collections.emptyList() : Arrays.asList(messageCodes); } @Nullable - public static CalculatorFixableError getErrorByMessageCode(@Nonnull String messageCode) { - for (CalculatorFixableError fixableError : values()) { - if (fixableError.messageCodes.contains(messageCode)) { - return fixableError; + public static FixableErrorType getErrorByCode(@Nonnull String code) { + for (FixableErrorType type : values()) { + if (type.messageCodes.contains(code)) { + return type; } } return null; } - - @Nullable - @Override - public CharSequence getFixCaption() { - return null; - } + public abstract void fix(@Nonnull PreferredPreferences preferences); } diff --git a/app/src/main/java/org/solovyev/android/calculator/errors/FixableErrorsActivity.java b/app/src/main/java/org/solovyev/android/calculator/errors/FixableErrorsActivity.java new file mode 100644 index 00000000..0a3c5a81 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/errors/FixableErrorsActivity.java @@ -0,0 +1,118 @@ +/* + * 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.errors; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.Fragment; +import android.support.v7.app.AppCompatActivity; +import org.solovyev.android.Activities; +import org.solovyev.android.calculator.CalculatorApplication; +import org.solovyev.android.calculator.Preferences; +import org.solovyev.common.msg.Message; + +import javax.annotation.Nonnull; +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; + +public class FixableErrorsActivity extends AppCompatActivity { + + public static final String EXTRA_ERRORS = "errors"; + public static final String STATE_ERRORS = "errors"; + @Inject + SharedPreferences preferences; + private ArrayList errors; + + public static void show(@Nonnull Context context, @Nonnull List messages) { + final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + + if (Preferences.Gui.showFixableErrorDialog.getPreference(preferences)) { + final ArrayList errors = new ArrayList<>(); + for (Message message : messages) { + errors.add(new FixableError(message)); + } + show(context, errors); + } + } + + public static void show(@Nonnull Context context, @Nonnull ArrayList errors) { + final Intent intent = new Intent(context, FixableErrorsActivity.class); + intent.putExtra(EXTRA_ERRORS, errors); + Activities.addIntentFlags(intent, false, context); + context.startActivity(intent); + } + + @Override + protected void onCreate(Bundle state) { + super.onCreate(state); + + if (state != null) { + errors = state.getParcelableArrayList(STATE_ERRORS); + } else { + final Intent intent = getIntent(); + errors = intent.getParcelableArrayListExtra(EXTRA_ERRORS); + } + + if (errors == null) { + finish(); + return; + } + ((CalculatorApplication) getApplication()).getComponent().inject(this); + if (state == null) { + showNextError(); + } + } + + @Override + protected void onSaveInstanceState(@Nonnull Bundle out) { + super.onSaveInstanceState(out); + out.putParcelableArrayList(STATE_ERRORS, errors); + } + + public void showNextError() { + if (errors.isEmpty()) { + finish(); + return; + } + if (!Preferences.Gui.showFixableErrorDialog.getPreference(preferences)) { + finish(); + return; + } + final FixableError fixableError = errors.remove(0); + FixableErrorFragment.show(fixableError, getSupportFragmentManager()); + } + + public void onDialogClosed() { + final Fragment fragment = getSupportFragmentManager().findFragmentByTag(FixableErrorFragment.FRAGMENT_TAG); + if (fragment == null) { + // activity is closing + return; + } + showNextError(); + } +} + diff --git a/app/src/main/java/org/solovyev/android/calculator/functions/EditFunctionFragment.java b/app/src/main/java/org/solovyev/android/calculator/functions/EditFunctionFragment.java index f081e2ee..1eb841ea 100644 --- a/app/src/main/java/org/solovyev/android/calculator/functions/EditFunctionFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/functions/EditFunctionFragment.java @@ -100,23 +100,23 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC return fragment; } - public static void showDialog(@Nonnull FragmentActivity activity) { - EditFunctionFragment.showDialog(null, activity.getSupportFragmentManager()); + public static void show(@Nonnull FragmentActivity activity) { + EditFunctionFragment.show(null, activity.getSupportFragmentManager()); } - public static void showDialog(@Nullable CppFunction function, @Nonnull Context context) { + public static void show(@Nullable CppFunction function, @Nonnull Context context) { if (!(context instanceof FunctionsActivity)) { final Intent intent = new Intent(context, FunctionsActivity.class); Activities.addIntentFlags(intent, false, context); intent.putExtra(FunctionsActivity.EXTRA_FUNCTION, function); context.startActivity(intent); } else { - EditFunctionFragment.showDialog(function, ((FunctionsActivity) context).getSupportFragmentManager()); + EditFunctionFragment.show(function, ((FunctionsActivity) context).getSupportFragmentManager()); } } - public static void showDialog(@Nullable CppFunction input, @Nonnull FragmentManager fm) { - App.showDialog(create(input), "function-editor", fm); + public static void show(@Nullable CppFunction function, @Nonnull FragmentManager fm) { + App.showDialog(create(function), "function-editor", fm); } @Override diff --git a/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsActivity.java b/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsActivity.java index 9e6bfe02..e7bf0f66 100644 --- a/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsActivity.java @@ -60,7 +60,7 @@ public class FunctionsActivity extends BaseActivity { final Bundle extras = getIntent().getExtras(); final CppFunction function = extras != null ? (CppFunction) extras.getParcelable(EXTRA_FUNCTION) : null; if (function != null) { - EditFunctionFragment.showDialog(function, this); + EditFunctionFragment.show(function, this); } } } diff --git a/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsFragment.java b/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsFragment.java index 90691338..0d49c3d0 100644 --- a/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsFragment.java @@ -71,7 +71,7 @@ public class FunctionsFragment extends BaseEntitiesFragment { fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - EditFunctionFragment.showDialog(getActivity()); + EditFunctionFragment.show(getActivity()); } }); return view; @@ -95,7 +95,7 @@ public class FunctionsFragment extends BaseEntitiesFragment { return true; case R.string.c_edit: if (function instanceof IFunction) { - EditFunctionFragment.showDialog(CppFunction.builder((IFunction) function).build(), activity.getSupportFragmentManager()); + EditFunctionFragment.show(CppFunction.builder((IFunction) function).build(), activity.getSupportFragmentManager()); } return true; case R.string.c_remove: diff --git a/app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorLayout.java b/app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorLayout.java index ef4d026d..fe426d9c 100644 --- a/app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorLayout.java +++ b/app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorLayout.java @@ -66,7 +66,7 @@ enum CalculatorLayout { @Nonnull static CalculatorLayout fromGuiLayout(@Nonnull Preferences.Gui.Layout layout) { - if (layout.isOptimized()) { + if (layout.optimized) { return optimized; } else { return big_buttons; diff --git a/app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorMode.java b/app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorMode.java index 6f1db027..598a30f9 100644 --- a/app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorMode.java +++ b/app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorMode.java @@ -46,7 +46,7 @@ enum CalculatorMode { @Override protected void apply(@Nonnull SharedPreferences preferences) { final Preferences.Gui.Layout layout = Preferences.Gui.layout.getPreference(preferences); - if (layout.isOptimized()) { + if (layout.optimized) { Preferences.Gui.layout.putPreference(preferences, Preferences.Gui.Layout.simple); } else { Preferences.Gui.layout.putPreference(preferences, Preferences.Gui.Layout.simple_mobile); @@ -62,7 +62,7 @@ enum CalculatorMode { @Override protected void apply(@Nonnull SharedPreferences preferences) { final Preferences.Gui.Layout layout = Preferences.Gui.layout.getPreference(preferences); - if (layout.isOptimized()) { + if (layout.optimized) { Preferences.Gui.layout.putPreference(preferences, main_calculator); } else { Preferences.Gui.layout.putPreference(preferences, main_calculator_mobile); diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 5c608e2e..dfb6fc90 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -175,7 +175,7 @@ + 16sp diff --git a/app/src/main/res/values/text_strings.xml b/app/src/main/res/values/text_strings.xml index e9eb41ff..969f4ed9 100644 --- a/app/src/main/res/values/text_strings.xml +++ b/app/src/main/res/values/text_strings.xml @@ -235,5 +235,6 @@ Clear New in %1$s version Do you want to try new Material themes? Choose them from the list: + Don\'t show again System language diff --git a/app/src/main/res/values/theme.xml b/app/src/main/res/values/theme.xml index 79002122..39d907c4 100644 --- a/app/src/main/res/values/theme.xml +++ b/app/src/main/res/values/theme.xml @@ -40,6 +40,15 @@ @drawable/divider_dark + +