Skip to content

Commit 6a2746f

Browse files
committed
Honor selected content upon input (Issue #214)
1 parent 8f9c970 commit 6a2746f

1 file changed

Lines changed: 76 additions & 16 deletions

File tree

  • app/src/main/java/org/solovyev/android/calculator

‎app/src/main/java/org/solovyev/android/calculator/Editor.java‎

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,49 @@ protected void onPostExecute(@Nonnull EditorState state) {
9898
}
9999
}
100100

101+
private class SplitText {
102+
public int selectionStart = 0;
103+
public int selectionEnd = 0;
104+
public int selectionLength = 0;
105+
public int insertionPos = 0;
106+
public boolean textSelected = false;
107+
public String textLeft = "";
108+
public String textMid = "";
109+
public String textRight = "";
110+
public String text = "";
111+
112+
public SplitText(String text, int cursorPos) {
113+
this.text = text;
114+
selectionStart = view.getSelectionStart();
115+
selectionEnd = view.getSelectionEnd();
116+
selectionLength = selectionEnd - selectionStart;
117+
textSelected = selectionLength != 0;
118+
insertionPos = textSelected ?
119+
clamp(selectionStart, text)
120+
: clamp(cursorPos, text);
121+
textLeft = text.substring(0, insertionPos);
122+
textMid = text.substring(selectionStart, selectionEnd);
123+
textRight = text.substring(insertionPos + selectionLength, text.length());
124+
}
125+
126+
public String getTextMid(boolean deleteSelection) {
127+
return deleteSelection ? "" : this.textMid;
128+
}
129+
130+
public String getDelTextLeft() {
131+
MathType type = MathType.getType(text, insertionPos - 1, false, engine).type;
132+
return this.textSelected ?
133+
this.textLeft
134+
: type == MathType.grouping_separator ?
135+
this.textLeft.substring(0,this.textLeft.length()-2)
136+
: this.textLeft.substring(0,this.textLeft.length()-1);
137+
}
138+
public int getDelPos() {
139+
return this.getDelTextLeft().length();
140+
}
141+
}
142+
143+
101144
@VisibleForTesting
102145
@Nullable
103146
EditorTextProcessor textProcessor;
@@ -240,20 +283,17 @@ public EditorState moveCursorRight() {
240283

241284
public boolean erase() {
242285
Check.isMainThread();
243-
final int selection = state.selection;
286+
final int delPos = state.selection;
244287
final String text = state.getTextString();
245-
if (selection <= 0 || text.length() <= 0 || selection > text.length()) {
288+
final SplitText st = new SplitText(text, delPos);
289+
290+
if (delPos <= 0 || text.length() <= 0 || delPos > text.length()) {
246291
return false;
247292
}
248-
int removeStart = selection - 1;
249-
if (MathType.getType(text, selection - 1, false, engine).type == MathType.grouping_separator) {
250-
// we shouldn't remove just separator as it will be re-added after the evaluation is done. Remove the digit
251-
// before
252-
removeStart -= 1;
253-
}
254293

255-
final String newText = text.substring(0, removeStart) + text.substring(selection, text.length());
256-
onTextChanged(EditorState.create(newText, removeStart));
294+
final String newText = st.getDelTextLeft() + st.getTextMid(true) + st.textRight;
295+
onTextChanged(EditorState.create(newText, st.getDelPos()));
296+
257297
return !newText.isEmpty();
258298
}
259299

@@ -277,16 +317,36 @@ public void insert(@Nonnull String text) {
277317
insert(text, 0);
278318
}
279319

280-
public void insert(@Nonnull String text, int selectionOffset) {
320+
public void insert(@Nonnull String textToInsert, int selectionOffset) {
281321
Check.isMainThread();
282-
if (TextUtils.isEmpty(text) && selectionOffset == 0) {
322+
if (TextUtils.isEmpty(textToInsert) && selectionOffset == 0) {
283323
return;
284324
}
285325
final String oldText = state.getTextString();
286-
final int selection = clamp(state.selection, oldText);
287-
final int newTextLength = text.length() + oldText.length();
288-
final int newSelection = clamp(text.length() + selection + selectionOffset, newTextLength);
289-
final String newText = oldText.substring(0, selection) + text + oldText.substring(selection);
326+
final MathType type = MathType.getType(textToInsert, 0, false, engine).type;
327+
final SplitText st = new SplitText(oldText, state.selection);
328+
329+
boolean deleteSelection = false;
330+
if (st.textSelected && type == MathType.digit) {
331+
deleteSelection = true;
332+
}
333+
334+
if (st.textSelected && type == MathType.binary_operation) {
335+
textToInsert = "()" + textToInsert;
336+
selectionOffset = -textToInsert.length() + 1;
337+
}
338+
339+
final int insertedTextLength = textToInsert.length();
340+
final int newTextLength = insertedTextLength + oldText.length();
341+
342+
final int pluginPos = insertedTextLength + selectionOffset;
343+
final String insertLeft = textToInsert.substring(0, pluginPos);
344+
final String insertRight = textToInsert.substring(pluginPos, insertedTextLength);
345+
final String newText = st.textLeft + insertLeft + st.getTextMid(deleteSelection) + insertRight + st.textRight;
346+
int newSelection = st.textLeft.length() + insertLeft.length() + st.textMid.length();
347+
if (st.textSelected) newSelection += insertRight.length();
348+
newSelection = clamp(newSelection, newText);
349+
290350
onTextChanged(EditorState.create(newText, newSelection));
291351
}
292352

0 commit comments

Comments
 (0)