public void insert(String delta) {
    String currentText = getText().toString();
    int selectionHandle = getSelectionStart();
    String textBeforeInsertionHandle = currentText.substring(0, selectionHandle);
    String textAfterInsertionHandle = currentText.substring(selectionHandle, currentText.length());

    // Add extra rules for decimal points and operators
    if (delta.length() == 1) {
      char text = delta.charAt(0);

      // don't allow two dots in the same number
      if (text == Constants.DECIMAL_POINT) {
        int p = selectionHandle - 1;
        while (p >= 0 && Solver.isDigit(getText().charAt(p))) {
          if (getText().charAt(p) == Constants.DECIMAL_POINT) {
            return;
          }
          --p;
        }
        p = selectionHandle;
        while (p < getText().length() && Solver.isDigit(getText().charAt(p))) {
          if (getText().charAt(p) == Constants.DECIMAL_POINT) {
            return;
          }
          ++p;
        }
      }

      char prevChar = selectionHandle > 0 ? getText().charAt(selectionHandle - 1) : '\0';

      // don't allow 2 successive minuses
      if (text == Constants.MINUS && prevChar == Constants.MINUS) {
        return;
      }

      // don't allow multiple successive operators
      if (Solver.isOperator(text) && text != Constants.MINUS) {
        while (Solver.isOperator(prevChar)) {
          if (selectionHandle == 1) {
            return;
          }

          --selectionHandle;
          prevChar = selectionHandle > 0 ? getText().charAt(selectionHandle - 1) : '\0';
          textBeforeInsertionHandle = textBeforeInsertionHandle.substring(0, selectionHandle);
        }
      }
    }

    mIsInserting = true;
    setText(
        textBeforeInsertionHandle + delta + BaseModule.SELECTION_HANDLE + textAfterInsertionHandle);
    mIsInserting = false;
  }
 protected String removeFormatting(String input) {
   input = input.replace(Constants.POWER_PLACEHOLDER, Constants.POWER);
   if (mSolver != null) {
     input = input.replace(String.valueOf(mSolver.getBaseModule().getSeparator()), "");
   }
   return input;
 }
  protected void onFormat(Editable s) {
    String text = removeFormatting(s.toString());

    // Get the selection handle, since we're setting text and that'll overwrite it
    MutableInteger selectionHandle = new MutableInteger(getSelectionStart());

    // Adjust the handle by removing any comas or spacing to the left
    String cs = s.subSequence(0, selectionHandle.intValue()).toString();
    selectionHandle.subtract(TextUtil.countOccurrences(cs, mSolver.getBaseModule().getSeparator()));

    // Update the text with formatted (comas, etc) text
    setText(Html.fromHtml(formatText(text, selectionHandle)));
    setSelection(selectionHandle.intValue());
  }
  protected boolean saveHistory(String expr, String result, boolean ensureResult) {
    if (mHistory == null) {
      return false;
    }

    expr = cleanExpression(expr);
    if (!ensureResult
        || (!TextUtils.isEmpty(expr)
            && !TextUtils.isEmpty(result)
            && !Solver.equal(expr, result)
            && (mHistory.current() == null || !mHistory.current().getFormula().equals(expr)))) {
      mHistory.enter(expr, result);
      return true;
    }
    return false;
  }
 @Override
 public void onEvaluate(String expr, String result, int errorResourceId) {
   if (mCurrentState == CalculatorState.INPUT || mCurrentState == CalculatorState.GRAPHING) {
     if (result == null || Solver.equal(result, expr)) {
       mResultEditText.setText(null);
     } else {
       mResultEditText.setText(result);
     }
   } else if (errorResourceId != INVALID_RES_ID) {
     onError(errorResourceId);
   } else if (saveHistory(expr, result, true)) {
     mDisplayView.scrollToMostRecent();
     onResult(result);
   } else if (mCurrentState == CalculatorState.EVALUATE) {
     // The current expression cannot be evaluated -> return to the input state.
     setState(CalculatorState.INPUT);
   }
   invalidateEqualsButton();
 }
 protected String cleanExpression(String expr) {
   expr = EquationFormatter.appendParenthesis(expr);
   expr = Solver.clean(expr);
   expr = mTokenizer.getLocalizedExpression(expr);
   return expr;
 }