From 841b0e220111869fcaf26468d88c7dd18e3caac1 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 14 May 2023 11:12:54 +0800 Subject: [PATCH] Implement document moving on Android * java/org/gnu/emacs/EmacsDocumentsProvider.java (notifyChangeByName): New function. (queryDocument1): Set FLAG_SUPPORTS_MOVE where necessary. (moveDocument): Implement new function. --- .../org/gnu/emacs/EmacsDocumentsProvider.java | 114 +++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/java/org/gnu/emacs/EmacsDocumentsProvider.java b/java/org/gnu/emacs/EmacsDocumentsProvider.java index a92a1a5d330..b4ac4624829 100644 --- a/java/org/gnu/emacs/EmacsDocumentsProvider.java +++ b/java/org/gnu/emacs/EmacsDocumentsProvider.java @@ -38,7 +38,9 @@ import android.webkit.MimeTypeMap; import android.net.Uri; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; /* ``Documents provider''. This allows Emacs's home directory to be @@ -155,6 +157,22 @@ public final class EmacsDocumentsProvider extends DocumentsProvider context.getContentResolver ().notifyChange (updatedUri, null); } + /* Inform the system that FILE's contents (or FILE itself) has + changed. FILE is a string describing containing the file name of + a directory as opposed to a File. */ + + private void + notifyChangeByName (String file) + { + Uri updatedUri; + Context context; + + context = getContext (); + updatedUri + = buildChildDocumentsUri ("org.gnu.emacs", file); + context.getContentResolver ().notifyChange (updatedUri, null); + } + /* Return the MIME type of a file FILE. */ private String @@ -212,6 +230,9 @@ public final class EmacsDocumentsProvider extends DocumentsProvider if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) flags |= Document.FLAG_SUPPORTS_RENAME; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + flags |= Document.FLAG_SUPPORTS_MOVE; } } else if (file.canWrite ()) @@ -224,7 +245,10 @@ public final class EmacsDocumentsProvider extends DocumentsProvider flags |= Document.FLAG_SUPPORTS_RENAME; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) - flags |= Document.FLAG_SUPPORTS_REMOVE; + { + flags |= Document.FLAG_SUPPORTS_REMOVE; + flags |= Document.FLAG_SUPPORTS_MOVE; + } } displayName = file.getName (); @@ -460,4 +484,92 @@ public final class EmacsDocumentsProvider extends DocumentsProvider { return documentId.startsWith (parentDocumentId); } + + @Override + public String + moveDocument (String sourceDocumentId, + String sourceParentDocumentId, + String targetParentDocumentId) + throws FileNotFoundException + { + File file, newName; + FileInputStream inputStream; + FileOutputStream outputStream; + byte buffer[]; + int length; + + file = new File (sourceDocumentId); + + /* Now, create the file name of the parent document. */ + newName = new File (targetParentDocumentId, + file.getName ()); + + /* Try to perform a simple rename, before falling back to + copying. */ + + if (file.renameTo (newName)) + { + notifyChangeByName (file.getParent ()); + notifyChangeByName (targetParentDocumentId); + return newName.getAbsolutePath (); + } + + /* If that doesn't work, create the new file and copy over the old + file's contents. */ + + inputStream = null; + outputStream = null; + + try + { + if (!newName.createNewFile () + || !newName.setWritable (true) + || !newName.setReadable (true)) + throw new FileNotFoundException ("failed to create new file"); + + /* Open the file in preparation for a copy. */ + + inputStream = new FileInputStream (file); + outputStream = new FileOutputStream (newName); + + /* Allocate the buffer used to hold data. */ + + buffer = new byte[4096]; + + while ((length = inputStream.read (buffer)) > 0) + outputStream.write (buffer, 0, length); + } + catch (IOException e) + { + throw new FileNotFoundException ("IOException: " + e); + } + finally + { + try + { + if (inputStream != null) + inputStream.close (); + } + catch (IOException e) + { + + } + + try + { + if (outputStream != null) + outputStream.close (); + } + catch (IOException e) + { + + } + } + + file.delete (); + notifyChangeByName (file.getParent ()); + notifyChangeByName (targetParentDocumentId); + + return newName.getAbsolutePath (); + } } -- 2.39.2