Skip to content

Commit 8348ea9

Browse files
Sirpixelalotclaude
andcommitted
Add Sora Editor integration for .rpy file editing with Java 17 upgrade
- Upgraded from Java 11 to Java 17 for Sora Editor compatibility - Integrated Sora Editor library (v0.23.7) with Material 3 theming - Added RpyEditorActivity with file loading/saving and unsaved changes warning - Added Edit RPY Files card to main menu with custom iOS 17 style icon - Implemented folder location memory using SharedPreferences - Removed View Files option from decompile completion dialog - FilePickerActivity now opens editor directly for .rpy files when OPEN_EDITOR flag is set - Simplified ProgressActivity completion dialogs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 89adee6 commit 8348ea9

File tree

13 files changed

+430
-25
lines changed

13 files changed

+430
-25
lines changed

app/build.gradle

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ android {
5555
}
5656
}
5757
compileOptions {
58-
sourceCompatibility JavaVersion.VERSION_11
59-
targetCompatibility JavaVersion.VERSION_11
58+
sourceCompatibility JavaVersion.VERSION_17
59+
targetCompatibility JavaVersion.VERSION_17
6060
}
6161
}
6262

@@ -69,6 +69,11 @@ dependencies {
6969
// JSON parsing for update checker
7070
implementation 'com.google.code.gson:gson:2.10.1'
7171

72+
// Sora Editor - Code editor for .rpy files
73+
implementation platform('io.github.rosemoe:editor-bom:0.23.7')
74+
implementation 'io.github.rosemoe:editor'
75+
implementation 'io.github.rosemoe:language-textmate'
76+
7277
testImplementation libs.junit
7378
androidTestImplementation libs.ext.junit
7479
androidTestImplementation libs.espresso.core

app/src/main/AndroidManifest.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@
4646
android:exported="false"
4747
android:theme="@style/Theme.Rentool" />
4848

49+
<activity
50+
android:name=".RpyEditorActivity"
51+
android:exported="false"
52+
android:theme="@style/Theme.Rentool" />
53+
4954
</application>
5055

5156
</manifest>

app/src/main/java/com/renpytool/FilePickerActivity.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,22 @@ private void confirmSelection() {
225225
}
226226

227227
private void selectFile(File file) {
228-
Intent resultIntent = new Intent();
229-
resultIntent.putExtra(EXTRA_SELECTED_PATH, file.getAbsolutePath());
230-
setResult(Activity.RESULT_OK, resultIntent);
231-
finish();
228+
// Check if we should open the editor instead of returning
229+
boolean openEditor = getIntent().getBooleanExtra("OPEN_EDITOR", false);
230+
231+
if (openEditor && file.getName().endsWith(".rpy")) {
232+
// Open .rpy file in editor
233+
Intent editorIntent = new Intent(this, RpyEditorActivity.class);
234+
editorIntent.putExtra(RpyEditorActivity.EXTRA_FILE_PATH, file.getAbsolutePath());
235+
startActivity(editorIntent);
236+
finish();
237+
} else {
238+
// Return selected file to calling activity
239+
Intent resultIntent = new Intent();
240+
resultIntent.putExtra(EXTRA_SELECTED_PATH, file.getAbsolutePath());
241+
setResult(Activity.RESULT_OK, resultIntent);
242+
finish();
243+
}
232244
}
233245

234246
private void selectCurrentDirectory() {

app/src/main/java/com/renpytool/MainActivity.java

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class MainActivity extends AppCompatActivity {
3737

3838
private static final int PERMISSION_REQUEST_CODE = 100;
3939

40-
private MaterialCardView cardExtract, cardCreate, cardDecompile;
40+
private MaterialCardView cardExtract, cardCreate, cardDecompile, cardEditRpy;
4141
private TextView tvExtractStatus, tvCreateStatus, tvDecompileStatus;
4242

4343
private Python python;
@@ -53,6 +53,9 @@ public class MainActivity extends AppCompatActivity {
5353
private ActivityResultLauncher<Intent> createOutputPickerLauncher;
5454
private ActivityResultLauncher<Intent> decompileDirPickerLauncher;
5555

56+
// Progress activity launcher for chaining operations
57+
private ActivityResultLauncher<Intent> progressActivityLauncher;
58+
5659
// Temporary storage for multi-step file picking
5760
private String selectedRpaPath;
5861
private ArrayList<String> selectedRpaPaths; // For batch extraction
@@ -92,6 +95,7 @@ private void initViews() {
9295
cardExtract = findViewById(R.id.card_extract);
9396
cardCreate = findViewById(R.id.card_create);
9497
cardDecompile = findViewById(R.id.card_decompile);
98+
cardEditRpy = findViewById(R.id.card_edit_rpy);
9599
tvExtractStatus = findViewById(R.id.tv_extract_status);
96100
tvCreateStatus = findViewById(R.id.tv_create_status);
97101
tvDecompileStatus = findViewById(R.id.tv_decompile_status);
@@ -100,6 +104,7 @@ private void initViews() {
100104
cardExtract.setOnClickListener(v -> startExtractFlow());
101105
cardCreate.setOnClickListener(v -> startCreateFlow());
102106
cardDecompile.setOnClickListener(v -> startDecompileFlow());
107+
cardEditRpy.setOnClickListener(v -> startEditRpyFlow());
103108
}
104109

105110

@@ -241,6 +246,22 @@ private void initFilePickerLaunchers() {
241246
}
242247
}
243248
});
249+
250+
// Progress Activity: Handle completion and chaining
251+
progressActivityLauncher = registerForActivityResult(
252+
new ActivityResultContracts.StartActivityForResult(),
253+
result -> {
254+
if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
255+
// Check if there's a chain operation requested
256+
String chainOperation = result.getData().getStringExtra("CHAIN_OPERATION");
257+
String chainPath = result.getData().getStringExtra("CHAIN_PATH");
258+
259+
if ("decompile".equals(chainOperation) && chainPath != null) {
260+
// Start decompile with the extracted path
261+
performDecompile(chainPath);
262+
}
263+
}
264+
});
244265
}
245266

246267
private void startExtractFlow() {
@@ -329,9 +350,10 @@ private void performBatchExtraction(ArrayList<String> rpaFilePaths, String extra
329350
ProgressTracker tracker = new ProgressTracker(MainActivity.this);
330351
tracker.clearProgress();
331352

332-
// Launch progress activity
353+
// Launch progress activity with extraction path
333354
Intent intent = new Intent(this, ProgressActivity.class);
334-
startActivity(intent);
355+
intent.putExtra("EXTRACT_PATH", extractDirPath);
356+
progressActivityLauncher.launch(intent);
335357

336358
executorService.execute(() -> {
337359
int totalFiles = rpaFilePaths.size();
@@ -433,9 +455,10 @@ private void performExtraction(String rpaFilePath, String extractDirPath) {
433455
ProgressTracker tracker = new ProgressTracker(MainActivity.this);
434456
tracker.clearProgress();
435457

436-
// Launch progress activity
458+
// Launch progress activity with extraction path
437459
Intent intent = new Intent(this, ProgressActivity.class);
438-
startActivity(intent);
460+
intent.putExtra("EXTRACT_PATH", extractDirPath);
461+
progressActivityLauncher.launch(intent);
439462

440463
executorService.execute(() -> {
441464
try {
@@ -748,8 +771,9 @@ private void performDecompile(String sourceDirPath) {
748771
ProgressTracker tracker = new ProgressTracker(MainActivity.this);
749772
tracker.clearProgress();
750773

751-
// Launch progress activity
774+
// Launch progress activity with source path
752775
Intent intent = new Intent(this, ProgressActivity.class);
776+
intent.putExtra("DECOMPILE_PATH", sourceDirPath);
753777
startActivity(intent);
754778

755779
executorService.execute(() -> {
@@ -935,6 +959,24 @@ private void showUpdateDialog(VersionInfo versionInfo) {
935959
.show();
936960
}
937961

962+
private void startEditRpyFlow() {
963+
// Launch file picker to browse for .rpy files
964+
Intent intent = new Intent(this, FilePickerActivity.class);
965+
intent.putExtra(FilePickerActivity.EXTRA_MODE, FilePickerActivity.MODE_FILE);
966+
intent.putExtra(FilePickerActivity.EXTRA_FILE_FILTER, ".rpy");
967+
intent.putExtra(FilePickerActivity.EXTRA_TITLE, "Select .rpy File to Edit");
968+
intent.putExtra("OPEN_EDITOR", true); // Flag to open editor directly
969+
970+
// Restore last folder location if available
971+
android.content.SharedPreferences prefs = getSharedPreferences("RentoolPrefs", MODE_PRIVATE);
972+
String lastFolder = prefs.getString("last_rpy_edit_folder", null);
973+
if (lastFolder != null) {
974+
intent.putExtra(FilePickerActivity.EXTRA_START_DIR, lastFolder);
975+
}
976+
977+
startActivity(intent);
978+
}
979+
938980
@Override
939981
protected void onDestroy() {
940982
super.onDestroy();

app/src/main/java/com/renpytool/ProgressActivity.java

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.renpytool;
22

33
import android.app.Activity;
4+
import android.content.Intent;
45
import android.os.Bundle;
56
import android.os.Handler;
67
import android.os.Looper;
@@ -13,6 +14,7 @@
1314

1415
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
1516

17+
import java.io.File;
1618
import java.util.Locale;
1719

1820
/**
@@ -156,19 +158,53 @@ private void updateUI(ProgressData data) {
156158
*/
157159
private void handleCompletion(ProgressData data) {
158160
if (data.isCompleted()) {
159-
// Show success dialog
160-
new MaterialAlertDialogBuilder(this)
161-
.setTitle("Success")
162-
.setMessage(String.format(Locale.US,
163-
"Operation completed successfully!\n\nProcessed %d files in %s",
164-
data.totalFiles,
165-
ProgressData.formatTime(data.getElapsedMs())))
166-
.setPositiveButton("OK", (dialog, which) -> {
167-
setResult(Activity.RESULT_OK);
168-
finish();
169-
})
170-
.setCancelable(false)
171-
.show();
161+
// Check if this was an extract operation and if there are .rpyc files
162+
String extractPath = getIntent().getStringExtra("EXTRACT_PATH");
163+
boolean isExtract = "extract".equalsIgnoreCase(data.operation);
164+
int rpycCount = 0;
165+
166+
if (isExtract && extractPath != null) {
167+
rpycCount = countRpycFiles(new File(extractPath));
168+
}
169+
170+
// Show enhanced dialog for extract with .rpyc files
171+
if (isExtract && rpycCount > 0) {
172+
new MaterialAlertDialogBuilder(this)
173+
.setTitle("Extraction Complete")
174+
.setMessage(String.format(Locale.US,
175+
"Extracted %d files successfully!\n\n📁 %s\n\nFound %d .rpyc files ready to decompile.",
176+
data.totalFiles,
177+
extractPath,
178+
rpycCount))
179+
.setPositiveButton("Decompile Now", (dialog, which) -> {
180+
// Pass extraction path back to MainActivity for chaining
181+
Intent intent = new Intent();
182+
intent.putExtra("CHAIN_OPERATION", "decompile");
183+
intent.putExtra("CHAIN_PATH", extractPath);
184+
setResult(Activity.RESULT_OK, intent);
185+
finish();
186+
})
187+
.setNegativeButton("Done", (dialog, which) -> {
188+
setResult(Activity.RESULT_OK);
189+
finish();
190+
})
191+
.setCancelable(false)
192+
.show();
193+
} else {
194+
// Standard success dialog
195+
new MaterialAlertDialogBuilder(this)
196+
.setTitle("Success")
197+
.setMessage(String.format(Locale.US,
198+
"Operation completed successfully!\n\nProcessed %d files in %s",
199+
data.totalFiles,
200+
ProgressData.formatTime(data.getElapsedMs())))
201+
.setPositiveButton("OK", (dialog, which) -> {
202+
setResult(Activity.RESULT_OK);
203+
finish();
204+
})
205+
.setCancelable(false)
206+
.show();
207+
}
172208
} else if (data.isFailed()) {
173209
// Show error dialog
174210
String errorMessage = data.errorMessage != null && !data.errorMessage.isEmpty()
@@ -187,6 +223,28 @@ private void handleCompletion(ProgressData data) {
187223
}
188224
}
189225

226+
/**
227+
* Count .rpyc files in a directory (recursively)
228+
*/
229+
private int countRpycFiles(File directory) {
230+
int count = 0;
231+
if (directory == null || !directory.exists() || !directory.isDirectory()) {
232+
return 0;
233+
}
234+
235+
File[] files = directory.listFiles();
236+
if (files != null) {
237+
for (File file : files) {
238+
if (file.isDirectory()) {
239+
count += countRpycFiles(file);
240+
} else if (file.getName().toLowerCase().endsWith(".rpyc")) {
241+
count++;
242+
}
243+
}
244+
}
245+
return count;
246+
}
247+
190248
/**
191249
* Disable back button - user must wait for operation to complete
192250
*/

0 commit comments

Comments
 (0)