diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d80ff689..20529517 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -13,9 +13,9 @@
+ a:name="org.solovyev.android.calculator.ApplicationContext">
-
@@ -25,71 +25,71 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/default.properties b/default.properties
deleted file mode 100644
index b74c4880..00000000
--- a/default.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "build.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=android-4
diff --git a/pom.xml b/pom.xml
index aae643d2..893eaf46 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
calculator
1.1.4
- pom
+ jar
${basedir}/src/misc/lib
@@ -80,7 +80,6 @@
${additionalLibs}/achartengine-0.7.0.jar
-
com.intellij
annotations
@@ -88,5 +87,4 @@
-
\ No newline at end of file
diff --git a/res/values-es/text_strings.xml b/res/values-es/text_strings.xml
index c33c5187..df9aad27 100644
--- a/res/values-es/text_strings.xml
+++ b/res/values-es/text_strings.xml
@@ -8,6 +8,7 @@
Calculadora++
+ Calculadora++ Free
Calc++
Configuración
Error
diff --git a/res/values-it/text_strings.xml b/res/values-it/text_strings.xml
index 3dd4d734..17415dc8 100644
--- a/res/values-it/text_strings.xml
+++ b/res/values-it/text_strings.xml
@@ -8,6 +8,7 @@
Calculator++
+ Calculator++ Free
Calc++
Impostazioni
Errore
diff --git a/res/values-ru/text_strings.xml b/res/values-ru/text_strings.xml
index 89db23c9..2df378bf 100644
--- a/res/values-ru/text_strings.xml
+++ b/res/values-ru/text_strings.xml
@@ -8,6 +8,7 @@
Калькулятор++
+ Калькулятор++ Free
Кальк++
Настройки
Ошибка
@@ -162,4 +163,7 @@
Устанавливает поведение по нажатию на кнопку Назад
Использовать кнопку назад как назад по истории
+ Внимание
+ Вы установили другую версию Калькулятора++.\nДля корректной работы приложения, пожалуйста, удалите предыдущую версию, все пользовательские данные будут автоматически перенесены в новое приложение.
+
\ No newline at end of file
diff --git a/res/values/text_strings.xml b/res/values/text_strings.xml
index cf9339ba..01fd64df 100644
--- a/res/values/text_strings.xml
+++ b/res/values/text_strings.xml
@@ -8,6 +8,7 @@
Calculator++
+ Calculator++ Free
Calc++
Settings
Error
@@ -162,4 +163,7 @@
Defines the behaviour of the Back button
Use Back button as history prev
+ Warning
+ It seems that you\'ve installed another version of Calculator++.\nFor correct work of the application please remove previous version, all user data will be automatically transferred to the new version.
+
\ No newline at end of file
diff --git a/src/main/java/org/solovyev/android/ResourceCache.java b/src/main/java/org/solovyev/android/ResourceCache.java
index dd3b82c6..09dc56b6 100644
--- a/src/main/java/org/solovyev/android/ResourceCache.java
+++ b/src/main/java/org/solovyev/android/ResourceCache.java
@@ -15,7 +15,6 @@ import android.view.View;
import android.widget.Button;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.solovyev.android.calculator.CalculatorActivity;
import org.solovyev.android.view.widgets.DragButton;
import java.lang.reflect.Field;
@@ -219,7 +218,7 @@ public enum ResourceCache {
try {
result.put(field.getName(), field.getInt(clazz));
} catch (IllegalAccessException e) {
- Log.e(CalculatorActivity.class.getName(), e.getMessage());
+ Log.e(ResourceCache.class.getName(), e.getMessage());
}
}
}
diff --git a/src/main/java/org/solovyev/android/calculator/AbstractCalculatorActivity.java b/src/main/java/org/solovyev/android/calculator/AbstractCalculatorActivity.java
new file mode 100644
index 00000000..297fe725
--- /dev/null
+++ b/src/main/java/org/solovyev/android/calculator/AbstractCalculatorActivity.java
@@ -0,0 +1,702 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ */
+
+package org.solovyev.android.calculator;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Vibrator;
+import android.preference.PreferenceManager;
+import android.text.ClipboardManager;
+import android.text.Html;
+import android.text.method.LinkMovementMethod;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.*;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+import jscl.AngleUnit;
+import jscl.NumeralBase;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.solovyev.android.AndroidUtils;
+import org.solovyev.android.ResourceCache;
+import org.solovyev.android.calculator.about.CalculatorReleaseNotesActivity;
+import org.solovyev.android.calculator.history.CalculatorHistory;
+import org.solovyev.android.calculator.history.CalculatorHistoryState;
+import org.solovyev.android.calculator.math.MathType;
+import org.solovyev.android.calculator.model.CalculatorEngine;
+import org.solovyev.android.view.FontSizeAdjuster;
+import org.solovyev.android.view.prefs.IntegerPreference;
+import org.solovyev.android.view.prefs.Preference;
+import org.solovyev.android.view.prefs.StringPreference;
+import org.solovyev.android.view.widgets.*;
+import org.solovyev.common.utils.Announcer;
+import org.solovyev.common.utils.Point2d;
+import org.solovyev.common.utils.StringUtils;
+import org.solovyev.common.utils.history.HistoryAction;
+
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+import java.util.Map;
+
+public abstract class AbstractCalculatorActivity extends Activity implements FontSizeAdjuster, SharedPreferences.OnSharedPreferenceChangeListener {
+
+ private static final int HVGA_WIDTH_PIXELS = 320;
+
+ public static class Preferences {
+ @NotNull
+ private static final String APP_TYPE_P_KEY = "application.type";
+ private static final ApplicationData.Type APP_TYPE_DEFAULT = null;
+ public static final Preference appType = StringPreference.newInstance(APP_TYPE_P_KEY, APP_TYPE_DEFAULT, ApplicationData.Type.class);
+
+
+ @NotNull
+ private static final String APP_VERSION_P_KEY = "application.version";
+ private static final int APP_VERSION_DEFAULT = -1;
+ public static final Preference appVersion = new IntegerPreference(APP_VERSION_P_KEY, APP_VERSION_DEFAULT);
+ }
+
+ @NotNull
+ public static final String SHOW_RELEASE_NOTES_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_show_release_notes";
+ public static final boolean SHOW_RELEASE_NOTES_P_DEFAULT = true;
+
+ @NotNull
+ public static final String USE_BACK_AS_PREV_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_use_back_button_as_prev";
+ public static final boolean USE_BACK_AS_PREV_DEFAULT = false;
+
+ @NotNull
+ private final Announcer dpclRegister = new Announcer(DragPreferencesChangeListener.class);
+
+ @NotNull
+ private CalculatorModel calculatorModel;
+
+ private volatile boolean initialized;
+
+ @NotNull
+ private String themeName;
+
+ @NotNull
+ private String layoutName;
+
+ @Nullable
+ private Vibrator vibrator;
+
+ private boolean useBackAsPrev = USE_BACK_AS_PREV_DEFAULT;
+
+ @NotNull
+ private final ApplicationData applicationData;
+
+ protected AbstractCalculatorActivity(@NotNull ApplicationData applicationData) {
+ this.applicationData = applicationData;
+ }
+
+ /**
+ * Called when the activity is first created.
+ */
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+
+ final boolean customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
+
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+
+ this.setTitle(this.applicationData.getApplicationTitle());
+
+ setDefaultValues(preferences);
+
+ setTheme(preferences);
+ super.onCreate(savedInstanceState);
+ setLayout(preferences);
+
+ if (customTitleSupported) {
+ try {
+ getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.calc_title);
+ final CalculatorAdditionalTitle additionalAdditionalTitleText = (CalculatorAdditionalTitle)findViewById(R.id.additional_title_text);
+ additionalAdditionalTitleText.init(preferences);
+ preferences.registerOnSharedPreferenceChangeListener(additionalAdditionalTitleText);
+ } catch (ClassCastException e) {
+ // super fix for issue with class cast in android.view.Window.setFeatureInt() (see app error reports)
+ Log.d(AbstractCalculatorActivity.class.getName(), e.getMessage(), e);
+ }
+ }
+
+ ResourceCache.instance.initCaptions(ApplicationContext.getInstance(), R.string.class);
+ firstTimeInit(preferences);
+
+ vibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
+
+ CalculatorHistory.instance.load(this, preferences);
+ calculatorModel = CalculatorModel.instance.init(this, preferences, CalculatorEngine.instance);
+
+ dpclRegister.clear();
+
+ final SimpleOnDragListener.Preferences dragPreferences = SimpleOnDragListener.getPreferences(preferences, this);
+
+ setOnDragListeners(dragPreferences, preferences);
+
+ final OnDragListener historyOnDragListener = new OnDragListenerVibrator(newOnDragListener(new HistoryDragProcessor(this.calculatorModel), dragPreferences), vibrator, preferences);
+ ((DragButton) findViewById(R.id.historyButton)).setOnDragListener(historyOnDragListener);
+
+ ((DragButton) findViewById(R.id.subtractionButton)).setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new SimpleOnDragListener.DragProcessor() {
+ @Override
+ public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
+ if (dragDirection == DragDirection.down) {
+ operatorsButtonClickHandler(dragButton);
+ return true;
+ }
+ return false;
+ }
+ }, dragPreferences), vibrator, preferences));
+
+
+ final OnDragListener toPositionOnDragListener = new OnDragListenerVibrator(new SimpleOnDragListener(new CursorDragProcessor(calculatorModel), dragPreferences), vibrator, preferences);
+ ((DragButton) findViewById(R.id.rightButton)).setOnDragListener(toPositionOnDragListener);
+ ((DragButton) findViewById(R.id.leftButton)).setOnDragListener(toPositionOnDragListener);
+
+ final DragButton equalsButton = (DragButton) findViewById(R.id.equalsButton);
+ if (equalsButton != null) {
+ equalsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new EvalDragProcessor(calculatorModel), dragPreferences), vibrator, preferences));
+ }
+
+ final AngleUnitsButton angleUnitsButton = (AngleUnitsButton) findViewById(R.id.sixDigitButton);
+ if (angleUnitsButton != null) {
+ angleUnitsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new AngleUnitsChanger(), dragPreferences), vibrator, preferences));
+ }
+
+ final NumeralBasesButton numeralBasesButton = (NumeralBasesButton) findViewById(R.id.clearButton);
+ if (numeralBasesButton != null) {
+ numeralBasesButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new NumeralBasesChanger(), dragPreferences), vibrator, preferences));
+ }
+
+ final DragButton varsButton = (DragButton) findViewById(R.id.varsButton);
+ if (varsButton != null) {
+ varsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new VarsDragProcessor(), dragPreferences), vibrator, preferences));
+ }
+
+ final DragButton roundBracketsButton = (DragButton) findViewById(R.id.roundBracketsButton);
+ if ( roundBracketsButton != null ) {
+ roundBracketsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new RoundBracketsDragProcessor(), dragPreferences), vibrator, preferences));
+ }
+
+
+ CalculatorEngine.instance.reset(this, preferences);
+
+ initMultiplicationButton();
+
+ preferences.registerOnSharedPreferenceChangeListener(this);
+ }
+
+ private class AngleUnitsChanger implements SimpleOnDragListener.DragProcessor {
+
+ private final DigitButtonDragProcessor processor = new DigitButtonDragProcessor(calculatorModel);
+
+ @Override
+ public boolean processDragEvent(@NotNull DragDirection dragDirection,
+ @NotNull DragButton dragButton,
+ @NotNull Point2d startPoint2d,
+ @NotNull MotionEvent motionEvent) {
+ boolean result = false;
+
+ if (dragButton instanceof AngleUnitsButton) {
+ if (dragDirection != DragDirection.left ) {
+ final String directionText = ((AngleUnitsButton) dragButton).getText(dragDirection);
+ if ( directionText != null ) {
+ try {
+
+ final AngleUnit angleUnits = AngleUnit.valueOf(directionText);
+
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(AbstractCalculatorActivity.this);
+
+ CalculatorEngine.Preferences.angleUnit.putPreference(preferences, angleUnits);
+
+ result = true;
+ } catch (IllegalArgumentException e) {
+ Log.d(this.getClass().getName(), "Unsupported angle units: " + directionText);
+ }
+ }
+ } else if ( dragDirection == DragDirection.left ) {
+ result = processor.processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent);
+ }
+ }
+
+ return result;
+ }
+ }
+
+ private class NumeralBasesChanger implements SimpleOnDragListener.DragProcessor {
+
+ @Override
+ public boolean processDragEvent(@NotNull DragDirection dragDirection,
+ @NotNull DragButton dragButton,
+ @NotNull Point2d startPoint2d,
+ @NotNull MotionEvent motionEvent) {
+ boolean result = false;
+
+ if ( dragButton instanceof NumeralBasesButton ) {
+ final String directionText = ((NumeralBasesButton) dragButton).getText(dragDirection);
+ if ( directionText != null ) {
+ try {
+
+ final NumeralBase numeralBase = NumeralBase.valueOf(directionText);
+
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(AbstractCalculatorActivity.this);
+ CalculatorEngine.Preferences.numeralBase.putPreference(preferences, numeralBase);
+
+ result = true;
+ } catch (IllegalArgumentException e) {
+ Log.d(this.getClass().getName(), "Unsupported numeral base: " + directionText);
+ }
+ }
+ }
+
+ return result;
+ }
+ }
+
+
+ private class VarsDragProcessor implements SimpleOnDragListener.DragProcessor {
+
+ @Override
+ public boolean processDragEvent(@NotNull DragDirection dragDirection,
+ @NotNull DragButton dragButton,
+ @NotNull Point2d startPoint2d,
+ @NotNull MotionEvent motionEvent) {
+ boolean result = false;
+
+ if (dragDirection == DragDirection.up) {
+ CalculatorActivityLauncher.createVar(AbstractCalculatorActivity.this, AbstractCalculatorActivity.this.calculatorModel);
+ result = true;
+ }
+
+ return result;
+ }
+ }
+
+ private void setDefaultValues(@NotNull SharedPreferences preferences) {
+ if (!preferences.contains(CalculatorEngine.Preferences.groupingSeparator.getKey())) {
+ final Locale locale = Locale.getDefault();
+ if (locale != null) {
+ final DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(locale);
+ int index = MathType.grouping_separator.getTokens().indexOf(String.valueOf(decimalFormatSymbols.getGroupingSeparator()));
+ final String groupingSeparator;
+ if (index >= 0) {
+ groupingSeparator = MathType.grouping_separator.getTokens().get(index);
+ } else {
+ groupingSeparator = " ";
+ }
+
+ CalculatorEngine.Preferences.groupingSeparator.putPreference(preferences, groupingSeparator);
+ }
+ }
+
+ if (!preferences.contains(CalculatorEngine.Preferences.angleUnit.getKey())) {
+ CalculatorEngine.Preferences.angleUnit.putDefault(preferences);
+ }
+
+ if (!preferences.contains(CalculatorEngine.Preferences.numeralBase.getKey())) {
+ CalculatorEngine.Preferences.numeralBase.putDefault(preferences);
+ }
+
+ }
+
+ private synchronized void setOnDragListeners(@NotNull SimpleOnDragListener.Preferences dragPreferences, @NotNull SharedPreferences preferences) {
+ final OnDragListener onDragListener = new OnDragListenerVibrator(newOnDragListener(new DigitButtonDragProcessor(calculatorModel), dragPreferences), vibrator, preferences);
+
+ for (Integer dragButtonId : ResourceCache.instance.getDragButtonIds()) {
+ ((DragButton) findViewById(dragButtonId)).setOnDragListener(onDragListener);
+ }
+ }
+
+ @NotNull
+ private SimpleOnDragListener newOnDragListener(@NotNull SimpleOnDragListener.DragProcessor dragProcessor,
+ @NotNull SimpleOnDragListener.Preferences dragPreferences) {
+ final SimpleOnDragListener onDragListener = new SimpleOnDragListener(dragProcessor, dragPreferences);
+ dpclRegister.addListener(onDragListener);
+ return onDragListener;
+ }
+
+ private class OnDragListenerVibrator extends OnDragListenerWrapper {
+
+ private static final float VIBRATION_TIME_SCALE = 0.5f;
+
+ @NotNull
+ private final VibratorContainer vibrator;
+
+ public OnDragListenerVibrator(@NotNull OnDragListener onDragListener,
+ @Nullable Vibrator vibrator,
+ @NotNull SharedPreferences preferences) {
+ super(onDragListener);
+ this.vibrator = new VibratorContainer(vibrator, preferences, VIBRATION_TIME_SCALE);
+ }
+
+ @Override
+ public boolean onDrag(@NotNull DragButton dragButton, @NotNull DragEvent event) {
+ boolean result = super.onDrag(dragButton, event);
+
+ if (result) {
+ vibrator.vibrate();
+ }
+
+ return result;
+ }
+ }
+
+
+ private synchronized void setLayout(@NotNull SharedPreferences preferences) {
+ final Map layouts = ResourceCache.instance.getNameToIdCache(R.layout.class);
+
+ layoutName = preferences.getString(getString(R.string.p_calc_layout_key), getString(R.string.p_calc_layout));
+
+ Integer layoutId = layouts.get(layoutName);
+ if (layoutId == null) {
+ Log.d(this.getClass().getName(), "No saved layout found => applying default layout: " + R.layout.main_calculator);
+ layoutId = R.layout.main_calculator;
+ } else {
+ Log.d(this.getClass().getName(), "Saved layout found: " + layoutId);
+ }
+
+ setContentView(layoutId);
+ }
+
+ private synchronized void setTheme(@NotNull SharedPreferences preferences) {
+ final Map styles = ResourceCache.instance.getNameToIdCache(R.style.class);
+
+ themeName = preferences.getString(getString(R.string.p_calc_theme_key), getString(R.string.p_calc_theme));
+
+ Integer styleId = styles.get(themeName);
+ if (styleId == null) {
+ Log.d(this.getClass().getName(), "No saved theme found => applying default theme: " + R.style.default_theme);
+ styleId = R.style.default_theme;
+ } else {
+ Log.d(this.getClass().getName(), "Saved theme found: " + styleId);
+ }
+
+ setTheme(styleId);
+ }
+
+ private synchronized void firstTimeInit(@NotNull SharedPreferences preferences) {
+ if (!initialized) {
+
+ final int savedVersion = Preferences.appVersion.getPreference(preferences);
+ final ApplicationData.Type savedAppType = Preferences.appType.getPreference(preferences);
+
+ final int appVersion = AndroidUtils.getAppVersionCode(this, AbstractCalculatorActivity.class.getPackage().getName());
+ final ApplicationData.Type appType = applicationData.getType();
+
+ Preferences.appVersion.putPreference(preferences, appVersion);
+ Preferences.appType.putPreference(preferences, appType);
+
+ if (savedVersion == Preferences.APP_VERSION_DEFAULT) {
+ // new start
+ final AlertDialog.Builder builder = new AlertDialog.Builder(this).setMessage(R.string.c_first_start_text);
+ builder.setPositiveButton(android.R.string.ok, null);
+ builder.setTitle(R.string.c_first_start_text_title);
+ builder.create().show();
+ } else {
+ if (savedVersion < appVersion) {
+ final boolean showReleaseNotes = preferences.getBoolean(SHOW_RELEASE_NOTES_P_KEY, SHOW_RELEASE_NOTES_P_DEFAULT);
+ if (showReleaseNotes) {
+ final String releaseNotes = CalculatorReleaseNotesActivity.getReleaseNotes(this, savedVersion + 1);
+ if (!StringUtils.isEmpty(releaseNotes)) {
+ final AlertDialog.Builder builder = new AlertDialog.Builder(this).setMessage(Html.fromHtml(releaseNotes));
+ builder.setPositiveButton(android.R.string.ok, null);
+ builder.setTitle(R.string.c_release_notes);
+ builder.create().show();
+ }
+ }
+ }
+ }
+
+ if (savedAppType != appType && savedAppType != null) {
+ // new start
+ final AlertDialog.Builder builder = new AlertDialog.Builder(this).setMessage(R.string.c_remove_prev_app_warning);
+ builder.setPositiveButton(android.R.string.ok, null);
+ builder.setTitle(R.string.c_warning);
+ builder.create().show();
+ }
+
+ ResourceCache.instance.init(R.id.class, this);
+ CalculatorEngine.instance.init(this, preferences);
+
+ initialized = true;
+ }
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void elementaryButtonClickHandler(@NotNull View v) {
+ throw new UnsupportedOperationException("Not implemented yet!");
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void numericButtonClickHandler(@NotNull View v) {
+ this.calculatorModel.evaluate();
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void historyButtonClickHandler(@NotNull View v) {
+ CalculatorActivityLauncher.showHistory(this);
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void eraseButtonClickHandler(@NotNull View v) {
+ calculatorModel.doTextOperation(new CalculatorModel.TextOperation() {
+ @Override
+ public void doOperation(@NotNull EditText editor) {
+ if (editor.getSelectionStart() > 0) {
+ editor.getText().delete(editor.getSelectionStart() - 1, editor.getSelectionStart());
+ }
+ }
+ });
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void simplifyButtonClickHandler(@NotNull View v) {
+ throw new UnsupportedOperationException("Not implemented yet!");
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void moveLeftButtonClickHandler(@NotNull View v) {
+ calculatorModel.moveCursorLeft();
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void moveRightButtonClickHandler(@NotNull View v) {
+ calculatorModel.moveCursorRight();
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void pasteButtonClickHandler(@NotNull View v) {
+ calculatorModel.doTextOperation(new CalculatorModel.TextOperation() {
+ @Override
+ public void doOperation(@NotNull EditText editor) {
+ final ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ if (clipboard.hasText()) {
+ editor.getText().insert(editor.getSelectionStart(), clipboard.getText());
+ }
+ }
+ });
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void copyButtonClickHandler(@NotNull View v) {
+ calculatorModel.copyResult(this);
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void clearButtonClickHandler(@NotNull View v) {
+ calculatorModel.clear();
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void digitButtonClickHandler(@NotNull View v) {
+ Log.d(String.valueOf(v.getId()), "digitButtonClickHandler() for: " + v.getId() + ". Pressed: " + v.isPressed());
+ calculatorModel.processDigitButtonAction(((DirectionDragButton) v).getText().toString());
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void functionsButtonClickHandler(@NotNull View v) {
+ CalculatorActivityLauncher.showFunctions(this);
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void operatorsButtonClickHandler(@NotNull View v) {
+ CalculatorActivityLauncher.showOperators(this);
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void varsButtonClickHandler(@NotNull View v) {
+ CalculatorActivityLauncher.showVars(this);
+ }
+
+ private final static String paypalDonateUrl = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=se%2esolovyev%40gmail%2ecom&lc=RU&item_name=Android%20Calculator¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted";
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void donateButtonClickHandler(@NotNull View v) {
+ final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
+ final View view = layoutInflater.inflate(R.layout.donate, null);
+
+ final TextView donate = (TextView) view.findViewById(R.id.donateText);
+ donate.setMovementMethod(LinkMovementMethod.getInstance());
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder(this)
+ .setCancelable(true)
+ .setNegativeButton(R.string.c_cancel, null)
+ .setPositiveButton(R.string.c_donate, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ final Intent i = new Intent(Intent.ACTION_VIEW);
+ i.setData(Uri.parse(paypalDonateUrl));
+ startActivity(i);
+ }
+ })
+ .setView(view);
+
+ builder.create().show();
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ if (useBackAsPrev) {
+ calculatorModel.doHistoryAction(HistoryAction.undo);
+ return true;
+ }
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ final MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.main_menu, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ boolean result;
+
+ switch (item.getItemId()) {
+ case R.id.main_menu_item_settings:
+ CalculatorActivityLauncher.showSettings(this);
+ result = true;
+ break;
+ case R.id.main_menu_item_history:
+ CalculatorActivityLauncher.showHistory(this);
+ result = true;
+ break;
+ case R.id.main_menu_item_about:
+ CalculatorActivityLauncher.showAbout(this);
+ result = true;
+ break;
+ case R.id.main_menu_item_help:
+ CalculatorActivityLauncher.showHelp(this);
+ result = true;
+ break;
+ case R.id.main_menu_item_exit:
+ this.finish();
+ result = true;
+ break;
+ default:
+ result = super.onOptionsItemSelected(item);
+ }
+
+ return result;
+ }
+
+ /**
+ * The font sizes in the layout files are specified for a HVGA display.
+ * Adjust the font sizes accordingly if we are running on a different
+ * display.
+ */
+ @Override
+ public void adjustFontSize(@NotNull TextView view) {
+ float fontPixelSize = view.getTextSize();
+ Display display = getWindowManager().getDefaultDisplay();
+ int h = Math.min(display.getWidth(), display.getHeight());
+ float ratio = (float) h / HVGA_WIDTH_PIXELS;
+ view.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontPixelSize * ratio);
+ }
+
+ public void restart() {
+ final Intent intent = getIntent();
+ /*
+ for compatibility with android_1.6_compatibility
+ overridePendingTransition(0, 0);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);*/
+
+ Log.d(this.getClass().getName(), "Finishing current activity!");
+ finish();
+
+ /*
+ for compatibility with android_1.6_compatibility
+
+ overridePendingTransition(0, 0);*/
+ Log.d(this.getClass().getName(), "Starting new activity!");
+ startActivity(intent);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+
+ final String newLayoutName = preferences.getString(getString(R.string.p_calc_layout_key), getString(R.string.p_calc_layout));
+ final String newThemeName = preferences.getString(getString(R.string.p_calc_theme_key), getString(R.string.p_calc_theme));
+ if (!themeName.equals(newThemeName) || !layoutName.equals(newLayoutName)) {
+ restart();
+ }
+
+ calculatorModel = CalculatorModel.instance.init(this, preferences, CalculatorEngine.instance);
+ calculatorModel.evaluate(calculatorModel.getDisplay().getJsclOperation());
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences preferences, @Nullable String key) {
+ if (key != null && key.startsWith("org.solovyev.android.calculator.DragButtonCalibrationActivity")) {
+ dpclRegister.announce().onDragPreferencesChange(SimpleOnDragListener.getPreferences(preferences, this));
+ }
+
+ if (CalculatorEngine.Preferences.getPreferenceKeys().contains(key)) {
+ CalculatorEngine.instance.reset(this, preferences);
+ this.calculatorModel.evaluate();
+ }
+
+ if ( USE_BACK_AS_PREV_P_KEY.equals(key) ) {
+ useBackAsPrev = preferences.getBoolean(USE_BACK_AS_PREV_P_KEY, USE_BACK_AS_PREV_DEFAULT);
+ }
+
+ if ( CalculatorEngine.Preferences.multiplicationSign.getKey().equals(key) ) {
+ initMultiplicationButton();
+ }
+ }
+
+ private void initMultiplicationButton() {
+ final View multiplicationButton = findViewById(R.id.multiplicationButton);
+ if ( multiplicationButton instanceof Button) {
+ ((Button) multiplicationButton).setText(CalculatorEngine.instance.getMultiplicationSign());
+ }
+ }
+
+ private static class RoundBracketsDragProcessor implements SimpleOnDragListener.DragProcessor {
+ @Override
+ public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
+ boolean result = false;
+ if ( dragDirection == DragDirection.left ) {
+ CalculatorModel.instance.doTextOperation(new CalculatorModel.TextOperation() {
+ @Override
+ public void doOperation(@NotNull EditText editor) {
+ final int cursorPosition = editor.getSelectionStart();
+ final StringBuilder text = new StringBuilder("(");
+ final String oldText = editor.getText().toString();
+ text.append(oldText.substring(0, cursorPosition));
+ text.append(")");
+ text.append(oldText.substring(cursorPosition));
+ editor.setText(text);
+ editor.setSelection(cursorPosition + 2);
+ }
+ });
+ result = true;
+ } else {
+ result = new DigitButtonDragProcessor(CalculatorModel.instance).processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent);
+ }
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/solovyev/android/calculator/ApplicationData.java b/src/main/java/org/solovyev/android/calculator/ApplicationData.java
new file mode 100644
index 00000000..afe2de29
--- /dev/null
+++ b/src/main/java/org/solovyev/android/calculator/ApplicationData.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2009-2012. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.android.calculator;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: serso
+ * Date: 1/2/12
+ * Time: 9:08 PM
+ */
+public interface ApplicationData {
+
+ public static enum Type {
+ free,
+ pro
+ }
+
+ boolean isFree();
+
+ boolean isShowAd();
+
+ int getApplicationTitle();
+
+ @NotNull
+ Type getType();
+
+}
diff --git a/src/main/java/org/solovyev/android/calculator/ApplicationDataImpl.java b/src/main/java/org/solovyev/android/calculator/ApplicationDataImpl.java
new file mode 100644
index 00000000..a1f04fe2
--- /dev/null
+++ b/src/main/java/org/solovyev/android/calculator/ApplicationDataImpl.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2009-2012. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.android.calculator;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: serso
+ * Date: 1/2/12
+ * Time: 9:32 PM
+ */
+public class ApplicationDataImpl implements ApplicationData {
+
+ private final boolean free;
+
+ private final int applicationTitle;
+
+ @NotNull
+ private final Type type;
+
+ public ApplicationDataImpl(boolean free, int applicationTitle, @NotNull Type type) {
+ this.free = free;
+ this.applicationTitle = applicationTitle;
+ this.type = type;
+ }
+
+ @Override
+ public boolean isFree() {
+ return this.free;
+ }
+
+ @Override
+ public boolean isShowAd() {
+ return this.free;
+ }
+
+ @Override
+ public int getApplicationTitle() {
+ return this.applicationTitle;
+ }
+
+ @Override
+ @NotNull
+ public Type getType() {
+ return type;
+ }
+}
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java
index 454c167c..e38bb76c 100644
--- a/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java
@@ -1,672 +1,26 @@
/*
- * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * Copyright (c) 2009-2012. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Vibrator;
-import android.preference.PreferenceManager;
-import android.text.ClipboardManager;
-import android.text.Html;
-import android.text.method.LinkMovementMethod;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.*;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-import jscl.AngleUnit;
-import jscl.NumeralBase;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.solovyev.android.AndroidUtils;
-import org.solovyev.android.ResourceCache;
-import org.solovyev.android.calculator.about.CalculatorReleaseNotesActivity;
-import org.solovyev.android.calculator.history.CalculatorHistory;
-import org.solovyev.android.calculator.history.CalculatorHistoryState;
-import org.solovyev.android.calculator.math.MathType;
-import org.solovyev.android.calculator.model.CalculatorEngine;
-import org.solovyev.android.view.FontSizeAdjuster;
-import org.solovyev.android.view.widgets.*;
-import org.solovyev.android.view.widgets.DragEvent;
-import org.solovyev.common.utils.Announcer;
-import org.solovyev.common.utils.Point2d;
-import org.solovyev.common.utils.StringUtils;
-import org.solovyev.common.utils.history.HistoryAction;
-import java.text.DecimalFormatSymbols;
-import java.util.Locale;
-import java.util.Map;
+/**
+ * User: serso
+ * Date: 1/2/12
+ * Time: 9:33 PM
+ */
+public class CalculatorActivity extends AbstractCalculatorActivity {
-public class CalculatorActivity extends Activity implements FontSizeAdjuster, SharedPreferences.OnSharedPreferenceChangeListener {
-
- private static final int HVGA_WIDTH_PIXELS = 320;
-
- @NotNull
- public static final String APP_VERSION_P_KEY = "application.version";
-
- @NotNull
- public static final String SHOW_RELEASE_NOTES_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_show_release_notes";
- public static final boolean SHOW_RELEASE_NOTES_P_DEFAULT = true;
-
- @NotNull
- public static final String USE_BACK_AS_PREV_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_use_back_button_as_prev";
- public static final boolean USE_BACK_AS_PREV_DEFAULT = false;
-
- @NotNull
- private final Announcer dpclRegister = new Announcer(DragPreferencesChangeListener.class);
-
- @NotNull
- private CalculatorModel calculatorModel;
-
- private volatile boolean initialized;
-
- @NotNull
- private String themeName;
-
- @NotNull
- private String layoutName;
-
- @Nullable
- private Vibrator vibrator;
-
- private boolean useBackAsPrev = USE_BACK_AS_PREV_DEFAULT;
-
- /**
- * Called when the activity is first created.
- */
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- Log.d(this.getClass().getName(), "org.solovyev.android.calculator.CalculatorActivity.onCreate()");
-
- final boolean customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
-
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
-
- setDefaultValues(preferences);
-
- setTheme(preferences);
- super.onCreate(savedInstanceState);
- setLayout(preferences);
-
- if (customTitleSupported) {
- try {
- getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.calc_title);
- final CalculatorAdditionalTitle additionalAdditionalTitleText = (CalculatorAdditionalTitle)findViewById(R.id.additional_title_text);
- additionalAdditionalTitleText.init(preferences);
- preferences.registerOnSharedPreferenceChangeListener(additionalAdditionalTitleText);
- } catch (ClassCastException e) {
- // super fix for issue with class cast in android.view.Window.setFeatureInt() (see app error reports)
- Log.d(CalculatorActivity.class.getName(), e.getMessage(), e);
- }
- }
-
- ResourceCache.instance.initCaptions(ApplicationContext.getInstance(), R.string.class);
- firstTimeInit(preferences);
-
- vibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
-
- CalculatorHistory.instance.load(this, preferences);
- calculatorModel = CalculatorModel.instance.init(this, preferences, CalculatorEngine.instance);
-
- dpclRegister.clear();
-
- final SimpleOnDragListener.Preferences dragPreferences = SimpleOnDragListener.getPreferences(preferences, this);
-
- setOnDragListeners(dragPreferences, preferences);
-
- final OnDragListener historyOnDragListener = new OnDragListenerVibrator(newOnDragListener(new HistoryDragProcessor(this.calculatorModel), dragPreferences), vibrator, preferences);
- ((DragButton) findViewById(R.id.historyButton)).setOnDragListener(historyOnDragListener);
-
- ((DragButton) findViewById(R.id.subtractionButton)).setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new SimpleOnDragListener.DragProcessor() {
- @Override
- public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
- if (dragDirection == DragDirection.down) {
- operatorsButtonClickHandler(dragButton);
- return true;
- }
- return false;
- }
- }, dragPreferences), vibrator, preferences));
-
-
- final OnDragListener toPositionOnDragListener = new OnDragListenerVibrator(new SimpleOnDragListener(new CursorDragProcessor(calculatorModel), dragPreferences), vibrator, preferences);
- ((DragButton) findViewById(R.id.rightButton)).setOnDragListener(toPositionOnDragListener);
- ((DragButton) findViewById(R.id.leftButton)).setOnDragListener(toPositionOnDragListener);
-
- final DragButton equalsButton = (DragButton) findViewById(R.id.equalsButton);
- if (equalsButton != null) {
- equalsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new EvalDragProcessor(calculatorModel), dragPreferences), vibrator, preferences));
- }
-
- final AngleUnitsButton angleUnitsButton = (AngleUnitsButton) findViewById(R.id.sixDigitButton);
- if (angleUnitsButton != null) {
- angleUnitsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new AngleUnitsChanger(), dragPreferences), vibrator, preferences));
- }
-
- final NumeralBasesButton numeralBasesButton = (NumeralBasesButton) findViewById(R.id.clearButton);
- if (numeralBasesButton != null) {
- numeralBasesButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new NumeralBasesChanger(), dragPreferences), vibrator, preferences));
- }
-
- final DragButton varsButton = (DragButton) findViewById(R.id.varsButton);
- if (varsButton != null) {
- varsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new VarsDragProcessor(), dragPreferences), vibrator, preferences));
- }
-
- final DragButton roundBracketsButton = (DragButton) findViewById(R.id.roundBracketsButton);
- if ( roundBracketsButton != null ) {
- roundBracketsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new RoundBracketsDragProcessor(), dragPreferences), vibrator, preferences));
- }
-
-
- CalculatorEngine.instance.reset(this, preferences);
-
- initMultiplicationButton();
-
- preferences.registerOnSharedPreferenceChangeListener(this);
- }
-
- private class AngleUnitsChanger implements SimpleOnDragListener.DragProcessor {
-
- private final DigitButtonDragProcessor processor = new DigitButtonDragProcessor(calculatorModel);
-
- @Override
- public boolean processDragEvent(@NotNull DragDirection dragDirection,
- @NotNull DragButton dragButton,
- @NotNull Point2d startPoint2d,
- @NotNull MotionEvent motionEvent) {
- boolean result = false;
-
- if (dragButton instanceof AngleUnitsButton) {
- if (dragDirection != DragDirection.left ) {
- final String directionText = ((AngleUnitsButton) dragButton).getText(dragDirection);
- if ( directionText != null ) {
- try {
-
- final AngleUnit angleUnits = AngleUnit.valueOf(directionText);
-
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(CalculatorActivity.this);
-
- CalculatorEngine.Preferences.angleUnit.putPreference(preferences, angleUnits);
-
- result = true;
- } catch (IllegalArgumentException e) {
- Log.d(this.getClass().getName(), "Unsupported angle units: " + directionText);
- }
- }
- } else if ( dragDirection == DragDirection.left ) {
- result = processor.processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent);
- }
- }
-
- return result;
- }
- }
-
- private class NumeralBasesChanger implements SimpleOnDragListener.DragProcessor {
-
- @Override
- public boolean processDragEvent(@NotNull DragDirection dragDirection,
- @NotNull DragButton dragButton,
- @NotNull Point2d startPoint2d,
- @NotNull MotionEvent motionEvent) {
- boolean result = false;
-
- if ( dragButton instanceof NumeralBasesButton ) {
- final String directionText = ((NumeralBasesButton) dragButton).getText(dragDirection);
- if ( directionText != null ) {
- try {
-
- final NumeralBase numeralBase = NumeralBase.valueOf(directionText);
-
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(CalculatorActivity.this);
- CalculatorEngine.Preferences.numeralBase.putPreference(preferences, numeralBase);
-
- result = true;
- } catch (IllegalArgumentException e) {
- Log.d(this.getClass().getName(), "Unsupported numeral base: " + directionText);
- }
- }
- }
-
- return result;
- }
- }
-
-
- private class VarsDragProcessor implements SimpleOnDragListener.DragProcessor {
-
- @Override
- public boolean processDragEvent(@NotNull DragDirection dragDirection,
- @NotNull DragButton dragButton,
- @NotNull Point2d startPoint2d,
- @NotNull MotionEvent motionEvent) {
- boolean result = false;
-
- if (dragDirection == DragDirection.up) {
- CalculatorActivityLauncher.createVar(CalculatorActivity.this, CalculatorActivity.this.calculatorModel);
- result = true;
- }
-
- return result;
- }
- }
-
- private void setDefaultValues(@NotNull SharedPreferences preferences) {
- if (!preferences.contains(CalculatorEngine.Preferences.groupingSeparator.getKey())) {
- final Locale locale = Locale.getDefault();
- if (locale != null) {
- final DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(locale);
- int index = MathType.grouping_separator.getTokens().indexOf(String.valueOf(decimalFormatSymbols.getGroupingSeparator()));
- final String groupingSeparator;
- if (index >= 0) {
- groupingSeparator = MathType.grouping_separator.getTokens().get(index);
- } else {
- groupingSeparator = " ";
- }
-
- CalculatorEngine.Preferences.groupingSeparator.putPreference(preferences, groupingSeparator);
- }
- }
-
- if (!preferences.contains(CalculatorEngine.Preferences.angleUnit.getKey())) {
- CalculatorEngine.Preferences.angleUnit.putDefault(preferences);
- }
-
- if (!preferences.contains(CalculatorEngine.Preferences.numeralBase.getKey())) {
- CalculatorEngine.Preferences.numeralBase.putDefault(preferences);
- }
-
- }
-
- private synchronized void setOnDragListeners(@NotNull SimpleOnDragListener.Preferences dragPreferences, @NotNull SharedPreferences preferences) {
- final OnDragListener onDragListener = new OnDragListenerVibrator(newOnDragListener(new DigitButtonDragProcessor(calculatorModel), dragPreferences), vibrator, preferences);
-
- for (Integer dragButtonId : ResourceCache.instance.getDragButtonIds()) {
- ((DragButton) findViewById(dragButtonId)).setOnDragListener(onDragListener);
- }
+ public CalculatorActivity() {
+ super(createApplicationData());
}
@NotNull
- private SimpleOnDragListener newOnDragListener(@NotNull SimpleOnDragListener.DragProcessor dragProcessor,
- @NotNull SimpleOnDragListener.Preferences dragPreferences) {
- final SimpleOnDragListener onDragListener = new SimpleOnDragListener(dragProcessor, dragPreferences);
- dpclRegister.addListener(onDragListener);
- return onDragListener;
+ private static ApplicationData createApplicationData() {
+ return new ApplicationDataImpl(false, R.string.c_app_name, ApplicationData.Type.pro);
}
-
- private class OnDragListenerVibrator extends OnDragListenerWrapper {
-
- private static final float VIBRATION_TIME_SCALE = 0.5f;
-
- @NotNull
- private final VibratorContainer vibrator;
-
- public OnDragListenerVibrator(@NotNull OnDragListener onDragListener,
- @Nullable Vibrator vibrator,
- @NotNull SharedPreferences preferences) {
- super(onDragListener);
- this.vibrator = new VibratorContainer(vibrator, preferences, VIBRATION_TIME_SCALE);
- }
-
- @Override
- public boolean onDrag(@NotNull DragButton dragButton, @NotNull DragEvent event) {
- boolean result = super.onDrag(dragButton, event);
-
- if (result) {
- vibrator.vibrate();
- }
-
- return result;
- }
- }
-
-
- private synchronized void setLayout(@NotNull SharedPreferences preferences) {
- final Map layouts = ResourceCache.instance.getNameToIdCache(R.layout.class);
-
- layoutName = preferences.getString(getString(R.string.p_calc_layout_key), getString(R.string.p_calc_layout));
-
- Integer layoutId = layouts.get(layoutName);
- if (layoutId == null) {
- Log.d(this.getClass().getName(), "No saved layout found => applying default layout: " + R.layout.main_calculator);
- layoutId = R.layout.main_calculator;
- } else {
- Log.d(this.getClass().getName(), "Saved layout found: " + layoutId);
- }
-
- setContentView(layoutId);
- }
-
- private synchronized void setTheme(@NotNull SharedPreferences preferences) {
- final Map styles = ResourceCache.instance.getNameToIdCache(R.style.class);
-
- themeName = preferences.getString(getString(R.string.p_calc_theme_key), getString(R.string.p_calc_theme));
-
- Integer styleId = styles.get(themeName);
- if (styleId == null) {
- Log.d(this.getClass().getName(), "No saved theme found => applying default theme: " + R.style.default_theme);
- styleId = R.style.default_theme;
- } else {
- Log.d(this.getClass().getName(), "Saved theme found: " + styleId);
- }
-
- setTheme(styleId);
- }
-
- private synchronized void firstTimeInit(@NotNull SharedPreferences preferences) {
- if (!initialized) {
-
- final int savedVersion = preferences.getInt(APP_VERSION_P_KEY, -1);
- final int appVersion = AndroidUtils.getAppVersionCode(this, CalculatorActivity.class.getPackage().getName());
-
- final SharedPreferences.Editor pEditor = preferences.edit();
- pEditor.putInt(APP_VERSION_P_KEY, appVersion);
- pEditor.commit();
-
- if (savedVersion == -1) {
- // new start
- final AlertDialog.Builder builder = new AlertDialog.Builder(this).setMessage(R.string.c_first_start_text);
- builder.setPositiveButton(android.R.string.ok, null);
- builder.setTitle(R.string.c_first_start_text_title);
- builder.create().show();
- } else {
- if (savedVersion < appVersion) {
- final boolean showReleaseNotes = preferences.getBoolean(SHOW_RELEASE_NOTES_P_KEY, SHOW_RELEASE_NOTES_P_DEFAULT);
- if (showReleaseNotes) {
- final String releaseNotes = CalculatorReleaseNotesActivity.getReleaseNotes(this, savedVersion + 1);
- if (!StringUtils.isEmpty(releaseNotes)) {
- final AlertDialog.Builder builder = new AlertDialog.Builder(this).setMessage(Html.fromHtml(releaseNotes));
- builder.setPositiveButton(android.R.string.ok, null);
- builder.setTitle(R.string.c_release_notes);
- builder.create().show();
- }
- }
- }
- }
-
- ResourceCache.instance.init(R.id.class, this);
- CalculatorEngine.instance.init(this, preferences);
-
- initialized = true;
- }
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void elementaryButtonClickHandler(@NotNull View v) {
- throw new UnsupportedOperationException("Not implemented yet!");
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void numericButtonClickHandler(@NotNull View v) {
- this.calculatorModel.evaluate();
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void historyButtonClickHandler(@NotNull View v) {
- CalculatorActivityLauncher.showHistory(this);
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void eraseButtonClickHandler(@NotNull View v) {
- calculatorModel.doTextOperation(new CalculatorModel.TextOperation() {
- @Override
- public void doOperation(@NotNull EditText editor) {
- if (editor.getSelectionStart() > 0) {
- editor.getText().delete(editor.getSelectionStart() - 1, editor.getSelectionStart());
- }
- }
- });
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void simplifyButtonClickHandler(@NotNull View v) {
- throw new UnsupportedOperationException("Not implemented yet!");
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void moveLeftButtonClickHandler(@NotNull View v) {
- calculatorModel.moveCursorLeft();
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void moveRightButtonClickHandler(@NotNull View v) {
- calculatorModel.moveCursorRight();
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void pasteButtonClickHandler(@NotNull View v) {
- calculatorModel.doTextOperation(new CalculatorModel.TextOperation() {
- @Override
- public void doOperation(@NotNull EditText editor) {
- final ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
- if (clipboard.hasText()) {
- editor.getText().insert(editor.getSelectionStart(), clipboard.getText());
- }
- }
- });
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void copyButtonClickHandler(@NotNull View v) {
- calculatorModel.copyResult(this);
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void clearButtonClickHandler(@NotNull View v) {
- calculatorModel.clear();
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void digitButtonClickHandler(@NotNull View v) {
- Log.d(String.valueOf(v.getId()), "digitButtonClickHandler() for: " + v.getId() + ". Pressed: " + v.isPressed());
- calculatorModel.processDigitButtonAction(((DirectionDragButton) v).getText().toString());
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void functionsButtonClickHandler(@NotNull View v) {
- CalculatorActivityLauncher.showFunctions(this);
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void operatorsButtonClickHandler(@NotNull View v) {
- CalculatorActivityLauncher.showOperators(this);
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void varsButtonClickHandler(@NotNull View v) {
- CalculatorActivityLauncher.showVars(this);
- }
-
- private final static String paypalDonateUrl = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=se%2esolovyev%40gmail%2ecom&lc=RU&item_name=Android%20Calculator¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted";
-
- @SuppressWarnings({"UnusedDeclaration"})
- public void donateButtonClickHandler(@NotNull View v) {
- final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
- final View view = layoutInflater.inflate(R.layout.donate, null);
-
- final TextView donate = (TextView) view.findViewById(R.id.donateText);
- donate.setMovementMethod(LinkMovementMethod.getInstance());
-
- final AlertDialog.Builder builder = new AlertDialog.Builder(this)
- .setCancelable(true)
- .setNegativeButton(R.string.c_cancel, null)
- .setPositiveButton(R.string.c_donate, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final Intent i = new Intent(Intent.ACTION_VIEW);
- i.setData(Uri.parse(paypalDonateUrl));
- startActivity(i);
- }
- })
- .setView(view);
-
- builder.create().show();
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- if (useBackAsPrev) {
- calculatorModel.doHistoryAction(HistoryAction.undo);
- return true;
- }
- }
- return super.onKeyDown(keyCode, event);
- }
-
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- final MenuInflater menuInflater = getMenuInflater();
- menuInflater.inflate(R.menu.main_menu, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- boolean result;
-
- switch (item.getItemId()) {
- case R.id.main_menu_item_settings:
- CalculatorActivityLauncher.showSettings(this);
- result = true;
- break;
- case R.id.main_menu_item_history:
- CalculatorActivityLauncher.showHistory(this);
- result = true;
- break;
- case R.id.main_menu_item_about:
- CalculatorActivityLauncher.showAbout(this);
- result = true;
- break;
- case R.id.main_menu_item_help:
- CalculatorActivityLauncher.showHelp(this);
- result = true;
- break;
- case R.id.main_menu_item_exit:
- this.finish();
- result = true;
- break;
- default:
- result = super.onOptionsItemSelected(item);
- }
-
- return result;
- }
-
- /**
- * The font sizes in the layout files are specified for a HVGA display.
- * Adjust the font sizes accordingly if we are running on a different
- * display.
- */
- @Override
- public void adjustFontSize(@NotNull TextView view) {
- float fontPixelSize = view.getTextSize();
- Display display = getWindowManager().getDefaultDisplay();
- int h = Math.min(display.getWidth(), display.getHeight());
- float ratio = (float) h / HVGA_WIDTH_PIXELS;
- view.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontPixelSize * ratio);
- }
-
- public void restart() {
- final Intent intent = getIntent();
- /*
- for compatibility with android_1.6_compatibility
- overridePendingTransition(0, 0);
- intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);*/
-
- Log.d(this.getClass().getName(), "Finishing current activity!");
- finish();
-
- /*
- for compatibility with android_1.6_compatibility
-
- overridePendingTransition(0, 0);*/
- Log.d(this.getClass().getName(), "Starting new activity!");
- startActivity(intent);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
-
- final String newLayoutName = preferences.getString(getString(R.string.p_calc_layout_key), getString(R.string.p_calc_layout));
- final String newThemeName = preferences.getString(getString(R.string.p_calc_theme_key), getString(R.string.p_calc_theme));
- if (!themeName.equals(newThemeName) || !layoutName.equals(newLayoutName)) {
- restart();
- }
-
- calculatorModel = CalculatorModel.instance.init(this, preferences, CalculatorEngine.instance);
- calculatorModel.evaluate(calculatorModel.getDisplay().getJsclOperation());
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences preferences, @Nullable String key) {
- if (key != null && key.startsWith("org.solovyev.android.calculator.DragButtonCalibrationActivity")) {
- dpclRegister.announce().onDragPreferencesChange(SimpleOnDragListener.getPreferences(preferences, this));
- }
-
- if (CalculatorEngine.Preferences.getPreferenceKeys().contains(key)) {
- CalculatorEngine.instance.reset(this, preferences);
- this.calculatorModel.evaluate();
- }
-
- if ( USE_BACK_AS_PREV_P_KEY.equals(key) ) {
- useBackAsPrev = preferences.getBoolean(USE_BACK_AS_PREV_P_KEY, USE_BACK_AS_PREV_DEFAULT);
- }
-
- if ( CalculatorEngine.Preferences.multiplicationSign.getKey().equals(key) ) {
- initMultiplicationButton();
- }
- }
-
- private void initMultiplicationButton() {
- final View multiplicationButton = findViewById(R.id.multiplicationButton);
- if ( multiplicationButton instanceof Button) {
- ((Button) multiplicationButton).setText(CalculatorEngine.instance.getMultiplicationSign());
- }
- }
-
- private static class RoundBracketsDragProcessor implements SimpleOnDragListener.DragProcessor {
- @Override
- public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
- boolean result = false;
- if ( dragDirection == DragDirection.left ) {
- CalculatorModel.instance.doTextOperation(new CalculatorModel.TextOperation() {
- @Override
- public void doOperation(@NotNull EditText editor) {
- final int cursorPosition = editor.getSelectionStart();
- final StringBuilder text = new StringBuilder("(");
- final String oldText = editor.getText().toString();
- text.append(oldText.substring(0, cursorPosition));
- text.append(")");
- text.append(oldText.substring(cursorPosition));
- editor.setText(text);
- editor.setSelection(cursorPosition + 2);
- }
- });
- result = true;
- } else {
- result = new DigitButtonDragProcessor(CalculatorModel.instance).processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent);
- }
- return result;
- }
- }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorActivityFree.java b/src/main/java/org/solovyev/android/calculator/CalculatorActivityFree.java
new file mode 100644
index 00000000..1c13ffc8
--- /dev/null
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorActivityFree.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2009-2012. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.android.calculator;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: serso
+ * Date: 1/2/12
+ * Time: 9:32 PM
+ */
+public class CalculatorActivityFree extends AbstractCalculatorActivity {
+
+ public CalculatorActivityFree() {
+ super(createApplicationData());
+ }
+
+ @NotNull
+ private static ApplicationData createApplicationData() {
+ return new ApplicationDataImpl(true, R.string.c_app_name_free, ApplicationData.Type.free);
+ }
+}
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorModel.java b/src/main/java/org/solovyev/android/calculator/CalculatorModel.java
index 9ce3515b..e5c4f80b 100644
--- a/src/main/java/org/solovyev/android/calculator/CalculatorModel.java
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorModel.java
@@ -280,7 +280,6 @@ public enum CalculatorModel implements CursorControl, HistoryControl= minVersion; i-- ) {
diff --git a/src/main/java/org/solovyev/android/calculator/help/CalculatorHelpTabActivity.java b/src/main/java/org/solovyev/android/calculator/help/CalculatorHelpTabActivity.java
index 566aa6d1..ac2ad236 100644
--- a/src/main/java/org/solovyev/android/calculator/help/CalculatorHelpTabActivity.java
+++ b/src/main/java/org/solovyev/android/calculator/help/CalculatorHelpTabActivity.java
@@ -15,7 +15,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.AndroidUtils;
import org.solovyev.android.calculator.R;
-import org.solovyev.android.AndroidUtils;
/**
* User: serso
diff --git a/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryActivity.java b/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryActivity.java
index dafaac7c..76990d9a 100644
--- a/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryActivity.java
+++ b/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryActivity.java
@@ -6,26 +6,29 @@
package org.solovyev.android.calculator.history;
-import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
-import android.content.DialogInterface;
import android.os.Bundle;
-import android.view.*;
-import android.widget.*;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.ListView;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.CalculatorModel;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.jscl.JsclOperation;
-import org.solovyev.android.view.AMenu;
import org.solovyev.android.view.AMenuBuilder;
-import org.solovyev.android.view.AMenuItem;
import org.solovyev.android.view.MenuImpl;
import org.solovyev.common.utils.*;
-import org.solovyev.common.utils.Filter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
/**
* User: serso
diff --git a/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryActivity.java b/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryActivity.java
index ca86b9a2..a0b6e05a 100644
--- a/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryActivity.java
+++ b/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryActivity.java
@@ -12,7 +12,6 @@ import android.widget.TabHost;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.AndroidUtils;
import org.solovyev.android.calculator.R;
-import org.solovyev.android.AndroidUtils;
/**
* User: serso
diff --git a/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorVarsActivity.java b/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorVarsActivity.java
index f6834862..ad674e1a 100644
--- a/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorVarsActivity.java
+++ b/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorVarsActivity.java
@@ -13,7 +13,6 @@ import org.jetbrains.annotations.Nullable;
import org.solovyev.android.AndroidUtils;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.model.VarCategory;
-import org.solovyev.android.AndroidUtils;
/**
* User: serso
diff --git a/src/main/java/org/solovyev/android/view/prefs/StringPreference.java b/src/main/java/org/solovyev/android/view/prefs/StringPreference.java
index de37604b..56ce5aca 100644
--- a/src/main/java/org/solovyev/android/view/prefs/StringPreference.java
+++ b/src/main/java/org/solovyev/android/view/prefs/StringPreference.java
@@ -37,6 +37,11 @@ public class StringPreference extends AbstractPreference {
return new StringPreference(id, parser.parseValue(defaultValue), parser);
}
+ @NotNull
+ public static StringPreference newInstance(@NotNull String id, @Nullable T defaultValue, @NotNull Class enumType) {
+ return new StringPreference(id, defaultValue, new EnumMapper(enumType));
+ }
+
@Override
protected T getPersistedValue(@NotNull SharedPreferences preferences) {
return mapper.parseValue(preferences.getString(getKey(), null));