Changed: Use ShareUtils to copy and paste text and prevent potential NPE

The `copyTextToClipboard()` method has been updated to pass clip label when copying text to clipboard and `getTextFromClipboard()` and `getTextStringFromClipboardIfSet()` methods have been added to get current clipboard.
This commit is contained in:
agnostic-apollo
2022-10-04 04:02:22 +05:00
parent 63d035ce39
commit 0c14c291b2
4 changed files with 78 additions and 30 deletions

View File

@@ -183,20 +183,16 @@ public class TermuxTerminalSessionActivityClient extends TermuxTerminalSessionCl
public void onCopyTextToClipboard(@NonNull TerminalSession session, String text) {
if (!mActivity.isVisible()) return;
ClipboardManager clipboard = (ClipboardManager) mActivity.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setPrimaryClip(new ClipData(null, new String[]{"text/plain"}, new ClipData.Item(text)));
ShareUtils.copyTextToClipboard(mActivity, text);
}
@Override
public void onPasteTextFromClipboard(@Nullable TerminalSession session) {
if (!mActivity.isVisible()) return;
ClipboardManager clipboard = (ClipboardManager) mActivity.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData = clipboard.getPrimaryClip();
if (clipData != null) {
CharSequence paste = clipData.getItemAt(0).coerceToText(mActivity);
if (!TextUtils.isEmpty(paste)) mActivity.getTerminalView().mEmulator.paste(paste.toString());
}
String text = ShareUtils.getTextStringFromClipboardIfSet(mActivity, true);
if (text != null)
mActivity.getTerminalView().mEmulator.paste(text);
}
@Override

View File

@@ -702,9 +702,7 @@ public class TermuxTerminalViewClient extends TermuxTerminalViewClientBase {
// Click to copy url to clipboard:
final AlertDialog dialog = new AlertDialog.Builder(mActivity).setItems(urls, (di, which) -> {
String url = (String) urls[which];
ClipboardManager clipboard = (ClipboardManager) mActivity.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setPrimaryClip(new ClipData(null, new String[]{"text/plain"}, new ClipData.Item(url)));
Toast.makeText(mActivity, R.string.msg_select_url_copied_to_clipboard, Toast.LENGTH_LONG).show();
ShareUtils.copyTextToClipboard(mActivity, url, mActivity.getString(R.string.msg_select_url_copied_to_clipboard));
}).setTitle(R.string.title_select_url_dialog).create();
// Long press to open URL:
@@ -789,12 +787,9 @@ public class TermuxTerminalViewClient extends TermuxTerminalViewClientBase {
if (session == null) return;
if (!session.isRunning()) return;
ClipboardManager clipboard = (ClipboardManager) mActivity.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData = clipboard.getPrimaryClip();
if (clipData == null) return;
CharSequence paste = clipData.getItemAt(0).coerceToText(mActivity);
if (!TextUtils.isEmpty(paste))
session.getEmulator().paste(paste.toString());
String text = ShareUtils.getTextStringFromClipboardIfSet(mActivity, true);
if (text != null)
session.getEmulator().paste(text);
}
}

View File

@@ -566,11 +566,14 @@ public final class TerminalView extends View {
if (action == MotionEvent.ACTION_DOWN) showContextMenu();
return true;
} else if (event.isButtonPressed(MotionEvent.BUTTON_TERTIARY)) {
ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData = clipboard.getPrimaryClip();
ClipboardManager clipboardManager = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData = clipboardManager.getPrimaryClip();
if (clipData != null) {
CharSequence paste = clipData.getItemAt(0).coerceToText(getContext());
if (!TextUtils.isEmpty(paste)) mEmulator.paste(paste.toString());
ClipData.Item clipItem = clipData.getItemAt(0);
if (clipItem != null) {
CharSequence text = clipItem.coerceToText(getContext());
if (!TextUtils.isEmpty(text)) mEmulator.paste(text.toString());
}
}
} else if (mEmulator.isMouseTrackingActive()) { // BUTTON_PRIMARY.
switch (event.getAction()) {

View File

@@ -12,7 +12,6 @@ import android.os.Build;
import android.os.Environment;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import com.termux.shared.R;
import com.termux.shared.data.DataUtils;
@@ -81,27 +80,82 @@ public class ShareUtils {
openSystemAppChooser(context, shareTextIntent, DataUtils.isNullOrEmpty(title) ? context.getString(R.string.title_share_with) : title);
}
/** Wrapper for {@link #copyTextToClipboard(Context, String, String, String)} with `null` `clipDataLabel` and `toastString`. */
public static void copyTextToClipboard(Context context, final String text) {
copyTextToClipboard(context, null, text, null);
}
/** Wrapper for {@link #copyTextToClipboard(Context, String, String, String)} with `null` `clipDataLabel`. */
public static void copyTextToClipboard(Context context, final String text, final String toastString) {
copyTextToClipboard(context, null, text, toastString);
}
/**
* Copy the text to clipboard.
* Copy the text to primary clip of the clipboard.
*
* @param context The context for operations.
* @param clipDataLabel The label to show to the user describing the copied text.
* @param text The text to copy.
* @param toastString If this is not {@code null} or empty, then a toast is shown if copying to
* clipboard is successful.
*/
public static void copyTextToClipboard(final Context context, final String text, final String toastString) {
public static void copyTextToClipboard(Context context, @Nullable final String clipDataLabel,
final String text, final String toastString) {
if (context == null || text == null) return;
final ClipboardManager clipboardManager = ContextCompat.getSystemService(context, ClipboardManager.class);
ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
if (clipboardManager == null) return;
clipboardManager.setPrimaryClip(ClipData.newPlainText(clipDataLabel,
DataUtils.getTruncatedCommandOutput(text, DataUtils.TRANSACTION_SIZE_LIMIT_IN_BYTES,
true, false, false)));
if (clipboardManager != null) {
clipboardManager.setPrimaryClip(ClipData.newPlainText(null, DataUtils.getTruncatedCommandOutput(text, DataUtils.TRANSACTION_SIZE_LIMIT_IN_BYTES, true, false, false)));
if (toastString != null && !toastString.isEmpty())
Logger.showToast(context, toastString, true);
}
/**
* Wrapper for {@link #getTextFromClipboard(Context, boolean)} that returns primary text {@link String}
* if its set and not empty.
*/
@Nullable
public static String getTextStringFromClipboardIfSet(Context context, boolean coerceToText) {
CharSequence textCharSequence = getTextFromClipboard(context, coerceToText);
if (textCharSequence == null) return null;
String textString = textCharSequence.toString();
return !textString.isEmpty() ? textString : null;
}
/**
* Get the text from primary clip of the clipboard.
*
* @param context The context for operations.
* @param coerceToText Whether to call {@link ClipData.Item#coerceToText(Context)} to coerce
* non-text data to text.
* @return Returns the {@link CharSequence} of primary text. This will be `null` if failed to get it.
*/
@Nullable
public static CharSequence getTextFromClipboard(Context context, boolean coerceToText) {
if (context == null) return null;
ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
if (clipboardManager == null) return null;
ClipData clipData = clipboardManager.getPrimaryClip();
if (clipData == null) return null;
ClipData.Item clipItem = clipData.getItemAt(0);
if (clipItem == null) return null;
return coerceToText ? clipItem.coerceToText(context) : clipItem.getText();
}
* Open a url.
*
* @param context The context for operations.