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