diff --git a/app/src/main/java/eu/faircode/email/EditTextCompose.java b/app/src/main/java/eu/faircode/email/EditTextCompose.java index a1cbad1904..5f7104860a 100644 --- a/app/src/main/java/eu/faircode/email/EditTextCompose.java +++ b/app/src/main/java/eu/faircode/email/EditTextCompose.java @@ -81,6 +81,8 @@ public class EditTextCompose extends FixedEditText { private int quoteStripe; private boolean lt_description; private boolean undo_manager; + private boolean paste_plain; + private boolean paste_quote; public EditTextCompose(Context context) { super(context); @@ -108,6 +110,8 @@ public class EditTextCompose extends FixedEditText { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); this.lt_description = prefs.getBoolean("lt_description", false); this.undo_manager = prefs.getBoolean("undo_manager", false); + this.paste_plain = prefs.getBoolean("paste_plain", false); + this.paste_quote = prefs.getBoolean("paste_quote", false); addTextChangedListener(new TextWatcher() { private Integer replace; @@ -290,12 +294,11 @@ public class EditTextCompose extends FixedEditText { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { try { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); - boolean paste_plain = prefs.getBoolean("paste_plain", false); - int order = 1000; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || paste_plain) menu.add(Menu.CATEGORY_SECONDARY, android.R.id.pasteAsPlainText, order++, getTitle(R.string.title_paste_plain)); + if (paste_quote) + menu.add(Menu.CATEGORY_SECONDARY, R.string.title_paste_as_quote, order++, getTitle(R.string.title_paste_as_quote)); if (undo_manager && can(android.R.id.undo)) menu.add(Menu.CATEGORY_SECONDARY, R.string.title_undo, order++, getTitle(R.string.title_undo)); if (undo_manager && can(android.R.id.redo)) @@ -330,6 +333,8 @@ public class EditTextCompose extends FixedEditText { int id = item.getItemId(); if (id == android.R.id.pasteAsPlainText) return insertPlain(); + else if (id == R.string.title_paste_as_quote && paste_quote) + return pasteAsQuote(); else if (id == R.string.title_undo && undo_manager) return EditTextCompose.super.onTextContextMenuItem(android.R.id.undo); else if (id == R.string.title_redo && undo_manager) @@ -379,6 +384,51 @@ public class EditTextCompose extends FixedEditText { return true; } + private boolean pasteAsQuote() { + ClipboardManager cbm = Helper.getSystemService(context, ClipboardManager.class); + if (!cbm.hasPrimaryClip()) + return true; + + ClipData clip = cbm.getPrimaryClip(); + if (clip == null || clip.getItemCount() < 1) + return true; + + ClipData.Item item = clip.getItemAt(0); + if (item == null) + return true; + + String h = item.getHtmlText(); + if (TextUtils.isEmpty(h)) { + CharSequence t = item.getText(); + if (TextUtils.isEmpty(t)) + return true; + h = "
" + HtmlHelper.formatPlainText(t.toString(), false) + "
"; + } + String style = HtmlHelper.getQuoteStyle("", 0, 0); + String html = "
" + h + "
"; + + Helper.getUIExecutor().submit(new RunnableEx("pasteq") { + @Override + public void delegate() { + SpannableStringBuilder ssb = getSpanned(context, html); + + EditTextCompose.this.post(new RunnableEx("pasteq") { + @Override + public void delegate() { + int start = getSelectionStart(); + if (start < 0) + start = 0; + getText().insert(start, ssb); + + StyleHelper.markAsInserted(getText(), start, start + ssb.length()); + } + }); + } + }); + + return true; + } + private boolean insertLine() { return StyleHelper.apply(R.id.menu_style_insert_line, null, null, EditTextCompose.this); } diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java b/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java index 5974926fde..da5768adb6 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java @@ -229,6 +229,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc private SwitchCompat swPreviewQuotes; private SwitchCompat swEasyCorrect; private SwitchCompat swPastePlain; + private SwitchCompat swPasteQuote; private EditText etFaviconUri; private SwitchCompat swInfra; private SwitchCompat swTldFlags; @@ -308,7 +309,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc "native_dkim", "native_arc", "native_arc_whitelist", "strict_alignment", "webp", "animate_images", "preview_hidden", "preview_quotes", - "easy_correct", "paste_plain", "favicon_uri", "infra", "tld_flags", "json_ld", "dup_msgids", "thread_byref", "save_user_flags", "mdn", + "easy_correct", "paste_plain", "paste_quote", "favicon_uri", "infra", "tld_flags", "json_ld", "dup_msgids", "thread_byref", "save_user_flags", "mdn", "app_chooser", "app_chooser_share", "share_task", "adjacent_links", "adjacent_documents", "adjacent_portrait", "adjacent_landscape", "delete_confirmation", "delete_notification", "global_keywords", "test_iab" @@ -492,6 +493,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc swPreviewQuotes = view.findViewById(R.id.swPreviewQuotes); swEasyCorrect = view.findViewById(R.id.swEasyCorrect); swPastePlain = view.findViewById(R.id.swPastePlain); + swPasteQuote = view.findViewById(R.id.swPasteQuote); etFaviconUri = view.findViewById(R.id.etFaviconUri); swInfra = view.findViewById(R.id.swInfra); swTldFlags = view.findViewById(R.id.swTldFlags); @@ -1668,6 +1670,13 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc } }); + swPasteQuote.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("paste_quote", checked).apply(); + } + }); + etFaviconUri.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { @@ -2550,6 +2559,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc swPreviewQuotes.setChecked(prefs.getBoolean("preview_quotes", true)); swEasyCorrect.setChecked(prefs.getBoolean("easy_correct", false)); swPastePlain.setChecked(prefs.getBoolean("paste_plain", false)); + swPasteQuote.setChecked(prefs.getBoolean("paste_quote", false)); etFaviconUri.setText(prefs.getString("favicon_uri", null)); swInfra.setChecked(prefs.getBoolean("infra", false)); swTldFlags.setChecked(prefs.getBoolean("tld_flags", false)); diff --git a/app/src/main/res/layout/fragment_options_misc.xml b/app/src/main/res/layout/fragment_options_misc.xml index 52c786bb66..46a3fa8e03 100644 --- a/app/src/main/res/layout/fragment_options_misc.xml +++ b/app/src/main/res/layout/fragment_options_misc.xml @@ -1746,6 +1746,17 @@ app:layout_constraintTop_toBottomOf="@id/swEasyCorrect" app:switchPadding="12dp" /> + + + app:layout_constraintTop_toBottomOf="@id/swPasteQuote" /> Preview quotes Easy correct Add paste as plain text + Add paste as quote Favicon alternative URI {domain} will be replaced Show infrastructure @@ -2363,6 +2364,7 @@ No Later Paste as plain text + Paste as quote Undo Redo Insert line