1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.messaging.ui; 17 18 import android.content.ClipData; 19 import android.content.ClipboardManager; 20 import android.content.Context; 21 import android.util.AttributeSet; 22 import android.widget.EditText; 23 24 /** 25 * We want the EditText used in Conversations to convert text to plain text on paste. This 26 * conversion would happen anyway on send, so without this class it could appear to the user 27 * that we would send e.g. bold or italic formatting, but in the sent message it would just be 28 * plain text. 29 */ 30 public class PlainTextEditText extends EditText { 31 private static final char OBJECT_UNICODE = '\uFFFC'; 32 PlainTextEditText(final Context context, final AttributeSet attrs)33 public PlainTextEditText(final Context context, final AttributeSet attrs) { 34 super(context, attrs); 35 } 36 37 // Intercept and modify the paste event. Let everything else through unchanged. 38 @Override onTextContextMenuItem(final int id)39 public boolean onTextContextMenuItem(final int id) { 40 if (id == android.R.id.paste) { 41 // We can use this to know where the text position was originally before we pasted 42 final int selectionStartPrePaste = getSelectionStart(); 43 44 // Let the EditText's normal paste routine fire, then modify the content after. 45 // This is simpler than re-implementing the paste logic, which we'd have to do 46 // if we want to get the text from the clipboard ourselves and then modify it. 47 48 final boolean result = super.onTextContextMenuItem(id); 49 CharSequence text = getText(); 50 int selectionStart = getSelectionStart(); 51 int selectionEnd = getSelectionEnd(); 52 53 // There is an option in the Chrome mobile app to copy image; however, instead of the 54 // image in the form of the uri, Chrome gives us the html source for the image, which 55 // the platform paste code turns into the unicode object character. The below section 56 // of code looks for that edge case and replaces it with the url for the image. 57 final int startIndex = selectionStart - 1; 58 final int pasteStringLength = selectionStart - selectionStartPrePaste; 59 // Only going to handle the case where the pasted object is the image 60 if (pasteStringLength == 1 && text.charAt(startIndex) == OBJECT_UNICODE) { 61 final ClipboardManager clipboard = 62 (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); 63 final ClipData clip = clipboard.getPrimaryClip(); 64 if (clip != null) { 65 ClipData.Item item = clip.getItemAt(0); 66 StringBuilder sb = new StringBuilder(text); 67 final String url = item.getText().toString(); 68 sb.replace(selectionStartPrePaste, selectionStart, url); 69 text = sb.toString(); 70 selectionStart = selectionStartPrePaste + url.length(); 71 selectionEnd = selectionStart; 72 } 73 } 74 75 // This removes the formatting due to the conversion to string. 76 setText(text.toString(), BufferType.EDITABLE); 77 78 // Restore the cursor selection state. 79 setSelection(selectionStart, selectionEnd); 80 return result; 81 } else { 82 return super.onTextContextMenuItem(id); 83 } 84 } 85 } 86