feat(config): persistent directories, auto-open files, and strict project scope
- Implemented persistent directory memory for Action Model and Dataset generators (per project). - Added configuration to automatically open generated files in the editor with a customizable limit. - Enforced strict project-scope file selection for i18n and XSD settings. - Switched to relative path storage for i18n/XSD configuration to enhance project portability. - Improved File Browser logic to start at the current directory or fallback to project root. - Fixed compilation errors and optimized imports in configuration classes. - Bumped plugin version to 3.2.4.
This commit is contained in:
Binary file not shown.
@@ -1 +1 @@
|
|||||||
2026-04-10
|
2026-04-18
|
||||||
6
CheckAPI.java
Normal file
6
CheckAPI.java
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import com.intellij.javaee.ExternalResourceManagerEx;
|
||||||
|
import com.intellij.javaee.ExternalResourceManager;
|
||||||
|
public class CheckAPI {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,6 +55,10 @@
|
|||||||
<FIELD NAME="PROJ_FROM_YEAR" TYPE="NUMBER" WIDTH="4" LABEL="plcp.from_year"/>
|
<FIELD NAME="PROJ_FROM_YEAR" TYPE="NUMBER" WIDTH="4" LABEL="plcp.from_year"/>
|
||||||
</FIELDS>
|
</FIELDS>
|
||||||
</DATASET>
|
</DATASET>
|
||||||
|
<FOREIGN-DATASETS>
|
||||||
|
<DATASET DATASET-ID="DS-PROJECT-STTGYS" MASTER-FIELDS="PROJ_ID,ACM_CODE" DETAIL-FIELDS="PROJ_ID" DELETE-WITH-MASTER="Y"/>
|
||||||
|
<DATASET DATASET-ID="DS-PROJECT-STTGYS-ITEMS" MASTER-FIELDS="PROJ_ID,ACM_CODE" DETAIL-FIELDS="PROJ_ID" DELETE-WITH-MASTER="Y"/>
|
||||||
|
</FOREIGN-DATASETS>
|
||||||
</DATASETS>
|
</DATASETS>
|
||||||
|
|
||||||
<FORM>
|
<FORM>
|
||||||
@@ -120,7 +124,7 @@
|
|||||||
<FIELD NAME="PROJ_YEAR" CAPTION="plcp.year" INPUTTYPE="TEXT" READONLY="Y" DATATYPE="TEXT"/>
|
<FIELD NAME="PROJ_YEAR" CAPTION="plcp.year" INPUTTYPE="TEXT" READONLY="Y" DATATYPE="TEXT"/>
|
||||||
<FIELD NAME="VPJM_CODE" CAPTION="plcp.pjm_code" INPUTTYPE="TEXT" READONLY="Y"/>
|
<FIELD NAME="VPJM_CODE" CAPTION="plcp.pjm_code" INPUTTYPE="TEXT" READONLY="Y"/>
|
||||||
<FIELD NAME="PJM_CODE" CAPTION="plcp.pjm_name" INPUTTYPE="COMBOBOX" REQUIRE="Y" EDIT-READONLY="Y">
|
<FIELD NAME="PJM_CODE" CAPTION="plcp.pjm_name" INPUTTYPE="COMBOBOX" REQUIRE="Y" EDIT-READONLY="Y">
|
||||||
<AJAX-OPTION URL="/api-data.jbx" DATASET="DS-PROJECT-02" VALUE-FIELD="PJM_CODE" TEXT-FIELD="PJM_NAME">
|
<AJAX-OPTION URL="/api-data.jbx" DATASET="DS-PROJECT-02" VIEW-DATASET="DS-PROJECT-03" VALUE-FIELD="PJM_CODE" TEXT-FIELD="PJM_NAME">
|
||||||
<UPDATE-FIELDS>
|
<UPDATE-FIELDS>
|
||||||
<FIELD SRC="PJM_CODE" TARGET="VPJM_CODE"></FIELD>
|
<FIELD SRC="PJM_CODE" TARGET="VPJM_CODE"></FIELD>
|
||||||
</UPDATE-FIELDS>
|
</UPDATE-FIELDS>
|
||||||
|
|||||||
9
FindAPI.java
Normal file
9
FindAPI.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import com.intellij.javaee.ExternalResourceManager;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
public class FindAPI {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
for (Method m : ExternalResourceManager.class.getMethods()) {
|
||||||
|
System.out.println(m.getName() + " " + java.util.Arrays.toString(m.getParameterTypes()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
InspectXSD.java
Normal file
17
InspectXSD.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import com.intellij.javaee.ExternalResourceManager;
|
||||||
|
import com.intellij.javaee.ExternalResourceManagerEx;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class InspectXSD {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
System.out.println("Methods in ExternalResourceManager:");
|
||||||
|
for (Method m : ExternalResourceManager.class.getMethods()) {
|
||||||
|
System.out.println(m.getName());
|
||||||
|
}
|
||||||
|
System.out.println("---");
|
||||||
|
System.out.println("Methods in ExternalResourceManagerEx:");
|
||||||
|
for (Method m : ExternalResourceManagerEx.class.getMethods()) {
|
||||||
|
System.out.println(m.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,11 +4,10 @@ plugins {
|
|||||||
id("org.jetbrains.intellij.platform") version "2.7.0"
|
id("org.jetbrains.intellij.platform") version "2.7.0"
|
||||||
}
|
}
|
||||||
group = "com.sdk.dynform.tools"
|
group = "com.sdk.dynform.tools"
|
||||||
version = "3.2.3"
|
version = "3.2.4"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
defaultRepositories()
|
defaultRepositories()
|
||||||
}
|
}
|
||||||
@@ -39,12 +38,20 @@ intellijPlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
changeNotes = """
|
changeNotes = """
|
||||||
|
<h2>[3.2.4]</h2>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Persistent Generation Directories:</strong> Generator now remembers the last used directory for Action Beans and Dataset XMLs independently per project.</li>
|
||||||
|
<li><strong>Auto-Open Generated Files:</strong> Added configuration to automatically open newly created files in the editor, with a customizable limit on the number of files.</li>
|
||||||
|
<li><strong>Strict Project-Relative Paths:</strong> I18n and XSD configuration now strictly enforces file selection within the project root and stores paths as relative for maximum portability.</li>
|
||||||
|
<li><strong>Smart File Browser:</strong> Improved file picker logic to automatically start at the current configured directory if it's within the project, falling back to the project root otherwise.</li>
|
||||||
|
</ul>
|
||||||
<h2>[3.2.3]</h2>
|
<h2>[3.2.3]</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Advanced Data Referencing:</strong> Implemented comprehensive reference and completion support for <code><FOREIGN-DATASETS></code> and <code><MASTER-DATA></code> structures.</li>
|
<li><strong>Advanced Data Referencing:</strong> Implemented comprehensive reference and completion support for <code><FOREIGN-DATASETS></code> and <code><MASTER-DATA></code> structures.</li>
|
||||||
<li><strong>Contextual Field Resolution:</strong> Enhanced field resolution logic to resolve fields from datasets specified by <code>DATASET-ID</code> and <code>DATAID</code> attributes within their respective tags.</li>
|
<li><strong>Contextual Field Resolution:</strong> Enhanced field resolution logic to resolve fields from datasets specified by <code>DATASET-ID</code> and <code>DATAID</code> attributes within their respective tags.</li>
|
||||||
<li><strong>Recursive Resource Scanning:</strong> Improved dataset and grid scanning to search across recursively included <code>.frml</code> files, ensuring consistent navigation and completion throughout the project.</li>
|
<li><strong>Recursive Resource Scanning:</strong> Improved dataset and grid scanning to search across recursively included <code>.frml</code> files, ensuring consistent navigation and completion throughout the project.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>[3.2.2]</h2>
|
<h2>[3.2.2]</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>UI/UX Improvement:</strong> Updated the I18n settings to allow selecting the message bundle XML file directly via a file browser, improving configuration usability.</li>
|
<li><strong>UI/UX Improvement:</strong> Updated the I18n settings to allow selecting the message bundle XML file directly via a file browser, improving configuration usability.</li>
|
||||||
|
|||||||
1
buildSrc.kts
Normal file
1
buildSrc.kts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
println("Checking methods")
|
||||||
@@ -13,9 +13,11 @@ import com.intellij.openapi.progress.ProgressIndicator;
|
|||||||
import com.intellij.openapi.progress.ProgressManager;
|
import com.intellij.openapi.progress.ProgressManager;
|
||||||
import com.intellij.openapi.progress.Task;
|
import com.intellij.openapi.progress.Task;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.sdk.dynform.helper.GUtils;
|
import com.sdk.dynform.helper.GUtils;
|
||||||
|
import com.sdk.dynform.tools.config.DynFormSettings;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -30,12 +32,23 @@ public class GenerateBeanAction extends AnAction {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DynFormSettings settings = DynFormSettings.getInstance(project);
|
||||||
FileChooserDescriptor descriptor = new FileChooserDescriptor(false,true,false,false,false,false);
|
FileChooserDescriptor descriptor = new FileChooserDescriptor(false,true,false,false,false,false);
|
||||||
PathChooserDialog pathChooser = FileChooserFactory.getInstance().createPathChooser(descriptor, project, null);
|
PathChooserDialog pathChooser = FileChooserFactory.getInstance().createPathChooser(descriptor, project, null);
|
||||||
VirtualFile baseDir = GUtils.findSourceRoot(project);
|
|
||||||
|
VirtualFile initialDir = GUtils.findSourceRoot(project);
|
||||||
|
if (settings.lastBeanPackagePath != null && !settings.lastBeanPackagePath.isEmpty()) {
|
||||||
|
VirtualFile lastDir = com.intellij.openapi.vfs.LocalFileSystem.getInstance().findFileByPath(settings.lastBeanPackagePath);
|
||||||
|
if (lastDir != null && lastDir.isValid()) {
|
||||||
|
initialDir = lastDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pathChooser.choose(baseDir, virtualFiles -> {
|
pathChooser.choose(initialDir, virtualFiles -> {
|
||||||
String packageName = GUtils.getSelectedPackage(project, virtualFiles.getFirst());
|
VirtualFile selectedDir = virtualFiles.getFirst();
|
||||||
|
settings.lastBeanPackagePath = selectedDir.getPath();
|
||||||
|
|
||||||
|
String packageName = GUtils.getSelectedPackage(project, selectedDir);
|
||||||
|
|
||||||
ArrayList<DbTable> tables = new ArrayList<>();
|
ArrayList<DbTable> tables = new ArrayList<>();
|
||||||
for (PsiElement psiElement : psiElements) {
|
for (PsiElement psiElement : psiElements) {
|
||||||
|
|||||||
@@ -13,9 +13,11 @@ import com.intellij.openapi.progress.ProgressIndicator;
|
|||||||
import com.intellij.openapi.progress.ProgressManager;
|
import com.intellij.openapi.progress.ProgressManager;
|
||||||
import com.intellij.openapi.progress.Task;
|
import com.intellij.openapi.progress.Task;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.sdk.dynform.helper.GUtils;
|
import com.sdk.dynform.helper.GUtils;
|
||||||
|
import com.sdk.dynform.tools.config.DynFormSettings;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -30,12 +32,23 @@ public class GenerateBeanActionV3 extends AnAction {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DynFormSettings settings = DynFormSettings.getInstance(project);
|
||||||
FileChooserDescriptor descriptor = new FileChooserDescriptor(false,true,false,false,false,false);
|
FileChooserDescriptor descriptor = new FileChooserDescriptor(false,true,false,false,false,false);
|
||||||
PathChooserDialog pathChooser = FileChooserFactory.getInstance().createPathChooser(descriptor, project, null);
|
PathChooserDialog pathChooser = FileChooserFactory.getInstance().createPathChooser(descriptor, project, null);
|
||||||
VirtualFile baseDir = GUtils.findSourceRoot(project);
|
|
||||||
|
VirtualFile initialDir = GUtils.findSourceRoot(project);
|
||||||
|
if (settings.lastBeanPackagePath != null && !settings.lastBeanPackagePath.isEmpty()) {
|
||||||
|
VirtualFile lastDir = com.intellij.openapi.vfs.LocalFileSystem.getInstance().findFileByPath(settings.lastBeanPackagePath);
|
||||||
|
if (lastDir != null && lastDir.isValid()) {
|
||||||
|
initialDir = lastDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pathChooser.choose(baseDir, virtualFiles -> {
|
pathChooser.choose(initialDir, virtualFiles -> {
|
||||||
String packageName = GUtils.getSelectedPackage(project, virtualFiles.getFirst());
|
VirtualFile selectedDir = virtualFiles.getFirst();
|
||||||
|
settings.lastBeanPackagePath = selectedDir.getPath();
|
||||||
|
|
||||||
|
String packageName = GUtils.getSelectedPackage(project, selectedDir);
|
||||||
|
|
||||||
ArrayList<DbTable> tables = new ArrayList<>();
|
ArrayList<DbTable> tables = new ArrayList<>();
|
||||||
for (PsiElement psiElement : psiElements) {
|
for (PsiElement psiElement : psiElements) {
|
||||||
|
|||||||
@@ -13,9 +13,11 @@ import com.intellij.openapi.progress.ProgressIndicator;
|
|||||||
import com.intellij.openapi.progress.ProgressManager;
|
import com.intellij.openapi.progress.ProgressManager;
|
||||||
import com.intellij.openapi.progress.Task;
|
import com.intellij.openapi.progress.Task;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.sdk.dynform.helper.GUtils;
|
import com.sdk.dynform.helper.GUtils;
|
||||||
|
import com.sdk.dynform.tools.config.DynFormSettings;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -30,15 +32,22 @@ public class GenerateDatasetAction extends AnAction {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DynFormSettings settings = DynFormSettings.getInstance(project);
|
||||||
FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, false, false, false, false);
|
FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, false, false, false, false);
|
||||||
descriptor.setTitle("Select Target Directory for Dataset XML");
|
descriptor.setTitle("Select Target Directory for Dataset XML");
|
||||||
PathChooserDialog pathChooser = FileChooserFactory.getInstance().createPathChooser(descriptor, project, null);
|
PathChooserDialog pathChooser = FileChooserFactory.getInstance().createPathChooser(descriptor, project, null);
|
||||||
|
|
||||||
//VirtualFile baseDir = GUtils.findSourceRoot(project);
|
VirtualFile initialDir = project.getBaseDir();
|
||||||
VirtualFile baseDir = project.getBaseDir();
|
if (settings.lastDatasetFolderPath != null && !settings.lastDatasetFolderPath.isEmpty()) {
|
||||||
|
VirtualFile lastDir = com.intellij.openapi.vfs.LocalFileSystem.getInstance().findFileByPath(settings.lastDatasetFolderPath);
|
||||||
|
if (lastDir != null && lastDir.isValid()) {
|
||||||
|
initialDir = lastDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pathChooser.choose(baseDir, virtualFiles -> {
|
pathChooser.choose(initialDir, virtualFiles -> {
|
||||||
VirtualFile targetDir = virtualFiles.getFirst();
|
VirtualFile targetDir = virtualFiles.getFirst();
|
||||||
|
settings.lastDatasetFolderPath = targetDir.getPath();
|
||||||
|
|
||||||
ArrayList<DbTable> tables = new ArrayList<>();
|
ArrayList<DbTable> tables = new ArrayList<>();
|
||||||
for (PsiElement psiElement : psiElements) {
|
for (PsiElement psiElement : psiElements) {
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import com.intellij.database.model.DasTableKey;
|
|||||||
import com.intellij.database.psi.DbTable;
|
import com.intellij.database.psi.DbTable;
|
||||||
import com.intellij.database.util.DasUtil;
|
import com.intellij.database.util.DasUtil;
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
|
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||||
import com.intellij.openapi.progress.ProgressIndicator;
|
import com.intellij.openapi.progress.ProgressIndicator;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.util.containers.JBIterable;
|
import com.intellij.util.containers.JBIterable;
|
||||||
import com.sdk.dynform.helper.GUtils;
|
import com.sdk.dynform.helper.GUtils;
|
||||||
|
import com.sdk.dynform.tools.config.DynFormSettings;
|
||||||
import freemarker.template.Configuration;
|
import freemarker.template.Configuration;
|
||||||
import freemarker.template.Template;
|
import freemarker.template.Template;
|
||||||
import freemarker.template.TemplateExceptionHandler;
|
import freemarker.template.TemplateExceptionHandler;
|
||||||
@@ -39,7 +41,7 @@ public class GeneratorServices {
|
|||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void genDataModel(Template template, Map<String, Object> model, VirtualFile targetDir, String classFile, ProgressIndicator indicator) {
|
private VirtualFile genDataModel(Template template, Map<String, Object> model, VirtualFile targetDir, String classFile, ProgressIndicator indicator) {
|
||||||
try {
|
try {
|
||||||
VirtualFile outputFile = targetDir.findOrCreateChildData(this, classFile);
|
VirtualFile outputFile = targetDir.findOrCreateChildData(this, classFile);
|
||||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||||
@@ -51,11 +53,20 @@ public class GeneratorServices {
|
|||||||
indicator.setText2("Generated " + outputFile.getName());
|
indicator.setText2("Generated " + outputFile.getName());
|
||||||
GUtils.showInfo(project, "ActionModels Generator", "Generated " + outputFile.getName());
|
GUtils.showInfo(project, "ActionModels Generator", "Generated " + outputFile.getName());
|
||||||
});
|
});
|
||||||
|
return outputFile;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void openInEditor(VirtualFile file) {
|
||||||
|
if (file != null) {
|
||||||
|
ApplicationManager.getApplication().invokeLater(() -> {
|
||||||
|
FileEditorManager.getInstance(project).openFile(file, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void execute(@NotNull ProgressIndicator indicator) {
|
public void execute(@NotNull ProgressIndicator indicator) {
|
||||||
// Use AtomicInteger to safely count files within the lambda expression
|
// Use AtomicInteger to safely count files within the lambda expression
|
||||||
AtomicInteger fileCount = new AtomicInteger(0);
|
AtomicInteger fileCount = new AtomicInteger(0);
|
||||||
@@ -81,30 +92,43 @@ public class GeneratorServices {
|
|||||||
Template tmpDTO = cfg.getTemplate("actionDTO.ftl");
|
Template tmpDTO = cfg.getTemplate("actionDTO.ftl");
|
||||||
Template tmpDTOExt = cfg.getTemplate("actionDTO.extend.ftl");
|
Template tmpDTOExt = cfg.getTemplate("actionDTO.extend.ftl");
|
||||||
|
|
||||||
tables.forEach(table -> {
|
DynFormSettings settings = DynFormSettings.getInstance(project);
|
||||||
|
|
||||||
|
for (int i = 0; i < tables.size(); i++) {
|
||||||
|
DbTable table = tables.get(i);
|
||||||
|
final boolean shouldOpen = settings.autoOpenGeneratedFiles && i < settings.openFilesLimit;
|
||||||
Map<String, Object> model = createModelForTable(table);
|
Map<String, Object> model = createModelForTable(table);
|
||||||
|
|
||||||
String className = model.get("className").toString();
|
String className = model.get("className").toString();
|
||||||
String classFile = className + ".java";
|
String classFile = className + ".java";
|
||||||
|
|
||||||
genDataModel(tmpBean, model, beanDir, classFile, indicator);
|
VirtualFile fBean = genDataModel(tmpBean, model, beanDir, classFile, indicator);
|
||||||
fileCount.getAndIncrement();
|
fileCount.getAndIncrement();
|
||||||
|
|
||||||
|
VirtualFile fBeanExt = null;
|
||||||
if (!Files.exists(Path.of(beanExtDir.toNioPath().toString(), classFile))) {
|
if (!Files.exists(Path.of(beanExtDir.toNioPath().toString(), classFile))) {
|
||||||
genDataModel(tmpBeanExt, model, beanExtDir, classFile, indicator);
|
fBeanExt = genDataModel(tmpBeanExt, model, beanExtDir, classFile, indicator);
|
||||||
fileCount.getAndIncrement();
|
fileCount.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIX: Use a separate variable for the DTO filename to avoid overwriting the wrong file.
|
// FIX: Use a separate variable for the DTO filename to avoid overwriting the wrong file.
|
||||||
String dtoClassFile = "DTO_" + className + ".java";
|
String dtoClassFile = "DTO_" + className + ".java";
|
||||||
genDataModel(tmpDTO, model, DTODir, dtoClassFile, indicator);
|
VirtualFile fDTO = genDataModel(tmpDTO, model, DTODir, dtoClassFile, indicator);
|
||||||
fileCount.getAndIncrement();
|
fileCount.getAndIncrement();
|
||||||
|
|
||||||
|
VirtualFile fDTOExt = null;
|
||||||
if (!Files.exists(Path.of(DTOExtDir.toNioPath().toString(), dtoClassFile))) {
|
if (!Files.exists(Path.of(DTOExtDir.toNioPath().toString(), dtoClassFile))) {
|
||||||
genDataModel(tmpDTOExt, model, DTOExtDir, dtoClassFile, indicator);
|
fDTOExt = genDataModel(tmpDTOExt, model, DTOExtDir, dtoClassFile, indicator);
|
||||||
fileCount.getAndIncrement();
|
fileCount.getAndIncrement();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
if (shouldOpen) {
|
||||||
|
openInEditor(fBean);
|
||||||
|
openInEditor(fBeanExt);
|
||||||
|
openInEditor(fDTO);
|
||||||
|
openInEditor(fDTOExt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// After the loop finishes, show a single, helpful summary notification.
|
// After the loop finishes, show a single, helpful summary notification.
|
||||||
String message = String.format("Generated %d files for %d tables successfully.", fileCount.get(), tables.size());
|
String message = String.format("Generated %d files for %d tables successfully.", fileCount.get(), tables.size());
|
||||||
@@ -125,14 +149,22 @@ public class GeneratorServices {
|
|||||||
|
|
||||||
Template tmpDataset = cfg.getTemplate("dataset.ftl");
|
Template tmpDataset = cfg.getTemplate("dataset.ftl");
|
||||||
|
|
||||||
tables.forEach(table -> {
|
DynFormSettings settings = DynFormSettings.getInstance(project);
|
||||||
|
|
||||||
|
for (int i = 0; i < tables.size(); i++) {
|
||||||
|
DbTable table = tables.get(i);
|
||||||
|
final boolean shouldOpen = settings.autoOpenGeneratedFiles && i < settings.openFilesLimit;
|
||||||
Map<String, Object> model = createModelForTable(table);
|
Map<String, Object> model = createModelForTable(table);
|
||||||
String tableName = model.get("tableName").toString();
|
String tableName = model.get("tableName").toString();
|
||||||
String fileName = GUtils.capitalize(tableName) + ".xml";
|
String fileName = GUtils.capitalize(tableName) + ".xml";
|
||||||
|
|
||||||
genDataModel(tmpDataset, model, targetDir, fileName, indicator);
|
VirtualFile fDataset = genDataModel(tmpDataset, model, targetDir, fileName, indicator);
|
||||||
fileCount.getAndIncrement();
|
fileCount.getAndIncrement();
|
||||||
});
|
|
||||||
|
if (shouldOpen) {
|
||||||
|
openInEditor(fDataset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String message = String.format("Generated %d dataset XML files successfully.", fileCount.get());
|
String message = String.format("Generated %d dataset XML files successfully.", fileCount.get());
|
||||||
GUtils.showInfo(project, "Dataset XML Generation Complete", message);
|
GUtils.showInfo(project, "Dataset XML Generation Complete", message);
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
|||||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||||
import com.intellij.openapi.options.Configurable;
|
import com.intellij.openapi.options.Configurable;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.project.ProjectUtil;
|
||||||
import com.intellij.openapi.ui.TextComponentAccessor;
|
import com.intellij.openapi.ui.TextComponentAccessor;
|
||||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||||
import com.intellij.openapi.util.NlsContexts;
|
import com.intellij.openapi.util.NlsContexts;
|
||||||
|
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||||
|
import com.intellij.openapi.vfs.VfsUtil;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.sdk.dynform.tools.dynform.DynFormXsdScanner;
|
import com.sdk.dynform.tools.dynform.DynFormXsdScanner;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -14,6 +17,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class DynFormConfigurable implements Configurable {
|
public class DynFormConfigurable implements Configurable {
|
||||||
|
|
||||||
@@ -25,6 +29,8 @@ public class DynFormConfigurable implements Configurable {
|
|||||||
private TextFieldWithBrowseButton i18nMessageFileField;
|
private TextFieldWithBrowseButton i18nMessageFileField;
|
||||||
private TextFieldWithBrowseButton xsdFolderField;
|
private TextFieldWithBrowseButton xsdFolderField;
|
||||||
private JTextField xsdPrefixField;
|
private JTextField xsdPrefixField;
|
||||||
|
private JCheckBox autoOpenCheck;
|
||||||
|
private JSpinner openLimitSpinner;
|
||||||
|
|
||||||
public DynFormConfigurable(@NotNull Project project) {
|
public DynFormConfigurable(@NotNull Project project) {
|
||||||
this.project = project;
|
this.project = project;
|
||||||
@@ -87,15 +93,38 @@ public class DynFormConfigurable implements Configurable {
|
|||||||
i18nGbc.weightx = 1.0;
|
i18nGbc.weightx = 1.0;
|
||||||
i18nMessageFileField = new TextFieldWithBrowseButton();
|
i18nMessageFileField = new TextFieldWithBrowseButton();
|
||||||
|
|
||||||
|
VirtualFile projectDir = ProjectUtil.guessProjectDir(project);
|
||||||
FileChooserDescriptor xmlDescriptor = new FileChooserDescriptor(true, false, false, false, false, false) {
|
FileChooserDescriptor xmlDescriptor = new FileChooserDescriptor(true, false, false, false, false, false) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
|
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
|
||||||
return super.isFileVisible(file, showHiddenFiles) && (file.isDirectory() || "xml".equalsIgnoreCase(file.getExtension()));
|
if (!super.isFileVisible(file, showHiddenFiles)) return false;
|
||||||
|
if (projectDir == null) return true;
|
||||||
|
return VfsUtil.isAncestor(projectDir, file, false);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
@Override
|
||||||
|
public void validateSelectedFiles(VirtualFile @NotNull [] files) throws Exception {
|
||||||
|
super.validateSelectedFiles(files);
|
||||||
|
for (VirtualFile file : files) {
|
||||||
|
if (projectDir != null && !VfsUtil.isAncestor(projectDir, file, false)) {
|
||||||
|
throw new Exception("File must be within the project directory.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.withRoots(projectDir);
|
||||||
|
|
||||||
i18nMessageFileField.addBrowseFolderListener("Select Message XML File", "Select the main message bundle XML file",
|
i18nMessageFileField.addBrowseFolderListener("Select Message XML File", "Select the main message bundle XML file (within project)",
|
||||||
project, xmlDescriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
|
project, xmlDescriptor, new TextComponentAccessor<>() {
|
||||||
|
@Override
|
||||||
|
public String getText(JTextField textField) {
|
||||||
|
return resolvePath(textField.getText(), projectDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setText(JTextField textField, @NotNull String text) {
|
||||||
|
textField.setText(relativizePath(text, projectDir));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
i18nPanel.add(i18nMessageFileField, i18nGbc);
|
i18nPanel.add(i18nMessageFileField, i18nGbc);
|
||||||
|
|
||||||
@@ -128,8 +157,38 @@ public class DynFormConfigurable implements Configurable {
|
|||||||
xsdGbc.gridx = 1;
|
xsdGbc.gridx = 1;
|
||||||
xsdGbc.weightx = 1.0;
|
xsdGbc.weightx = 1.0;
|
||||||
xsdFolderField = new TextFieldWithBrowseButton();
|
xsdFolderField = new TextFieldWithBrowseButton();
|
||||||
xsdFolderField.addBrowseFolderListener("Select XSD Folder", "Select the folder containing DynForm .xsd schemas",
|
|
||||||
project, FileChooserDescriptorFactory.createSingleFolderDescriptor(), TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
|
FileChooserDescriptor folderDescriptor = new FileChooserDescriptor(false, true, false, false, false, false) {
|
||||||
|
@Override
|
||||||
|
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
|
||||||
|
if (!super.isFileVisible(file, showHiddenFiles)) return false;
|
||||||
|
if (projectDir == null) return true;
|
||||||
|
return VfsUtil.isAncestor(projectDir, file, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validateSelectedFiles(VirtualFile @NotNull [] files) throws Exception {
|
||||||
|
super.validateSelectedFiles(files);
|
||||||
|
for (VirtualFile file : files) {
|
||||||
|
if (projectDir != null && !VfsUtil.isAncestor(projectDir, file, false)) {
|
||||||
|
throw new Exception("Folder must be within the project directory.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.withRoots(projectDir);
|
||||||
|
|
||||||
|
xsdFolderField.addBrowseFolderListener("Select XSD Folder", "Select the folder containing DynForm .xsd schemas (within project)",
|
||||||
|
project, folderDescriptor, new TextComponentAccessor<>() {
|
||||||
|
@Override
|
||||||
|
public String getText(JTextField textField) {
|
||||||
|
return resolvePath(textField.getText(), projectDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setText(JTextField textField, @NotNull String text) {
|
||||||
|
textField.setText(relativizePath(text, projectDir));
|
||||||
|
}
|
||||||
|
});
|
||||||
xsdPanel.add(xsdFolderField, xsdGbc);
|
xsdPanel.add(xsdFolderField, xsdGbc);
|
||||||
|
|
||||||
xsdGbc.gridx = 0;
|
xsdGbc.gridx = 0;
|
||||||
@@ -142,6 +201,34 @@ public class DynFormConfigurable implements Configurable {
|
|||||||
|
|
||||||
mainPanel.add(xsdPanel, gbc);
|
mainPanel.add(xsdPanel, gbc);
|
||||||
|
|
||||||
|
// --- Generator Settings Group ---
|
||||||
|
gbc.gridy++;
|
||||||
|
JPanel generatorPanel = new JPanel(new GridBagLayout());
|
||||||
|
generatorPanel.setBorder(BorderFactory.createTitledBorder("Action Models Generator"));
|
||||||
|
|
||||||
|
GridBagConstraints genGbc = new GridBagConstraints();
|
||||||
|
genGbc.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
genGbc.insets = new Insets(2, 2, 2, 2);
|
||||||
|
genGbc.gridx = 0;
|
||||||
|
genGbc.gridy = 0;
|
||||||
|
genGbc.weightx = 1.0;
|
||||||
|
genGbc.gridwidth = 2;
|
||||||
|
|
||||||
|
autoOpenCheck = new JCheckBox("Automatically open generated files in editor");
|
||||||
|
generatorPanel.add(autoOpenCheck, genGbc);
|
||||||
|
|
||||||
|
genGbc.gridy++;
|
||||||
|
genGbc.gridwidth = 1;
|
||||||
|
genGbc.weightx = 0.0;
|
||||||
|
generatorPanel.add(new JLabel("Limit of tables to open:"), genGbc);
|
||||||
|
|
||||||
|
genGbc.gridx = 1;
|
||||||
|
genGbc.weightx = 1.0;
|
||||||
|
openLimitSpinner = new JSpinner(new SpinnerNumberModel(3, 0, 100, 1));
|
||||||
|
generatorPanel.add(openLimitSpinner, genGbc);
|
||||||
|
|
||||||
|
mainPanel.add(generatorPanel, gbc);
|
||||||
|
|
||||||
// Spacer
|
// Spacer
|
||||||
gbc.gridy++;
|
gbc.gridy++;
|
||||||
gbc.weighty = 1.0;
|
gbc.weighty = 1.0;
|
||||||
@@ -153,21 +240,30 @@ public class DynFormConfigurable implements Configurable {
|
|||||||
@Override
|
@Override
|
||||||
public boolean isModified() {
|
public boolean isModified() {
|
||||||
DynFormSettings settings = DynFormSettings.getInstance(project);
|
DynFormSettings settings = DynFormSettings.getInstance(project);
|
||||||
|
VirtualFile projectDir = ProjectUtil.guessProjectDir(project);
|
||||||
return settings.displayMode != getCurrentModeFromUI() ||
|
return settings.displayMode != getCurrentModeFromUI() ||
|
||||||
settings.showIcon != showIconCheck.isSelected() ||
|
settings.showIcon != showIconCheck.isSelected() ||
|
||||||
!settings.i18nMessageFile.equals(i18nMessageFileField.getText()) ||
|
!settings.i18nMessageFile.equals(relativizePath(i18nMessageFileField.getText(), projectDir)) ||
|
||||||
!settings.xsdFolderPath.equals(xsdFolderField.getText()) ||
|
!settings.xsdFolderPath.equals(relativizePath(xsdFolderField.getText(), projectDir)) ||
|
||||||
!settings.xsdPrefix.equals(xsdPrefixField.getText());
|
!settings.xsdPrefix.equals(xsdPrefixField.getText()) ||
|
||||||
|
settings.autoOpenGeneratedFiles != autoOpenCheck.isSelected() ||
|
||||||
|
settings.openFilesLimit != (int) openLimitSpinner.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply() {
|
public void apply() {
|
||||||
DynFormSettings settings = DynFormSettings.getInstance(project);
|
DynFormSettings settings = DynFormSettings.getInstance(project);
|
||||||
|
VirtualFile projectDir = ProjectUtil.guessProjectDir(project);
|
||||||
|
|
||||||
settings.displayMode = getCurrentModeFromUI();
|
settings.displayMode = getCurrentModeFromUI();
|
||||||
settings.showIcon = showIconCheck.isSelected();
|
settings.showIcon = showIconCheck.isSelected();
|
||||||
settings.i18nMessageFile = i18nMessageFileField.getText();
|
|
||||||
settings.xsdFolderPath = xsdFolderField.getText();
|
settings.i18nMessageFile = relativizePath(i18nMessageFileField.getText(), projectDir);
|
||||||
|
settings.xsdFolderPath = relativizePath(xsdFolderField.getText(), projectDir);
|
||||||
|
|
||||||
settings.xsdPrefix = xsdPrefixField.getText();
|
settings.xsdPrefix = xsdPrefixField.getText();
|
||||||
|
settings.autoOpenGeneratedFiles = autoOpenCheck.isSelected();
|
||||||
|
settings.openFilesLimit = (int) openLimitSpinner.getValue();
|
||||||
|
|
||||||
// Register XSDs to IntelliJ for this project
|
// Register XSDs to IntelliJ for this project
|
||||||
DynFormXsdScanner.scanAndRegister(project, settings.xsdFolderPath, settings.xsdPrefix);
|
DynFormXsdScanner.scanAndRegister(project, settings.xsdFolderPath, settings.xsdPrefix);
|
||||||
@@ -176,6 +272,45 @@ public class DynFormConfigurable implements Configurable {
|
|||||||
com.intellij.codeInsight.daemon.DaemonCodeAnalyzer.getInstance(project).restart();
|
com.intellij.codeInsight.daemon.DaemonCodeAnalyzer.getInstance(project).restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String relativizePath(String path, VirtualFile projectDir) {
|
||||||
|
if (projectDir == null || path == null || path.isEmpty()) return path;
|
||||||
|
File file = new File(path);
|
||||||
|
if (!file.isAbsolute()) return path; // Already relative or placeholder
|
||||||
|
|
||||||
|
VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
|
||||||
|
if (vFile != null) {
|
||||||
|
String relativePath = VfsUtil.getRelativePath(vFile, projectDir);
|
||||||
|
if (relativePath != null) return relativePath;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolvePath(String path, VirtualFile projectDir) {
|
||||||
|
if (projectDir == null) return path;
|
||||||
|
if (path == null || path.isEmpty()) return projectDir.getPath();
|
||||||
|
|
||||||
|
VirtualFile vFile;
|
||||||
|
File file = new File(path);
|
||||||
|
if (file.isAbsolute()) {
|
||||||
|
vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
|
||||||
|
} else {
|
||||||
|
vFile = projectDir.findFileByRelativePath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vFile != null && VfsUtil.isAncestor(projectDir, vFile, false)) {
|
||||||
|
return vFile.getPath();
|
||||||
|
}
|
||||||
|
return projectDir.getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isWithinProject(String path, VirtualFile projectDir) {
|
||||||
|
if (projectDir == null || path == null || path.isEmpty()) return true;
|
||||||
|
File file = new File(path);
|
||||||
|
String absolutePath = file.getAbsolutePath();
|
||||||
|
String projectPath = projectDir.getPath();
|
||||||
|
return absolutePath.startsWith(projectPath);
|
||||||
|
}
|
||||||
|
|
||||||
private DynFormSettings.DisplayMode getCurrentModeFromUI() {
|
private DynFormSettings.DisplayMode getCurrentModeFromUI() {
|
||||||
if (foldingBtn.isSelected()) return DynFormSettings.DisplayMode.FOLDING;
|
if (foldingBtn.isSelected()) return DynFormSettings.DisplayMode.FOLDING;
|
||||||
if (inlayBtn.isSelected()) return DynFormSettings.DisplayMode.INLAY_HINTS;
|
if (inlayBtn.isSelected()) return DynFormSettings.DisplayMode.INLAY_HINTS;
|
||||||
@@ -185,6 +320,7 @@ public class DynFormConfigurable implements Configurable {
|
|||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
DynFormSettings settings = DynFormSettings.getInstance(project);
|
DynFormSettings settings = DynFormSettings.getInstance(project);
|
||||||
|
|
||||||
switch (settings.displayMode) {
|
switch (settings.displayMode) {
|
||||||
case FOLDING: foldingBtn.setSelected(true); break;
|
case FOLDING: foldingBtn.setSelected(true); break;
|
||||||
case INLAY_HINTS: inlayBtn.setSelected(true); break;
|
case INLAY_HINTS: inlayBtn.setSelected(true); break;
|
||||||
@@ -194,5 +330,7 @@ public class DynFormConfigurable implements Configurable {
|
|||||||
i18nMessageFileField.setText(settings.i18nMessageFile);
|
i18nMessageFileField.setText(settings.i18nMessageFile);
|
||||||
xsdFolderField.setText(settings.xsdFolderPath);
|
xsdFolderField.setText(settings.xsdFolderPath);
|
||||||
xsdPrefixField.setText(settings.xsdPrefix);
|
xsdPrefixField.setText(settings.xsdPrefix);
|
||||||
|
autoOpenCheck.setSelected(settings.autoOpenGeneratedFiles);
|
||||||
|
openLimitSpinner.setValue(settings.openFilesLimit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,12 @@ public class DynFormSettings implements PersistentStateComponent<DynFormSettings
|
|||||||
public String xsdFolderPath = "";
|
public String xsdFolderPath = "";
|
||||||
public String xsdPrefix = "/dynf";
|
public String xsdPrefix = "/dynf";
|
||||||
|
|
||||||
|
// Action Models Generator Settings
|
||||||
|
public boolean autoOpenGeneratedFiles = true;
|
||||||
|
public int openFilesLimit = 3;
|
||||||
|
public String lastBeanPackagePath = "";
|
||||||
|
public String lastDatasetFolderPath = "";
|
||||||
|
|
||||||
public static DynFormSettings getInstance(Project project) {
|
public static DynFormSettings getInstance(Project project) {
|
||||||
return project.getService(DynFormSettings.class);
|
return project.getService(DynFormSettings.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.intellij.javaee.ExternalResourceManagerEx;
|
|||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.project.ProjectUtil;
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
|
||||||
@@ -16,6 +17,17 @@ public class DynFormXsdScanner {
|
|||||||
if (project == null || folderPath == null || folderPath.isEmpty()) return;
|
if (project == null || folderPath == null || folderPath.isEmpty()) return;
|
||||||
|
|
||||||
File dir = new File(folderPath);
|
File dir = new File(folderPath);
|
||||||
|
if (!dir.exists() || !dir.isDirectory()) {
|
||||||
|
// Try relative path from project root
|
||||||
|
VirtualFile projectDir = ProjectUtil.guessProjectDir(project);
|
||||||
|
if (projectDir != null) {
|
||||||
|
VirtualFile vDir = projectDir.findFileByRelativePath(folderPath);
|
||||||
|
if (vDir != null && vDir.isDirectory()) {
|
||||||
|
dir = new File(vDir.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!dir.exists() || !dir.isDirectory()) return;
|
if (!dir.exists() || !dir.isDirectory()) return;
|
||||||
|
|
||||||
File[] xsdFiles = dir.listFiles((d, name) -> name.toLowerCase().endsWith(".xsd"));
|
File[] xsdFiles = dir.listFiles((d, name) -> name.toLowerCase().endsWith(".xsd"));
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.sdk.dynform.tools.i18n;
|
package com.sdk.dynform.tools.i18n;
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.project.ProjectUtil;
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
@@ -29,10 +30,16 @@ public class I18nUtils {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find the file using its absolute path
|
// Try to find the file using its absolute path or relative path from project root
|
||||||
VirtualFile file = LocalFileSystem.getInstance().findFileByPath(filePath);
|
VirtualFile file = LocalFileSystem.getInstance().findFileByPath(filePath);
|
||||||
|
if (file == null) {
|
||||||
|
VirtualFile projectDir = ProjectUtil.guessProjectDir(project);
|
||||||
|
if (projectDir != null) {
|
||||||
|
file = projectDir.findFileByRelativePath(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If not found by absolute path, fallback to searching by filename in the project
|
// If not found by path, fallback to searching by filename in the project
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
String filename = new java.io.File(filePath).getName();
|
String filename = new java.io.File(filePath).getName();
|
||||||
Collection<VirtualFile> files = FilenameIndex.getVirtualFilesByName(filename, GlobalSearchScope.everythingScope(project));
|
Collection<VirtualFile> files = FilenameIndex.getVirtualFilesByName(filename, GlobalSearchScope.everythingScope(project));
|
||||||
|
|||||||
@@ -34,6 +34,13 @@
|
|||||||
]]></description>
|
]]></description>
|
||||||
|
|
||||||
<change-notes><![CDATA[
|
<change-notes><![CDATA[
|
||||||
|
<h2>[3.2.4]</h2>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Persistent Generation Directories:</strong> Generator now remembers the last used directory for Action Beans and Dataset XMLs independently per project.</li>
|
||||||
|
<li><strong>Auto-Open Generated Files:</strong> Added configuration to automatically open newly created files in the editor, with a customizable limit on the number of files.</li>
|
||||||
|
<li><strong>Strict Project-Relative Paths:</strong> I18n and XSD configuration now strictly enforces file selection within the project root and stores paths as relative for maximum portability.</li>
|
||||||
|
<li><strong>Smart File Browser:</strong> Improved file picker logic to automatically start at the current configured directory if it's within the project, falling back to the project root otherwise.</li>
|
||||||
|
</ul>
|
||||||
<h2>[3.2.3]</h2>
|
<h2>[3.2.3]</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Advanced Data Referencing:</strong> Implemented comprehensive reference and completion support for <code><FOREIGN-DATASETS></code> and <code><MASTER-DATA></code> structures.</li>
|
<li><strong>Advanced Data Referencing:</strong> Implemented comprehensive reference and completion support for <code><FOREIGN-DATASETS></code> and <code><MASTER-DATA></code> structures.</li>
|
||||||
|
|||||||
Reference in New Issue
Block a user