This commit is contained in:
OpenSauce 2025-10-05 15:10:35 -04:00 committed by GitHub
commit 52638b0629
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 100 additions and 16 deletions

View file

@ -689,6 +689,19 @@ object NativeLibrary {
FileUtil.renameFile(path, destinationFilename)
}
@Keep
@JvmStatic
fun moveFile(filename: String, sourceDirPath: String, destinationDirPath: String): Boolean =
if (FileUtil.isNativePath(sourceDirPath)) {
try {
CitraApplication.documentsTree.moveFile(filename, sourceDirPath, destinationDirPath)
} catch (e: Exception) {
false
}
} else {
FileUtil.moveFile(filename, sourceDirPath, destinationDirPath)
}
@Keep
@JvmStatic
fun deleteDocument(path: String): Boolean =

View file

@ -191,7 +191,7 @@ class DocumentsTree {
}
@Synchronized
fun renameFile(filepath: String, destinationFilename: String?): Boolean {
fun renameFile(filepath: String, destinationFilename: String): Boolean {
val node = resolvePath(filepath) ?: return false
try {
val filename = URLDecoder.decode(destinationFilename, FileUtil.DECODE_METHOD)
@ -203,6 +203,20 @@ class DocumentsTree {
}
}
@Synchronized
fun moveFile(filename: String, sourceDirPath: String, destDirPath: String): Boolean {
val sourceFileNode = resolvePath(sourceDirPath + "/" + filename) ?: return false
val sourceDirNode = resolvePath(sourceDirPath) ?: return false
val destDirNode = resolvePath(destDirPath) ?: return false
try {
val newUri = DocumentsContract.moveDocument(context.contentResolver, sourceFileNode.uri!!, sourceDirNode.uri!!, destDirNode.uri!!)
sourceFileNode.rename(filename, newUri)
return true
} catch (e: Exception) {
error("[DocumentsTree]: Cannot move file, error: " + e.message)
}
}
@Synchronized
fun deleteDocument(filepath: String): Boolean {
val node = resolvePath(filepath) ?: return false

View file

@ -1,4 +1,4 @@
// Copyright 2023 Citra Emulator Project
// Copyright Citra Emulator Project / Azahar Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@ -11,6 +11,7 @@ import android.net.Uri
import android.provider.DocumentsContract
import android.system.Os
import android.util.Pair
import androidx.core.net.toUri
import androidx.documentfile.provider.DocumentFile
import org.citra.citra_emu.CitraApplication
import org.citra.citra_emu.model.CheapDocument
@ -434,6 +435,20 @@ object FileUtil {
return false
}
@JvmStatic
fun moveFile(filename: String, sourceDirUriString: String, destDirUriString: String): Boolean {
try {
val sourceFileUri = ("$sourceDirUriString%2F$filename").toUri()
val sourceDirUri = sourceDirUriString.toUri()
val destDirUri = destDirUriString.toUri()
DocumentsContract.moveDocument(context.contentResolver, sourceFileUri, sourceDirUri, destDirUri)
return true
} catch (e: Exception) {
Log.error("[FileUtil]: Cannot move file, error: " + e.message)
}
return false
}
@JvmStatic
fun deleteDocument(path: String): Boolean {
try {

View file

@ -1,4 +1,4 @@
// Copyright 2023 Citra Emulator Project
// Copyright Citra Emulator Project / Azahar Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@ -172,6 +172,18 @@ bool RenameFile(const std::string& source, const std::string& filename) {
j_destination_path);
}
bool MoveFile(const std::string& filename, const std::string& source_dir_path,
const std::string& destination_dir_path) {
if (rename_file == nullptr)
return false;
auto env = GetEnvForThread();
jstring j_filename = env->NewStringUTF(filename.c_str());
jstring j_source_dir_path = env->NewStringUTF(source_dir_path.c_str());
jstring j_destination_dir_path = env->NewStringUTF(destination_dir_path.c_str());
return env->CallStaticBooleanMethod(native_library, move_file, j_filename, j_source_dir_path,
j_destination_dir_path);
}
#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \
F(FunctionName, ReturnValue, JMethodID, Caller)
#define F(FunctionName, ReturnValue, JMethodID, Caller) \

View file

@ -1,4 +1,4 @@
// Copyright 2023 Citra Emulator Project
// Copyright Citra Emulator Project / Azahar Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@ -24,7 +24,11 @@
const std::string& destination_filename), \
copy_file, "copyFile", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z") \
V(RenameFile, bool, (const std::string& source, const std::string& filename), rename_file, \
"renameFile", "(Ljava/lang/String;Ljava/lang/String;)Z")
"renameFile", "(Ljava/lang/String;Ljava/lang/String;)Z") \
V(MoveFile, bool, \
(const std::string& filename, const std::string& source_dir_path, \
const std::string& destination_dir_path), \
move_file, "moveFile", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z")
#define ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(V) \
V(IsDirectory, bool, is_directory, CallStaticBooleanMethod, "isDirectory", \
"(Ljava/lang/String;)Z") \

View file

@ -304,20 +304,41 @@ bool DeleteDir(const std::string& filename) {
return false;
}
bool Rename(const std::string& srcFilename, const std::string& destFilename) {
LOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFilename);
bool Rename(const std::string& srcFilePath, const std::string& destFileName) {
LOG_TRACE(Common_Filesystem, "{} --> {}", srcFilePath, destFileName);
#ifdef _WIN32
if (_wrename(Common::UTF8ToUTF16W(srcFilename).c_str(),
Common::UTF8ToUTF16W(destFilename).c_str()) == 0)
if (_wrename(Common::UTF8ToUTF16W(srcFilePath).c_str(),
Common::UTF8ToUTF16W(std::string(GetFilename(destFileName))).c_str()) == 0)
return true;
#elif ANDROID
if (AndroidStorage::RenameFile(srcFilename, std::string(GetFilename(destFilename))))
if (AndroidStorage::RenameFile(srcFilePath, std::string(GetFilename(destFileName))))
return true;
#else
if (rename(srcFilename.c_str(), destFilename.c_str()) == 0)
if (rename(srcFilePath.c_str(), std::string(GetFilename(destFileName)).c_str()) == 0)
return true;
#endif
LOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilename, destFilename,
LOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilePath, destFileName,
GetLastErrorMsg());
return false;
}
bool Move(const std::string& srcFileName, const std::string& srcDirPath,
const std::string& destDirPath) {
const auto srcFilePath = srcDirPath + DIR_SEP + srcFileName;
const auto destFilePath = destDirPath + DIR_SEP + srcFileName;
LOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFileName);
#ifdef _WIN32
if (_wrename(Common::UTF8ToUTF16W(srcFilePath).c_str(),
Common::UTF8ToUTF16W(destFilePath).c_str()) == 0)
return true;
#elif ANDROID
if (AndroidStorage::MoveFile(srcFileName, srcDirPath, destDirPath))
return true;
#else
if (rename(srcFilePath.c_str(), destFilePath.c_str()) == 0)
return true;
#endif
LOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilePath, destFilePath,
GetLastErrorMsg());
return false;
}

View file

@ -136,13 +136,18 @@ bool Delete(const std::string& filename);
// Deletes a directory filename, returns true on success
bool DeleteDir(const std::string& filename);
// renames file srcFilename to destFilename, returns true on success
bool Rename(const std::string& srcFilename, const std::string& destFilename);
// Renames file srcFilepath to destFilename, returns true on success.
// If a full path is passed to destFileName, everything except the name of the file is ignored.
bool Rename(const std::string& srcFilePath, const std::string& destFileName);
// copies file srcFilename to destFilename, returns true on success
// Moves file srcFileName from srcDirPath to destDirPath, returns true on success
bool Move(const std::string& srcFileName, const std::string& srcDirPath,
const std::string& destDirPath);
// Copies file srcFilename to destFilename, returns true on success
bool Copy(const std::string& srcFilename, const std::string& destFilename);
// creates an empty file filename, returns true on success
// Creates an empty file filename, returns true on success
bool CreateEmptyFile(const std::string& filename);
/**