|
|
|
@ -121,6 +121,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
|
|
|
|
|
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
|
|
|
|
import com.google.android.material.bottomnavigation.LabelVisibilityMode;
|
|
|
|
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
|
|
|
|
import com.google.android.material.snackbar.Snackbar;
|
|
|
|
|
|
|
|
|
|
import org.bouncycastle.cert.jcajce.JcaCertStore;
|
|
|
|
@ -241,7 +242,6 @@ public class FragmentCompose extends FragmentBase {
|
|
|
|
|
private TextView tvDsn;
|
|
|
|
|
private TextView tvPlainTextOnly;
|
|
|
|
|
private EditTextCompose etBody;
|
|
|
|
|
private ImageButton ibTranslate;
|
|
|
|
|
private TextView tvNoInternet;
|
|
|
|
|
private TextView tvSignature;
|
|
|
|
|
private CheckBox cbSignature;
|
|
|
|
@ -250,6 +250,7 @@ public class FragmentCompose extends FragmentBase {
|
|
|
|
|
private ImageButton ibCloseRefHint;
|
|
|
|
|
private ImageButton ibReferenceEdit;
|
|
|
|
|
private ImageButton ibReferenceImages;
|
|
|
|
|
private FloatingActionButton fabTranslate;
|
|
|
|
|
private BottomNavigationView style_bar;
|
|
|
|
|
private BottomNavigationView media_bar;
|
|
|
|
|
private BottomNavigationView bottom_navigation;
|
|
|
|
@ -358,7 +359,6 @@ public class FragmentCompose extends FragmentBase {
|
|
|
|
|
tvDsn = view.findViewById(R.id.tvDsn);
|
|
|
|
|
tvPlainTextOnly = view.findViewById(R.id.tvPlainTextOnly);
|
|
|
|
|
etBody = view.findViewById(R.id.etBody);
|
|
|
|
|
ibTranslate = view.findViewById(R.id.ibTranslate);
|
|
|
|
|
tvNoInternet = view.findViewById(R.id.tvNoInternet);
|
|
|
|
|
tvSignature = view.findViewById(R.id.tvSignature);
|
|
|
|
|
cbSignature = view.findViewById(R.id.cbSignature);
|
|
|
|
@ -367,6 +367,7 @@ public class FragmentCompose extends FragmentBase {
|
|
|
|
|
ibCloseRefHint = view.findViewById(R.id.ibCloseRefHint);
|
|
|
|
|
ibReferenceEdit = view.findViewById(R.id.ibReferenceEdit);
|
|
|
|
|
ibReferenceImages = view.findViewById(R.id.ibReferenceImages);
|
|
|
|
|
fabTranslate = view.findViewById(R.id.fabTranslate);
|
|
|
|
|
style_bar = view.findViewById(R.id.style_bar);
|
|
|
|
|
media_bar = view.findViewById(R.id.media_bar);
|
|
|
|
|
bottom_navigation = view.findViewById(R.id.bottom_navigation);
|
|
|
|
@ -716,116 +717,6 @@ public class FragmentCompose extends FragmentBase {
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
ibTranslate.setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(View v) {
|
|
|
|
|
List<DeepL.Language> languages = DeepL.getTargetLanguages(getContext());
|
|
|
|
|
if (languages == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
boolean canTranslate =
|
|
|
|
|
(DeepL.canTranslate(getContext()) &&
|
|
|
|
|
DeepL.getParagraph(etBody) != null);
|
|
|
|
|
|
|
|
|
|
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(getContext(), getViewLifecycleOwner(), v);
|
|
|
|
|
|
|
|
|
|
popupMenu.getMenu().add(Menu.NONE, 1, 1, R.string.title_translate_configure);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < languages.size(); i++) {
|
|
|
|
|
DeepL.Language lang = languages.get(i);
|
|
|
|
|
MenuItem item = popupMenu.getMenu().add(Menu.NONE, i + 2, i + 2, lang.name)
|
|
|
|
|
.setIntent(new Intent().putExtra("target", lang.target));
|
|
|
|
|
if (lang.icon != null)
|
|
|
|
|
item.setIcon(lang.icon);
|
|
|
|
|
item.setEnabled(canTranslate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onMenuItemClick(MenuItem item) {
|
|
|
|
|
if (item.getItemId() == 1) {
|
|
|
|
|
DeepL.FragmentDialogDeepL fragment = new DeepL.FragmentDialogDeepL();
|
|
|
|
|
fragment.show(getParentFragmentManager(), "deepl:configure");
|
|
|
|
|
} else {
|
|
|
|
|
String target = item.getIntent().getStringExtra("target");
|
|
|
|
|
onMenuTranslate(target);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
popupMenu.showWithIcons(getContext(), v);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void onMenuTranslate(String target) {
|
|
|
|
|
final Pair<Integer, Integer> paragraph = DeepL.getParagraph(etBody);
|
|
|
|
|
if (paragraph == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Editable edit = etBody.getText();
|
|
|
|
|
String text = edit.subSequence(paragraph.first, paragraph.second).toString();
|
|
|
|
|
|
|
|
|
|
Bundle args = new Bundle();
|
|
|
|
|
args.putString("target", target);
|
|
|
|
|
args.putString("text", text);
|
|
|
|
|
|
|
|
|
|
new SimpleTask<DeepL.Translation>() {
|
|
|
|
|
@Override
|
|
|
|
|
protected void onPreExecute(Bundle args) {
|
|
|
|
|
ToastEx.makeText(getContext(), R.string.title_translating, Toast.LENGTH_SHORT).show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected DeepL.Translation onExecute(Context context, Bundle args) throws Throwable {
|
|
|
|
|
String target = args.getString("target");
|
|
|
|
|
String text = args.getString("text");
|
|
|
|
|
return DeepL.translate(text, target, context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void onExecuted(Bundle args, DeepL.Translation translation) {
|
|
|
|
|
if (paragraph.second > edit.length())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
FragmentActivity activity = getActivity();
|
|
|
|
|
if (activity == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Context context = getContext();
|
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
|
|
|
|
|
|
|
|
|
// Insert translated text
|
|
|
|
|
edit.insert(paragraph.second, "\n\n" + translation.translated_text);
|
|
|
|
|
etBody.setSelection(paragraph.second + 2 + translation.translated_text.length());
|
|
|
|
|
|
|
|
|
|
boolean small = prefs.getBoolean("deepl_small", false);
|
|
|
|
|
if (small) {
|
|
|
|
|
RelativeSizeSpan[] spans = edit.getSpans(
|
|
|
|
|
paragraph.first, paragraph.second, RelativeSizeSpan.class);
|
|
|
|
|
for (RelativeSizeSpan span : spans)
|
|
|
|
|
edit.removeSpan(span);
|
|
|
|
|
edit.setSpan(new RelativeSizeSpan(HtmlHelper.FONT_SMALL),
|
|
|
|
|
paragraph.first, paragraph.second,
|
|
|
|
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Updated frequency
|
|
|
|
|
String key = "translated_" + args.getString("target");
|
|
|
|
|
int count = prefs.getInt(key, 0);
|
|
|
|
|
prefs.edit().putInt(key, count + 1).apply();
|
|
|
|
|
|
|
|
|
|
activity.invalidateOptionsMenu();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void onException(Bundle args, Throwable ex) {
|
|
|
|
|
Throwable exex = new Throwable("DeepL", ex);
|
|
|
|
|
Log.unexpectedError(getParentFragmentManager(), exex, false);
|
|
|
|
|
}
|
|
|
|
|
}.execute(FragmentCompose.this, args, "compose:translate");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tvSignature.setTypeface(monospaced ? Typeface.MONOSPACE : Typeface.DEFAULT);
|
|
|
|
|
|
|
|
|
|
cbSignature.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
|
|
@ -924,6 +815,13 @@ public class FragmentCompose extends FragmentBase {
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
fabTranslate.setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(View v) {
|
|
|
|
|
onTranslate(v);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
style_bar.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
|
|
|
@ -1006,13 +904,13 @@ public class FragmentCompose extends FragmentBase {
|
|
|
|
|
grpAttachments.setVisibility(View.GONE);
|
|
|
|
|
tvNoInternet.setVisibility(View.GONE);
|
|
|
|
|
grpBody.setVisibility(View.GONE);
|
|
|
|
|
ibTranslate.setVisibility(
|
|
|
|
|
DeepL.isAvailable(getContext()) ? View.VISIBLE : View.GONE);
|
|
|
|
|
grpSignature.setVisibility(View.GONE);
|
|
|
|
|
grpReferenceHint.setVisibility(View.GONE);
|
|
|
|
|
ibReferenceEdit.setVisibility(View.GONE);
|
|
|
|
|
ibReferenceImages.setVisibility(View.GONE);
|
|
|
|
|
tvReference.setVisibility(View.GONE);
|
|
|
|
|
fabTranslate.setVisibility(
|
|
|
|
|
DeepL.isAvailable(getContext()) ? View.VISIBLE : View.GONE);
|
|
|
|
|
style_bar.setVisibility(View.GONE);
|
|
|
|
|
media_bar.setVisibility(View.GONE);
|
|
|
|
|
bottom_navigation.setVisibility(View.GONE);
|
|
|
|
@ -2065,6 +1963,113 @@ public class FragmentCompose extends FragmentBase {
|
|
|
|
|
fragmentTransaction.commit();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void onTranslate(View anchor) {
|
|
|
|
|
final Context context = anchor.getContext();
|
|
|
|
|
|
|
|
|
|
List<DeepL.Language> languages = DeepL.getTargetLanguages(context);
|
|
|
|
|
if (languages == null)
|
|
|
|
|
languages = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
Pair<Integer, Integer> paragraph = DeepL.getParagraph(etBody);
|
|
|
|
|
boolean canTranslate = (DeepL.canTranslate(context) && paragraph != null);
|
|
|
|
|
|
|
|
|
|
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, getViewLifecycleOwner(), anchor);
|
|
|
|
|
|
|
|
|
|
popupMenu.getMenu().add(Menu.NONE, 1, 1, R.string.title_translate_configure);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < languages.size(); i++) {
|
|
|
|
|
DeepL.Language lang = languages.get(i);
|
|
|
|
|
MenuItem item = popupMenu.getMenu().add(Menu.NONE, i + 2, i + 2, lang.name)
|
|
|
|
|
.setIntent(new Intent().putExtra("target", lang.target));
|
|
|
|
|
if (lang.icon != null)
|
|
|
|
|
item.setIcon(lang.icon);
|
|
|
|
|
item.setEnabled(canTranslate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onMenuItemClick(MenuItem item) {
|
|
|
|
|
if (item.getItemId() == 1) {
|
|
|
|
|
DeepL.FragmentDialogDeepL fragment = new DeepL.FragmentDialogDeepL();
|
|
|
|
|
fragment.show(getParentFragmentManager(), "deepl:configure");
|
|
|
|
|
} else {
|
|
|
|
|
String target = item.getIntent().getStringExtra("target");
|
|
|
|
|
onMenuTranslate(target);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void onMenuTranslate(String target) {
|
|
|
|
|
final Pair<Integer, Integer> paragraph = DeepL.getParagraph(etBody);
|
|
|
|
|
if (paragraph == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Editable edit = etBody.getText();
|
|
|
|
|
String text = edit.subSequence(paragraph.first, paragraph.second).toString();
|
|
|
|
|
|
|
|
|
|
Bundle args = new Bundle();
|
|
|
|
|
args.putString("target", target);
|
|
|
|
|
args.putString("text", text);
|
|
|
|
|
|
|
|
|
|
new SimpleTask<DeepL.Translation>() {
|
|
|
|
|
@Override
|
|
|
|
|
protected void onPreExecute(Bundle args) {
|
|
|
|
|
ToastEx.makeText(context, R.string.title_translating, Toast.LENGTH_SHORT).show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected DeepL.Translation onExecute(Context context, Bundle args) throws Throwable {
|
|
|
|
|
String target = args.getString("target");
|
|
|
|
|
String text = args.getString("text");
|
|
|
|
|
return DeepL.translate(text, target, context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void onExecuted(Bundle args, DeepL.Translation translation) {
|
|
|
|
|
if (paragraph.second > edit.length())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
FragmentActivity activity = getActivity();
|
|
|
|
|
if (activity == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
|
|
|
|
|
|
|
|
|
// Insert translated text
|
|
|
|
|
edit.insert(paragraph.second, "\n\n" + translation.translated_text);
|
|
|
|
|
etBody.setSelection(paragraph.second + 2 + translation.translated_text.length());
|
|
|
|
|
|
|
|
|
|
boolean small = prefs.getBoolean("deepl_small", false);
|
|
|
|
|
if (small) {
|
|
|
|
|
RelativeSizeSpan[] spans = edit.getSpans(
|
|
|
|
|
paragraph.first, paragraph.second, RelativeSizeSpan.class);
|
|
|
|
|
for (RelativeSizeSpan span : spans)
|
|
|
|
|
edit.removeSpan(span);
|
|
|
|
|
edit.setSpan(new RelativeSizeSpan(HtmlHelper.FONT_SMALL),
|
|
|
|
|
paragraph.first, paragraph.second,
|
|
|
|
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Updated frequency
|
|
|
|
|
String key = "translated_" + args.getString("target");
|
|
|
|
|
int count = prefs.getInt(key, 0);
|
|
|
|
|
prefs.edit().putInt(key, count + 1).apply();
|
|
|
|
|
|
|
|
|
|
activity.invalidateOptionsMenu();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void onException(Bundle args, Throwable ex) {
|
|
|
|
|
Throwable exex = new Throwable("DeepL", ex);
|
|
|
|
|
Log.unexpectedError(getParentFragmentManager(), exex, false);
|
|
|
|
|
}
|
|
|
|
|
}.execute(FragmentCompose.this, args, "compose:translate");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
popupMenu.showWithIcons(context, anchor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean onActionStyle(int action, View anchor) {
|
|
|
|
|
Log.i("Style action=" + action);
|
|
|
|
|
return StyleHelper.apply(action, getViewLifecycleOwner(), anchor, etBody);
|
|
|
|
|