aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationFragment.java60
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java9
-rw-r--r--src/main/res/menu/message_context.xml4
-rw-r--r--src/main/res/values-ru/strings.xml1
-rw-r--r--src/main/res/values/strings.xml1
5 files changed, 75 insertions, 0 deletions
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
index c6f6b8cd..da6f6da0 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
@@ -12,6 +12,8 @@ import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.os.Handler;
import android.text.InputType;
+import android.text.Selection;
+import android.text.Spannable;
import android.util.Log;
import android.util.Pair;
import android.view.ContextMenu;
@@ -38,6 +40,8 @@ import android.widget.Toast;
import net.java.otr4j.session.SessionStatus;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -536,6 +540,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
activity.getMenuInflater().inflate(R.menu.message_context, menu);
menu.setHeaderTitle(R.string.message_options);
MenuItem copyText = menu.findItem(R.id.copy_text);
+ MenuItem selectText = menu.findItem(R.id.select_text);
MenuItem retryDecryption = menu.findItem(R.id.retry_decryption);
MenuItem correctMessage = menu.findItem(R.id.correct_message);
MenuItem shareWith = menu.findItem(R.id.share_with);
@@ -548,6 +553,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
&& !GeoHelper.isGeoUri(m.getBody())
&& m.treatAsDownloadable() != Message.Decision.MUST) {
copyText.setVisible(true);
+ selectText.setVisible(METHOD_START_SELECTION != null);
}
if (m.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
retryDecryption.setVisible(true);
@@ -597,6 +603,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
case R.id.copy_text:
copyText(selectedMessage);
return true;
+ case R.id.select_text:
+ selectText(selectedMessage);
+ return true;
case R.id.correct_message:
correctMessage(selectedMessage);
return true;
@@ -656,6 +665,30 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
}
}
+ private void selectText(Message message) {
+ final int index;
+ synchronized (this.messageList) {
+ index = this.messageList.indexOf(message);
+ }
+ if (index >= 0) {
+ final int first = this.messagesView.getFirstVisiblePosition();
+ final int last = first + this.messagesView.getChildCount();
+ if (index >= first && index < last) {
+ final View view = this.messagesView.getChildAt(index - first);
+ final TextView messageBody = this.messageListAdapter.getMessageBody(view);
+ if (messageBody != null) {
+ final Spannable text = (Spannable) messageBody.getText();
+ Selection.setSelection(text, 0, text.length());
+ try {
+ Object editor = FIELD_EDITOR != null ? FIELD_EDITOR.get(messageBody) : messageBody;
+ METHOD_START_SELECTION.invoke(editor);
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+ }
+
private void deleteFile(Message message) {
if (activity.xmppConnectionService.getFileBackend().deleteFile(message)) {
message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED));
@@ -1430,4 +1463,31 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
}
}
+ private static final Field FIELD_EDITOR;
+ private static final Method METHOD_START_SELECTION;
+
+ static {
+ Field editor;
+ try {
+ editor = TextView.class.getDeclaredField("mEditor");
+ editor.setAccessible(true);
+ } catch (Exception e) {
+ editor = null;
+ }
+ FIELD_EDITOR = editor;
+ Class<?> editorClass = editor != null ? editor.getType() : TextView.class;
+ String[] startSelectionNames = {"startSelectionActionMode", "startSelectionActionModeWithSelection"};
+ Method startSelection = null;
+ for (String startSelectionName : startSelectionNames) {
+ try {
+ startSelection = editorClass.getDeclaredMethod(startSelectionName);
+ startSelection.setAccessible(true);
+ break;
+ } catch (Exception e) {
+ startSelection = null;
+ }
+ }
+ METHOD_START_SELECTION = startSelection;
+ }
+
}
diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
index 9e2b3ba7..30a5dd6e 100644
--- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
+++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
@@ -736,6 +736,15 @@ public class MessageAdapter extends ArrayAdapter<Message> {
this.mUseGreenBackground = activity.useGreenBackground();
}
+ public TextView getMessageBody(View view) {
+ final Object tag = view.getTag();
+ if (tag instanceof ViewHolder) {
+ final ViewHolder viewHolder = (ViewHolder) tag;
+ return viewHolder.messageBody;
+ }
+ return null;
+ }
+
public interface OnContactPictureClicked {
void onContactPictureClicked(Message message);
}
diff --git a/src/main/res/menu/message_context.xml b/src/main/res/menu/message_context.xml
index bc8acede..9bdbbcea 100644
--- a/src/main/res/menu/message_context.xml
+++ b/src/main/res/menu/message_context.xml
@@ -5,6 +5,10 @@
android:id="@+id/copy_text"
android:title="@string/copy_text"
android:visible="false"/>
+ <item
+ android:id="@+id/select_text"
+ android:title="@string/select_text"
+ android:visible="false"/>
<item
android:id="@+id/retry_decryption"
android:title="Retry decryption"
diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml
index 5d25af21..c551962e 100644
--- a/src/main/res/values-ru/strings.xml
+++ b/src/main/res/values-ru/strings.xml
@@ -325,6 +325,7 @@
<string name="check_x_filesize_on_host">Проверьте размер %1$s на %2$s</string>
<string name="message_options">Опции сообщения</string>
<string name="copy_text">Копировать текст</string>
+ <string name="select_text">Выбрать текст</string>
<string name="copy_original_url">Копировать адрес ссылки</string>
<string name="send_again">Отправить ещё раз</string>
<string name="file_url">URL файла</string>
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 22d89a81..1d53a278 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -362,6 +362,7 @@
<string name="check_x_filesize_on_host">Check %1$s size on %2$s</string>
<string name="message_options">Message options</string>
<string name="copy_text">Copy text</string>
+ <string name="select_text">Select text</string>
<string name="copy_original_url">Copy original URL</string>
<string name="send_again">Send again</string>
<string name="file_url">File URL</string>