Remove spans on copying or pasting a text
This commit is contained in:
		
							parent
							
								
									7226fc0010
								
							
						
					
					
						commit
						8835f08cf7
					
				| @ -1,7 +1,11 @@ | |||||||
| package eu.siacs.conversations.ui; | package eu.siacs.conversations.ui; | ||||||
| 
 | 
 | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
|  | import android.os.Build; | ||||||
| import android.os.Handler; | import android.os.Handler; | ||||||
|  | import android.text.Editable; | ||||||
|  | import android.text.InputFilter; | ||||||
|  | import android.text.Spanned; | ||||||
| import android.util.AttributeSet; | import android.util.AttributeSet; | ||||||
| import android.view.KeyEvent; | import android.view.KeyEvent; | ||||||
| import android.widget.EditText; | import android.widget.EditText; | ||||||
| @ -89,4 +93,36 @@ public class EditMessage extends EditText { | |||||||
| 		boolean onTabPressed(boolean repeated); | 		boolean onTabPressed(boolean repeated); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	private static final InputFilter SPAN_FILTER = new InputFilter() { | ||||||
|  | 
 | ||||||
|  | 		@Override | ||||||
|  | 		public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { | ||||||
|  | 			return source instanceof Spanned ? source.toString() : source; | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public boolean onTextContextMenuItem(int id) { | ||||||
|  | 		if (id == android.R.id.paste) { | ||||||
|  | 			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | ||||||
|  | 				return super.onTextContextMenuItem(android.R.id.pasteAsPlainText); | ||||||
|  | 			} else { | ||||||
|  | 				Editable editable = getEditableText(); | ||||||
|  | 				InputFilter[] filters = editable.getFilters(); | ||||||
|  | 				InputFilter[] tempFilters = new InputFilter[filters != null ? filters.length + 1 : 1]; | ||||||
|  | 				if (filters != null) { | ||||||
|  | 					System.arraycopy(filters, 0, tempFilters, 1, filters.length); | ||||||
|  | 				} | ||||||
|  | 				tempFilters[0] = SPAN_FILTER; | ||||||
|  | 				editable.setFilters(tempFilters); | ||||||
|  | 				try { | ||||||
|  | 					return super.onTextContextMenuItem(id); | ||||||
|  | 				} finally { | ||||||
|  | 					editable.setFilters(filters); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			return super.onTextContextMenuItem(id); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -54,12 +54,13 @@ import eu.siacs.conversations.entities.Transferable; | |||||||
| import eu.siacs.conversations.persistance.FileBackend; | import eu.siacs.conversations.persistance.FileBackend; | ||||||
| import eu.siacs.conversations.ui.ConversationActivity; | import eu.siacs.conversations.ui.ConversationActivity; | ||||||
| import eu.siacs.conversations.ui.widget.ClickableMovementMethod; | import eu.siacs.conversations.ui.widget.ClickableMovementMethod; | ||||||
|  | import eu.siacs.conversations.ui.widget.CopyTextView; | ||||||
| import eu.siacs.conversations.ui.widget.ListSelectionManager; | import eu.siacs.conversations.ui.widget.ListSelectionManager; | ||||||
| import eu.siacs.conversations.utils.CryptoHelper; | import eu.siacs.conversations.utils.CryptoHelper; | ||||||
| import eu.siacs.conversations.utils.GeoHelper; | import eu.siacs.conversations.utils.GeoHelper; | ||||||
| import eu.siacs.conversations.utils.UIHelper; | import eu.siacs.conversations.utils.UIHelper; | ||||||
| 
 | 
 | ||||||
| public class MessageAdapter extends ArrayAdapter<Message> { | public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextView.CopyHandler { | ||||||
| 
 | 
 | ||||||
| 	private static final int SENT = 0; | 	private static final int SENT = 0; | ||||||
| 	private static final int RECEIVED = 1; | 	private static final int RECEIVED = 1; | ||||||
| @ -487,7 +488,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { | |||||||
| 					viewHolder.edit_indicator = (ImageView) view.findViewById(R.id.edit_indicator); | 					viewHolder.edit_indicator = (ImageView) view.findViewById(R.id.edit_indicator); | ||||||
| 					viewHolder.image = (ImageView) view | 					viewHolder.image = (ImageView) view | ||||||
| 						.findViewById(R.id.message_image); | 						.findViewById(R.id.message_image); | ||||||
| 					viewHolder.messageBody = (TextView) view | 					viewHolder.messageBody = (CopyTextView) view | ||||||
| 						.findViewById(R.id.message_body); | 						.findViewById(R.id.message_body); | ||||||
| 					viewHolder.time = (TextView) view | 					viewHolder.time = (TextView) view | ||||||
| 						.findViewById(R.id.message_time); | 						.findViewById(R.id.message_time); | ||||||
| @ -508,7 +509,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { | |||||||
| 					viewHolder.edit_indicator = (ImageView) view.findViewById(R.id.edit_indicator); | 					viewHolder.edit_indicator = (ImageView) view.findViewById(R.id.edit_indicator); | ||||||
| 					viewHolder.image = (ImageView) view | 					viewHolder.image = (ImageView) view | ||||||
| 						.findViewById(R.id.message_image); | 						.findViewById(R.id.message_image); | ||||||
| 					viewHolder.messageBody = (TextView) view | 					viewHolder.messageBody = (CopyTextView) view | ||||||
| 						.findViewById(R.id.message_body); | 						.findViewById(R.id.message_body); | ||||||
| 					viewHolder.time = (TextView) view | 					viewHolder.time = (TextView) view | ||||||
| 						.findViewById(R.id.message_time); | 						.findViewById(R.id.message_time); | ||||||
| @ -526,7 +527,10 @@ public class MessageAdapter extends ArrayAdapter<Message> { | |||||||
| 					viewHolder = null; | 					viewHolder = null; | ||||||
| 					break; | 					break; | ||||||
| 			} | 			} | ||||||
| 			if (viewHolder.messageBody != null) listSelectionManager.onCreate(viewHolder.messageBody); | 			if (viewHolder.messageBody != null) { | ||||||
|  | 				listSelectionManager.onCreate(viewHolder.messageBody); | ||||||
|  | 				viewHolder.messageBody.setCopyHandler(this); | ||||||
|  | 			} | ||||||
| 			view.setTag(viewHolder); | 			view.setTag(viewHolder); | ||||||
| 		} else { | 		} else { | ||||||
| 			viewHolder = (ViewHolder) view.getTag(); | 			viewHolder = (ViewHolder) view.getTag(); | ||||||
| @ -684,6 +688,11 @@ public class MessageAdapter extends ArrayAdapter<Message> { | |||||||
| 		listSelectionManager.onAfterNotifyDataSetChanged(); | 		listSelectionManager.onAfterNotifyDataSetChanged(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public String transformTextForCopy(CharSequence text, int start, int end) { | ||||||
|  | 		return text.toString().substring(start, end); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	public void openDownloadable(Message message) { | 	public void openDownloadable(Message message) { | ||||||
| 		DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); | 		DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); | ||||||
| 		if (!file.exists()) { | 		if (!file.exists()) { | ||||||
| @ -761,7 +770,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { | |||||||
| 		protected ImageView indicator; | 		protected ImageView indicator; | ||||||
| 		protected ImageView indicatorReceived; | 		protected ImageView indicatorReceived; | ||||||
| 		protected TextView time; | 		protected TextView time; | ||||||
| 		protected TextView messageBody; | 		protected CopyTextView messageBody; | ||||||
| 		protected ImageView contact_picture; | 		protected ImageView contact_picture; | ||||||
| 		protected TextView status_message; | 		protected TextView status_message; | ||||||
| 		protected TextView encryption; | 		protected TextView encryption; | ||||||
|  | |||||||
| @ -0,0 +1,66 @@ | |||||||
|  | package eu.siacs.conversations.ui.widget; | ||||||
|  | 
 | ||||||
|  | import android.annotation.TargetApi; | ||||||
|  | import android.content.ClipData; | ||||||
|  | import android.content.ClipboardManager; | ||||||
|  | import android.content.Context; | ||||||
|  | import android.os.Build; | ||||||
|  | import android.util.AttributeSet; | ||||||
|  | import android.widget.TextView; | ||||||
|  | 
 | ||||||
|  | public class CopyTextView extends TextView { | ||||||
|  | 
 | ||||||
|  | 	public CopyTextView(Context context) { | ||||||
|  | 		super(context); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public CopyTextView(Context context, AttributeSet attrs) { | ||||||
|  | 		super(context, attrs); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public CopyTextView(Context context, AttributeSet attrs, int defStyleAttr) { | ||||||
|  | 		super(context, attrs, defStyleAttr); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@SuppressWarnings("unused") | ||||||
|  | 	@TargetApi(Build.VERSION_CODES.LOLLIPOP) | ||||||
|  | 	public CopyTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { | ||||||
|  | 		super(context, attrs, defStyleAttr, defStyleRes); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public interface CopyHandler { | ||||||
|  | 		public String transformTextForCopy(CharSequence text, int start, int end); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private CopyHandler copyHandler; | ||||||
|  | 
 | ||||||
|  | 	public void setCopyHandler(CopyHandler copyHandler) { | ||||||
|  | 		this.copyHandler = copyHandler; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public boolean onTextContextMenuItem(int id) { | ||||||
|  | 		CharSequence text = getText(); | ||||||
|  | 		int min = 0; | ||||||
|  | 		int max = text.length(); | ||||||
|  | 		if (isFocused()) { | ||||||
|  | 			final int selStart = getSelectionStart(); | ||||||
|  | 			final int selEnd = getSelectionEnd(); | ||||||
|  | 			min = Math.max(0, Math.min(selStart, selEnd)); | ||||||
|  | 			max = Math.max(0, Math.max(selStart, selEnd)); | ||||||
|  | 		} | ||||||
|  | 		String textForCopy = null; | ||||||
|  | 		if (id == android.R.id.copy && copyHandler != null) { | ||||||
|  | 			textForCopy = copyHandler.transformTextForCopy(getText(), min, max); | ||||||
|  | 		} | ||||||
|  | 		try { | ||||||
|  | 			return super.onTextContextMenuItem(id); | ||||||
|  | 		} finally { | ||||||
|  | 			if (textForCopy != null) { | ||||||
|  | 				ClipboardManager clipboard = (ClipboardManager) getContext(). | ||||||
|  | 						getSystemService(Context.CLIPBOARD_SERVICE); | ||||||
|  | 				clipboard.setPrimaryClip(ClipData.newPlainText(null, textForCopy)); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -49,7 +49,7 @@ | |||||||
|                 android:background="@color/black87" |                 android:background="@color/black87" | ||||||
|                 android:scaleType="centerCrop" /> |                 android:scaleType="centerCrop" /> | ||||||
| 
 | 
 | ||||||
|             <TextView |             <eu.siacs.conversations.ui.widget.CopyTextView | ||||||
|                 android:id="@+id/message_body" |                 android:id="@+id/message_body" | ||||||
|                 android:layout_width="wrap_content" |                 android:layout_width="wrap_content" | ||||||
|                 android:layout_height="wrap_content" |                 android:layout_height="wrap_content" | ||||||
|  | |||||||
| @ -50,7 +50,7 @@ | |||||||
|                 android:longClickable="true" |                 android:longClickable="true" | ||||||
|                 android:scaleType="centerCrop" /> |                 android:scaleType="centerCrop" /> | ||||||
| 
 | 
 | ||||||
|             <TextView |             <eu.siacs.conversations.ui.widget.CopyTextView | ||||||
|                 android:id="@+id/message_body" |                 android:id="@+id/message_body" | ||||||
|                 android:layout_width="wrap_content" |                 android:layout_width="wrap_content" | ||||||
|                 android:layout_height="wrap_content" |                 android:layout_height="wrap_content" | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Mishiranu
						Mishiranu