From 401d9ca46938f1f214a3c9aa16760e1e2bd9de23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 16 Jul 2020 15:49:18 +0200 Subject: [PATCH] Add a file picker (WIP) --- Common/Net/URL.cpp | 2 +- UI/MainScreen.cpp | 7 +-- android/jni/app-android.cpp | 5 +++ .../src/org/ppsspp/ppsspp/NativeActivity.java | 45 ++++++++++++++++++- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/Common/Net/URL.cpp b/Common/Net/URL.cpp index 681fc45ff2..1183022ed7 100644 --- a/Common/Net/URL.cpp +++ b/Common/Net/URL.cpp @@ -126,7 +126,7 @@ std::string UriDecode(const std::string & sSrc) const unsigned char * const SRC_END = pSrc + SRC_LEN; const unsigned char * const SRC_LAST_DEC = SRC_END - 2; // last decodable '%' - char * const pStart = new char[SRC_LEN]; + char * const pStart = new char[SRC_LEN]; // Output will be shorter. char * pEnd = pStart; while (pSrc < SRC_LAST_DEC) diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 68c921f7f0..14157e7824 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -1111,9 +1111,10 @@ void MainScreen::CreateViews() { TextView *ver = rightColumnItems->Add(new TextView(versionString, new LinearLayoutParams(Margins(70, -6, 0, 0)))); ver->SetSmall(true); ver->SetClip(false); -#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP) - rightColumnItems->Add(new Choice(mm->T("Load","Load...")))->OnClick.Handle(this, &MainScreen::OnLoadFile); -#endif + + if (System_GetPropertyBool(SYSPROP_HAS_FILE_BROWSER)) { + rightColumnItems->Add(new Choice(mm->T("Load", "Load...")))->OnClick.Handle(this, &MainScreen::OnLoadFile); + } rightColumnItems->Add(new Choice(mm->T("Game Settings", "Settings")))->OnClick.Handle(this, &MainScreen::OnGameSettings); rightColumnItems->Add(new Choice(mm->T("Credits")))->OnClick.Handle(this, &MainScreen::OnCredits); rightColumnItems->Add(new Choice(mm->T("www.ppsspp.org")))->OnClick.Handle(this, &MainScreen::OnPPSSPPOrg); diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 6b64d49693..fb47bb0d77 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -429,6 +429,11 @@ bool System_GetPropertyBool(SystemProperty prop) { return true; case SYSPROP_HAS_IMAGE_BROWSER: return true; + case SYSPROP_HAS_FILE_BROWSER: + return true; + case SYSPROP_HAS_FOLDER_BROWSER: + // Uses OPEN_DOCUMENT_TREE + return androidVersion >= 21; case SYSPROP_APP_GOLD: #ifdef GOLD return true; diff --git a/android/src/org/ppsspp/ppsspp/NativeActivity.java b/android/src/org/ppsspp/ppsspp/NativeActivity.java index e4632578c7..4cb4af3d4b 100644 --- a/android/src/org/ppsspp/ppsspp/NativeActivity.java +++ b/android/src/org/ppsspp/ppsspp/NativeActivity.java @@ -25,6 +25,7 @@ import android.os.Bundle; import android.os.Environment; import android.os.PowerManager; import android.os.Vibrator; +import android.provider.DocumentsContract; import android.provider.MediaStore; import android.text.InputType; import android.util.Log; @@ -99,7 +100,10 @@ public abstract class NativeActivity extends Activity { // This is to avoid losing the game/menu state etc when we are just // switched-away from or rotated etc. private boolean shuttingDown; + private static final int RESULT_LOAD_IMAGE = 1; + private static final int RESULT_BROWSE_FILE = 2; + private static final int RESULT_OPEN_DOCUMENT_TREE = 3; // Allow for multiple connected gamepads but just consider them the same for now. // Actually this is not entirely true, see the code. @@ -1121,7 +1125,10 @@ public abstract class NativeActivity extends Activity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) { + if (resultCode != RESULT_OK || data == null) { + return; + } + if (requestCode == RESULT_LOAD_IMAGE) { Uri selectedImage = data.getData(); if (selectedImage != null) { String[] filePathColumn = {MediaStore.Images.Media.DATA}; @@ -1132,6 +1139,19 @@ public abstract class NativeActivity extends Activity { cursor.close(); NativeApp.sendMessage("bgImage_updated", picturePath); } + } else if (requestCode == RESULT_BROWSE_FILE) { + Uri selectedFile = data.getData(); + if (selectedFile != null) { + // NativeApp.sendMessage("br"); + Log.i(TAG, "Browse file finished:" + selectedFile.toString()); + } + } else if (requestCode == RESULT_OPEN_DOCUMENT_TREE) { + Uri selectedFile = data.getData(); + if (selectedFile != null) { + // Convert URI to normal path. (This might not be possible in Android 12+) + // NativeApp.sendMessage("browse_folderSelect", selectedFile.toString()); + Log.i(TAG, "Browse folder finished: " + selectedFile.toString()); + } } } @@ -1263,6 +1283,29 @@ public abstract class NativeActivity extends Activity { Log.e(TAG, e.toString()); return false; } + } else if (command.equals("browse_file")) { + try { + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("application/octet-stream"); + //intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri); + startActivityForResult(intent, RESULT_BROWSE_FILE); + } catch (Exception e) { + Log.e(TAG, e.toString()); + return false; + } + } else if (command.equals("browse_folder")) { + try { + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); + // intent.setType("application/octet-stream"); + // intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivityForResult(intent, RESULT_OPEN_DOCUMENT_TREE); + } catch (Exception e) { + Log.e(TAG, e.toString()); + return false; + } } else if (command.equals("sharejpeg")) { try { Intent share = new Intent(Intent.ACTION_SEND);