From fdb972632c2996f0f1c8c2b0a3c0a4da34c957a0 Mon Sep 17 00:00:00 2001 From: Harshad Vedartham Date: Tue, 31 Oct 2023 14:48:24 -0700 Subject: [PATCH] Reworked attachments, nr3 - #2125 #2106 #2132 (PR #2132) --- .../frontend/AttachLinkOrFileDialog.java | 36 +++++++----- .../frontend/textview/HighlightingEditor.java | 2 +- .../frontend/textview/TextViewUtils.java | 5 +- .../gsantner/opoc/util/GsContextUtils.java | 57 ++++++------------- 4 files changed, 44 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/frontend/AttachLinkOrFileDialog.java b/app/src/main/java/net/gsantner/markor/frontend/AttachLinkOrFileDialog.java index f7bbc3715..9e1a50ef6 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/AttachLinkOrFileDialog.java +++ b/app/src/main/java/net/gsantner/markor/frontend/AttachLinkOrFileDialog.java @@ -120,7 +120,7 @@ public static void showInsertImageOrLinkDialog( final AlertDialog dialog = builder.setView(view).create(); // Helper func - final GsCallback.a1 _insertItem = (type) -> insertItem(type, textFormatId, activity, edit, currentFile, dialog); + final GsCallback.a1 _insertItem = (type) -> insertItem(type, textFormatId, activity, edit, currentFile, sel, dialog); // Setup all the various choices final InsertType browseType, okType; @@ -216,14 +216,20 @@ private static void insertItem( final Activity activity, final Editable text, final File currentFile, + @Nullable final int[] region, @Nullable AlertDialog dialog ) { - final int[] sel = TextViewUtils.getSelection(text); + final int[] sel; + if (region != null && region.length > 1 && region[0] >= 0 && region[1] >= 0) { + sel = region; + } else { + sel = TextViewUtils.getSelection(text); + } final AppSettings _appSettings = ApplicationObject.settings(); final File attachmentDir = _appSettings.getAttachmentFolder(currentFile); - // Source, dest to be written when the user hits accept + // Title, path to be written when the user hits accept final GsCallback.a2 insertLink = (title, path) -> { if (TextViewUtils.isNullOrEmpty(path)) { return; @@ -244,7 +250,7 @@ private static void insertItem( newText = newText.replaceFirst("\\|]]$", "]]"); } - if (!text.subSequence(sel[0], sel[1]).equals(newText)) { + if (!newText.equals(text.subSequence(sel[0], sel[1]).toString())) { text.replace(sel[0], sel[1], newText); } @@ -297,13 +303,17 @@ private static void insertItem( } case IMAGE_EDIT: { if (pathEdit != null) { - String filepath = pathEdit.getText().toString().replace("%20", " "); - if (!filepath.startsWith("/")) { - filepath = new File(currentFile.getParent(), filepath).getAbsolutePath(); + final String path = pathEdit.getText().toString().replace("%20", " "); + + final File abs = new File(path).getAbsoluteFile(); + if (abs.isFile()) { + shu.requestFileEdit(activity, abs); + break; } - File file = new File(filepath); - if (file.exists() && file.isFile()) { - shu.requestPictureEdit(activity, file); + + final File rel = new File(currentFile.getParentFile(), path).getAbsoluteFile(); + if (rel.isFile()) { + shu.requestFileEdit(activity, rel); } } break; @@ -355,7 +365,7 @@ public static void insertCameraPhoto( final Editable text, final File currentFile ) { - insertItem(InsertType.IMAGE_CAMERA, textFormatId, activity, text, currentFile, null); + insertItem(InsertType.IMAGE_CAMERA, textFormatId, activity, text, currentFile, null, null); } public static void insertGalleryPhoto( @@ -364,7 +374,7 @@ public static void insertGalleryPhoto( final Editable text, final File currentFile ) { - insertItem(InsertType.IMAGE_GALLERY, textFormatId, activity, text, currentFile, null); + insertItem(InsertType.IMAGE_GALLERY, textFormatId, activity, text, currentFile, null, null); } public static void insertAudioRecording( @@ -373,6 +383,6 @@ public static void insertAudioRecording( final Editable text, final File currentFile ) { - insertItem(InsertType.AUDIO_RECORDING, textFormatId, activity, text, currentFile, null); + insertItem(InsertType.AUDIO_RECORDING, textFormatId, activity, text, currentFile, null, null); } } diff --git a/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java b/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java index b2b58424f..7b828ffe5 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java +++ b/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java @@ -428,7 +428,7 @@ public void insertOrReplaceTextOnCursor(final String newText) { if (newCursorPos >= 0) { setSelection(sel[0] + newCursorPos); - TextViewUtils.showSelection(this); + postDelayed(() -> TextViewUtils.showSelection(this), 500); } } } diff --git a/app/src/main/java/net/gsantner/markor/frontend/textview/TextViewUtils.java b/app/src/main/java/net/gsantner/markor/frontend/textview/TextViewUtils.java index 889d2debf..1f75c1827 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/textview/TextViewUtils.java +++ b/app/src/main/java/net/gsantner/markor/frontend/textview/TextViewUtils.java @@ -728,7 +728,10 @@ public static boolean isViewVisible(final View view) { // Check if keyboard open. Only available after android 11 :( public static Boolean isImeOpen(final View view) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - return view.getRootWindowInsets().isVisible(WindowInsets.Type.ime()); + final WindowInsets insets = view.getRootWindowInsets(); + if (insets != null) { + insets.isVisible(WindowInsets.Type.ime()); + } } return null; // Uncertain } diff --git a/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java b/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java index 3e1652506..b701fb2bc 100644 --- a/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java +++ b/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java @@ -143,8 +143,6 @@ import java.io.OutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.net.URI; -import java.net.URISyntaxException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; @@ -163,8 +161,6 @@ public class GsContextUtils { //######################## public static final GsContextUtils instance = new GsContextUtils(); - private static String _authority = null; - public GsContextUtils() { } @@ -1081,15 +1077,12 @@ public List getProvidersInfos(final Context context) { } public String getFileProvider(final Context context) { - if (_authority == null) { - for (final ProviderInfo info : getProvidersInfos(context)) { - if (info.name.matches("(?i).*fileprovider.*")) { - _authority = info.authority; - break; - } + for (final ProviderInfo info : getProvidersInfos(context)) { + if (info.name.matches("(?i).*fileprovider.*")) { + return info.authority; } } - return _authority; + throw new RuntimeException("Error at GsContextUtils::getFileProviderAuthority(context): No FileProvider authority setup"); } /** @@ -1127,30 +1120,11 @@ public T animateToActivity(final Activity context, fi } - public String getFileProviderAuthority(final Context context) { - final String provider = getFileProvider(context); - if (TextUtils.isEmpty(provider)) { - throw new RuntimeException("Error at GsContextUtils::getFileProviderAuthority(context): No FileProvider authority setup"); - } - return provider; - } - - public T setChooserTitle(final String title) { m_chooserTitle = title; return thisp(); } - /** - * Convert a {@link File} to an {@link Uri} - * - * @param file the file - * @return Uri for this file - */ - public Uri getUriByFileProviderAuthority(final Context context, final File file) { - return FileProvider.getUriForFile(context, getFileProviderAuthority(context), file); - } - /** * Allow to choose a handling app for given intent * @@ -1248,7 +1222,7 @@ public boolean shareStream(final Context context, final File file, final String intent.setType(mimeType); try { - Uri fileUri = FileProvider.getUriForFile(context, getFileProviderAuthority(context), file); + final Uri fileUri = FileProvider.getUriForFile(context, getFileProvider(context), file); intent.putExtra(Intent.EXTRA_STREAM, fileUri); showChooser(context, intent, null); return true; @@ -1267,7 +1241,7 @@ public boolean shareStreamMultiple(final Context context, final Collection ArrayList uris = new ArrayList<>(); for (File file : files) { File uri = new File(file.toString()); - uris.add(FileProvider.getUriForFile(context, getFileProviderAuthority(context), file)); + uris.add(FileProvider.getUriForFile(context, getFileProvider(context), file)); } try { @@ -1336,7 +1310,7 @@ public boolean viewFileInOtherApp(final Context context, final File file, @Nulla // On some specific devices the first won't work Uri fileUri = null; try { - fileUri = FileProvider.getUriForFile(context, getFileProviderAuthority(context), file); + fileUri = FileProvider.getUriForFile(context, getFileProvider(context), file); } catch (Exception ignored) { try { fileUri = Uri.fromFile(file); @@ -1373,7 +1347,7 @@ public boolean requestApkInstallation(final Context context, final File file) { Uri fileUri = null; try { - fileUri = FileProvider.getUriForFile(context, getFileProviderAuthority(context), file); + fileUri = FileProvider.getUriForFile(context, getFileProvider(context), file); } catch (Exception ignored) { try { fileUri = Uri.fromFile(file); @@ -1776,7 +1750,7 @@ public void requestCameraPicture(final Activity activity) { // Continue only if the File was successfully created final Uri uri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - uri = FileProvider.getUriForFile(activity, getFileProviderAuthority(activity), imageTemp); + uri = FileProvider.getUriForFile(activity, getFileProvider(activity), imageTemp); } else { uri = Uri.fromFile(imageTemp); } @@ -1932,18 +1906,19 @@ public void onReceive(Context context, Intent intent) { } /** - * Request edit of image (by image editor/viewer - for example to crop image) + * Request edit of file * * @param file File that should be edited */ - public void requestPictureEdit(final Context context, final File file) { - final Uri uri = getUriByFileProviderAuthority(context, file); + public void requestFileEdit(final Context context, final File file) { + final Uri uri = FileProvider.getUriForFile(context, getFileProvider(context), file); final Intent intent = new Intent(Intent.ACTION_EDIT); - intent.setDataAndType(uri, "image/*"); - intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.setDataAndType(uri, GsFileUtils.getMimeType(file)); + intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); intent.putExtra(EXTRA_FILEPATH, file.getAbsolutePath()); - startActivity(context, Intent.createChooser(intent, null)); + startActivity(context, intent); } /**