Merge "Improve copy/paste handling, minor instant result fixes" into mnc-dev
diff --git a/res/values/color.xml b/res/values/color.xml
index 3ed5b06..384fd26 100644
--- a/res/values/color.xml
+++ b/res/values/color.xml
@@ -32,6 +32,9 @@
     <!-- Text color for the result in the calculator display. -->
     <color name="display_result_text_color">#6C000000</color>
 
+    <!-- Lighter color for exponent while scrolling. -->
+    <color name="display_result_exponent_text_color">#40000000</color>
+
     <!-- Background color for the numeric pad. -->
     <color name="pad_numeric_background_color">#434343</color>
 
diff --git a/src/com/android/calculator2/Calculator.java b/src/com/android/calculator2/Calculator.java
index dd6c541..d5242fa 100644
--- a/src/com/android/calculator2/Calculator.java
+++ b/src/com/android/calculator2/Calculator.java
@@ -122,6 +122,7 @@
         @Override
         public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
             if (keyEvent.getAction() != KeyEvent.ACTION_UP) return true;
+            stopActionMode();
             switch (keyCode) {
                 case KeyEvent.KEYCODE_NUMPAD_ENTER:
                 case KeyEvent.KEYCODE_ENTER:
@@ -311,15 +312,28 @@
         }
     }
 
+    // Stop any active ActionMode.  Return true if there was one.
+    private boolean stopActionMode() {
+        if (mResult.stopActionMode()) {
+            return true;
+        }
+        if (mFormulaText.stopActionMode()) {
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public void onBackPressed() {
-        if (mPadViewPager == null || mPadViewPager.getCurrentItem() == 0) {
-            // If the user is currently looking at the first pad (or the pad is not paged),
-            // allow the system to handle the Back button.
-            super.onBackPressed();
-        } else {
-            // Otherwise, select the previous pad.
-            mPadViewPager.setCurrentItem(mPadViewPager.getCurrentItem() - 1);
+        if (!stopActionMode()) {
+            if (mPadViewPager != null && mPadViewPager.getCurrentItem() != 0) {
+                // Select the previous pad.
+                mPadViewPager.setCurrentItem(mPadViewPager.getCurrentItem() - 1);
+            } else {
+                // If the user is currently looking at the first pad (or the pad is not paged),
+                // allow the system to handle the Back button.
+                super.onBackPressed();
+            }
         }
     }
 
@@ -380,6 +394,7 @@
 
     public void onButtonClick(View view) {
         mCurrentButton = view;
+        stopActionMode();
 
         // Always cancel in-progress evaluation.
         // If we were waiting for the result, do nothing else.
diff --git a/src/com/android/calculator2/CalculatorResult.java b/src/com/android/calculator2/CalculatorResult.java
index 72c3b54..c569d4c 100644
--- a/src/com/android/calculator2/CalculatorResult.java
+++ b/src/com/android/calculator2/CalculatorResult.java
@@ -28,8 +28,8 @@
 import android.widget.TextView;
 import android.widget.OverScroller;
 import android.text.Editable;
-import android.text.Spanned;
 import android.text.SpannableString;
+import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -90,6 +90,8 @@
                             // the difference is not noticeable.
     private static final int MAX_WIDTH = 100;
                             // Maximum number of digits displayed
+    private ActionMode mActionMode;
+    private final ForegroundColorSpan mExponentColorSpan;
 
     public CalculatorResult(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -107,6 +109,7 @@
                         mCurrentPos = mScroller.getFinalX();
                     }
                     mScroller.forceFinished(true);
+                    stopActionMode();
                     CalculatorResult.this.cancelLongPress();
                     // Ignore scrolls of error string, etc.
                     if (!mScrollable) return true;
@@ -124,6 +127,7 @@
                         mCurrentPos = mScroller.getFinalX();
                     }
                     mScroller.forceFinished(true);
+                    stopActionMode();
                     CalculatorResult.this.cancelLongPress();
                     if (!mScrollable) return true;
                     int duration = (int)(e2.getEventTime() - e1.getEventTime());
@@ -135,13 +139,17 @@
                 }
                 @Override
                 public void onLongPress(MotionEvent e) {
-                    startActionMode(mCopyActionModeCallback,
-                                    ActionMode.TYPE_FLOATING);
+                    if (mValid) {
+                        mActionMode = startActionMode(mCopyActionModeCallback,
+                                ActionMode.TYPE_FLOATING);
+                    }
                 }
             });
         setOnTouchListener(mTouchListener);
         setHorizontallyScrolling(false);  // do it ourselves
         setCursorVisible(false);
+        mExponentColorSpan = new ForegroundColorSpan(
+                context.getColor(R.color.display_result_exponent_text_color));
 
         // Copy ActionMode is triggered explicitly, not through
         // setCustomSelectionActionModeCallback.
@@ -364,6 +372,7 @@
 
     void clear() {
         mValid = false;
+        mScrollable = false;
         setText("");
     }
 
@@ -376,8 +385,7 @@
         if (epos > 0 && result.indexOf('.') == -1) {
           // Gray out exponent if used as position indicator
             SpannableString formattedResult = new SpannableString(result);
-            formattedResult.setSpan(new ForegroundColorSpan(Color.LTGRAY),
-                                    epos, result.length(),
+            formattedResult.setSpan(mExponentColorSpan, epos, result.length(),
                                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
             setText(formattedResult);
         } else {
@@ -432,9 +440,18 @@
 
         @Override
         public void onDestroyActionMode(ActionMode mode) {
+            mActionMode = null;
         }
     };
 
+    public boolean stopActionMode() {
+        if (mActionMode != null) {
+            mActionMode.finish();
+            return true;
+        }
+        return false;
+    }
+
     private void setPrimaryClip(ClipData clip) {
         ClipboardManager clipboard = (ClipboardManager) getContext().
                 getSystemService(Context.CLIPBOARD_SERVICE);
diff --git a/src/com/android/calculator2/CalculatorText.java b/src/com/android/calculator2/CalculatorText.java
index 1f91572..1b16bca 100644
--- a/src/com/android/calculator2/CalculatorText.java
+++ b/src/com/android/calculator2/CalculatorText.java
@@ -45,6 +45,7 @@
 
 public class CalculatorText extends TextView implements View.OnLongClickListener{
 
+    private ActionMode mActionMode;
 
     private final ActionMode.Callback mPasteActionModeCallback =
             new ActionMode.Callback() {
@@ -76,6 +77,7 @@
 
         @Override
         public void onDestroyActionMode(ActionMode mode) {
+            mActionMode = null;
         }
 
         @Override
@@ -149,7 +151,7 @@
 
     @Override
     public boolean onLongClick(View v) {
-        startActionMode(mPasteActionModeCallback, ActionMode.TYPE_FLOATING);
+        mActionMode = startActionMode(mPasteActionModeCallback, ActionMode.TYPE_FLOATING);
         return true;
     }
 
@@ -229,6 +231,14 @@
         return super.getCompoundPaddingBottom() - Math.min(getPaddingBottom(), fontMetrics.descent);
     }
 
+    public boolean stopActionMode() {
+        if (mActionMode != null) {
+            mActionMode.finish();
+            return true;
+        }
+        return false;
+    }
+
     public interface OnTextSizeChangeListener {
         void onTextSizeChanged(TextView textView, float oldSize);
     }
diff --git a/src/com/android/calculator2/Evaluator.java b/src/com/android/calculator2/Evaluator.java
index 3b393ef..ad232db 100644
--- a/src/com/android/calculator2/Evaluator.java
+++ b/src/com/android/calculator2/Evaluator.java
@@ -752,6 +752,7 @@
     }
 
     void restoreInstanceState(DataInput in) {
+        mChangedValue = true;
         try {
             CalculatorExpr.initExprInput();
             mDegreeMode = in.readBoolean();