Android: Allow opening/getting files relative to downloads directory
This commit is contained in:
parent
600ae7bcc0
commit
46d19eeb1f
|
@ -20,6 +20,7 @@ import java.io.OutputStream;
|
|||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* File helper class - used to bridge native code to Java storage access framework APIs.
|
||||
|
@ -53,6 +54,21 @@ public class FileHelper {
|
|||
DocumentsContract.Document.COLUMN_LAST_MODIFIED
|
||||
};
|
||||
|
||||
/**
|
||||
* Projection used when getting the display name for a file.
|
||||
*/
|
||||
private static final String[] getDisplayNameProjection = new String[]{
|
||||
DocumentsContract.Document.COLUMN_DISPLAY_NAME,
|
||||
};
|
||||
|
||||
/**
|
||||
* Projection used when getting a relative file for a file.
|
||||
*/
|
||||
private static final String[] getRelativeFileProjection = new String[]{
|
||||
DocumentsContract.Document.COLUMN_DOCUMENT_ID,
|
||||
DocumentsContract.Document.COLUMN_DISPLAY_NAME,
|
||||
};
|
||||
|
||||
private final Context context;
|
||||
private final ContentResolver contentResolver;
|
||||
|
||||
|
@ -244,6 +260,7 @@ public class FileHelper {
|
|||
|
||||
/**
|
||||
* Returns the file name component of a path or URI.
|
||||
*
|
||||
* @param path Path/URI to examine.
|
||||
* @return File name component of path/URI.
|
||||
*/
|
||||
|
@ -265,6 +282,14 @@ public class FileHelper {
|
|||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the given URI represents a {@link DocumentsContract.Document} tree.
|
||||
*/
|
||||
public static boolean isTreeUri(Uri uri) {
|
||||
final List<String> paths = uri.getPathSegments();
|
||||
return (paths.size() >= 2 && paths.get(0).equals("tree"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a file descriptor for a content URI string. Called by native code.
|
||||
*
|
||||
|
@ -353,6 +378,91 @@ public class FileHelper {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the display name for the given URI.
|
||||
*
|
||||
* @param uriString URI to resolve display name for.
|
||||
* @return display name for the URI, or null.
|
||||
*/
|
||||
public String getDisplayNameForURIPath(String uriString) {
|
||||
try {
|
||||
final Uri fullUri = Uri.parse(uriString);
|
||||
final Cursor cursor = contentResolver.query(fullUri, getDisplayNameProjection,
|
||||
null, null, null);
|
||||
if (cursor.getCount() == 0 || !cursor.moveToNext())
|
||||
return null;
|
||||
|
||||
return cursor.getString(0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path for a sibling file relative to another URI.
|
||||
*
|
||||
* @param uriString URI to find the file relative to.
|
||||
* @param newFileName Sibling file name.
|
||||
* @return URI for the sibling file name, or null.
|
||||
*/
|
||||
public String getRelativePathForURIPath(String uriString, String newFileName) {
|
||||
try {
|
||||
final Uri fullUri = Uri.parse(uriString);
|
||||
|
||||
// if this is a document (expected)...
|
||||
Uri treeUri;
|
||||
String treeDocId;
|
||||
if (DocumentsContract.isDocumentUri(context, fullUri)) {
|
||||
// we need to remove the last part of the URI (the specific document ID) to get the parent
|
||||
final String lastPathSegment = fullUri.getLastPathSegment();
|
||||
int lastSeparatorIndex = lastPathSegment.lastIndexOf('/');
|
||||
if (lastSeparatorIndex < 0)
|
||||
lastSeparatorIndex = lastPathSegment.lastIndexOf(':');
|
||||
if (lastSeparatorIndex < 0)
|
||||
return null;
|
||||
|
||||
// the parent becomes the document ID
|
||||
treeDocId = lastPathSegment.substring(0, lastSeparatorIndex);
|
||||
|
||||
// but, we need to access it through the subtree if this was a tree URI (permissions...)
|
||||
if (isTreeUri(fullUri)) {
|
||||
treeUri = DocumentsContract.buildTreeDocumentUri(fullUri.getAuthority(), DocumentsContract.getTreeDocumentId(fullUri));
|
||||
} else {
|
||||
treeUri = DocumentsContract.buildTreeDocumentUri(fullUri.getAuthority(), treeDocId);
|
||||
}
|
||||
} else {
|
||||
treeDocId = DocumentsContract.getDocumentId(fullUri);
|
||||
treeUri = fullUri;
|
||||
}
|
||||
|
||||
final Uri queryUri = DocumentsContract.buildChildDocumentsUriUsingTree(treeUri, treeDocId);
|
||||
final Cursor cursor = contentResolver.query(queryUri, getRelativeFileProjection, null, null, null);
|
||||
final int count = cursor.getCount();
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
try {
|
||||
final String displayName = cursor.getString(1);
|
||||
if (!displayName.equalsIgnoreCase(newFileName))
|
||||
continue;
|
||||
|
||||
final String childDocumentId = cursor.getString(0);
|
||||
final Uri uri = DocumentsContract.buildDocumentUriUsingTree(treeUri, childDocumentId);
|
||||
cursor.close();
|
||||
return uri.toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Java class containing the data for a file in a find operation.
|
||||
*/
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "assert.h"
|
||||
#include "file_system.h"
|
||||
#include "log.h"
|
||||
#include "string_util.h"
|
||||
#include <array>
|
||||
Log_SetChannel(CDImage);
|
||||
|
||||
|
@ -17,45 +18,50 @@ u32 CDImage::GetBytesPerSector(TrackMode mode)
|
|||
|
||||
std::unique_ptr<CDImage> CDImage::Open(const char* filename, Common::Error* error)
|
||||
{
|
||||
const char* extension = std::strrchr(filename, '.');
|
||||
const char* extension;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
std::string filename_display_name(FileSystem::GetDisplayNameFromPath(filename));
|
||||
if (filename_display_name.empty())
|
||||
filename_display_name = filename;
|
||||
|
||||
extension = std::strrchr(filename_display_name.c_str(), '.');
|
||||
#else
|
||||
extension = std::strrchr(filename, '.');
|
||||
#endif
|
||||
|
||||
if (!extension)
|
||||
{
|
||||
Log_ErrorPrintf("Invalid filename: '%s'", filename);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define CASE_COMPARE _stricmp
|
||||
#else
|
||||
#define CASE_COMPARE strcasecmp
|
||||
#endif
|
||||
|
||||
if (CASE_COMPARE(extension, ".cue") == 0)
|
||||
if (StringUtil::Strcasecmp(extension, ".cue") == 0)
|
||||
{
|
||||
return OpenCueSheetImage(filename, error);
|
||||
}
|
||||
else if (CASE_COMPARE(extension, ".bin") == 0 || CASE_COMPARE(extension, ".img") == 0 ||
|
||||
CASE_COMPARE(extension, ".iso") == 0)
|
||||
else if (StringUtil::Strcasecmp(extension, ".bin") == 0 || StringUtil::Strcasecmp(extension, ".img") == 0 ||
|
||||
StringUtil::Strcasecmp(extension, ".iso") == 0)
|
||||
{
|
||||
return OpenBinImage(filename, error);
|
||||
}
|
||||
else if (CASE_COMPARE(extension, ".chd") == 0)
|
||||
else if (StringUtil::Strcasecmp(extension, ".chd") == 0)
|
||||
{
|
||||
return OpenCHDImage(filename, error);
|
||||
}
|
||||
else if (CASE_COMPARE(extension, ".ecm") == 0)
|
||||
else if (StringUtil::Strcasecmp(extension, ".ecm") == 0)
|
||||
{
|
||||
return OpenEcmImage(filename, error);
|
||||
}
|
||||
else if (CASE_COMPARE(extension, ".mds") == 0)
|
||||
else if (StringUtil::Strcasecmp(extension, ".mds") == 0)
|
||||
{
|
||||
return OpenMdsImage(filename, error);
|
||||
}
|
||||
else if (CASE_COMPARE(extension, ".pbp") == 0)
|
||||
else if (StringUtil::Strcasecmp(extension, ".pbp") == 0)
|
||||
{
|
||||
return OpenPBPImage(filename, error);
|
||||
}
|
||||
else if (CASE_COMPARE(extension, ".m3u") == 0)
|
||||
else if (StringUtil::Strcasecmp(extension, ".m3u") == 0)
|
||||
{
|
||||
return OpenM3uImage(filename, error);
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ bool CDImageBin::Open(const char* filename, Common::Error* error)
|
|||
|
||||
AddLeadOutIndex();
|
||||
|
||||
m_sbi.LoadSBI(FileSystem::ReplaceExtension(filename, "sbi").c_str());
|
||||
m_sbi.LoadSBIFromImagePath(filename);
|
||||
|
||||
return Seek(1, Position{0, 0, 0});
|
||||
}
|
||||
|
|
|
@ -279,7 +279,7 @@ bool CDImageCHD::Open(const char* filename, Common::Error* error)
|
|||
m_lba_count = disc_lba;
|
||||
AddLeadOutIndex();
|
||||
|
||||
m_sbi.LoadSBI(FileSystem::ReplaceExtension(filename, "sbi").c_str());
|
||||
m_sbi.LoadSBIFromImagePath(filename);
|
||||
|
||||
return Seek(1, Position{0, 0, 0});
|
||||
}
|
||||
|
|
|
@ -269,7 +269,7 @@ bool CDImageCueSheet::OpenAndParse(const char* filename, Common::Error* error)
|
|||
m_lba_count = disc_lba;
|
||||
AddLeadOutIndex();
|
||||
|
||||
m_sbi.LoadSBI(FileSystem::ReplaceExtension(filename, "sbi").c_str());
|
||||
m_sbi.LoadSBIFromImagePath(filename);
|
||||
|
||||
return Seek(1, Position{0, 0, 0});
|
||||
}
|
||||
|
|
|
@ -385,7 +385,7 @@ bool CDImageEcm::Open(const char* filename, Common::Error* error)
|
|||
|
||||
AddLeadOutIndex();
|
||||
|
||||
m_sbi.LoadSBI(FileSystem::ReplaceExtension(filename, "sbi").c_str());
|
||||
m_sbi.LoadSBIFromImagePath(filename);
|
||||
|
||||
m_chunk_buffer.reserve(RAW_SECTOR_SIZE * 2);
|
||||
return Seek(1, Position{0, 0, 0});
|
||||
|
|
|
@ -250,7 +250,7 @@ bool CDImageMds::OpenAndParse(const char* filename, Common::Error* error)
|
|||
m_lba_count = m_tracks.back().start_lba + m_tracks.back().length;
|
||||
AddLeadOutIndex();
|
||||
|
||||
m_sbi.LoadSBI(FileSystem::ReplaceExtension(filename, "sbi").c_str());
|
||||
m_sbi.LoadSBIFromImagePath(filename);
|
||||
|
||||
return Seek(1, Position{0, 0, 0});
|
||||
}
|
||||
|
|
|
@ -673,8 +673,8 @@ bool CDImagePBP::OpenDisc(u32 index, Common::Error* error)
|
|||
|
||||
if (m_disc_offsets.size() > 1)
|
||||
{
|
||||
std::string sbi_path =
|
||||
FileSystem::StripExtension(m_filename) + StringUtil::StdStringFromFormat("_%u.sbi", index + 1);
|
||||
std::string sbi_path(FileSystem::StripExtension(m_filename));
|
||||
sbi_path += TinyString::FromFormat("_%u.sbi", index + 1);
|
||||
m_sbi.LoadSBI(sbi_path.c_str());
|
||||
}
|
||||
else
|
||||
|
|
|
@ -83,6 +83,11 @@ bool CDSubChannelReplacement::LoadSBI(const char* path)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CDSubChannelReplacement::LoadSBIFromImagePath(const char* image_path)
|
||||
{
|
||||
return LoadSBI(FileSystem::ReplaceExtension(image_path, "sbi").c_str());
|
||||
}
|
||||
|
||||
void CDSubChannelReplacement::AddReplacementSubChannelQ(u32 lba, const CDImage::SubChannelQ& subq)
|
||||
{
|
||||
auto iter = m_replacement_subq.find(lba);
|
||||
|
|
|
@ -14,6 +14,7 @@ public:
|
|||
u32 GetReplacementSectorCount() const { return static_cast<u32>(m_replacement_subq.size()); }
|
||||
|
||||
bool LoadSBI(const char* path);
|
||||
bool LoadSBIFromImagePath(const char* image_path);
|
||||
|
||||
/// Adds a sector to the replacement map.
|
||||
void AddReplacementSubChannelQ(u32 lba, const CDImage::SubChannelQ& subq);
|
||||
|
|
|
@ -51,6 +51,8 @@ static jfieldID s_android_FileHelper_FindResult_relativeName;
|
|||
static jfieldID s_android_FileHelper_FindResult_size;
|
||||
static jfieldID s_android_FileHelper_FindResult_modifiedTime;
|
||||
static jfieldID s_android_FileHelper_FindResult_flags;
|
||||
static jmethodID s_android_FileHelper_getDisplayName;
|
||||
static jmethodID s_android_FileHelper_getRelativePathForURIPath;
|
||||
|
||||
// helper for retrieving the current per-thread jni environment
|
||||
static JNIEnv* GetJNIEnv()
|
||||
|
@ -89,6 +91,8 @@ void SetAndroidFileHelper(void* jvm, void* env, void* object)
|
|||
|
||||
jenv->DeleteGlobalRef(s_android_FileHelper_object);
|
||||
jenv->DeleteGlobalRef(s_android_FileHelper_class);
|
||||
s_android_FileHelper_getRelativePathForURIPath = {};
|
||||
s_android_FileHelper_getDisplayName = {};
|
||||
s_android_FileHelper_openURIAsFileDescriptor = {};
|
||||
s_android_FileHelper_FindFiles = {};
|
||||
s_android_FileHelper_object = {};
|
||||
|
@ -114,7 +118,13 @@ void SetAndroidFileHelper(void* jvm, void* env, void* object)
|
|||
s_android_FileHelper_FindFiles =
|
||||
jenv->GetMethodID(s_android_FileHelper_class, "findFiles",
|
||||
"(Ljava/lang/String;I)[Lcom/github/stenzek/duckstation/FileHelper$FindResult;");
|
||||
Assert(s_android_FileHelper_openURIAsFileDescriptor && s_android_FileHelper_FindFiles);
|
||||
s_android_FileHelper_getDisplayName =
|
||||
jenv->GetMethodID(s_android_FileHelper_class, "getDisplayNameForURIPath", "(Ljava/lang/String;)Ljava/lang/String;");
|
||||
s_android_FileHelper_getRelativePathForURIPath =
|
||||
jenv->GetMethodID(s_android_FileHelper_class, "getRelativePathForURIPath",
|
||||
"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
|
||||
Assert(s_android_FileHelper_openURIAsFileDescriptor && s_android_FileHelper_FindFiles &&
|
||||
s_android_FileHelper_getDisplayName && s_android_FileHelper_getRelativePathForURIPath);
|
||||
|
||||
jclass fr_class = jenv->FindClass("com/github/stenzek/duckstation/FileHelper$FindResult");
|
||||
Assert(fr_class);
|
||||
|
@ -279,6 +289,68 @@ static bool FindUriFiles(const char* path, const char* pattern, u32 flags, FindR
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool GetDisplayNameForUriPath(const char* path, std::string* result)
|
||||
{
|
||||
if (!s_android_FileHelper_object)
|
||||
return false;
|
||||
|
||||
JNIEnv* env = GetJNIEnv();
|
||||
|
||||
jstring path_jstr = env->NewStringUTF(path);
|
||||
jstring result_jstr = static_cast<jstring>(
|
||||
env->CallObjectMethod(s_android_FileHelper_object, s_android_FileHelper_getDisplayName, path_jstr));
|
||||
env->DeleteLocalRef(path_jstr);
|
||||
if (!result_jstr)
|
||||
return false;
|
||||
|
||||
const char* result_name = env->GetStringUTFChars(result_jstr, nullptr);
|
||||
if (result_name)
|
||||
{
|
||||
Log_DevPrintf("GetDisplayNameForUriPath(\"%s\") -> \"%s\"", path, result_name);
|
||||
result->assign(result_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
result->clear();
|
||||
}
|
||||
|
||||
env->ReleaseStringUTFChars(result_jstr, result_name);
|
||||
env->DeleteLocalRef(result_jstr);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GetRelativePathForUriPath(const char* path, const char* filename, std::string* result)
|
||||
{
|
||||
if (!s_android_FileHelper_object)
|
||||
return false;
|
||||
|
||||
JNIEnv* env = GetJNIEnv();
|
||||
|
||||
jstring path_jstr = env->NewStringUTF(path);
|
||||
jstring filename_jstr = env->NewStringUTF(filename);
|
||||
jstring result_jstr = static_cast<jstring>(env->CallObjectMethod(
|
||||
s_android_FileHelper_object, s_android_FileHelper_getRelativePathForURIPath, path_jstr, filename_jstr));
|
||||
env->DeleteLocalRef(filename_jstr);
|
||||
env->DeleteLocalRef(path_jstr);
|
||||
if (!result_jstr)
|
||||
return false;
|
||||
|
||||
const char* result_name = env->GetStringUTFChars(result_jstr, nullptr);
|
||||
if (result_name)
|
||||
{
|
||||
Log_DevPrintf("GetRelativePathForUriPath(\"%s\", \"%s\") -> \"%s\"", path, filename, result_name);
|
||||
result->assign(result_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
result->clear();
|
||||
}
|
||||
|
||||
env->ReleaseStringUTFChars(result_jstr, result_name);
|
||||
env->DeleteLocalRef(result_jstr);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // __ANDROID__
|
||||
|
||||
ChangeNotifier::ChangeNotifier(const String& directoryPath, bool recursiveWatch)
|
||||
|
@ -510,17 +582,33 @@ bool IsAbsolutePath(const std::string_view& path)
|
|||
#endif
|
||||
}
|
||||
|
||||
std::string StripExtension(const std::string_view& path)
|
||||
std::string_view StripExtension(const std::string_view& path)
|
||||
{
|
||||
std::string_view::size_type pos = path.rfind('.');
|
||||
if (pos == std::string::npos)
|
||||
return std::string(path);
|
||||
return path;
|
||||
|
||||
return std::string(path, 0, pos);
|
||||
return path.substr(0, pos);
|
||||
}
|
||||
|
||||
std::string ReplaceExtension(const std::string_view& path, const std::string_view& new_extension)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
// This is more complex on android because the path may not contain the actual filename.
|
||||
if (IsUriPath(path))
|
||||
{
|
||||
std::string display_name(GetDisplayNameFromPath(path));
|
||||
std::string_view::size_type pos = display_name.rfind('.');
|
||||
if (pos == std::string::npos)
|
||||
return std::string(path);
|
||||
|
||||
display_name.erase(pos + 1);
|
||||
display_name.append(new_extension);
|
||||
|
||||
return BuildRelativePath(path, display_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string_view::size_type pos = path.rfind('.');
|
||||
if (pos == std::string::npos)
|
||||
return std::string(path);
|
||||
|
@ -572,6 +660,28 @@ static std::string_view::size_type GetLastSeperatorPosition(const std::string_vi
|
|||
return last_separator;
|
||||
}
|
||||
|
||||
std::string GetDisplayNameFromPath(const std::string_view& path)
|
||||
{
|
||||
#if defined(__ANDROID__)
|
||||
std::string result;
|
||||
|
||||
if (IsUriPath(path))
|
||||
{
|
||||
std::string temp(path);
|
||||
if (!GetDisplayNameForUriPath(temp.c_str(), &result))
|
||||
result = std::move(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = path;
|
||||
}
|
||||
|
||||
return result;
|
||||
#else
|
||||
return std::string(GetFileNameFromPath(path));
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string_view GetPathDirectory(const std::string_view& path)
|
||||
{
|
||||
std::string::size_type pos = GetLastSeperatorPosition(path, false);
|
||||
|
@ -583,7 +693,7 @@ std::string_view GetPathDirectory(const std::string_view& path)
|
|||
|
||||
std::string_view GetFileNameFromPath(const std::string_view& path)
|
||||
{
|
||||
std::string::size_type pos = GetLastSeperatorPosition(path, true);
|
||||
std::string_view::size_type pos = GetLastSeperatorPosition(path, true);
|
||||
if (pos == std::string_view::npos)
|
||||
return path;
|
||||
|
||||
|
@ -630,6 +740,15 @@ std::vector<std::string> GetRootDirectoryList()
|
|||
std::string BuildRelativePath(const std::string_view& filename, const std::string_view& new_filename)
|
||||
{
|
||||
std::string new_string;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
if (IsUriPath(filename) &&
|
||||
GetRelativePathForUriPath(std::string(filename).c_str(), std::string(new_filename).c_str(), &new_string))
|
||||
{
|
||||
return new_string;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string_view::size_type pos = GetLastSeperatorPosition(filename, true);
|
||||
if (pos != std::string_view::npos)
|
||||
new_string.assign(filename, 0, pos);
|
||||
|
|
|
@ -145,11 +145,15 @@ void SanitizeFileName(std::string& Destination, bool StripSlashes = true);
|
|||
bool IsAbsolutePath(const std::string_view& path);
|
||||
|
||||
/// Removes the extension of a filename.
|
||||
std::string StripExtension(const std::string_view& path);
|
||||
std::string_view StripExtension(const std::string_view& path);
|
||||
|
||||
/// Replaces the extension of a filename with another.
|
||||
std::string ReplaceExtension(const std::string_view& path, const std::string_view& new_extension);
|
||||
|
||||
/// Returns the display name of a filename. Usually this is the same as the path, except on Android
|
||||
/// where it resolves a content URI to its name.
|
||||
std::string GetDisplayNameFromPath(const std::string_view& path);
|
||||
|
||||
/// Returns the directory component of a filename.
|
||||
std::string_view GetPathDirectory(const std::string_view& path);
|
||||
|
||||
|
|
|
@ -33,8 +33,7 @@ HostInterface::HostInterface()
|
|||
g_host_interface = this;
|
||||
|
||||
// we can get the program directory at construction time
|
||||
const std::string program_path = FileSystem::GetProgramPath();
|
||||
m_program_directory = FileSystem::GetPathDirectory(program_path.c_str());
|
||||
m_program_directory = FileSystem::GetPathDirectory(FileSystem::GetProgramPath());
|
||||
}
|
||||
|
||||
HostInterface::~HostInterface()
|
||||
|
@ -896,8 +895,7 @@ void HostInterface::CheckForSettingsChanges(const Settings& old_settings)
|
|||
|
||||
void HostInterface::SetUserDirectoryToProgramDirectory()
|
||||
{
|
||||
const std::string program_path(FileSystem::GetProgramPath());
|
||||
const std::string program_directory(FileSystem::GetPathDirectory(program_path.c_str()));
|
||||
const std::string program_directory(FileSystem::GetProgramPath());
|
||||
m_user_directory = program_directory;
|
||||
}
|
||||
|
||||
|
|
|
@ -2914,7 +2914,7 @@ void CommonHostInterface::GetGameInfo(const char* path, CDImage* image, std::str
|
|||
}
|
||||
else
|
||||
{
|
||||
*title = FileSystem::GetFileTitleFromPath(path);
|
||||
*title = FileSystem::GetFileTitleFromPath(std::string(path));
|
||||
if (image)
|
||||
*code = System::GetGameCodeForImage(image, true);
|
||||
}
|
||||
|
|
|
@ -662,7 +662,7 @@ static void DoChangeDiscFromFile()
|
|||
};
|
||||
|
||||
OpenFileSelector(ICON_FA_COMPACT_DISC " Select Disc Image", false, std::move(callback), GetDiscImageFilters(),
|
||||
std::string(FileSystem::GetPathDirectory(System::GetMediaFileName().c_str())));
|
||||
std::string(FileSystem::GetPathDirectory(System::GetMediaFileName())));
|
||||
}
|
||||
|
||||
static void DoChangeDisc()
|
||||
|
@ -1076,7 +1076,7 @@ static bool SettingInfoButton(const SettingInfo& si, const char* section)
|
|||
CloseFileSelector();
|
||||
};
|
||||
OpenFileSelector(si.visible_name, false, std::move(callback), ImGuiFullscreen::FileSelectorFilters(),
|
||||
std::string(FileSystem::GetPathDirectory(value.c_str())));
|
||||
std::string(FileSystem::GetPathDirectory(std::move(value))));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -2372,7 +2372,7 @@ void DrawQuickMenu(MainWindowType type)
|
|||
SmallString subtitle;
|
||||
if (!code.empty())
|
||||
subtitle.Format("%s - ", code.c_str());
|
||||
subtitle.AppendString(FileSystem::GetFileNameFromPath(System::GetRunningPath().c_str()));
|
||||
subtitle.AppendString(FileSystem::GetFileNameFromPath(System::GetRunningPath()));
|
||||
|
||||
const ImVec2 title_size(
|
||||
g_large_font->CalcTextSizeA(g_large_font->FontSize, std::numeric_limits<float>::max(), -1.0f, title.c_str()));
|
||||
|
@ -2805,7 +2805,7 @@ void DrawGameListWindow()
|
|||
else
|
||||
summary.Format("%s - %s - ", entry->code.c_str(), Settings::GetDiscRegionName(entry->region));
|
||||
|
||||
summary.AppendString(FileSystem::GetFileNameFromPath(entry->path.c_str()));
|
||||
summary.AppendString(FileSystem::GetFileNameFromPath(entry->path));
|
||||
|
||||
ImGui::GetWindowDrawList()->AddImage(cover_texture->GetHandle(), bb.Min, bb.Min + image_size, ImVec2(0.0f, 0.0f),
|
||||
ImVec2(1.0f, 1.0f), IM_COL32(255, 255, 255, 255));
|
||||
|
|
|
@ -487,11 +487,8 @@ void GameList::ScanDirectory(const char* path, bool recursive, ProgressCallback*
|
|||
if (AddFileFromCache(ffd.FileName, modified_time))
|
||||
continue;
|
||||
|
||||
const std::string_view file_part(FileSystem::GetFileNameFromPath(ffd.FileName));
|
||||
if (!file_part.empty())
|
||||
progress->SetFormattedStatusText("Scanning '%*s'...", static_cast<int>(file_part.size()), file_part.data());
|
||||
|
||||
// ownership of fp is transferred
|
||||
progress->SetFormattedStatusText("Scanning '%s'...", FileSystem::GetDisplayNameFromPath(ffd.FileName).c_str());
|
||||
ScanFile(std::move(ffd.FileName), modified_time);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue