Skip to content

Commit

Permalink
#169: Imagedetail rename file via SAF (SD-Card)
Browse files Browse the repository at this point in the history
  • Loading branch information
k3b committed Apr 5, 2020
1 parent dc235ef commit 1705127
Show file tree
Hide file tree
Showing 9 changed files with 537 additions and 255 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
import de.k3b.android.androFotoFinder.tagDB.TagSql;
import de.k3b.android.androFotoFinder.tagDB.TagTask;
import de.k3b.android.androFotoFinder.tagDB.TagsPickerFragment;
import de.k3b.android.util.AndroidFileApi;
import de.k3b.android.util.AndroidFileCommands;
import de.k3b.android.util.FileManagerUtil;
import de.k3b.android.util.IntentUtil;
Expand All @@ -75,6 +74,7 @@
import de.k3b.android.widget.AboutDialogPreference;
import de.k3b.android.widget.ActivityWithCallContext;
import de.k3b.android.widget.Dialogs;
import de.k3b.android.widget.FilePermissionActivity;
import de.k3b.database.QueryParameter;
import de.k3b.geo.api.GeoPointDto;
import de.k3b.geo.io.GeoUri;
Expand Down Expand Up @@ -664,79 +664,62 @@ private boolean checkForIncompleteMediaDatabase(String jpgFullFilePath, String w
return false;
}

private void onRenameFileAnswer(final SelectedFiles currentFoto, final long fotoId,
private void onRenameFileAnswer(final CharSequence title, final SelectedFiles currentFoto, final long fotoId,
final String fotoSourcePath, final String newFileName) {
File src = new File(fotoSourcePath);
try {
File dest = new File(src.getParentFile(), newFileName);
File dest = new File(src.getParentFile(), newFileName);

File srcXmpShort = FileProcessor.getSidecar(src, false);
boolean hasSideCarShort = ((srcXmpShort != null) && (mFileCommands.osFileExists(srcXmpShort)));
File srcXmpLong = FileProcessor.getSidecar(src, true);
boolean hasSideCarLong = ((srcXmpLong != null) && (mFileCommands.osFileExists(srcXmpLong)));
File srcXmpShort = FileProcessor.getSidecar(src, false);
boolean hasSideCarShort = ((srcXmpShort != null) && (mFileCommands.osFileExists(srcXmpShort)));
File srcXmpLong = FileProcessor.getSidecar(src, true);
boolean hasSideCarLong = ((srcXmpLong != null) && (mFileCommands.osFileExists(srcXmpLong)));

File destXmpShort = FileProcessor.getSidecar(dest, false);
File destXmpLong = FileProcessor.getSidecar(dest, true);
File destXmpShort = FileProcessor.getSidecar(dest, false);
File destXmpLong = FileProcessor.getSidecar(dest, true);

if (src.equals(dest)) return; // new name == old name ==> nothing to do
if (src.equals(dest)) return; // new name == old name ==> nothing to do

String errorMessage = null;
if (hasSideCarShort && mFileCommands.osFileExists(destXmpShort)) {
errorMessage = getString(R.string.image_err_file_exists_format, destXmpShort.getAbsoluteFile());
}
if (hasSideCarLong && mFileCommands.osFileExists(destXmpLong)) {
errorMessage = getString(R.string.image_err_file_exists_format, destXmpLong.getAbsoluteFile());
}
if (mFileCommands.osFileExists(dest)) {
errorMessage = getString(R.string.image_err_file_exists_format, dest.getAbsoluteFile());
}
String errorMessage = null;
if (hasSideCarShort && mFileCommands.osFileExists(destXmpShort)) {
errorMessage = getString(R.string.image_err_file_exists_format, destXmpShort.getAbsoluteFile());
}
if (hasSideCarLong && mFileCommands.osFileExists(destXmpLong)) {
errorMessage = getString(R.string.image_err_file_exists_format, destXmpLong.getAbsoluteFile());
}
if (mFileCommands.osFileExists(dest)) {
errorMessage = getString(R.string.image_err_file_exists_format, dest.getAbsoluteFile());
}

PhotoChangeNotifyer.setPhotoChangedListener(this);
if (errorMessage != null) {
// dest-file already exists
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
onRenameFileQueston(currentFoto, fotoId, fotoSourcePath, newFileName);
} else if (osRenameTo(dest, currentFoto)) {
mModifyCount++;
} else {
// rename failed
errorMessage = getString(R.string.image_err_file_rename_format, src.getAbsoluteFile());
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
}
} catch (AndroidFileApi.PermissionException ex) {
//!!! TODO
/*
requestWritePermission(src, new IOnDirectoryPermissionGrantedHandler() {
@Override
public void afterGrant(FilePermissionActivity activity) {
((ImageDetailActivityViewPager) activity).onRenameFileAnswer(currentFoto, fotoId, fotoSourcePath, newFileName);
}
});
*/
PhotoChangeNotifyer.setPhotoChangedListener(this);
if (errorMessage != null) {
// dest-file already exists
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
onRenameFileQueston(title, currentFoto, fotoId, fotoSourcePath, newFileName);
} else if (osRenameTo(title, dest, currentFoto)) {
mModifyCount++;
} else {
// rename failed
errorMessage = getString(R.string.image_err_file_rename_format, src.getAbsoluteFile());
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
}
}

private boolean osRenameTo(final File dest, final SelectedFiles currentFoto) {
boolean done = mFileCommands.rename(currentFoto, dest, null);
/*
if (!done) {
File oldFile = currentFoto.getFile(0);
DocumentFile[] dirs = requestDocumentDirWithPermissionsOrNull(
private boolean osRenameTo(final CharSequence title, final File dest, final SelectedFiles currentFoto) {
// close rename dialog to allow messagebox that prepares to ask
closeDialogIfNeeded();
File missingRoot = getMissingRootDirFileOrNull(currentFoto.getFiles());
if (missingRoot == null) {
return mFileCommands.setContext(this).rename(currentFoto, dest, null);
} else {
requestRootUriDialog(missingRoot, title,
new IOnDirectoryPermissionGrantedHandler() {
@Override
public void afterGrant(FilePermissionActivity activity) {
((ImageDetailActivityViewPager) activity).osRenameTo(dest, currentFoto);
((ImageDetailActivityViewPager) activity).osRenameTo(title, dest, currentFoto);
}
}, oldFile);
if (dirs != null) {
done = dirs[0].renameTo(dest.getName());
return true;
!!!
}
});
return false;
}
*/
return done;
}

@Override
Expand Down Expand Up @@ -800,7 +783,7 @@ public boolean onPrepareOptionsMenu(Menu menu) {
return super.onPrepareOptionsMenu(menu);
}

private boolean onRenameFileQueston(final SelectedFiles currentFoto, final long fotoId, final String fotoPath, final String _newName) {
private boolean onRenameFileQueston(final CharSequence title, final SelectedFiles currentFoto, final long fotoId, final String fotoPath, final String _newName) {
if (AndroidFileCommands.canProcessFile(this, false)) {
final String newName = (_newName == null)
? new File(getCurrentFilePath()).getName()
Expand All @@ -811,16 +794,16 @@ private boolean onRenameFileQueston(final SelectedFiles currentFoto, final long
@Override
protected void onDialogResult(String newFileName, Object... parameters) {
if (newFileName != null) {
onRenameFileAnswer(currentFoto, (Long) parameters[0], (String) parameters[1], newFileName);
onRenameFileAnswer(title, currentFoto, (Long) parameters[0], (String) parameters[1], newFileName);
}
}
};
dialog.editFileName(this, getString(R.string.rename_menu_title), newName, fotoId, fotoPath);
dialog.editFileName(this, title, newName, fotoId, fotoPath);
}
return true;
}

private boolean cmdMoveOrCopyWithDestDirPicker(final boolean move, String lastCopyToPath, final SelectedFiles fotos) {
private boolean cmdMoveOrCopyWithDestDirPicker(CharSequence title, final boolean move, String lastCopyToPath, final SelectedFiles fotos) {
if (AndroidFileCommands.canProcessFile(this, false)) {
PhotoChangeNotifyer.setPhotoChangedListener(this);
mDestDirPicker = MoveOrCopyDestDirPicker.newInstance(move, fotos);
Expand Down Expand Up @@ -933,14 +916,14 @@ public boolean onOptionsItemSelected(MenuItem menuItem) {
break;

case R.id.cmd_copy:
result = cmdMoveOrCopyWithDestDirPicker(false, mFileCommands.getLastCopyToPath(), getCurrentFoto());
result = cmdMoveOrCopyWithDestDirPicker(menuItem.getTitle(), false, mFileCommands.getLastCopyToPath(), getCurrentFoto());
break;
case R.id.cmd_move:
result = cmdMoveOrCopyWithDestDirPicker(true, mFileCommands.getLastCopyToPath(), getCurrentFoto());
result = cmdMoveOrCopyWithDestDirPicker(menuItem.getTitle(), true, mFileCommands.getLastCopyToPath(), getCurrentFoto());
break;
case R.id.menu_item_rename:
PhotoChangeNotifyer.setPhotoChangedListener(this);
result = onRenameFileQueston(getCurrentFoto(), getCurrentImageId(), getCurrentFilePath(), null);
result = onRenameFileQueston(menuItem.getTitle(), getCurrentFoto(), getCurrentImageId(), getCurrentFilePath(), null);
break;
case R.id.menu_exif:
result = onEditExif(menuItem, getCurrentFoto(), getCurrentImageId(), getCurrentFilePath());
Expand Down Expand Up @@ -1074,7 +1057,7 @@ private void reloadIfDataHasChanged() {
}

//TODO implementation not completed yet
private boolean onRenameDirQueston(final SelectedFiles currentFoto, final long fotoId, final String fotoPath, final String _newName) {
private boolean onRenameDirQueston(final CharSequence title, final SelectedFiles currentFoto, final long fotoId, final String fotoPath, final String _newName) {
if (AndroidFileCommands.canProcessFile(this, false)) {
final String newName = (_newName == null)
? new File(getCurrentFilePath()).getName()
Expand All @@ -1085,7 +1068,7 @@ private boolean onRenameDirQueston(final SelectedFiles currentFoto, final long f
@Override
protected void onDialogResult(String newFileName, Object... parameters) {
if (newFileName != null) {
onRenameSubDirAnswer(currentFoto, (Long) parameters[0], (String) parameters[1], newFileName);
onRenameSubDirAnswer(title, currentFoto, (Long) parameters[0], (String) parameters[1], newFileName);
}
}
};
Expand All @@ -1094,7 +1077,7 @@ protected void onDialogResult(String newFileName, Object... parameters) {
return true;
}

private void onRenameSubDirAnswer(SelectedFiles currentFoto, final long fotoId, final String fotoSourcePath, String newFileName) {
private void onRenameSubDirAnswer(final CharSequence title, SelectedFiles currentFoto, final long fotoId, final String fotoSourcePath, String newFileName) {
File src = new File(fotoSourcePath);
File dest = new File(src.getParentFile(), newFileName);

Expand Down Expand Up @@ -1122,8 +1105,8 @@ private void onRenameSubDirAnswer(SelectedFiles currentFoto, final long fotoId,
if (errorMessage != null) {
// dest-file already exists
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
onRenameDirQueston(currentFoto, fotoId, fotoSourcePath, newFileName);
} else if (osRenameTo(dest, currentFoto)) {
onRenameDirQueston(title, currentFoto, fotoId, fotoSourcePath, newFileName);
} else if (osRenameTo(title, dest, currentFoto)) {
mModifyCount++;
} else {
// rename failed
Expand Down
56 changes: 39 additions & 17 deletions app/src/main/java/de/k3b/android/util/AndroidFileApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,63 @@
*/
package de.k3b.android.util;

import android.app.Activity;
import android.content.Context;
import android.support.v4.provider.DocumentFile;
import android.util.Log;

import java.io.File;

import de.k3b.android.androFotoFinder.Global;
import de.k3b.android.widget.FilePermissionActivity;
import de.k3b.io.FileApi;

/**
* File api abstraction based on android dependand {@link android.support.v4.provider.DocumentFile} API
*/
public class AndroidFileApi extends FileApi {
protected boolean osRenameTo(File dest, File source) throws PermissionException {
private DocumentFileTranslator documentFileTranslator = null;
private Context mContext = null;

public void setContext(Activity activity) {
if (activity != null) {
mContext = activity.getApplicationContext();
if (mContext instanceof FilePermissionActivity) {
documentFileTranslator = ((FilePermissionActivity) mContext).getDocumentFileTranslator();
}
}
}

protected DocumentFile getOrCreateDirectory(File dir) {
return getDocumentFileTranslator().getOrCreateDirectory(dir);
}

private DocumentFileTranslator getDocumentFileTranslator() {
if (this.documentFileTranslator == null) {
this.documentFileTranslator = DocumentFileTranslator.create(this.mContext);
}
return this.documentFileTranslator;
}

protected boolean osRenameTo(File dest, File source) {
final String context = this.getClass().getSimpleName() +
".osRenameTo(" + dest + " <== " + source + ")";
if ((source != null) && (dest != null)) {
if (dest.getParentFile().equals(source.getParentFile())) {
Boolean result = null;
try {
final DocumentFile documentFile = DocumentFile.fromFile(source);
if (!documentFile.canWrite()) throw new PermissionException(source, context);
DocumentFile documentFile = DocumentFile.fromFile(source);
if (!documentFile.canWrite()) {
if (source.isDirectory()) {
documentFile = getOrCreateDirectory(source);
} else {
DocumentFile dir = getOrCreateDirectory(source.getParentFile());
DocumentFile found = dir.findFile(source.getName());
if (found != null) {
documentFile = found;
}
}
}
result = documentFile.renameTo(dest.getName());
return result;
} finally {
Expand All @@ -53,18 +89,4 @@ protected boolean osRenameTo(File dest, File source) throws PermissionException
Log.w(TAG, context + " move between different directories is not implemented yet");
return super.osRenameTo(dest, source);
}

public static class PermissionException extends RuntimeException {
private final File sourceFile;

public PermissionException(File source, String errorMessage) {
super(errorMessage);
this.sourceFile = source;
}

public File getSourceFile() {
return sourceFile;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ public AndroidFileCommands setContext(Activity activity) {
this.mContext = activity.getApplicationContext();
closeLogFile();
mScanner = PhotoPropertiesMediaFilesScanner.getInstance(mContext);
((AndroidFileApi) this.fileApi).setContext(activity);
}

return this;
Expand Down
Loading

0 comments on commit 1705127

Please sign in to comment.