separating application. admob library added
@ -13,9 +13,9 @@
|
|||||||
|
|
||||||
<application a:icon="@drawable/icon"
|
<application a:icon="@drawable/icon"
|
||||||
a:label="@string/c_app_name"
|
a:label="@string/c_app_name"
|
||||||
a:name="org.solovyev.android.calculator.ApplicationContext">
|
a:name=".ApplicationContext">
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.CalculatorActivityFree"
|
<activity a:name=".CalculatorActivity"
|
||||||
a:label="@string/c_app_name">
|
a:label="@string/c_app_name">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -25,71 +25,71 @@
|
|||||||
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.CalculatorPreferencesActivity"
|
<activity a:name=".CalculatorPreferencesActivity"
|
||||||
a:label="@string/c_app_settings"
|
a:label="@string/c_app_settings"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.history.CalculatorHistoryActivity"
|
<activity a:name=".history.CalculatorHistoryActivity"
|
||||||
a:label="@string/c_app_history"
|
a:label="@string/c_app_history"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.history.HistoryActivityTab"
|
<activity a:name=".history.HistoryActivityTab"
|
||||||
a:label="@string/c_history"
|
a:label="@string/c_history"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.history.SavedHistoryActivityTab"
|
<activity a:name=".history.SavedHistoryActivityTab"
|
||||||
a:label="@string/c_saved_history"
|
a:label="@string/c_saved_history"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.about.CalculatorAboutTabActivity"
|
<activity a:name=".about.CalculatorAboutTabActivity"
|
||||||
a:label="@string/c_about"
|
a:label="@string/c_about"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.about.CalculatorAboutActivity"
|
<activity a:name=".about.CalculatorAboutActivity"
|
||||||
a:label="@string/c_about"
|
a:label="@string/c_about"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.about.CalculatorReleaseNotesActivity"
|
<activity a:name=".about.CalculatorReleaseNotesActivity"
|
||||||
a:label="@string/c_about"
|
a:label="@string/c_about"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.help.CalculatorHelpTabActivity"
|
<activity a:name=".help.CalculatorHelpTabActivity"
|
||||||
a:label="@string/c_help"
|
a:label="@string/c_help"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.help.HelpFaqActivity"
|
<activity a:name=".help.HelpFaqActivity"
|
||||||
a:label="@string/c_help"
|
a:label="@string/c_help"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.help.HelpHintsActivity"
|
<activity a:name=".help.HelpHintsActivity"
|
||||||
a:label="@string/c_help"
|
a:label="@string/c_help"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.help.HelpScreensActivity"
|
<activity a:name=".help.HelpScreensActivity"
|
||||||
a:label="@string/c_help"
|
a:label="@string/c_help"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.math.edit.CalculatorFunctionsActivity"
|
<activity a:name=".math.edit.CalculatorFunctionsActivity"
|
||||||
a:label="@string/c_functions"
|
a:label="@string/c_functions"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.math.edit.CalculatorFunctionsTabActivity"
|
<activity a:name=".math.edit.CalculatorFunctionsTabActivity"
|
||||||
a:label="@string/c_functions"
|
a:label="@string/c_functions"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.math.edit.CalculatorOperatorsActivity"
|
<activity a:name=".math.edit.CalculatorOperatorsActivity"
|
||||||
a:label="@string/c_operators"
|
a:label="@string/c_operators"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.math.edit.CalculatorVarsActivity"
|
<activity a:name=".math.edit.CalculatorVarsActivity"
|
||||||
a:label="@string/c_vars_and_constants"
|
a:label="@string/c_vars_and_constants"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.math.edit.CalculatorVarsTabActivity"
|
<activity a:name=".math.edit.CalculatorVarsTabActivity"
|
||||||
a:label="@string/c_vars_and_constants"
|
a:label="@string/c_vars_and_constants"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name="org.solovyev.android.calculator.CalculatorPlotActivity"
|
<activity a:name=".CalculatorPlotActivity"
|
||||||
a:label="@string/c_plot_graph"/>
|
a:label="@string/c_plot_graph"/>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
10
pom.xml
@ -49,7 +49,7 @@
|
|||||||
<groupId>xerces</groupId>
|
<groupId>xerces</groupId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
<!-- <scope>system</scope>
|
<!-- <scope>system</scope>
|
||||||
<systemPath>${additionalLibs}/jscl.jar</systemPath>-->
|
<systemPath>${additionalLibs}/jscl.jar</systemPath>-->
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@ -80,6 +80,14 @@
|
|||||||
<systemPath>${additionalLibs}/achartengine-0.7.0.jar</systemPath>
|
<systemPath>${additionalLibs}/achartengine-0.7.0.jar</systemPath>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>admob</groupId>
|
||||||
|
<artifactId>admob</artifactId>
|
||||||
|
<version>4.3.1</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${additionalLibs}/GoogleAdMobAdsSdk-4.3.1.jar</systemPath>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.intellij</groupId>
|
<groupId>com.intellij</groupId>
|
||||||
<artifactId>annotations</artifactId>
|
<artifactId>annotations</artifactId>
|
||||||
|
@ -164,6 +164,5 @@
|
|||||||
<string name="c_calc_use_back_button_as_prev_title">Использовать кнопку назад как назад по истории</string>
|
<string name="c_calc_use_back_button_as_prev_title">Использовать кнопку назад как назад по истории</string>
|
||||||
|
|
||||||
<string name="c_warning">Внимание</string>
|
<string name="c_warning">Внимание</string>
|
||||||
<string name="c_remove_prev_app_warning">Вы установили другую версию Калькулятора++.\nДля корректной работы приложения, пожалуйста, удалите предыдущую версию, все пользовательские данные будут автоматически перенесены в новое приложение.</string>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -164,6 +164,5 @@
|
|||||||
<string name="c_calc_use_back_button_as_prev_title">Use Back button as history prev</string>
|
<string name="c_calc_use_back_button_as_prev_title">Use Back button as history prev</string>
|
||||||
|
|
||||||
<string name="c_warning">Warning</string>
|
<string name="c_warning">Warning</string>
|
||||||
<string name="c_remove_prev_app_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.</string>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -1,702 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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<ApplicationData.Type> 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<Integer> 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<DragPreferencesChangeListener> dpclRegister = new Announcer<DragPreferencesChangeListener>(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<CalculatorHistoryState>(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<String, Integer> 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<String, Integer> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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();
|
|
||||||
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +1,675 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2012. Created by serso aka se.solovyev.
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
* For more information, please, contact se.solovyev@gmail.com
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
* or visit http://se.solovyev.org
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.solovyev.android.calculator;
|
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.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.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;
|
||||||
* User: serso
|
import java.util.Locale;
|
||||||
* Date: 1/2/12
|
import java.util.Map;
|
||||||
* Time: 9:33 PM
|
|
||||||
*/
|
|
||||||
public class CalculatorActivity extends AbstractCalculatorActivity {
|
|
||||||
|
|
||||||
public CalculatorActivity() {
|
public class CalculatorActivity extends Activity implements FontSizeAdjuster, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
super(createApplicationData());
|
|
||||||
|
private static final int HVGA_WIDTH_PIXELS = 320;
|
||||||
|
|
||||||
|
public static class Preferences {
|
||||||
|
@NotNull
|
||||||
|
private static final String APP_VERSION_P_KEY = "application.version";
|
||||||
|
private static final int APP_VERSION_DEFAULT = -1;
|
||||||
|
public static final Preference<Integer> appVersion = new IntegerPreference(APP_VERSION_P_KEY, APP_VERSION_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static ApplicationData createApplicationData() {
|
public static final String SHOW_RELEASE_NOTES_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_show_release_notes";
|
||||||
return new ApplicationDataImpl(false, R.string.c_app_name, ApplicationData.Type.pro);
|
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<DragPreferencesChangeListener> dpclRegister = new Announcer<DragPreferencesChangeListener>(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) {
|
||||||
|
|
||||||
|
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<CalculatorHistoryState>(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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<String, Integer> 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<String, Integer> 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 int appVersion = AndroidUtils.getAppVersionCode(this, CalculatorActivity.class.getPackage().getName());
|
||||||
|
|
||||||
|
Preferences.appVersion.putPreference(preferences, appVersion);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -15,7 +15,7 @@ import android.widget.TextView;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.solovyev.android.AndroidUtils;
|
import org.solovyev.android.AndroidUtils;
|
||||||
import org.solovyev.android.ResourceCache;
|
import org.solovyev.android.ResourceCache;
|
||||||
import org.solovyev.android.calculator.AbstractCalculatorActivity;
|
import org.solovyev.android.calculator.CalculatorActivity;
|
||||||
import org.solovyev.android.calculator.R;
|
import org.solovyev.android.calculator.R;
|
||||||
import org.solovyev.common.utils.StringUtils;
|
import org.solovyev.common.utils.StringUtils;
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ public class CalculatorReleaseNotesActivity extends Activity {
|
|||||||
final StringBuilder result = new StringBuilder();
|
final StringBuilder result = new StringBuilder();
|
||||||
|
|
||||||
final String releaseNotesForTitle = context.getString(R.string.c_release_notes_for_title);
|
final String releaseNotesForTitle = context.getString(R.string.c_release_notes_for_title);
|
||||||
final int version = AndroidUtils.getAppVersionCode(context, AbstractCalculatorActivity.class.getPackage().getName());
|
final int version = AndroidUtils.getAppVersionCode(context, CalculatorActivity.class.getPackage().getName());
|
||||||
|
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for ( int i = version; i >= minVersion; i-- ) {
|
for ( int i = version; i >= minVersion; i-- ) {
|
||||||
|
BIN
src/misc/doc/GoogleAdMobAdsSdk-4.3.1.jar
Normal file
BIN
src/misc/lib/GoogleAdMobAdsSdk-4.3.1.jar
Normal file
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |