From 7f5d3c9fe4b4896615bd4a2f796091c00d031e84 Mon Sep 17 00:00:00 2001 From: serso Date: Fri, 8 Jan 2016 21:01:56 +0100 Subject: [PATCH] Application refactor --- .../android/calculator/ActivityUi.java | 10 +- .../android/calculator/AndroidCalculator.java | 28 +-- .../org/solovyev/android/calculator/App.java | 142 ++++++----- .../solovyev/android/calculator/BaseUi.java | 4 +- .../calculator/CalculatorActivity.java | 6 +- .../calculator/CalculatorActivityMobile.java | 2 +- .../calculator/CalculatorApplication.java | 220 ++++-------------- .../calculator/CalculatorBroadcaster.java | 4 + .../calculator/CalculatorDisplayFragment.java | 4 +- .../calculator/CalculatorEditorFragment.java | 4 +- .../calculator/CalculatorFragment.java | 4 +- .../CalculatorKeyboardFragment.java | 4 +- .../calculator/CalculatorListFragment.java | 4 +- .../android/calculator/Preferences.java | 62 ++--- .../history/BaseHistoryFragment.java | 35 +-- .../history/CalculatorHistoryImpl.java | 22 +- .../android/calculator/history/History.java | 58 ++++- .../calculator/history/HistoryUtils.java | 48 +--- .../calculator/language/Languages.java | 48 ++-- .../edit/AbstractMathEntityListFragment.java | 17 +- .../plot/AbstractCalculatorPlotFragment.java | 2 +- .../preferences/PreferencesFragment.java | 14 +- .../calculator/widget/CalculatorWidget.java | 16 +- .../wizard/ChooseLayoutWizardStep.java | 7 +- .../wizard/ChooseModeWizardStep.java | 16 +- .../wizard/ChooseThemeWizardStep.java | 13 +- .../wizard/OnScreenCalculatorWizardStep.java | 5 +- .../calculator/wizard/WizardActivity.java | 19 +- .../calculator/history/HistoryUtilsTest.java | 18 +- 29 files changed, 320 insertions(+), 516 deletions(-) diff --git a/app/src/main/java/org/solovyev/android/calculator/ActivityUi.java b/app/src/main/java/org/solovyev/android/calculator/ActivityUi.java index bf8920c4..809b8471 100644 --- a/app/src/main/java/org/solovyev/android/calculator/ActivityUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/ActivityUi.java @@ -70,8 +70,8 @@ public class ActivityUi extends BaseUi { public static boolean restartIfThemeChanged(@Nonnull Activity activity, @Nonnull Preferences.Gui.Theme oldTheme) { final Preferences.Gui.Theme newTheme = Preferences.Gui.theme.getPreference(App.getPreferences()); - final int themeId = oldTheme.getThemeId(activity); - final int newThemeId = newTheme.getThemeId(activity); + final int themeId = oldTheme.getThemeFor(activity); + final int newThemeId = newTheme.getThemeFor(activity); if (themeId != newThemeId) { Activities.restartActivity(activity); return true; @@ -100,7 +100,7 @@ public class ActivityUi extends BaseUi { final SharedPreferences preferences = App.getPreferences(); theme = Preferences.Gui.getTheme(preferences); - activity.setTheme(theme.getThemeId(activity)); + activity.setTheme(theme.getThemeFor(activity)); layout = Preferences.Gui.getLayout(preferences); language = App.getLanguages().getCurrent(); @@ -109,7 +109,7 @@ public class ActivityUi extends BaseUi { @Override public void onCreate(@Nonnull Activity activity) { super.onCreate(activity); - App.getLanguages().updateLanguage(activity, false); + App.getLanguages().updateContextLocale(activity, false); if (activity instanceof CalculatorEventListener) { Locator.getInstance().getCalculator().addCalculatorEventListener((CalculatorEventListener) activity); @@ -302,7 +302,7 @@ public class ActivityUi extends BaseUi { } private void addHelpInfo(@Nonnull Activity activity, @Nonnull View root) { - if (CalculatorApplication.isMonkeyRunner(activity)) { + if (App.isMonkeyRunner(activity)) { if (root instanceof ViewGroup) { final TextView helperTextView = new TextView(activity); diff --git a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java b/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java index 583d0ee1..e8d665f5 100644 --- a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java +++ b/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java @@ -184,46 +184,46 @@ public class AndroidCalculator implements Calculator, CalculatorEventListener, S public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { switch (calculatorEventType) { case calculation_messages: - CalculatorActivityLauncher.showCalculationMessagesDialog(CalculatorApplication.getInstance(), (List) data); + CalculatorActivityLauncher.showCalculationMessagesDialog(App.getApplication(), (List) data); break; case show_history: - CalculatorActivityLauncher.showHistory(CalculatorApplication.getInstance()); + CalculatorActivityLauncher.showHistory(App.getApplication()); break; case show_history_detached: - CalculatorActivityLauncher.showHistory(CalculatorApplication.getInstance(), true); + CalculatorActivityLauncher.showHistory(App.getApplication(), true); break; case show_functions: - CalculatorActivityLauncher.showFunctions(CalculatorApplication.getInstance()); + CalculatorActivityLauncher.showFunctions(App.getApplication()); break; case show_functions_detached: - CalculatorActivityLauncher.showFunctions(CalculatorApplication.getInstance(), true); + CalculatorActivityLauncher.showFunctions(App.getApplication(), true); break; case show_operators: - CalculatorActivityLauncher.showOperators(CalculatorApplication.getInstance()); + CalculatorActivityLauncher.showOperators(App.getApplication()); break; case show_operators_detached: - CalculatorActivityLauncher.showOperators(CalculatorApplication.getInstance(), true); + CalculatorActivityLauncher.showOperators(App.getApplication(), true); break; case show_vars: - CalculatorActivityLauncher.showVars(CalculatorApplication.getInstance()); + CalculatorActivityLauncher.showVars(App.getApplication()); break; case show_vars_detached: - CalculatorActivityLauncher.showVars(CalculatorApplication.getInstance(), true); + CalculatorActivityLauncher.showVars(App.getApplication(), true); break; case show_settings: - CalculatorActivityLauncher.showSettings(CalculatorApplication.getInstance()); + CalculatorActivityLauncher.showSettings(App.getApplication()); break; case show_settings_detached: - CalculatorActivityLauncher.showSettings(CalculatorApplication.getInstance(), true); + CalculatorActivityLauncher.showSettings(App.getApplication(), true); break; case show_settings_widget: - CalculatorActivityLauncher.showWidgetSettings(CalculatorApplication.getInstance(), true); + CalculatorActivityLauncher.showWidgetSettings(App.getApplication(), true); break; case show_like_dialog: - CalculatorActivityLauncher.likeButtonPressed(CalculatorApplication.getInstance()); + CalculatorActivityLauncher.likeButtonPressed(App.getApplication()); break; case open_app: - CalculatorActivityLauncher.openApp(CalculatorApplication.getInstance()); + CalculatorActivityLauncher.openApp(App.getApplication()); break; } } diff --git a/app/src/main/java/org/solovyev/android/calculator/App.java b/app/src/main/java/org/solovyev/android/calculator/App.java index 3a919368..5f95f739 100644 --- a/app/src/main/java/org/solovyev/android/calculator/App.java +++ b/app/src/main/java/org/solovyev/android/calculator/App.java @@ -25,10 +25,13 @@ package org.solovyev.android.calculator; import android.app.Application; import android.content.Context; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.graphics.Typeface; import android.os.Build; +import android.os.Handler; +import android.os.Looper; import android.preference.PreferenceManager; -import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; @@ -37,13 +40,16 @@ import android.support.v4.app.FragmentTransaction; import android.text.Spannable; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; +import org.solovyev.android.Check; import org.solovyev.android.UiThreadExecutor; import org.solovyev.android.Views; import org.solovyev.android.calculator.ga.Ga; import org.solovyev.android.calculator.language.Languages; import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService; import org.solovyev.android.calculator.view.ScreenMetrics; +import org.solovyev.android.calculator.wizard.CalculatorWizards; import org.solovyev.android.checkout.*; +import org.solovyev.android.wizard.Wizards; import org.solovyev.common.listeners.JEvent; import org.solovyev.common.listeners.JEventListener; import org.solovyev.common.listeners.JEventListeners; @@ -54,6 +60,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Arrays; import java.util.concurrent.Executor; +import java.util.concurrent.Executors; /** * User: serso @@ -69,7 +76,7 @@ import java.util.concurrent.Executor; */ public final class App { - public static final String TAG = "Calculator++"; + public static final String TAG = "C++"; @Nonnull public static String subTag(@Nonnull String subTag) { @@ -84,7 +91,7 @@ public final class App { @Nonnull private static final Products products = Products.create().add(ProductTypes.IN_APP, Arrays.asList("ad_free")); @Nonnull - private static final Languages languages = new Languages(); + private static Languages languages; @Nonnull private static volatile Application application; @Nonnull @@ -102,59 +109,60 @@ public final class App { private static volatile Billing billing; @Nullable private static Boolean lg = null; + @Nullable + private static Typeface typeFace; @Nonnull private static volatile ScreenMetrics screenMetrics; + @Nonnull + private static final Handler handler = new Handler(Looper.getMainLooper()); + @Nonnull + private static Wizards wizards; + @Nonnull + private static final Executor initializer = Executors.newSingleThreadExecutor(); private App() { throw new AssertionError(); } - /* - ********************************************************************** - * - * METHODS - * - ********************************************************************** - */ - - public static void init(@Nonnull Application application) { - init(application, new UiThreadExecutor(), Listeners.newEventBus()); + public static void init(@Nonnull Application application, @Nonnull Languages languages) { + init(application, new UiThreadExecutor(), Listeners.newEventBus(), languages); } public static void init(@Nonnull Application application, @Nonnull UiThreadExecutor uiThreadExecutor, - @Nonnull JEventListeners, JEvent> eventBus) { - if (!initialized) { - App.application = application; - App.preferences = PreferenceManager.getDefaultSharedPreferences(application); - App.uiThreadExecutor = uiThreadExecutor; - App.eventBus = eventBus; - App.ga = new Ga(application, preferences, eventBus); - App.billing = new Billing(application, new Billing.DefaultConfiguration() { - @Nonnull - @Override - public String getPublicKey() { - return CalculatorSecurity.getPK(); - } - - @Nullable - @Override - public Inventory getFallbackInventory(@Nonnull Checkout checkout, @Nonnull Executor onLoadExecutor) { - if (RobotmediaDatabase.exists(billing.getContext())) { - return new RobotmediaInventory(checkout, onLoadExecutor); - } else { - return null; - } - } - }); - App.broadcaster = new CalculatorBroadcaster(application, preferences); - App.screenMetrics = new ScreenMetrics(application); - App.languages.init(App.preferences); - - App.initialized = true; - } else { + @Nonnull JEventListeners, JEvent> eventBus, + @Nonnull Languages languages) { + if (initialized) { throw new IllegalStateException("Already initialized!"); } + App.application = application; + App.preferences = PreferenceManager.getDefaultSharedPreferences(application); + App.uiThreadExecutor = uiThreadExecutor; + App.eventBus = eventBus; + App.ga = new Ga(application, preferences, eventBus); + App.billing = new Billing(application, new Billing.DefaultConfiguration() { + @Nonnull + @Override + public String getPublicKey() { + return CalculatorSecurity.getPK(); + } + + @Nullable + @Override + public Inventory getFallbackInventory(@Nonnull Checkout checkout, @Nonnull Executor onLoadExecutor) { + if (RobotmediaDatabase.exists(billing.getContext())) { + return new RobotmediaInventory(checkout, onLoadExecutor); + } else { + return null; + } + } + }); + App.broadcaster = new CalculatorBroadcaster(application, preferences); + App.screenMetrics = new ScreenMetrics(application); + App.languages = languages; + App.wizards = new CalculatorWizards(application); + + App.initialized = true; } private static void checkInit() { @@ -163,21 +171,13 @@ public final class App { } } - /** - * @return if App has already been initialized, false otherwise - */ - public static boolean isInitialized() { - return initialized; - } - /** * @param real type of application - * @return application instance which was provided in {@link App#init(android.app.Application)} method + * @return application instance which was provided in {@link App#init} method */ @SuppressWarnings("unchecked") @Nonnull public static A getApplication() { - checkInit(); return (A) application; } @@ -188,7 +188,6 @@ public final class App { */ @Nonnull public static DelayedExecutor getUiThreadExecutor() { - checkInit(); return uiThreadExecutor; } @@ -197,7 +196,6 @@ public final class App { */ @Nonnull public static JEventListeners, JEvent> getEventBus() { - checkInit(); return eventBus; } @@ -206,6 +204,16 @@ public final class App { return broadcaster; } + @Nonnull + public static Wizards getWizards() { + return wizards; + } + + @Nonnull + public static Handler getHandler() { + return handler; + } + @Nonnull public static Ga getGa() { return ga; @@ -240,6 +248,11 @@ public final class App { return Preferences.Widget.getTheme(getPreferences()); } + @Nonnull + public static Executor getInitializer() { + return initializer; + } + @Nonnull public static Preferences.Gui.Theme getThemeIn(@Nonnull Context context) { if (context instanceof CalculatorOnscreenService) { @@ -289,15 +302,24 @@ public final class App { dialogFragment.show(ft, fragmentTag); } - @NonNull - public static String toColorString(@ColorInt int color) { - return Integer.toHexString(color).substring(2); - } - @NonNull public static SpannableString colorString(@Nonnull String s, int color) { final SpannableString spannable = new SpannableString(s); spannable.setSpan(new ForegroundColorSpan(color), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return spannable; } -} + + @Nonnull + public static Typeface getTypeFace() { + Check.isMainThread(); + if (typeFace == null) { + typeFace = Typeface.createFromAsset(application.getAssets(), "fonts/Roboto-Regular.ttf"); + } + return typeFace; + } + + public static boolean isMonkeyRunner(@Nonnull Context context) { + // NOTE: this code is only for monkeyrunner + return context.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) == PackageManager.PERMISSION_GRANTED; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/solovyev/android/calculator/BaseUi.java b/app/src/main/java/org/solovyev/android/calculator/BaseUi.java index bff45d9c..597d6843 100644 --- a/app/src/main/java/org/solovyev/android/calculator/BaseUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/BaseUi.java @@ -126,7 +126,7 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan preferences.registerOnSharedPreferenceChangeListener(this); // let's disable locking of screen for monkeyrunner - if (CalculatorApplication.isMonkeyRunner(activity)) { + if (App.isMonkeyRunner(activity)) { final KeyguardManager km = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE); //noinspection deprecation km.newKeyguardLock(activity.getClass().getName()).disableKeyguard(); @@ -145,7 +145,7 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan protected void fixFonts(@Nonnull View root) { // some devices ship own fonts which causes issues with rendering. Let's use our own font for all text views - final Typeface typeFace = CalculatorApplication.getInstance().getTypeFace(); + final Typeface typeFace = App.getTypeFace(); Views.processViewsOfType(root, TextView.class, new Views.ViewProcessor() { @Override public void process(@Nonnull TextView view) { 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 0f166dc7..45ac6ba5 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java @@ -86,10 +86,10 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference Preferences.appVersion.putPreference(preferences, appVersion); - if (!CalculatorApplication.isMonkeyRunner(context)) { + if (!App.isMonkeyRunner(context)) { boolean dialogShown = false; - final Wizards wizards = CalculatorApplication.getInstance().getWizards(); + final Wizards wizards = App.getWizards(); final Wizard wizard = wizards.getWizard(CalculatorWizards.FIRST_TIME_WIZARD); if (wizard.isStarted() && !wizard.isFinished()) { continueWizard(wizards, wizard.getName(), context); @@ -186,7 +186,7 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference Locator.getInstance().getPreferenceService().checkPreferredPreferences(false); - if (CalculatorApplication.isMonkeyRunner(this)) { + if (App.isMonkeyRunner(this)) { Locator.getInstance().getKeyboard().buttonPressed("123"); Locator.getInstance().getKeyboard().buttonPressed("+"); Locator.getInstance().getKeyboard().buttonPressed("321"); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityMobile.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityMobile.java index 10b05a94..6c13cbdf 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityMobile.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityMobile.java @@ -42,7 +42,7 @@ public class CalculatorActivityMobile extends CalculatorActivity { super.onCreate(savedInstanceState); - if (!CalculatorApplication.isMonkeyRunner(this)) { + if (!App.isMonkeyRunner(this)) { this.finish(); } } 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 551908f1..ac9ea68d 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java @@ -22,143 +22,50 @@ package org.solovyev.android.calculator; -import android.content.Context; import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.graphics.Typeface; -import android.os.Handler; import android.preference.PreferenceManager; import android.util.Log; - +import android.util.TimingLogger; import com.squareup.leakcanary.LeakCanary; - import org.acra.ACRA; -import org.acra.ReportingInteractionMode; -import org.acra.annotation.ReportsCrashes; +import org.acra.ACRAConfiguration; +import org.acra.sender.HttpSender; import org.solovyev.android.Android; import org.solovyev.android.calculator.history.AndroidCalculatorHistory; import org.solovyev.android.calculator.language.Language; +import org.solovyev.android.calculator.language.Languages; import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.calculator.onscreen.CalculatorOnscreenStartActivity; import org.solovyev.android.calculator.plot.AndroidCalculatorPlotter; import org.solovyev.android.calculator.plot.CalculatorPlotterImpl; import org.solovyev.android.calculator.view.EditorTextProcessor; -import org.solovyev.android.calculator.wizard.CalculatorWizards; -import org.solovyev.android.wizard.Wizards; import org.solovyev.common.msg.MessageType; +import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; - -@ReportsCrashes( - formUri = "https://serso.cloudant.com/acra-cpp/_design/acra-storage/_update/report", - reportType = org.acra.sender.HttpSender.Type.JSON, - httpMethod = org.acra.sender.HttpSender.Method.PUT, - formUriBasicAuthLogin = "timbeenterumisideffecird", - formUriBasicAuthPassword = "ECL65PO2TH5quIFNAK4hQ5Ng", - mode = ReportingInteractionMode.TOAST, - resToastText = R.string.crashed) public class CalculatorApplication extends android.app.Application implements SharedPreferences.OnSharedPreferenceChangeListener { - - /* - ********************************************************************** - * - * CONSTANTS - * - ********************************************************************** - */ - - public static final String AD_FREE_PRODUCT_ID = "ad_free"; - public static final String AD_FREE_P_KEY = "org.solovyev.android.calculator_ad_free"; - public static final String ADMOB = "ca-app-pub-2228934497384784/2916398892"; @Nonnull - static final String MAIL = "se.solovyev@gmail.com"; - private static final String TAG = "C++"; - @Nonnull - private static CalculatorApplication instance; - - /* - ********************************************************************** - * - * FIELDS - * - ********************************************************************** - */ - @Nonnull - protected final Handler uiHandler = new Handler(); - @Nonnull - private final List listeners = new ArrayList(); - @Nonnull - private final Wizards wizards = new CalculatorWizards(this); - - private Typeface typeFace; - - /* - ********************************************************************** - * - * CONSTRUCTORS - * - ********************************************************************** - */ - - public CalculatorApplication() { - instance = this; - } - - /* - ********************************************************************** - * - * METHODS - * - ********************************************************************** - */ - - @Nonnull - public static CalculatorApplication getInstance() { - return instance; - } - - @Nonnull - public static SharedPreferences getPreferences() { - return PreferenceManager.getDefaultSharedPreferences(getInstance()); - } - - public static boolean isMonkeyRunner(@Nonnull Context context) { - // NOTE: this code is only for monkeyrunner - return context.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) == PackageManager.PERMISSION_GRANTED; - } + private final List listeners = new ArrayList<>(); @Override public void onCreate() { - if (!BuildConfig.DEBUG) { - ACRA.init(this); - } else { - LeakCanary.install(this); - } - - if (!App.isInitialized()) { - App.init(this); - } - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); - Preferences.setDefaultValues(preferences); + final Languages languages = new Languages(preferences); + + onPreCreate(preferences, languages); + super.onCreate(); + onPostCreate(preferences, languages); + } + + private void onPostCreate(@Nonnull SharedPreferences preferences, @Nonnull Languages languages) { + App.init(this, languages); preferences.registerOnSharedPreferenceChangeListener(this); - - setTheme(preferences); - setLanguageInitially(); - - super.onCreate(); - App.getLanguages().updateLanguage(this, true); - - if (!Preferences.Ga.initialReportDone.getPreference(preferences)) { - App.getGa().reportInitially(preferences); - Preferences.Ga.initialReportDone.putPreference(preferences, true); - } + languages.updateContextLocale(this, true); + App.getGa().reportInitially(preferences); final AndroidCalculator calculator = new AndroidCalculator(this); @@ -186,86 +93,55 @@ public class CalculatorApplication extends android.app.Application implements Sh Locator.getInstance().getCalculator().init(); - new Thread(new Runnable() { + App.getInitializer().execute(new Runnable() { @Override public void run() { try { - // prepare engine - Locator.getInstance().getEngine().getMathEngine0().evaluate("1+1"); - Locator.getInstance().getEngine().getMathEngine0().evaluate("1*1"); + // warm-up engine + CalculatorMathEngine mathEngine = Locator.getInstance().getEngine().getMathEngine(); + mathEngine.evaluate("1+1"); + mathEngine.evaluate("1*1"); } catch (Throwable e) { - Log.e(TAG, e.getMessage(), e); + Log.e(App.TAG, e.getMessage(), e); } - } - }).start(); + }); - Locator.getInstance().getLogger().debug(TAG, "Application started!"); - Locator.getInstance().getNotifier().showDebugMessage(TAG, "Application started!"); - - App.getUiThreadExecutor().execute(new Runnable() { + App.getHandler().postDelayed(new Runnable() { @Override public void run() { // we must update the widget when app starts - App.getBroadcaster().sendEditorStateChangedIntent(); + App.getBroadcaster().sendInitIntent(); } - }, 100, TimeUnit.MILLISECONDS); + }, 100); } - private void setLanguageInitially() { - // should be called before onCreate() - final Language language = App.getLanguages().getCurrent(); + private void onPreCreate(@Nonnull SharedPreferences preferences, @Nonnull Languages languages) { + // first we need to setup crash handler and memory leak analyzer + if (!BuildConfig.DEBUG) { + ACRA.init(this, new ACRAConfiguration() + .setFormUri("https://serso.cloudant.com/acra-cpp/_design/acra-storage/_update/report") + .setReportType(HttpSender.Type.JSON) + .setHttpMethod(HttpSender.Method.PUT) + .setFormUriBasicAuthLogin("timbeenterumisideffecird") + .setFormUriBasicAuthPassword("ECL65PO2TH5quIFNAK4hQ5Ng")); + } else { + LeakCanary.install(this); + } + + // then we should set default preferences + Preferences.setDefaultValues(preferences); + + // and change application's theme/language is needed + final Preferences.Gui.Theme theme = Preferences.Gui.getTheme(preferences); + setTheme(theme.theme); + + final Language language = languages.getCurrent(); if (!language.isSystem() && !language.locale.equals(Locale.getDefault())) { Locale.setDefault(language.locale); } } - private void setTheme(@Nonnull SharedPreferences preferences) { - final Preferences.Gui.Theme theme = Preferences.Gui.getTheme(preferences); - setTheme(theme.getThemeId()); - } - - @Nonnull - public FragmentUi createFragmentHelper(int layoutId) { - return new FragmentUi(layoutId); - } - - @Nonnull - public FragmentUi createFragmentHelper(int layoutId, int titleResId) { - return new FragmentUi(layoutId, titleResId); - } - - @Nonnull - public FragmentUi createFragmentHelper(int layoutId, int titleResId, boolean listenersOnCreate) { - return new FragmentUi(layoutId, titleResId, listenersOnCreate); - } - - /* - ********************************************************************** - * - * STATIC - * - ********************************************************************** - */ - - @Nonnull - public Handler getUiHandler() { - return uiHandler; - } - - @Nonnull - public Wizards getWizards() { - return wizards; - } - - @Nonnull - public Typeface getTypeFace() { - if (typeFace == null) { - typeFace = Typeface.createFromAsset(getAssets(), "fonts/Roboto-Regular.ttf"); - } - return typeFace; - } - @Override public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { if (Preferences.Onscreen.showAppIcon.getKey().equals(key)) { diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorBroadcaster.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorBroadcaster.java index 834c39fc..78bff9eb 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorBroadcaster.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorBroadcaster.java @@ -43,6 +43,10 @@ public final class CalculatorBroadcaster implements CalculatorEventListener, Sha sendBroadcastIntent(ACTION_EDITOR_STATE_CHANGED); } + public void sendInitIntent() { + sendBroadcastIntent(ACTION_INIT); + } + public void sendBroadcastIntent(@Nonnull String action) { context.sendBroadcast(new Intent(action)); } 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 6406bc4f..475b992b 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java @@ -51,9 +51,9 @@ public class CalculatorDisplayFragment extends Fragment { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.getActivity()); final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(prefs); if (!layout.isOptimized()) { - fragmentUi = CalculatorApplication.getInstance().createFragmentHelper(R.layout.cpp_app_display_mobile, R.string.result); + fragmentUi = new FragmentUi(R.layout.cpp_app_display_mobile, R.string.result); } else { - fragmentUi = CalculatorApplication.getInstance().createFragmentHelper(R.layout.cpp_app_display, R.string.result); + fragmentUi = new FragmentUi(R.layout.cpp_app_display, R.string.result); } fragmentUi.onCreate(this); 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 18ab0d7b..53acaec1 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java @@ -81,9 +81,9 @@ public class CalculatorEditorFragment extends Fragment { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.getActivity()); final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(prefs); if (!layout.isOptimized()) { - fragmentUi = CalculatorApplication.getInstance().createFragmentHelper(R.layout.cpp_app_editor_mobile, R.string.editor); + fragmentUi = new FragmentUi(R.layout.cpp_app_editor_mobile, R.string.editor); } else { - fragmentUi = CalculatorApplication.getInstance().createFragmentHelper(R.layout.cpp_app_editor, R.string.editor); + fragmentUi = new FragmentUi(R.layout.cpp_app_editor, R.string.editor); } fragmentUi.onCreate(this); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorFragment.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorFragment.java index 0aacbb32..37ad7c76 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorFragment.java @@ -42,11 +42,11 @@ public abstract class CalculatorFragment extends Fragment { private final FragmentUi fragmentUi; protected CalculatorFragment(int layoutResId, int titleResId) { - fragmentUi = CalculatorApplication.getInstance().createFragmentHelper(layoutResId, titleResId); + fragmentUi = new FragmentUi(layoutResId, titleResId); } protected CalculatorFragment(@Nonnull CalculatorFragmentType fragmentType) { - fragmentUi = CalculatorApplication.getInstance().createFragmentHelper(fragmentType.getDefaultLayoutId(), fragmentType.getDefaultTitleResId()); + fragmentUi = new FragmentUi(fragmentType.getDefaultLayoutId(), fragmentType.getDefaultTitleResId()); } protected CalculatorFragment(@Nonnull FragmentUi fragmentUi) { 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 2be3cd89..50e4dfb2 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardFragment.java @@ -55,9 +55,9 @@ public class CalculatorKeyboardFragment extends Fragment implements SharedPrefer final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(preferences); if (!layout.isOptimized()) { - ui = CalculatorApplication.getInstance().createFragmentHelper(R.layout.cpp_app_keyboard_mobile); + ui = new FragmentUi(R.layout.cpp_app_keyboard_mobile); } else { - ui = CalculatorApplication.getInstance().createFragmentHelper(R.layout.cpp_app_keyboard); + ui = new FragmentUi(R.layout.cpp_app_keyboard); } ui.onCreate(this); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorListFragment.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorListFragment.java index 77648c5e..2688724f 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorListFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorListFragment.java @@ -42,11 +42,11 @@ public abstract class CalculatorListFragment extends ListFragment { private final FragmentUi ui; protected CalculatorListFragment(int layoutResId, int titleResId) { - ui = CalculatorApplication.getInstance().createFragmentHelper(layoutResId, titleResId); + ui = new FragmentUi(layoutResId, titleResId); } protected CalculatorListFragment(@Nonnull CalculatorFragmentType fragmentType) { - ui = CalculatorApplication.getInstance().createFragmentHelper(fragmentType.getDefaultLayoutId(), fragmentType.getDefaultTitleResId()); + ui = new FragmentUi(fragmentType.getDefaultLayoutId(), fragmentType.getDefaultTitleResId()); } protected CalculatorListFragment(@Nonnull FragmentUi ui) { 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 5536ad4c..d51b6f50 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Preferences.java +++ b/app/src/main/java/org/solovyev/android/calculator/Preferences.java @@ -31,31 +31,23 @@ 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.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 org.solovyev.android.prefs.*; +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; @@ -128,9 +120,6 @@ public final class Preferences { applyDefaultPreference(preferences, Widget.theme); - applyDefaultPreference(preferences, Ga.initialReportDone); - - // renew value after each application start Calculations.showCalculationMessagesDialog.putDefault(preferences); Calculations.lastPreferredPreferencesCheck.putDefault(preferences); @@ -258,10 +247,6 @@ public final class Preferences { } - public static class Ga { - public static final Preference initialReportDone = BooleanPreference.of("ga.initial_report_done", false); - } - public static class Gui { public static final Preference theme = StringPreference.ofEnum("org.solovyev.android.calculator.CalculatorActivity_calc_theme", Theme.material_theme, Theme.class); @@ -300,39 +285,38 @@ public final class Preferences { private static final SparseArray textColors = new SparseArray<>(); - private final int themeId; - private final int wizardThemeId; - private final int dialogThemeId; + @StyleRes + public final int theme; + @StyleRes + public final int wizardTheme; + @StyleRes + public final int dialogTheme; public final boolean light; - Theme(@StyleRes int themeId) { - this(themeId, R.style.Cpp_Theme_Wizard, R.style.Cpp_Theme_Dialog_Material); + Theme(@StyleRes int theme) { + this(theme, R.style.Cpp_Theme_Wizard, R.style.Cpp_Theme_Dialog_Material); } - Theme(@StyleRes int themeId, @StyleRes int wizardThemeId, int dialogThemeId) { - this.themeId = themeId; - this.wizardThemeId = wizardThemeId; - this.dialogThemeId = dialogThemeId; - this.light = themeId == R.style.Cpp_Theme_Material_Light; + Theme(@StyleRes int theme, @StyleRes int wizardTheme, @StyleRes int dialogTheme) { + this.theme = theme; + this.wizardTheme = wizardTheme; + this.dialogTheme = dialogTheme; + this.light = theme == R.style.Cpp_Theme_Material_Light; } - public int getThemeId() { - return getThemeId(null); - } - - public int getThemeId(@Nullable Context context) { + public int getThemeFor(@Nullable Context context) { if (context instanceof WizardActivity) { - return wizardThemeId; + return wizardTheme; } if (context instanceof PurchaseDialogActivity) { - return dialogThemeId; + return dialogTheme; } - return themeId; + return theme; } @Nonnull public TextColor getTextColor(@Nonnull Context context) { - final int themeId = getThemeId(context); + final int themeId = getThemeFor(context); TextColor textColor = textColors.get(themeId); if (textColor == null) { final ContextThemeWrapper themeContext = new ContextThemeWrapper(context, themeId); 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 99018e25..b98aa3ff 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 @@ -32,35 +32,15 @@ import android.preference.PreferenceManager; import android.support.v4.app.FragmentActivity; import android.support.v4.app.ListFragment; import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; +import android.view.*; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; - import com.melnykov.fab.FloatingActionButton; - -import org.solovyev.android.calculator.CalculatorApplication; -import org.solovyev.android.calculator.CalculatorEventData; -import org.solovyev.android.calculator.CalculatorEventListener; -import org.solovyev.android.calculator.CalculatorEventType; -import org.solovyev.android.calculator.CalculatorFragmentType; -import org.solovyev.android.calculator.FragmentUi; -import org.solovyev.android.calculator.Locator; -import org.solovyev.android.calculator.Preferences; +import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.android.menu.AMenuItem; -import org.solovyev.android.menu.ActivityMenu; -import org.solovyev.android.menu.AndroidMenuHelper; -import org.solovyev.android.menu.ContextMenuBuilder; -import org.solovyev.android.menu.IdentifiableMenuItem; -import org.solovyev.android.menu.ListActivityMenu; -import org.solovyev.android.menu.ListContextMenu; +import org.solovyev.android.menu.*; import org.solovyev.common.JPredicate; import org.solovyev.common.collections.Collections; import org.solovyev.common.equals.Equalizer; @@ -68,13 +48,12 @@ import org.solovyev.common.filter.Filter; import org.solovyev.common.filter.FilterRulesChain; import org.solovyev.common.text.Strings; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import static org.solovyev.android.calculator.CalculatorEventType.clear_history_requested; public abstract class BaseHistoryFragment extends ListFragment implements CalculatorEventListener { @@ -126,7 +105,7 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul private AlertDialog clearDialog; protected BaseHistoryFragment(@Nonnull CalculatorFragmentType fragmentType) { - ui = CalculatorApplication.getInstance().createFragmentHelper(fragmentType.getDefaultLayoutId(), fragmentType.getDefaultTitleResId(), false); + ui = new FragmentUi(fragmentType.getDefaultLayoutId(), fragmentType.getDefaultTitleResId(), false); } public static boolean isAlreadySaved(@Nonnull HistoryState historyState) { @@ -402,7 +381,7 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul toggle_datetime(R.id.menu_history_toggle_datetime) { @Override public void onClick(@Nonnull MenuItem data, @Nonnull Context context) { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(CalculatorApplication.getInstance()); + final SharedPreferences preferences = App.getPreferences(); final Boolean showDatetime = Preferences.History.showDatetime.getPreference(preferences); Preferences.History.showDatetime.putPreference(preferences, !showDatetime); } diff --git a/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java b/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java index 9049e5c3..19102e88 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java @@ -29,7 +29,6 @@ import org.solovyev.common.history.SimpleHistoryHelper; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -37,11 +36,6 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.solovyev.android.calculator.CalculatorEventType.*; -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:12 - */ public class CalculatorHistoryImpl implements CalculatorHistory { private final AtomicInteger counter = new AtomicInteger(0); @@ -50,7 +44,7 @@ public class CalculatorHistoryImpl implements CalculatorHistory { private final HistoryHelper history = SimpleHistoryHelper.newInstance(); @Nonnull - private final List savedHistory = new ArrayList(); + private final History savedHistory = new History(); @Nonnull private final CalculatorEventHolder lastEventData = new CalculatorEventHolder(CalculatorUtils.createFirstEventDataId()); @@ -188,7 +182,7 @@ public class CalculatorHistoryImpl implements CalculatorHistory { @Override @Nonnull public List getSavedHistory() { - return Collections.unmodifiableList(savedHistory); + return Collections.unmodifiableList(savedHistory.getItems()); } @Override @@ -222,21 +216,25 @@ public class CalculatorHistoryImpl implements CalculatorHistory { public void fromXml(@Nonnull String xml) { clearSavedHistory(); - HistoryUtils.fromXml(xml, this.savedHistory); - for (HistoryState historyState : savedHistory) { + final History history = History.fromXml(xml); + if (history == null) { + return; + } + for (HistoryState historyState : history.getItems()) { historyState.setSaved(true); historyState.setId(counter.incrementAndGet()); + savedHistory.add(historyState); } } @Override public String toXml() { - return HistoryUtils.toXml(this.savedHistory); + return savedHistory.toXml(); } @Override public void clearSavedHistory() { - this.savedHistory.clear(); + savedHistory.clear(); } @Override diff --git a/app/src/main/java/org/solovyev/android/calculator/history/History.java b/app/src/main/java/org/solovyev/android/calculator/history/History.java index 9f2857ca..7abf636b 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/History.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/History.java @@ -24,26 +24,64 @@ package org.solovyev.android.calculator.history; import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; +import org.simpleframework.xml.Serializer; +import org.simpleframework.xml.core.Persister; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.StringWriter; import java.util.ArrayList; import java.util.List; -/** - * User: serso - * Date: 12/17/11 - * Time: 9:30 PM - */ - @Root public class History { - @ElementList(type = HistoryState.class) - private List historyItems = new ArrayList(); + @Nonnull + @ElementList(type = HistoryState.class, name = "historyItems") + private List items = new ArrayList(); public History() { } - public List getHistoryItems() { - return historyItems; + @Nullable + public static History fromXml(@Nullable String xml) { + if (xml == null) { + return null; + } + final Serializer serializer = new Persister(); + try { + return serializer.read(History.class, xml); + } catch (Exception e) { + return null; + } + } + + @Nonnull + public String toXml() { + final StringWriter xml = new StringWriter(); + final Serializer serializer = new Persister(); + try { + serializer.write(this, xml); + } catch (Exception e) { + return ""; + } + return xml.toString(); + } + + @Nonnull + public List getItems() { + return items; + } + + public void add(@Nonnull HistoryState state) { + items.add(state); + } + + public void clear() { + items.clear(); + } + + public void remove(@Nonnull HistoryState state) { + items.remove(state); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/history/HistoryUtils.java b/app/src/main/java/org/solovyev/android/calculator/history/HistoryUtils.java index 12895ad7..fcb21b08 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/HistoryUtils.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/HistoryUtils.java @@ -22,57 +22,11 @@ package org.solovyev.android.calculator.history; -import org.simpleframework.xml.Serializer; -import org.simpleframework.xml.core.Persister; - -import java.io.StringWriter; -import java.util.List; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -/** - * User: serso - * Date: 12/17/11 - * Time: 9:59 PM - */ -class HistoryUtils { +final class HistoryUtils { // not intended for instantiation private HistoryUtils() { throw new AssertionError(); } - public static void fromXml(@Nullable String xml, @Nonnull List historyItems) { - if (xml != null) { - final Serializer serializer = new Persister(); - try { - final History history = serializer.read(History.class, xml); - for (HistoryState historyItem : history.getHistoryItems()) { - historyItems.add(historyItem); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - @Nonnull - public static String toXml(@Nonnull List historyItems) { - final History history = new History(); - for (HistoryState historyState : historyItems) { - if (historyState.isSaved()) { - history.getHistoryItems().add(historyState); - } - } - - final StringWriter xml = new StringWriter(); - final Serializer serializer = new Persister(); - try { - serializer.write(history, xml); - } catch (Exception e) { - throw new RuntimeException(e); - } - return xml.toString(); - } } diff --git a/app/src/main/java/org/solovyev/android/calculator/language/Languages.java b/app/src/main/java/org/solovyev/android/calculator/language/Languages.java index a0042c96..fbf85730 100644 --- a/app/src/main/java/org/solovyev/android/calculator/language/Languages.java +++ b/app/src/main/java/org/solovyev/android/calculator/language/Languages.java @@ -7,19 +7,13 @@ import android.content.res.Resources; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; - import org.solovyev.android.Check; import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.Preferences; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Locale; - import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.*; public final class Languages implements SharedPreferences.OnSharedPreferenceChangeListener { @@ -31,6 +25,13 @@ public final class Languages implements SharedPreferences.OnSharedPreferenceChan private static final Locale[] locales = Locale.getAvailableLocales(); @Nonnull private final List list = new ArrayList<>(); + @Nonnull + private final SharedPreferences preferences; + + public Languages(@Nonnull SharedPreferences preferences) { + this.preferences = preferences; + this.preferences.registerOnSharedPreferenceChangeListener(this); + } @Nullable private static Language makeLanguage(@Nonnull String localeId) { @@ -67,10 +68,6 @@ public final class Languages implements SharedPreferences.OnSharedPreferenceChan return null; } - public void init(@Nonnull SharedPreferences preferences) { - preferences.registerOnSharedPreferenceChangeListener(this); - } - @Nonnull public List getList() { Check.isMainThread(); @@ -120,7 +117,7 @@ public final class Languages implements SharedPreferences.OnSharedPreferenceChan @Nonnull public Language getCurrent() { - return get(Preferences.Gui.language.getPreference(App.getPreferences())); + return get(Preferences.Gui.language.getPreference(preferences)); } @Nonnull @@ -145,25 +142,26 @@ public final class Languages implements SharedPreferences.OnSharedPreferenceChan @Override public void onSharedPreferenceChanged(@Nonnull SharedPreferences p, String key) { if (Preferences.Gui.language.isSameKey(key)) { - updateLanguage(App.getApplication(), false); + updateContextLocale(App.getApplication(), false); } } - public void updateLanguage(@Nonnull Context context, boolean initial) { + public void updateContextLocale(@Nonnull Context context, boolean initial) { final Language language = getCurrent(); // we don't need to set system language while starting up the app - if (!initial || !language.isSystem()) { - if (!Locale.getDefault().equals(language.locale)) { - Locale.setDefault(language.locale); - } + if (initial && language.isSystem()) { + return; + } + if (!Locale.getDefault().equals(language.locale)) { + Locale.setDefault(language.locale); + } - final Resources r = context.getResources(); - final DisplayMetrics dm = r.getDisplayMetrics(); - final Configuration c = r.getConfiguration(); - if (c.locale == null || !c.locale.equals(language.locale)) { - c.locale = language.locale; - r.updateConfiguration(c, dm); - } + final Resources r = context.getResources(); + final DisplayMetrics dm = r.getDisplayMetrics(); + final Configuration c = r.getConfiguration(); + if (c.locale == null || !c.locale.equals(language.locale)) { + c.locale = language.locale; + r.updateConfiguration(c, dm); } } } \ No newline at end of file diff --git a/app/src/main/java/org/solovyev/android/calculator/math/edit/AbstractMathEntityListFragment.java b/app/src/main/java/org/solovyev/android/calculator/math/edit/AbstractMathEntityListFragment.java index 95ac4e29..fcf4e3b2 100644 --- a/app/src/main/java/org/solovyev/android/calculator/math/edit/AbstractMathEntityListFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/math/edit/AbstractMathEntityListFragment.java @@ -33,15 +33,7 @@ import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; - -import org.solovyev.android.calculator.CalculatorApplication; -import org.solovyev.android.calculator.CalculatorEventData; -import org.solovyev.android.calculator.CalculatorEventListener; -import org.solovyev.android.calculator.CalculatorEventType; -import org.solovyev.android.calculator.CalculatorFragmentType; -import org.solovyev.android.calculator.CalculatorMathRegistry; -import org.solovyev.android.calculator.FragmentUi; -import org.solovyev.android.calculator.R; +import org.solovyev.android.calculator.*; import org.solovyev.android.menu.AMenuItem; import org.solovyev.android.menu.ContextMenuBuilder; import org.solovyev.android.menu.LabeledMenuItem; @@ -52,11 +44,10 @@ import org.solovyev.common.filter.Filter; import org.solovyev.common.math.MathEntity; import org.solovyev.common.text.Strings; -import java.util.Comparator; -import java.util.List; - import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Comparator; +import java.util.List; /** @@ -94,7 +85,7 @@ public abstract class AbstractMathEntityListFragment exten private String category; protected AbstractMathEntityListFragment(@Nonnull CalculatorFragmentType fragmentType) { - ui = CalculatorApplication.getInstance().createFragmentHelper(fragmentType.getDefaultLayoutId(), fragmentType.getDefaultTitleResId()); + ui = new FragmentUi(fragmentType.getDefaultLayoutId(), fragmentType.getDefaultTitleResId()); } @Nonnull diff --git a/app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java b/app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java index e3cef31f..570eb77a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java @@ -98,7 +98,7 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment public AbstractCalculatorPlotFragment() { - super(CalculatorApplication.getInstance().createFragmentHelper(R.layout.cpp_plot_fragment, R.string.c_graph, false)); + super(new FragmentUi(R.layout.cpp_plot_fragment, R.string.c_graph, false)); } public static void applyToPaint(@Nonnull PlotLineDef plotLineDef, @Nonnull Paint paint) { diff --git a/app/src/main/java/org/solovyev/android/calculator/preferences/PreferencesFragment.java b/app/src/main/java/org/solovyev/android/calculator/preferences/PreferencesFragment.java index fc15ce8e..44c4aea2 100644 --- a/app/src/main/java/org/solovyev/android/calculator/preferences/PreferencesFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/preferences/PreferencesFragment.java @@ -10,12 +10,7 @@ import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.widget.ListView; - -import org.solovyev.android.calculator.AdView; -import org.solovyev.android.calculator.App; -import org.solovyev.android.calculator.CalculatorApplication; -import org.solovyev.android.calculator.Preferences; -import org.solovyev.android.calculator.R; +import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.language.Language; import org.solovyev.android.calculator.language.Languages; import org.solovyev.android.checkout.BillingRequests; @@ -23,10 +18,9 @@ import org.solovyev.android.checkout.Checkout; import org.solovyev.android.checkout.ProductTypes; import org.solovyev.android.checkout.RequestListener; -import java.util.List; - import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.List; import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.precision; import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.roundResult; @@ -81,7 +75,7 @@ public class PreferencesFragment extends org.solovyev.android.material.preferenc restartWizardPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - startWizard(CalculatorApplication.getInstance().getWizards(), DEFAULT_WIZARD_FLOW, getActivity()); + startWizard(App.getWizards(), DEFAULT_WIZARD_FLOW, getActivity()); return true; } }); @@ -105,7 +99,7 @@ public class PreferencesFragment extends org.solovyev.android.material.preferenc getCheckout().whenReady(new Checkout.ListenerAdapter() { @Override public void onReady(@Nonnull BillingRequests requests) { - requests.isPurchased(ProductTypes.IN_APP, CalculatorApplication.AD_FREE_PRODUCT_ID, new RequestListener() { + requests.isPurchased(ProductTypes.IN_APP, "ad_free", new RequestListener() { @Override public void onSuccess(@Nonnull Boolean purchased) { if (buyPremiumPreference != null) { diff --git a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidget.java b/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidget.java index ed25ac0b..903e6801 100644 --- a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidget.java +++ b/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidget.java @@ -41,28 +41,19 @@ import android.text.SpannedString; import android.text.TextUtils; import android.text.style.StyleSpan; import android.widget.RemoteViews; - import org.solovyev.android.Check; import org.solovyev.android.Views; -import org.solovyev.android.calculator.App; -import org.solovyev.android.calculator.CalculatorButton; -import org.solovyev.android.calculator.DisplayState; -import org.solovyev.android.calculator.EditorState; -import org.solovyev.android.calculator.Locator; +import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.Preferences.SimpleTheme; -import org.solovyev.android.calculator.R; - -import java.util.EnumMap; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.EnumMap; import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT; import static android.content.Intent.ACTION_CONFIGURATION_CHANGED; import static android.os.Build.VERSION_CODES.JELLY_BEAN; -import static org.solovyev.android.calculator.CalculatorBroadcaster.ACTION_DISPLAY_STATE_CHANGED; -import static org.solovyev.android.calculator.CalculatorBroadcaster.ACTION_EDITOR_STATE_CHANGED; -import static org.solovyev.android.calculator.CalculatorBroadcaster.ACTION_THEME_CHANGED; +import static org.solovyev.android.calculator.CalculatorBroadcaster.*; import static org.solovyev.android.calculator.CalculatorReceiver.newButtonClickedIntent; public class CalculatorWidget extends AppWidgetProvider { @@ -211,6 +202,7 @@ public class CalculatorWidget extends AppWidgetProvider { case ACTION_CONFIGURATION_CHANGED: case ACTION_APPWIDGET_OPTIONS_CHANGED: case ACTION_THEME_CHANGED: + case ACTION_INIT: updateWidget(context, false); break; } diff --git a/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseLayoutWizardStep.java b/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseLayoutWizardStep.java index 11084ae7..3cfdc7cc 100644 --- a/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseLayoutWizardStep.java +++ b/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseLayoutWizardStep.java @@ -27,13 +27,12 @@ import android.view.View; import android.widget.AdapterView; import android.widget.ImageView; import android.widget.Spinner; - +import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.Preferences; import org.solovyev.android.calculator.R; import javax.annotation.Nonnull; -import static org.solovyev.android.calculator.CalculatorApplication.getPreferences; import static org.solovyev.android.calculator.wizard.CalculatorLayout.big_buttons; import static org.solovyev.android.calculator.wizard.CalculatorLayout.optimized; @@ -55,7 +54,7 @@ public class ChooseLayoutWizardStep extends WizardFragment implements AdapterVie public void onViewCreated(View root, Bundle savedInstanceState) { super.onViewCreated(root, savedInstanceState); - final CalculatorLayout layout = CalculatorLayout.fromGuiLayout(Preferences.Gui.layout.getPreference(getPreferences())); + final CalculatorLayout layout = CalculatorLayout.fromGuiLayout(Preferences.Gui.layout.getPreference(App.getPreferences())); image = (ImageView) root.findViewById(R.id.wizard_layout_image); final Spinner spinner = (Spinner) root.findViewById(R.id.wizard_layout_spinner); @@ -78,7 +77,7 @@ public class ChooseLayoutWizardStep extends WizardFragment implements AdapterVie @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { final CalculatorLayout layout = position == 0 ? big_buttons : optimized; - layout.apply(getPreferences()); + layout.apply(App.getPreferences()); updateImage(layout); } diff --git a/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseModeWizardStep.java b/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseModeWizardStep.java index 5dd97429..56b1ba30 100644 --- a/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseModeWizardStep.java +++ b/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseModeWizardStep.java @@ -27,25 +27,17 @@ import android.view.View; import android.widget.AdapterView; import android.widget.Spinner; import android.widget.TextView; - +import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.Preferences; import org.solovyev.android.calculator.R; import org.solovyev.android.views.dragbutton.DirectionDragButton; import javax.annotation.Nonnull; -import static org.solovyev.android.calculator.CalculatorApplication.getPreferences; import static org.solovyev.android.calculator.wizard.CalculatorMode.engineer; import static org.solovyev.android.calculator.wizard.CalculatorMode.simple; -import static org.solovyev.android.views.dragbutton.DirectionDragButton.Direction.down; -import static org.solovyev.android.views.dragbutton.DirectionDragButton.Direction.left; -import static org.solovyev.android.views.dragbutton.DirectionDragButton.Direction.up; +import static org.solovyev.android.views.dragbutton.DirectionDragButton.Direction.*; -/** - * User: serso - * Date: 6/16/13 - * Time: 9:59 PM - */ public class ChooseModeWizardStep extends WizardFragment implements AdapterView.OnItemSelectedListener { private DirectionDragButton button; @@ -60,7 +52,7 @@ public class ChooseModeWizardStep extends WizardFragment implements AdapterView. public void onViewCreated(View root, Bundle savedInstanceState) { super.onViewCreated(root, savedInstanceState); - final CalculatorMode mode = CalculatorMode.fromGuiLayout(Preferences.Gui.layout.getPreference(getPreferences())); + final CalculatorMode mode = CalculatorMode.fromGuiLayout(Preferences.Gui.layout.getPreference(App.getPreferences())); final Spinner spinner = (Spinner) root.findViewById(R.id.wizard_mode_spinner); spinner.setAdapter(WizardArrayAdapter.create(getActivity(), R.array.cpp_modes)); spinner.setSelection(mode == simple ? 0 : 1); @@ -88,7 +80,7 @@ public class ChooseModeWizardStep extends WizardFragment implements AdapterView. @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { final CalculatorMode mode = position == 0 ? simple : engineer; - mode.apply(getPreferences()); + mode.apply(App.getPreferences()); updateDescription(mode); } diff --git a/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseThemeWizardStep.java b/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseThemeWizardStep.java index 326a7840..30c05e9e 100644 --- a/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseThemeWizardStep.java +++ b/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseThemeWizardStep.java @@ -30,17 +30,14 @@ import android.view.View; import android.widget.AdapterView; import android.widget.FrameLayout; import android.widget.Spinner; - +import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.Preferences; import org.solovyev.android.calculator.R; +import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.List; -import javax.annotation.Nonnull; - -import static org.solovyev.android.calculator.CalculatorApplication.getPreferences; - public class ChooseThemeWizardStep extends WizardFragment implements AdapterView.OnItemSelectedListener { @Nonnull @@ -57,7 +54,7 @@ public class ChooseThemeWizardStep extends WizardFragment implements AdapterView public void onViewCreated(View root, Bundle savedInstanceState) { super.onViewCreated(root, savedInstanceState); - final Preferences.Gui.Theme theme = Preferences.Gui.getTheme(getPreferences()); + final Preferences.Gui.Theme theme = Preferences.Gui.getTheme(App.getPreferences()); final Spinner spinner = (Spinner) root.findViewById(R.id.wizard_theme_spinner); themes.clear(); themes.add(new ThemeUi(Preferences.Gui.Theme.material_theme, R.string.p_material_theme)); @@ -86,14 +83,14 @@ public class ChooseThemeWizardStep extends WizardFragment implements AdapterView private void updateImage(@Nonnull Preferences.Gui.Theme theme) { preview.removeAllViews(); - final ContextThemeWrapper context = new ContextThemeWrapper(getActivity(), theme.getThemeId()); + final ContextThemeWrapper context = new ContextThemeWrapper(getActivity(), theme.theme); LayoutInflater.from(context).inflate(R.layout.cpp_wizard_step_choose_theme_preview, preview); } @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { final ThemeUi theme = adapter.getItem(position); - Preferences.Gui.theme.putPreference(getPreferences(), theme.theme); + Preferences.Gui.theme.putPreference(App.getPreferences(), theme.theme); updateImage(theme.theme); } diff --git a/app/src/main/java/org/solovyev/android/calculator/wizard/OnScreenCalculatorWizardStep.java b/app/src/main/java/org/solovyev/android/calculator/wizard/OnScreenCalculatorWizardStep.java index bdfb1598..264d873a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/wizard/OnScreenCalculatorWizardStep.java +++ b/app/src/main/java/org/solovyev/android/calculator/wizard/OnScreenCalculatorWizardStep.java @@ -34,7 +34,6 @@ import org.solovyev.android.calculator.R; import javax.annotation.Nullable; -import static org.solovyev.android.calculator.CalculatorApplication.getPreferences; public class OnScreenCalculatorWizardStep extends WizardFragment implements CompoundButton.OnCheckedChangeListener { @@ -50,7 +49,7 @@ public class OnScreenCalculatorWizardStep extends WizardFragment implements Comp public void onViewCreated(View root, Bundle savedInstanceState) { super.onViewCreated(root, savedInstanceState); - final Boolean enabled = Preferences.Onscreen.showAppIcon.getPreference(getPreferences()); + final Boolean enabled = Preferences.Onscreen.showAppIcon.getPreference(App.getPreferences()); checkbox = (CheckBox) root.findViewById(R.id.wizard_onscreen_app_enabled_checkbox); checkbox.setChecked(enabled); checkbox.setOnCheckedChangeListener(this); @@ -68,7 +67,7 @@ public class OnScreenCalculatorWizardStep extends WizardFragment implements Comp @Override public void onCheckedChanged(CompoundButton buttonView, boolean checked) { - Preferences.Onscreen.showAppIcon.putPreference(getPreferences(), checked); + Preferences.Onscreen.showAppIcon.putPreference(App.getPreferences(), checked); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/wizard/WizardActivity.java b/app/src/main/java/org/solovyev/android/calculator/wizard/WizardActivity.java index b886e6f0..8bd05fa6 100644 --- a/app/src/main/java/org/solovyev/android/calculator/wizard/WizardActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/wizard/WizardActivity.java @@ -8,22 +8,9 @@ import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.view.ViewPager; - import com.viewpagerindicator.PageIndicator; - -import org.solovyev.android.calculator.ActivityUi; -import org.solovyev.android.calculator.App; -import org.solovyev.android.calculator.BaseActivity; -import org.solovyev.android.calculator.CalculatorApplication; -import org.solovyev.android.calculator.Preferences; -import org.solovyev.android.calculator.R; -import org.solovyev.android.wizard.ListWizardFlow; -import org.solovyev.android.wizard.Wizard; -import org.solovyev.android.wizard.WizardFlow; -import org.solovyev.android.wizard.WizardStep; -import org.solovyev.android.wizard.WizardUi; -import org.solovyev.android.wizard.Wizards; -import org.solovyev.android.wizard.WizardsAware; +import org.solovyev.android.calculator.*; +import org.solovyev.android.wizard.*; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -38,7 +25,7 @@ public class WizardActivity extends BaseActivity implements WizardsAware, Shared @Nonnull private WizardPagerAdapter pagerAdapter; @Nonnull - private Wizards wizards = CalculatorApplication.getInstance().getWizards(); + private Wizards wizards = App.getWizards(); @Nullable private AlertDialog dialog; diff --git a/app/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java b/app/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java index 4fd1fffe..12a5a2a2 100644 --- a/app/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java @@ -140,24 +140,24 @@ public class HistoryUtilsTest { DisplayState calculatorDisplay = DisplayState.createError(JsclOperation.simplify, "Error"); - CalculatorEditorViewState calculatorEditor = EditorState.create("1+1", 3); + EditorState calculatorEditor = EditorState.create("1+1", 3); - HistoryState state = HistoryState.newInstance(calculatorEditor, calculatorDisplay); + HistoryState state = HistoryState.create(calculatorEditor, calculatorDisplay); state.setTime(date.getTime()); history.addState(state); - assertEquals(emptyHistory, HistoryUtils.toXml(history.getStates())); + assertEquals(emptyHistory, History.toXml(history.getStates())); state.setSaved(true); - assertEquals(toXml1, HistoryUtils.toXml(history.getStates())); + assertEquals(toXml1, History.toXml(history.getStates())); calculatorDisplay = DisplayState.createValid(JsclOperation.numeric, null, "5/6", 3); calculatorEditor = EditorState.create("5/6", 2); - state = HistoryState.newInstance(calculatorEditor, calculatorDisplay); + state = HistoryState.create(calculatorEditor, calculatorDisplay); state.setSaved(true); state.setTime(date.getTime()); history.addState(state); @@ -166,7 +166,7 @@ public class HistoryUtilsTest { calculatorEditor = EditorState.create("", 1); - state = HistoryState.newInstance(calculatorEditor, calculatorDisplay); + state = HistoryState.create(calculatorEditor, calculatorDisplay); state.setSaved(true); state.setTime(date.getTime()); history.addState(state); @@ -175,17 +175,17 @@ public class HistoryUtilsTest { calculatorEditor = EditorState.create("4+5/35sin(41)+dfdsfsdfs", 0); - state = HistoryState.newInstance(calculatorEditor, calculatorDisplay); + state = HistoryState.create(calculatorEditor, calculatorDisplay); state.setSaved(true); state.setTime(date.getTime()); history.addState(state); - String xml = HistoryUtils.toXml(history.getStates()); + String xml = History.toXml(history.getStates()); assertEquals(toXml2, xml); final List fromXml = new ArrayList(); final HistoryHelper historyFromXml = SimpleHistoryHelper.newInstance(); - HistoryUtils.fromXml(xml, fromXml); + History.fromXml(xml, fromXml); for (HistoryState historyState : fromXml) { historyFromXml.addState(historyState); }