Fragments

This commit is contained in:
serso 2012-09-25 12:10:11 +04:00
parent 2f2914dd46
commit 5242d65e3a
12 changed files with 1970 additions and 1938 deletions

View File

@ -1,317 +1,322 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.solovyev.android</groupId>
<artifactId>calculatorpp-parent</artifactId>
<version>1.3.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.solovyev.android</groupId>
<artifactId>calculatorpp</artifactId>
<packaging>apk</packaging>
<name>Calculator++ Application</name>
<dependencies>
<!-- OWN -->
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>calculatorpp-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>common-core</artifactId>
</dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>common-text</artifactId>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-core</artifactId>
<type>apklib</type>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-ads</artifactId>
<type>apklib</type>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-view</artifactId>
<type>apklib</type>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-preferences</artifactId>
<type>apklib</type>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-other</artifactId>
<type>apklib</type>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-menu</artifactId>
<type>apklib</type>
</dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>jscl</artifactId>
</dependency>
<!--OTHER-->
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.simpleframework</groupId>
<artifactId>simple-xml</artifactId>
</dependency>
<dependency>
<groupId>achartengine</groupId>
<artifactId>achartengine</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>admob</groupId>
<artifactId>admob</artifactId>
<version>6.1.0</version>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>billing</artifactId>
<version>0.1</version>
<!--<type>apklib</type>-->
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>11.0.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.intellij</groupId>
<artifactId>annotations</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<manifest>
<debuggable>true</debuggable>
</manifest>
</configuration>
<executions>
<execution>
<id>manifestUpdate</id>
<phase>process-resources</phase>
<goals>
<goal>manifest-update</goal>
</goals>
</execution>
<execution>
<id>alignApk</id>
<phase>package</phase>
<goals>
<goal>zipalign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<!-- via this activation the profile is automatically used when the release is done with the maven release
plugin -->
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>${project.basedir}/misc/env/jarsigner.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<executions>
<execution>
<id>signing</id>
<goals>
<goal>sign</goal>
<goal>verify</goal>
</goals>
<phase>package</phase>
<inherited>true</inherited>
<configuration>
<removeExistingSignatures>true</removeExistingSignatures>
<archiveDirectory/>
<includes>
<include>${project.build.directory}/${project.artifactId}-${project.version}.apk</include>
</includes>
<keystore>${sign.keystore}</keystore>
<alias>${sign.alias}</alias>
<storepass>${sign.storepass}</storepass>
<keypass>${sign.keypass}</keypass>
<verbose>false</verbose>
</configuration>
</execution>
</executions>
</plugin>
<!-- the signed apk then needs to be zipaligned and we activate proguard and we run the manifest
update -->
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<sign>
<debug>false</debug>
</sign>
<zipalign>
<verbose>false</verbose>
<inputApk>${project.build.directory}/${project.artifactId}-${project.version}.apk</inputApk>
<outputApk>${project.build.directory}/${project.artifactId}-${project.version}-signed-aligned.apk</outputApk>
</zipalign>
<manifest>
<debuggable>false</debuggable>
<versionCodeAutoIncrement>true</versionCodeAutoIncrement>
</manifest>
<proguard>
<skip>true</skip>
</proguard>
</configuration>
<executions>
<execution>
<id>manifestUpdate</id>
<phase>process-resources</phase>
<goals>
<goal>manifest-update</goal>
</goals>
</execution>
<execution>
<id>alignApk</id>
<phase>package</phase>
<goals>
<goal>zipalign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.artifactId}-${project.version}-signed-aligned.apk</file>
<type>apk</type>
<classifier>signed-aligned</classifier>
</artifact>
<artifact>
<file>${project.build.directory}/proguard/mapping.txt</file>
<type>map</type>
<classifier>release</classifier>
</artifact>
</artifacts>
</configuration>
<executions>
<execution>
<id>attach-signed-aligned</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.solovyev.android</groupId>
<artifactId>calculatorpp-parent</artifactId>
<version>1.3.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.solovyev.android</groupId>
<artifactId>calculatorpp</artifactId>
<packaging>apk</packaging>
<name>Calculator++ Application</name>
<dependencies>
<!-- OWN -->
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>calculatorpp-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>common-core</artifactId>
</dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>common-text</artifactId>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-core</artifactId>
<type>apklib</type>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-ads</artifactId>
<type>apklib</type>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-view</artifactId>
<type>apklib</type>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-preferences</artifactId>
<type>apklib</type>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-other</artifactId>
<type>apklib</type>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-menu</artifactId>
<type>apklib</type>
</dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>jscl</artifactId>
</dependency>
<!--OTHER-->
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>support-v4</artifactId>
</dependency>
<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.simpleframework</groupId>
<artifactId>simple-xml</artifactId>
</dependency>
<dependency>
<groupId>achartengine</groupId>
<artifactId>achartengine</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>admob</groupId>
<artifactId>admob</artifactId>
<version>6.1.0</version>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>billing</artifactId>
<version>0.1</version>
<!--<type>apklib</type>-->
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>11.0.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.intellij</groupId>
<artifactId>annotations</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<manifest>
<debuggable>true</debuggable>
</manifest>
</configuration>
<executions>
<execution>
<id>manifestUpdate</id>
<phase>process-resources</phase>
<goals>
<goal>manifest-update</goal>
</goals>
</execution>
<execution>
<id>alignApk</id>
<phase>package</phase>
<goals>
<goal>zipalign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<!-- via this activation the profile is automatically used when the release is done with the maven release
plugin -->
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>${project.basedir}/misc/env/jarsigner.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<executions>
<execution>
<id>signing</id>
<goals>
<goal>sign</goal>
<goal>verify</goal>
</goals>
<phase>package</phase>
<inherited>true</inherited>
<configuration>
<removeExistingSignatures>true</removeExistingSignatures>
<archiveDirectory/>
<includes>
<include>${project.build.directory}/${project.artifactId}-${project.version}.apk</include>
</includes>
<keystore>${sign.keystore}</keystore>
<alias>${sign.alias}</alias>
<storepass>${sign.storepass}</storepass>
<keypass>${sign.keypass}</keypass>
<verbose>false</verbose>
</configuration>
</execution>
</executions>
</plugin>
<!-- the signed apk then needs to be zipaligned and we activate proguard and we run the manifest
update -->
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<sign>
<debug>false</debug>
</sign>
<zipalign>
<verbose>false</verbose>
<inputApk>${project.build.directory}/${project.artifactId}-${project.version}.apk</inputApk>
<outputApk>${project.build.directory}/${project.artifactId}-${project.version}-signed-aligned.apk</outputApk>
</zipalign>
<manifest>
<debuggable>false</debuggable>
<versionCodeAutoIncrement>true</versionCodeAutoIncrement>
</manifest>
<proguard>
<skip>true</skip>
</proguard>
</configuration>
<executions>
<execution>
<id>manifestUpdate</id>
<phase>process-resources</phase>
<goals>
<goal>manifest-update</goal>
</goals>
</execution>
<execution>
<id>alignApk</id>
<phase>package</phase>
<goals>
<goal>zipalign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.artifactId}-${project.version}-signed-aligned.apk</file>
<type>apk</type>
<classifier>signed-aligned</classifier>
</artifact>
<artifact>
<file>${project.build.directory}/proguard/mapping.txt</file>
<type>map</type>
<classifier>release</classifier>
</artifact>
</artifacts>
</configuration>
<executions>
<execution>
<id>attach-signed-aligned</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -1,84 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2009-2011. Created by serso aka se.solovyev.
~ For more information, please, contact se.solovyev@gmail.com
~ or visit http://se.solovyev.org
-->
<LinearLayout
xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_width="fill_parent"
a:layout_height="fill_parent"
a:id="@+id/ad_parent_view"
a:orientation="vertical"
a:layout_gravity="center"
a:background="#ff000000">
<include layout="@layout/calc_editor"/>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_equals_button"
a:layout_weight="1"
a:layout_width="0dp"
a:layout_height="fill_parent"/>
<include layout="@layout/calc_display"
a:layout_weight="4"
a:layout_width="0dp"
a:layout_height="fill_parent"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_seven_digit_button"/>
<include layout="@layout/calc_eight_digit_button"/>
<include layout="@layout/calc_nine_digit_button"/>
<include layout="@layout/calc_multiplication_button"/>
<include layout="@layout/calc_clear_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_four_digit_button"/>
<include layout="@layout/calc_five_digit_button"/>
<include layout="@layout/calc_six_digit_button"/>
<include layout="@layout/calc_division_button"/>
<include layout="@layout/calc_erase_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_one_digit_button"/>
<include layout="@layout/calc_two_digit_button"/>
<include layout="@layout/calc_three_digit_button"/>
<include layout="@layout/calc_plus_button"/>
<include layout="@layout/calc_copy_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_round_brackets_button"/>
<include layout="@layout/calc_zero_digit_button"/>
<include layout="@layout/calc_dot_button"/>
<include layout="@layout/calc_subtraction_button"/>
<include layout="@layout/calc_paste_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_left_button"/>
<include layout="@layout/calc_right_button"/>
<include layout="@layout/calc_vars_button"/>
<include layout="@layout/calc_functions_button"/>
<include layout="@layout/calc_history_button"/>
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2009-2011. Created by serso aka se.solovyev.
~ For more information, please, contact se.solovyev@gmail.com
~ or visit http://se.solovyev.org
-->
<LinearLayout
xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_width="fill_parent"
a:layout_height="fill_parent"
a:id="@+id/ad_parent_view"
a:orientation="vertical"
a:layout_gravity="center"
a:background="#ff000000">
<LinearLayout a:id="@+id/editorContainer"
a:layout_weight="2"
a:layout_width="match_parent"
a:layout_height="0dp"/>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_equals_button"
a:layout_weight="1"
a:layout_width="0dp"
a:layout_height="fill_parent"/>
<LinearLayout a:id="@+id/displayContainer"
a:layout_weight="4"
a:layout_width="0dp"
a:layout_height="match_parent"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_seven_digit_button"/>
<include layout="@layout/calc_eight_digit_button"/>
<include layout="@layout/calc_nine_digit_button"/>
<include layout="@layout/calc_multiplication_button"/>
<include layout="@layout/calc_clear_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_four_digit_button"/>
<include layout="@layout/calc_five_digit_button"/>
<include layout="@layout/calc_six_digit_button"/>
<include layout="@layout/calc_division_button"/>
<include layout="@layout/calc_erase_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_one_digit_button"/>
<include layout="@layout/calc_two_digit_button"/>
<include layout="@layout/calc_three_digit_button"/>
<include layout="@layout/calc_plus_button"/>
<include layout="@layout/calc_copy_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_round_brackets_button"/>
<include layout="@layout/calc_zero_digit_button"/>
<include layout="@layout/calc_dot_button"/>
<include layout="@layout/calc_subtraction_button"/>
<include layout="@layout/calc_paste_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_left_button"/>
<include layout="@layout/calc_right_button"/>
<include layout="@layout/calc_vars_button"/>
<include layout="@layout/calc_functions_button"/>
<include layout="@layout/calc_history_button"/>
</LinearLayout>
</LinearLayout>

View File

@ -7,9 +7,8 @@
-->
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_weight="2"
a:layout_width="fill_parent"
a:layout_height="0dp">
a:layout_width="match_parent"
a:layout_height="wrap_content">
<org.solovyev.android.calculator.AndroidCalculatorEditorView
a:id="@+id/calculatorEditor"

View File

@ -1,7 +1,11 @@
package org.solovyev.android.calculator;
import android.app.Activity;
import android.content.SharedPreferences;
import android.app.AlertDialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import jscl.NumeralBase;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
@ -22,17 +26,44 @@ public class AndroidCalculator implements Calculator {
@NotNull
private final Calculator calculator = new CalculatorImpl();
public void init(@NotNull final Activity activity, @NotNull SharedPreferences preferences) {
final AndroidCalculatorEditorView editorView = (AndroidCalculatorEditorView) activity.findViewById(R.id.calculatorEditor);
editorView.init(preferences);
preferences.registerOnSharedPreferenceChangeListener(editorView);
CalculatorLocatorImpl.getInstance().getEditor().setView(editorView);
public static void showEvaluationError(@NotNull Context context, @NotNull final String errorMessage) {
final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
final View errorMessageView = layoutInflater.inflate(R.layout.display_error_message, null);
((TextView) errorMessageView.findViewById(R.id.error_message_text_view)).setText(errorMessage);
final AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setPositiveButton(R.string.c_cancel, null)
.setView(errorMessageView);
builder.create().show();
}
public void init(@NotNull final Activity activity) {
setEditor(activity);
setDisplay(activity);
}
public void setDisplay(@NotNull Activity activity) {
final AndroidCalculatorDisplayView displayView = (AndroidCalculatorDisplayView) activity.findViewById(R.id.calculatorDisplay);
displayView.setOnClickListener(new CalculatorDisplayOnClickListener(activity));
setDisplay(activity, displayView);
}
public void setDisplay(@NotNull Context context, @NotNull AndroidCalculatorDisplayView displayView) {
displayView.init(context);
CalculatorLocatorImpl.getInstance().getDisplay().setView(displayView);
}
public void setEditor(@NotNull Activity activity) {
final AndroidCalculatorEditorView editorView = (AndroidCalculatorEditorView) activity.findViewById(R.id.calculatorEditor);
setEditor(activity, editorView);
}
public void setEditor(@NotNull Context context, @NotNull AndroidCalculatorEditorView editorView) {
editorView.init(context);
CalculatorLocatorImpl.getInstance().getEditor().setView(editorView);
}
/*
**********************************************************************

View File

@ -1,189 +1,199 @@
/*
* 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.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.util.AttributeSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.text.TextProcessor;
import org.solovyev.android.calculator.view.TextHighlighter;
import org.solovyev.android.view.AutoResizeTextView;
/**
* User: serso
* Date: 9/17/11
* Time: 10:58 PM
*/
public class AndroidCalculatorDisplayView extends AutoResizeTextView implements CalculatorDisplayView {
/*
**********************************************************************
*
* STATIC FIELDS
*
**********************************************************************
*/
@NotNull
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false);
/*
**********************************************************************
*
* FIELDS
*
**********************************************************************
*/
@NotNull
private volatile CalculatorDisplayViewState state = CalculatorDisplayViewStateImpl.newDefaultInstance();
private volatile boolean viewStateChange = false;
@NotNull
private final Object lock = new Object();
@NotNull
private final Handler handler = new Handler();
/*
**********************************************************************
*
* CONSTRUCTORS
*
**********************************************************************
*/
public AndroidCalculatorDisplayView(Context context) {
super(context);
this.addTextChangedListener(new TextWatcherImpl());
}
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs) {
super(context, attrs);
this.addTextChangedListener(new TextWatcherImpl());
}
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.addTextChangedListener(new TextWatcherImpl());
}
/*
**********************************************************************
*
* METHODS
*
**********************************************************************
*/
@Override
public void setState(@NotNull final CalculatorDisplayViewState state) {
final CharSequence text = prepareText(state.getStringResult(), state.isValid());
handler.post(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
viewStateChange = true;
AndroidCalculatorDisplayView.this.state = state;
if (state.isValid()) {
setTextColor(getResources().getColor(R.color.default_text_color));
setText(text);
adjustTextSize();
} else {
// update text in order to get rid of HTML tags
setText(getText().toString());
setTextColor(getResources().getColor(R.color.display_error_text_color));
// error messages are never shown -> just greyed out text (error message will be shown on click)
//setText(state.getErrorMessage());
//redraw();
}
} finally {
viewStateChange = false;
}
}
}
});
}
@NotNull
@Override
public CalculatorDisplayViewState getState() {
synchronized (lock) {
return this.state;
}
}
@Nullable
private static CharSequence prepareText(@Nullable String text, boolean valid) {
CharSequence result;
if (valid && text != null) {
//Log.d(this.getClass().getName(), text);
try {
final TextHighlighter.Result processedText = textHighlighter.process(text);
text = processedText.toString();
result = Html.fromHtml(text);
} catch (CalculatorParseException e) {
result = text;
}
} else {
result = text;
}
return result;
}
private void adjustTextSize() {
// todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize())
setAddEllipsis(false);
setMinTextSize(10);
resizeText();
}
public void handleTextChange(Editable s) {
synchronized (lock) {
if (!viewStateChange) {
// external text change => need to notify display
// todo serso: implement
}
}
}
private final class TextWatcherImpl implements TextWatcher {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
handleTextChange(s);
}
}
}
/*
* 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.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.util.AttributeSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.text.TextProcessor;
import org.solovyev.android.calculator.view.TextHighlighter;
import org.solovyev.android.view.AutoResizeTextView;
/**
* User: serso
* Date: 9/17/11
* Time: 10:58 PM
*/
public class AndroidCalculatorDisplayView extends AutoResizeTextView implements CalculatorDisplayView {
/*
**********************************************************************
*
* STATIC FIELDS
*
**********************************************************************
*/
@NotNull
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false);
/*
**********************************************************************
*
* FIELDS
*
**********************************************************************
*/
@NotNull
private volatile CalculatorDisplayViewState state = CalculatorDisplayViewStateImpl.newDefaultInstance();
private volatile boolean viewStateChange = false;
@NotNull
private final Object lock = new Object();
@NotNull
private final Handler handler = new Handler();
private volatile boolean initialized = false;
/*
**********************************************************************
*
* CONSTRUCTORS
*
**********************************************************************
*/
public AndroidCalculatorDisplayView(Context context) {
super(context);
this.addTextChangedListener(new TextWatcherImpl());
}
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs) {
super(context, attrs);
this.addTextChangedListener(new TextWatcherImpl());
}
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.addTextChangedListener(new TextWatcherImpl());
}
/*
**********************************************************************
*
* METHODS
*
**********************************************************************
*/
@Override
public void setState(@NotNull final CalculatorDisplayViewState state) {
final CharSequence text = prepareText(state.getStringResult(), state.isValid());
handler.post(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
viewStateChange = true;
AndroidCalculatorDisplayView.this.state = state;
if (state.isValid()) {
setTextColor(getResources().getColor(R.color.default_text_color));
setText(text);
adjustTextSize();
} else {
// update text in order to get rid of HTML tags
setText(getText().toString());
setTextColor(getResources().getColor(R.color.display_error_text_color));
// error messages are never shown -> just greyed out text (error message will be shown on click)
//setText(state.getErrorMessage());
//redraw();
}
} finally {
viewStateChange = false;
}
}
}
});
}
@NotNull
@Override
public CalculatorDisplayViewState getState() {
synchronized (lock) {
return this.state;
}
}
@Nullable
private static CharSequence prepareText(@Nullable String text, boolean valid) {
CharSequence result;
if (valid && text != null) {
//Log.d(this.getClass().getName(), text);
try {
final TextHighlighter.Result processedText = textHighlighter.process(text);
text = processedText.toString();
result = Html.fromHtml(text);
} catch (CalculatorParseException e) {
result = text;
}
} else {
result = text;
}
return result;
}
private void adjustTextSize() {
// todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize())
setAddEllipsis(false);
setMinTextSize(10);
resizeText();
}
public void handleTextChange(Editable s) {
synchronized (lock) {
if (!viewStateChange) {
// external text change => need to notify display
// todo serso: implement
}
}
}
public synchronized void init(@NotNull Context context) {
if (!initialized) {
this.setOnClickListener(new CalculatorDisplayOnClickListener(context));
this.initialized = true;
}
}
private final class TextWatcherImpl implements TextWatcher {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
handleTextChange(s);
}
}
}

View File

@ -1,204 +1,213 @@
/*
* 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.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextMenu;
import android.widget.EditText;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.text.TextProcessor;
import org.solovyev.android.calculator.view.TextHighlighter;
import org.solovyev.common.collections.CollectionsUtils;
/**
* User: serso
* Date: 9/17/11
* Time: 12:25 AM
*/
public class AndroidCalculatorEditorView extends EditText implements SharedPreferences.OnSharedPreferenceChangeListener, CalculatorEditorView {
private static final String CALC_COLOR_DISPLAY_KEY = "org.solovyev.android.calculator.CalculatorModel_color_display";
private static final boolean CALC_COLOR_DISPLAY_DEFAULT = true;
private boolean highlightText = true;
@NotNull
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false);
@NotNull
private volatile CalculatorEditorViewState viewState = CalculatorEditorViewStateImpl.newDefaultInstance();
private volatile boolean viewStateChange = false;
// NOTE: static because super constructor calls some overridden methods (like onSelectionChanged and current lock is not yet created)
@NotNull
private static final Object lock = new Object();
@NotNull
private final Handler handler = new Handler();
public AndroidCalculatorEditorView(Context context) {
super(context);
this.addTextChangedListener(new TextWatcherImpl());
}
public AndroidCalculatorEditorView(Context context, AttributeSet attrs) {
super(context, attrs);
this.addTextChangedListener(new TextWatcherImpl());
}
public AndroidCalculatorEditorView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.addTextChangedListener(new TextWatcherImpl());
}
@Override
public boolean onCheckIsTextEditor() {
// NOTE: code below can be used carefully and should not be copied without special intention
// The main purpose of code is to disable soft input (virtual keyboard) but leave all the TextEdit functionality, like cursor, scrolling, copy/paste menu etc
if (Build.VERSION.SDK_INT >= 11) {
// fix for missing cursor in android 3 and higher
try {
// IDEA: return false always except if method was called from TextView.isCursorVisible() method
for (StackTraceElement stackTraceElement : CollectionsUtils.asList(Thread.currentThread().getStackTrace())) {
if ("isCursorVisible".equals(stackTraceElement.getMethodName())) {
return true;
}
}
} catch (RuntimeException e) {
// just in case...
}
return false;
} else {
return false;
}
}
@Override
protected void onCreateContextMenu(ContextMenu menu) {
super.onCreateContextMenu(menu);
menu.removeItem(android.R.id.selectAll);
}
@Nullable
private CharSequence prepareText(@NotNull String text, boolean highlightText) {
CharSequence result;
if (highlightText) {
try {
final TextHighlighter.Result processesText = textHighlighter.process(text);
assert processesText.getOffset() == 0;
result = Html.fromHtml(processesText.toString());
} catch (CalculatorParseException e) {
// set raw text
result = text;
Log.e(this.getClass().getName(), e.getMessage(), e);
}
} else {
result = text;
}
return result;
}
public boolean isHighlightText() {
return highlightText;
}
public void setHighlightText(boolean highlightText) {
this.highlightText = highlightText;
CalculatorLocatorImpl.getInstance().getEditor().updateViewState();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (CALC_COLOR_DISPLAY_KEY.equals(key)) {
this.setHighlightText(preferences.getBoolean(CALC_COLOR_DISPLAY_KEY, CALC_COLOR_DISPLAY_DEFAULT));
}
}
public void init(@NotNull SharedPreferences preferences) {
onSharedPreferenceChanged(preferences, CALC_COLOR_DISPLAY_KEY);
}
@Override
public void setState(@NotNull final CalculatorEditorViewState viewState) {
final CharSequence text = prepareText(viewState.getText(), highlightText);
handler.post(new Runnable() {
@Override
public void run() {
final AndroidCalculatorEditorView editorView = AndroidCalculatorEditorView.this;
synchronized (lock) {
try {
editorView.viewStateChange = true;
editorView.viewState = viewState;
editorView.setText(text, BufferType.EDITABLE);
editorView.setSelection(viewState.getSelection());
} finally {
editorView.viewStateChange = false;
}
}
}
});
}
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
synchronized (lock) {
if (!viewStateChange) {
// external text change => need to notify editor
super.onSelectionChanged(selStart, selEnd);
CalculatorLocatorImpl.getInstance().getEditor().setSelection(selStart);
}
}
}
public void handleTextChange(Editable s) {
synchronized (lock) {
if (!viewStateChange) {
// external text change => need to notify editor
CalculatorLocatorImpl.getInstance().getEditor().setText(String.valueOf(s));
}
}
}
private final class TextWatcherImpl implements TextWatcher {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
handleTextChange(s);
}
}
}
/*
* 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.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextMenu;
import android.widget.EditText;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.text.TextProcessor;
import org.solovyev.android.calculator.view.TextHighlighter;
import org.solovyev.common.collections.CollectionsUtils;
/**
* User: serso
* Date: 9/17/11
* Time: 12:25 AM
*/
public class AndroidCalculatorEditorView extends EditText implements SharedPreferences.OnSharedPreferenceChangeListener, CalculatorEditorView {
private static final String CALC_COLOR_DISPLAY_KEY = "org.solovyev.android.calculator.CalculatorModel_color_display";
private static final boolean CALC_COLOR_DISPLAY_DEFAULT = true;
private volatile boolean initialized = false;
private boolean highlightText = true;
@NotNull
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false);
@NotNull
private volatile CalculatorEditorViewState viewState = CalculatorEditorViewStateImpl.newDefaultInstance();
private volatile boolean viewStateChange = false;
// NOTE: static because super constructor calls some overridden methods (like onSelectionChanged and current lock is not yet created)
@NotNull
private static final Object lock = new Object();
@NotNull
private final Handler handler = new Handler();
public AndroidCalculatorEditorView(Context context) {
super(context);
}
public AndroidCalculatorEditorView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AndroidCalculatorEditorView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onCheckIsTextEditor() {
// NOTE: code below can be used carefully and should not be copied without special intention
// The main purpose of code is to disable soft input (virtual keyboard) but leave all the TextEdit functionality, like cursor, scrolling, copy/paste menu etc
if (Build.VERSION.SDK_INT >= 11) {
// fix for missing cursor in android 3 and higher
try {
// IDEA: return false always except if method was called from TextView.isCursorVisible() method
for (StackTraceElement stackTraceElement : CollectionsUtils.asList(Thread.currentThread().getStackTrace())) {
if ("isCursorVisible".equals(stackTraceElement.getMethodName())) {
return true;
}
}
} catch (RuntimeException e) {
// just in case...
}
return false;
} else {
return false;
}
}
@Override
protected void onCreateContextMenu(ContextMenu menu) {
super.onCreateContextMenu(menu);
menu.removeItem(android.R.id.selectAll);
}
@Nullable
private CharSequence prepareText(@NotNull String text, boolean highlightText) {
CharSequence result;
if (highlightText) {
try {
final TextHighlighter.Result processesText = textHighlighter.process(text);
assert processesText.getOffset() == 0;
result = Html.fromHtml(processesText.toString());
} catch (CalculatorParseException e) {
// set raw text
result = text;
Log.e(this.getClass().getName(), e.getMessage(), e);
}
} else {
result = text;
}
return result;
}
public boolean isHighlightText() {
return highlightText;
}
public void setHighlightText(boolean highlightText) {
this.highlightText = highlightText;
CalculatorLocatorImpl.getInstance().getEditor().updateViewState();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (CALC_COLOR_DISPLAY_KEY.equals(key)) {
this.setHighlightText(preferences.getBoolean(CALC_COLOR_DISPLAY_KEY, CALC_COLOR_DISPLAY_DEFAULT));
}
}
public synchronized void init(@NotNull Context context) {
if (!initialized) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
preferences.registerOnSharedPreferenceChangeListener(this);
this.addTextChangedListener(new TextWatcherImpl());
onSharedPreferenceChanged(preferences, CALC_COLOR_DISPLAY_KEY);
initialized = true;
}
}
@Override
public void setState(@NotNull final CalculatorEditorViewState viewState) {
final CharSequence text = prepareText(viewState.getText(), highlightText);
handler.post(new Runnable() {
@Override
public void run() {
final AndroidCalculatorEditorView editorView = AndroidCalculatorEditorView.this;
synchronized (lock) {
try {
editorView.viewStateChange = true;
editorView.viewState = viewState;
editorView.setText(text, BufferType.EDITABLE);
editorView.setSelection(viewState.getSelection());
} finally {
editorView.viewStateChange = false;
}
}
}
});
}
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
synchronized (lock) {
if (!viewStateChange) {
// external text change => need to notify editor
super.onSelectionChanged(selStart, selEnd);
CalculatorLocatorImpl.getInstance().getEditor().setSelection(selStart);
}
}
}
public void handleTextChange(Editable s) {
synchronized (lock) {
if (!viewStateChange) {
// external text change => need to notify editor
CalculatorLocatorImpl.getInstance().getEditor().setText(String.valueOf(s));
}
}
}
private final class TextWatcherImpl implements TextWatcher {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
handleTextChange(s);
}
}
}

View File

@ -0,0 +1,32 @@
package org.solovyev.android.calculator;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* User: Solovyev_S
* Date: 25.09.12
* Time: 12:03
*/
public class CalculatorDisplayFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.calc_display, null);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((AndroidCalculator) CalculatorLocatorImpl.getInstance().getCalculator()).setDisplay(getActivity());
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}

View File

@ -1,53 +1,53 @@
package org.solovyev.android.calculator;
import android.app.Activity;
import android.view.View;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.menu.AMenuBuilder;
import org.solovyev.android.menu.MenuImpl;
import java.util.ArrayList;
import java.util.List;
/**
* User: Solovyev_S
* Date: 21.09.12
* Time: 10:58
*/
public class CalculatorDisplayOnClickListener implements View.OnClickListener {
@NotNull
private final Activity activity;
public CalculatorDisplayOnClickListener(@NotNull Activity activity) {
this.activity = activity;
}
@Override
public void onClick(View v) {
if (v instanceof CalculatorDisplayView) {
final CalculatorDisplay cd = CalculatorLocatorImpl.getInstance().getDisplay();
final CalculatorDisplayViewState displayViewState = cd.getViewState();
if (displayViewState.isValid()) {
final List<CalculatorDisplayMenuItem> filteredMenuItems = new ArrayList<CalculatorDisplayMenuItem>(CalculatorDisplayMenuItem.values().length);
for (CalculatorDisplayMenuItem menuItem : CalculatorDisplayMenuItem.values()) {
if (menuItem.isItemVisible(displayViewState)) {
filteredMenuItems.add(menuItem);
}
}
if (!filteredMenuItems.isEmpty()) {
AMenuBuilder.newInstance(activity, MenuImpl.newInstance(filteredMenuItems)).create(displayViewState).show();
}
} else {
final String errorMessage = displayViewState.getErrorMessage();
if (errorMessage != null) {
CalculatorModel.showEvaluationError(activity, errorMessage);
}
}
}
}
}
package org.solovyev.android.calculator;
import android.content.Context;
import android.view.View;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.menu.AMenuBuilder;
import org.solovyev.android.menu.MenuImpl;
import java.util.ArrayList;
import java.util.List;
/**
* User: Solovyev_S
* Date: 21.09.12
* Time: 10:58
*/
public class CalculatorDisplayOnClickListener implements View.OnClickListener {
@NotNull
private final Context context;
public CalculatorDisplayOnClickListener(@NotNull Context context) {
this.context = context;
}
@Override
public void onClick(View v) {
if (v instanceof CalculatorDisplayView) {
final CalculatorDisplay cd = CalculatorLocatorImpl.getInstance().getDisplay();
final CalculatorDisplayViewState displayViewState = cd.getViewState();
if (displayViewState.isValid()) {
final List<CalculatorDisplayMenuItem> filteredMenuItems = new ArrayList<CalculatorDisplayMenuItem>(CalculatorDisplayMenuItem.values().length);
for (CalculatorDisplayMenuItem menuItem : CalculatorDisplayMenuItem.values()) {
if (menuItem.isItemVisible(displayViewState)) {
filteredMenuItems.add(menuItem);
}
}
if (!filteredMenuItems.isEmpty()) {
AMenuBuilder.newInstance(context, MenuImpl.newInstance(filteredMenuItems)).create(displayViewState).show();
}
} else {
final String errorMessage = displayViewState.getErrorMessage();
if (errorMessage != null) {
AndroidCalculator.showEvaluationError(context, errorMessage);
}
}
}
}
}

View File

@ -0,0 +1,32 @@
package org.solovyev.android.calculator;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* User: Solovyev_S
* Date: 25.09.12
* Time: 10:49
*/
public class CalculatorEditorFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.calc_editor, null);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((AndroidCalculator) CalculatorLocatorImpl.getInstance().getCalculator()).setEditor(getActivity());
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}

View File

@ -1,103 +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.SharedPreferences;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.gui.CursorControl;
/**
* User: serso
* Date: 9/12/11
* Time: 11:15 PM
*/
public enum CalculatorModel implements CalculatorEngineControl, CursorControl {
instance;
@NotNull
private final CalculatorEditor editor;
@NotNull
private final CalculatorDisplay display;
private CalculatorModel() {
display = CalculatorLocatorImpl.getInstance().getDisplay();
editor = CalculatorLocatorImpl.getInstance().getEditor();
}
public CalculatorModel attachViews(@NotNull final Activity activity, @NotNull SharedPreferences preferences) {
Log.d(this.getClass().getName(), "CalculatorModel initialization with activity: " + activity);
final AndroidCalculatorEditorView editorView = (AndroidCalculatorEditorView) activity.findViewById(R.id.calculatorEditor);
editorView.init(preferences);
preferences.registerOnSharedPreferenceChangeListener(editorView);
editor.setView(editorView);
final AndroidCalculatorDisplayView displayView = (AndroidCalculatorDisplayView) activity.findViewById(R.id.calculatorDisplay);
displayView.setOnClickListener(new CalculatorDisplayOnClickListener(activity));
display.setView(displayView);
return this;
}
public static void showEvaluationError(@NotNull Activity activity, @NotNull final String errorMessage) {
final LayoutInflater layoutInflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
final View errorMessageView = layoutInflater.inflate(R.layout.display_error_message, null);
((TextView) errorMessageView.findViewById(R.id.error_message_text_view)).setText(errorMessage);
final AlertDialog.Builder builder = new AlertDialog.Builder(activity)
.setPositiveButton(R.string.c_cancel, null)
.setView(errorMessageView);
builder.create().show();
}
@Override
public void setCursorOnStart() {
this.editor.setCursorOnStart();
}
@Override
public void setCursorOnEnd() {
this.editor.setCursorOnEnd();
}
@Override
public void moveCursorLeft() {
this.editor.moveCursorLeft();
}
@Override
public void moveCursorRight() {
this.editor.moveCursorRight();
}
@Override
public void evaluate() {
CalculatorLocatorImpl.getInstance().getCalculator().evaluate(JsclOperation.numeric, this.editor.getViewState().getText());
}
@Override
public void simplify() {
CalculatorLocatorImpl.getInstance().getCalculator().evaluate(JsclOperation.simplify, this.editor.getViewState().getText());
}
@NotNull
public CalculatorDisplay getDisplay() {
return display;
}
}

494
pom.xml
View File

@ -1,245 +1,251 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.solovyev.android</groupId>
<artifactId>calculatorpp-parent</artifactId>
<packaging>pom</packaging>
<version>1.3.2</version>
<name>Calculator++</name>
<modules>
<module>calculatorpp</module>
<module>calculatorpp-test</module>
<module>calculatorpp-core</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>common-core</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>common-text</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-core</artifactId>
<type>apklib</type>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-ads</artifactId>
<type>apklib</type>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-view</artifactId>
<type>apklib</type>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-preferences</artifactId>
<type>apklib</type>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-menu</artifactId>
<type>apklib</type>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>jscl</artifactId>
<version>0.0.2</version>
<exclusions>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-other</artifactId>
<type>apklib</type>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
</dependency>
<dependency>
<groupId>com.intellij</groupId>
<artifactId>annotations</artifactId>
<version>7.0.3</version>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>4.0.1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android-test</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>11.0.2</version>
</dependency>
<dependency>
<groupId>org.simpleframework</groupId>
<artifactId>simple-xml</artifactId>
<version>2.6.1</version>
<exclusions>
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>stax</groupId>
</exclusion>
<exclusion>
<artifactId>xpp3</artifactId>
<groupId>xpp3</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>com.electriccloud</groupId>
<artifactId>javac2-maven-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<id>@NotNull Instrumentation</id>
<goals>
<goal>instrument</goal>
</goals>
<!--compile phase instead of process-classes because of proguard.
@NotNull instrumentation will be done now after compilation and before proguard-->
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<version>1.2</version>
</plugin>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<sourceDirectories>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
</sourceDirectories>
<sdk>
<platform>15</platform>
</sdk>
<emulator>
<avd>23</avd>
<wait>10000</wait>
<!--<options>-no-skin</options>-->
</emulator>
<zipalign>
<verbose>true</verbose>
</zipalign>
<undeployBeforeDeploy>true</undeployBeforeDeploy>
</configuration>
</plugin>
<plugin>
<groupId>com.pyx4me</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.4</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.5</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<!-- the standard profile runs instrumentation tests -->
<id>standard</id>
</profile>
<profile>
<!-- the release profile does sign, proguard, zipalign -->
<id>release</id>
<!-- via this activation the profile is automatically used when the release is done with the maven release
plugin -->
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
</profile>
</profiles>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.solovyev.android</groupId>
<artifactId>calculatorpp-parent</artifactId>
<packaging>pom</packaging>
<version>1.3.2</version>
<name>Calculator++</name>
<modules>
<module>calculatorpp</module>
<module>calculatorpp-test</module>
<module>calculatorpp-core</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>common-core</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>common-text</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-core</artifactId>
<type>apklib</type>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-ads</artifactId>
<type>apklib</type>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-view</artifactId>
<type>apklib</type>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-preferences</artifactId>
<type>apklib</type>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-menu</artifactId>
<type>apklib</type>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>jscl</artifactId>
<version>0.0.2</version>
<exclusions>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.solovyev.android</groupId>
<artifactId>android-common-other</artifactId>
<type>apklib</type>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
</dependency>
<dependency>
<groupId>com.intellij</groupId>
<artifactId>annotations</artifactId>
<version>7.0.3</version>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>4.0.1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>support-v4</artifactId>
<version>r7</version>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android-test</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>11.0.2</version>
</dependency>
<dependency>
<groupId>org.simpleframework</groupId>
<artifactId>simple-xml</artifactId>
<version>2.6.1</version>
<exclusions>
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>stax</groupId>
</exclusion>
<exclusion>
<artifactId>xpp3</artifactId>
<groupId>xpp3</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>com.electriccloud</groupId>
<artifactId>javac2-maven-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<id>@NotNull Instrumentation</id>
<goals>
<goal>instrument</goal>
</goals>
<!--compile phase instead of process-classes because of proguard.
@NotNull instrumentation will be done now after compilation and before proguard-->
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<version>1.2</version>
</plugin>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<sourceDirectories>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
</sourceDirectories>
<sdk>
<platform>15</platform>
</sdk>
<emulator>
<avd>23</avd>
<wait>10000</wait>
<!--<options>-no-skin</options>-->
</emulator>
<zipalign>
<verbose>true</verbose>
</zipalign>
<undeployBeforeDeploy>true</undeployBeforeDeploy>
</configuration>
</plugin>
<plugin>
<groupId>com.pyx4me</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.4</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.5</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<!-- the standard profile runs instrumentation tests -->
<id>standard</id>
</profile>
<profile>
<!-- the release profile does sign, proguard, zipalign -->
<id>release</id>
<!-- via this activation the profile is automatically used when the release is done with the maven release
plugin -->
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
</profile>
</profiles>
</project>