diff --git a/jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java b/jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java index 59320ce8a07..58580d4a2a3 100644 --- a/jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java +++ b/jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java @@ -10,12 +10,15 @@ import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; +import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileVisitOption; import java.nio.file.FileVisitResult; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; import java.nio.file.StandardOpenOption; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.FileTime; @@ -267,6 +270,20 @@ public static String readFile(Path textFile) throws IOException { return Files.readString(textFile); } + public static boolean renameFile(Path sourcePath, Path targetPath) { + try { + Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING); + return true; + } catch (NoSuchFileException e) { + LOG.error("File to rename not found {}", sourcePath, e); + } catch (FileAlreadyExistsException e) { + LOG.error("File with that name already exists {}", targetPath, e); + } catch (IOException e) { + LOG.error("Error renaming file {}", e.getMessage(), e); + } + return false; + } + @NotNull public static File prepareFile(File file) { File saveFile = cutFileName(file); diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JInputFile.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JInputFile.java index 9378c6d2937..2dee7fd59f1 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JInputFile.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JInputFile.java @@ -23,6 +23,7 @@ public JPopupMenu onTreePopupMenu(MainWindow mainWindow) { JPopupMenu menu = new JPopupMenu(); menu.add(new SimpleMenuItem(NLS.str("popup.add_files"), mainWindow::addFiles)); menu.add(new SimpleMenuItem(NLS.str("popup.remove"), () -> mainWindow.removeInput(filePath))); + menu.add(new SimpleMenuItem(NLS.str("popup.rename"), () -> mainWindow.renameInput(filePath))); return menu; } diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JInputScript.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JInputScript.java index d73ca364349..de0e8f3362b 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JInputScript.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JInputScript.java @@ -66,6 +66,7 @@ public JPopupMenu onTreePopupMenu(MainWindow mainWindow) { menu.add(new SimpleMenuItem(NLS.str("popup.add_scripts"), mainWindow::addFiles)); menu.add(new SimpleMenuItem(NLS.str("popup.new_script"), mainWindow::addNewScript)); menu.add(new SimpleMenuItem(NLS.str("popup.remove"), () -> mainWindow.removeInput(scriptPath))); + menu.add(new SimpleMenuItem(NLS.str("popup.rename"), () -> mainWindow.renameInput(scriptPath))); return menu; } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java index f25840b86ce..ce59ad66550 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java @@ -441,14 +441,38 @@ public void addNewScript() { } List inputs = project.getFilePaths(); inputs.add(scriptFile); - project.setFilePaths(inputs); - project.save(); - reopen(); + refreshTree(inputs); } public void removeInput(Path file) { List inputs = project.getFilePaths(); inputs.remove(file); + refreshTree(inputs); + } + + public void renameInput(Path file) { + String newName = JOptionPane.showInputDialog(this, NLS.str("message.enter_new_name"), file.getFileName().toString()); + if (newName == null || newName.trim().isEmpty()) { + return; + } + Path targetPath = file.resolveSibling(newName); + + boolean success = FileUtils.renameFile(file, targetPath); + if (success) { + List inputs = project.getFilePaths(); + inputs.remove(file); + inputs.add(targetPath); + + refreshTree(inputs); + } else { + JOptionPane.showMessageDialog(this, + NLS.str("message.could_not_rename"), + NLS.str("message.errorTitle"), + JOptionPane.ERROR_MESSAGE); + } + } + + private void refreshTree(List inputs) { project.setFilePaths(inputs); project.save(); reopen(); diff --git a/jadx-gui/src/main/resources/i18n/Messages_de_DE.properties b/jadx-gui/src/main/resources/i18n/Messages_de_DE.properties index 6c4d838286a..6ddefc4c1e5 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_de_DE.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_de_DE.properties @@ -109,6 +109,8 @@ message.no_classes=Keine Klassen geladen, nichts zu dekompilieren! message.saveIncomplete=Speichern unvollständig.
%s
%d Klassen oder Ressourcen wurden nicht gespeichert! message.indexIncomplete=Index einiger Klassen übersprungen.
%s
%d Klassen wurden nicht indiziert und werden nicht in den Suchergebnissen erscheinen! message.indexingClassesSkipped=Jadx hat nur noch wenig Speicherplatz. Daher wurden %d Klassen nicht indiziert.
Wenn Sie möchten, dass alle Klassen indiziert werden, Jadx mit erhöhter maximaler Heap-Größe neustarten. +#message.enter_new_name=Enter new name +#message.could_not_rename=Can't rename the file heapUsage.text=JADX-Speicherauslastung: %.2f GB von %.2f GB diff --git a/jadx-gui/src/main/resources/i18n/Messages_en_US.properties b/jadx-gui/src/main/resources/i18n/Messages_en_US.properties index 29879d195f9..639613e2d0e 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_en_US.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_en_US.properties @@ -109,6 +109,8 @@ message.no_classes=No classes loaded, nothing to decompile! message.saveIncomplete=Save incomplete.
%s
%d classes or resources were not saved! message.indexIncomplete=Index of some classes skipped.
%s
%d classes were not indexed and will not appear in search results! message.indexingClassesSkipped=Jadx is running low on memory. Therefore %d classes were not indexed.
If you want all classes to be indexed restart Jadx with increased maximum heap size. +message.enter_new_name=Enter new name +message.could_not_rename=Can't rename the file heapUsage.text=JADX memory usage: %.2f GB of %.2f GB diff --git a/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties b/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties index e3d76efcad6..09ac0cb2c87 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties @@ -109,6 +109,8 @@ nav.forward=Adelante #message.saveIncomplete=Save incomplete.
%s
%d classes or resources were not saved! #message.indexIncomplete=Index of some classes skipped.
%s
%d classes were not indexed and will not appear in search results! #message.indexingClassesSkipped=Jadx is running low on memory. Therefore %d classes were not indexed.
If you want all classes to be indexed restart Jadx with increased maximum heap size. +#message.enter_new_name=Enter new name +#message.could_not_rename=Can't rename the file #heapUsage.text=JADX memory usage: %.2f GB of %.2f GB diff --git a/jadx-gui/src/main/resources/i18n/Messages_id_ID.properties b/jadx-gui/src/main/resources/i18n/Messages_id_ID.properties index 7127221e208..3829fea60b1 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_id_ID.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_id_ID.properties @@ -109,6 +109,8 @@ message.no_classes=Tidak ada kelas yang dimuat, tidak ada yang dapat didekompila message.saveIncomplete=Simpan tidak lengkap.
%s
%d kelas atau sumber daya tidak disimpan! message.indexIncomplete=Indeks beberapa kelas dilewati.
%s
%d kelas tidak diindeks dan tidak akan muncul dalam hasil pencarian! message.indexingClassesSkipped=JADX kekurangan memori. Oleh karena itu %d kelas tidak diindeks.
Jika Anda ingin semua kelas diindeks, restart JADX dengan ukuran heap maksimum yang lebih besar. +#message.enter_new_name=Enter new name +#message.could_not_rename=Can't rename the file heapUsage.text=Penggunaan memori JADX: %.2f GB dari %.2f GB diff --git a/jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties b/jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties index 9367bcf0f15..c622373b81d 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties @@ -109,6 +109,8 @@ message.no_classes=로드된 클래스 없음, 디컴파일 대상 존재하지 message.saveIncomplete=저장이 완료되지 않았습니다.
%s
%d개의 클래스 또는 리소스가 저장되지 않았습니다! message.indexIncomplete=일부 클래스의 색인을 건너뛰었습니다.
%s
%d개의 클래스는 색인이 생성되지 않았으며 검색 결과에 나타나지 않습니다. message.indexingClassesSkipped=Jadx의 메모리가 부족합니다. 따라서 %d 개의 클래스가 인덱싱되지 않았습니다.
모든 클래스를 인덱싱하려면 최대 힙 크기를 늘린 상태로 Jadx를 다시 시작하십시오. +#message.enter_new_name=Enter new name +#message.could_not_rename=Can't rename the file heapUsage.text=JADX 메모리 사용량 : %.2f GB / %.2f GB diff --git a/jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties b/jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties index d74a87aa080..894fb91e30d 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties @@ -109,6 +109,8 @@ message.no_classes=Nenhuma classe carregada, nada para ser descompilado! message.saveIncomplete=Operação não foi completa.
%s
%d classes ou recursos não foram salvos! message.indexIncomplete=Indexação de algumas classes foram ignoradas.
%s
%d classes não foram indexadas não vão aparecer nos resultados de busca! message.indexingClassesSkipped=Jadx está rodando com pouca memória. Por conta disso, %d classes não foram indexadas.
Se você deseja que todas classes sejam indexadas, reinicie com um limite de memória heap maior. +#message.enter_new_name=Enter new name +#message.could_not_rename=Can't rename the file heapUsage.text=Uso de memória do JADX: %.2f GB of %.2f GB diff --git a/jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties b/jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties index c75507d16d3..ab57fe79879 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties @@ -109,6 +109,8 @@ message.no_classes=Классы не найдены, нечего декомпи message.saveIncomplete=Сохранение не завершено.
%s
%d классов или ресурсов не сохранено! message.indexIncomplete=Индексирование некоторых классов пропущено.
%s
%d классов не индексировано, и не будет отображаться в результатах поиска! message.indexingClassesSkipped=JaDX запущен с малым количеством ОЗУ. %d классов не индексировано.
Если вы хотите их индексировать, перезапустите JaDX с большим Heap Size. +#message.enter_new_name=Enter new name +#message.could_not_rename=Can't rename the file heapUsage.text=JADX использует: %.2f ГБ из %.2f ГБ diff --git a/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties b/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties index 2dbfc25fb9d..5d68c47f799 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties @@ -109,6 +109,8 @@ message.no_classes=无类被加载,没什么可反编译! message.saveIncomplete=保存未完成。
%s
%d 类或资源未被保存! message.indexIncomplete=已跳过某些类索引。
%s
%d 类未被索引,不会出现在搜索结果中! message.indexingClassesSkipped=Jadx 的内存不足。因此,%d 个类没有编入索引。
如果要将所有类编入索引,请增加的最大堆空间后重新启动 Jadx。 +#message.enter_new_name=Enter new name +#message.could_not_rename=Can't rename the file heapUsage.text=JADX 内存使用率:%.2f GB / %.2f GB diff --git a/jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties b/jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties index 961acfef6a2..b119f873238 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties @@ -109,6 +109,8 @@ message.no_classes=未載入任何類別,沒有東西可以反編譯! message.saveIncomplete=儲存未完成。
%s
%d 個類別或資源尚未儲存! message.indexIncomplete=某些類別的索引被略過。
%s
%d 個類別未被索引,故不會出現在搜尋結果中。 message.indexingClassesSkipped=Jadx 的記憶體不足。故 %d 個類別未被索引。
如果您想要索引所有類別,請增加最大堆疊大小並重新啟動。 +#message.enter_new_name=Enter new name +#message.could_not_rename=Can't rename the file heapUsage.text=JADX 記憶體使用率:%.2f GB / %.2f GB