diff --git a/DevResources/xsd/ajax.xsd b/DevResources/xsd/ajax.xsd
new file mode 100755
index 0000000..ba082ca
--- /dev/null
+++ b/DevResources/xsd/ajax.xsd
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DevResources/xsd/dynf-form-def.xsd b/DevResources/xsd/dynf-form-def.xsd
new file mode 100755
index 0000000..65a6483
--- /dev/null
+++ b/DevResources/xsd/dynf-form-def.xsd
@@ -0,0 +1,1349 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ javascript function exam : (value,row,index)=>{ }
+
+
+
+
+ javascript function exam : (data,value)=>{ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ javascript (value,index,data )=>{ return value;}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ javascript function
+ exam : (data)=>{ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ javascript function exam : ({$ctx,data})=>{ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ javascript function exam : ({ev, row})=>{ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ javascript function exam : ($ctx,data)=>{ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ javascript function exam : ($ctx,data)=>{}
+
+
+
+
+ javascript function exam : ($ctx,data)=>{}
+
+
+
+
+ javascript function exam : ($ctx,data)=>{}
+
+
+
+
+ javascript function exam : ($ctx,data)=>{}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ javascript function exam : (filter)=>{}
+
+
+
+
+
+
+
+
+
+ javascript function exam : (column)=>{ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ javascript function
+ exam : (data)=>{ }
+
+
+
+
+ javascript function
+ exam : (data)=>{ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DevResources/xsd/lovdef.xsd b/DevResources/xsd/lovdef.xsd
new file mode 100755
index 0000000..4c607cb
--- /dev/null
+++ b/DevResources/xsd/lovdef.xsd
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DevResources/xsd/system-config.xsd b/DevResources/xsd/system-config.xsd
new file mode 100644
index 0000000..42bb86f
--- /dev/null
+++ b/DevResources/xsd/system-config.xsd
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 59eb9df..1e408a3 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -5,7 +5,7 @@ plugins {
}
group = "com.sdk.dynform.tools"
-version = "3.1.0"
+version = "3.2.0"
repositories {
mavenCentral()
@@ -39,6 +39,12 @@ intellijPlatform {
}
changeNotes = """
+
[3.2.0]
+
+ - Schema Validation: Introduced project-level automatic XSD registration. Configure a target folder and namespace prefix to seamlessly map
.xsd files to the ExternalResourceManager.
+ - Architecture: Finalized rebranding by standardizing internal packages to
com.sdk.dynform.* for better consistency.
+ - UI Improvement: Streamlined the plugin settings UI into distinct Internationalization and Schema Validation groups.
+
[3.1.0]
- Advanced Navigation: Implemented bidirectional field referencing between
<FIELDS>, <LAYOUT>, and <TITLES> tags in .frml files.
@@ -55,7 +61,7 @@ intellijPlatform {
[3.0.1]
- - Rebranding: Renamed plugin to "Dynamic Form Helper" (DynamicFormTools) to better reflect its expanding capabilities.
+ - Rebranding: Renamed plugin to "DynamicForm Tools" to better reflect its expanding capabilities.
- I18n Support: Added comprehensive tools for internationalization:
- Inlay hints and code folding for i18n keys in Java, XML, and JavaScript.
diff --git a/src/main/java/com/sdk/dynform/tools/generators/actionmodels/GenerateAction.java b/src/main/java/com/sdk/dynform/tools/actionbean/GenerateAction.java
similarity index 99%
rename from src/main/java/com/sdk/dynform/tools/generators/actionmodels/GenerateAction.java
rename to src/main/java/com/sdk/dynform/tools/actionbean/GenerateAction.java
index dff9ffa..985b295 100644
--- a/src/main/java/com/sdk/dynform/tools/generators/actionmodels/GenerateAction.java
+++ b/src/main/java/com/sdk/dynform/tools/actionbean/GenerateAction.java
@@ -1,4 +1,4 @@
-package com.sdk.dynform.tools.generators.actionmodels;
+package com.sdk.dynform.tools.actionbean;
import com.intellij.database.model.DasColumn;
import com.intellij.database.model.ObjectKind;
diff --git a/src/main/java/com/sdk/dynform/tools/generators/actionmodels/GenerateBeanAction.java b/src/main/java/com/sdk/dynform/tools/actionbean/GenerateBeanAction.java
similarity index 98%
rename from src/main/java/com/sdk/dynform/tools/generators/actionmodels/GenerateBeanAction.java
rename to src/main/java/com/sdk/dynform/tools/actionbean/GenerateBeanAction.java
index 0ee9ef6..266ec63 100644
--- a/src/main/java/com/sdk/dynform/tools/generators/actionmodels/GenerateBeanAction.java
+++ b/src/main/java/com/sdk/dynform/tools/actionbean/GenerateBeanAction.java
@@ -1,4 +1,4 @@
-package com.sdk.dynform.tools.generators.actionmodels;
+package com.sdk.dynform.tools.actionbean;
import com.intellij.database.psi.DbTable;
import com.intellij.openapi.actionSystem.AnAction;
diff --git a/src/main/java/com/sdk/dynform/tools/generators/actionmodels/GenerateBeanActionV3.java b/src/main/java/com/sdk/dynform/tools/actionbean/GenerateBeanActionV3.java
similarity index 98%
rename from src/main/java/com/sdk/dynform/tools/generators/actionmodels/GenerateBeanActionV3.java
rename to src/main/java/com/sdk/dynform/tools/actionbean/GenerateBeanActionV3.java
index 8e3a0be..535ddf6 100644
--- a/src/main/java/com/sdk/dynform/tools/generators/actionmodels/GenerateBeanActionV3.java
+++ b/src/main/java/com/sdk/dynform/tools/actionbean/GenerateBeanActionV3.java
@@ -1,4 +1,4 @@
-package com.sdk.dynform.tools.generators.actionmodels;
+package com.sdk.dynform.tools.actionbean;
import com.intellij.database.psi.DbTable;
import com.intellij.openapi.actionSystem.AnAction;
diff --git a/src/main/java/com/sdk/dynform/tools/generators/actionmodels/GenerateDatasetAction.java b/src/main/java/com/sdk/dynform/tools/actionbean/GenerateDatasetAction.java
similarity index 98%
rename from src/main/java/com/sdk/dynform/tools/generators/actionmodels/GenerateDatasetAction.java
rename to src/main/java/com/sdk/dynform/tools/actionbean/GenerateDatasetAction.java
index ffc9929..57a05f2 100644
--- a/src/main/java/com/sdk/dynform/tools/generators/actionmodels/GenerateDatasetAction.java
+++ b/src/main/java/com/sdk/dynform/tools/actionbean/GenerateDatasetAction.java
@@ -1,4 +1,4 @@
-package com.sdk.dynform.tools.generators.actionmodels;
+package com.sdk.dynform.tools.actionbean;
import com.intellij.database.psi.DbTable;
import com.intellij.openapi.actionSystem.AnAction;
diff --git a/src/main/java/com/sdk/dynform/tools/generators/actionmodels/GeneratorServices.java b/src/main/java/com/sdk/dynform/tools/actionbean/GeneratorServices.java
similarity index 99%
rename from src/main/java/com/sdk/dynform/tools/generators/actionmodels/GeneratorServices.java
rename to src/main/java/com/sdk/dynform/tools/actionbean/GeneratorServices.java
index 7f19e24..bcc98b3 100644
--- a/src/main/java/com/sdk/dynform/tools/generators/actionmodels/GeneratorServices.java
+++ b/src/main/java/com/sdk/dynform/tools/actionbean/GeneratorServices.java
@@ -1,4 +1,4 @@
-package com.sdk.dynform.tools.generators.actionmodels;
+package com.sdk.dynform.tools.actionbean;
import com.intellij.database.model.DasColumn;
import com.intellij.database.model.DasTableKey;
diff --git a/src/main/java/com/sdk/dynform/tools/config/DynFormConfigurable.java b/src/main/java/com/sdk/dynform/tools/config/DynFormConfigurable.java
new file mode 100644
index 0000000..aa95db9
--- /dev/null
+++ b/src/main/java/com/sdk/dynform/tools/config/DynFormConfigurable.java
@@ -0,0 +1,161 @@
+package com.sdk.dynform.tools.config;
+
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.TextComponentAccessor;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.util.NlsContexts;
+import com.sdk.dynform.tools.dynform.DynFormXsdScanner;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class DynFormConfigurable implements Configurable {
+
+ private final Project project;
+ private JRadioButton foldingBtn;
+ private JRadioButton inlayBtn;
+ private JRadioButton disabledBtn;
+ private JCheckBox showIconCheck;
+ private TextFieldWithBrowseButton xsdFolderField;
+ private JTextField xsdPrefixField;
+
+ public DynFormConfigurable(@NotNull Project project) {
+ this.project = project;
+ }
+
+ @Override
+ public @NlsContexts.ConfigurableName String getDisplayName() {
+ return "DynamicForm Tools";
+ }
+
+ @Override
+ public @Nullable JComponent createComponent() {
+ JPanel mainPanel = new JPanel(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.insets = new Insets(5, 5, 5, 5);
+
+ // --- I18n Settings Group ---
+ JPanel i18nPanel = new JPanel();
+ i18nPanel.setLayout(new BoxLayout(i18nPanel, BoxLayout.Y_AXIS));
+ i18nPanel.setBorder(BorderFactory.createTitledBorder("Internationalization (i18n)"));
+
+ i18nPanel.add(new JLabel("Message Display Mode:"));
+ foldingBtn = new JRadioButton("Folding (Hide key, show translation)");
+ inlayBtn = new JRadioButton("Inlay Hints (Show translation next to key)");
+ disabledBtn = new JRadioButton("Disabled");
+
+ ButtonGroup group = new ButtonGroup();
+ group.add(foldingBtn);
+ group.add(inlayBtn);
+ group.add(disabledBtn);
+
+ i18nPanel.add(foldingBtn);
+ i18nPanel.add(inlayBtn);
+ i18nPanel.add(disabledBtn);
+
+ i18nPanel.add(Box.createVerticalStrut(10));
+ showIconCheck = new JCheckBox("Show icon in code completion");
+ i18nPanel.add(showIconCheck);
+
+ mainPanel.add(i18nPanel, gbc);
+
+ // --- XSD Settings Group ---
+ gbc.gridy++;
+ JPanel xsdPanel = new JPanel(new GridBagLayout());
+ xsdPanel.setBorder(BorderFactory.createTitledBorder("Schema Validation (XSD)"));
+
+ GridBagConstraints xsdGbc = new GridBagConstraints();
+ xsdGbc.fill = GridBagConstraints.HORIZONTAL;
+ xsdGbc.insets = new Insets(2, 2, 2, 2);
+ xsdGbc.gridx = 0;
+ xsdGbc.gridy = 0;
+ xsdGbc.weightx = 0.0;
+
+ xsdPanel.add(new JLabel("XSD Namespace Prefix:"), xsdGbc);
+
+ xsdGbc.gridx = 1;
+ xsdGbc.weightx = 1.0;
+ xsdPrefixField = new JTextField();
+ xsdPanel.add(xsdPrefixField, xsdGbc);
+
+ xsdGbc.gridx = 0;
+ xsdGbc.gridy = 1;
+ xsdGbc.weightx = 0.0;
+ xsdPanel.add(new JLabel("XSD Schemas Folder:"), xsdGbc);
+
+ xsdGbc.gridx = 1;
+ xsdGbc.weightx = 1.0;
+ xsdFolderField = new TextFieldWithBrowseButton();
+ xsdFolderField.addBrowseFolderListener("Select XSD Folder", "Select the folder containing DynForm .xsd schemas",
+ project, FileChooserDescriptorFactory.createSingleFolderDescriptor(), TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
+ xsdPanel.add(xsdFolderField, xsdGbc);
+
+ xsdGbc.gridx = 0;
+ xsdGbc.gridy = 2;
+ xsdGbc.gridwidth = 2;
+ xsdGbc.weightx = 1.0;
+ JLabel hintLabel = new JLabel("Plugin will map: / -> /");
+ hintLabel.setFont(hintLabel.getFont().deriveFont(Font.ITALIC, 11f));
+ xsdPanel.add(hintLabel, xsdGbc);
+
+ mainPanel.add(xsdPanel, gbc);
+
+ // Spacer
+ gbc.gridy++;
+ gbc.weighty = 1.0;
+ mainPanel.add(new JPanel(), gbc);
+
+ return mainPanel;
+ }
+
+ @Override
+ public boolean isModified() {
+ DynFormSettings settings = DynFormSettings.getInstance(project);
+ return settings.displayMode != getCurrentModeFromUI() ||
+ settings.showIcon != showIconCheck.isSelected() ||
+ !settings.xsdFolderPath.equals(xsdFolderField.getText()) ||
+ !settings.xsdPrefix.equals(xsdPrefixField.getText());
+ }
+
+ @Override
+ public void apply() {
+ DynFormSettings settings = DynFormSettings.getInstance(project);
+ settings.displayMode = getCurrentModeFromUI();
+ settings.showIcon = showIconCheck.isSelected();
+ settings.xsdFolderPath = xsdFolderField.getText();
+ settings.xsdPrefix = xsdPrefixField.getText();
+
+ // Register XSDs to IntelliJ for this project
+ DynFormXsdScanner.scanAndRegister(project, settings.xsdFolderPath, settings.xsdPrefix);
+
+ // Refresh editor
+ com.intellij.codeInsight.daemon.DaemonCodeAnalyzer.getInstance(project).restart();
+ }
+
+ private DynFormSettings.DisplayMode getCurrentModeFromUI() {
+ if (foldingBtn.isSelected()) return DynFormSettings.DisplayMode.FOLDING;
+ if (inlayBtn.isSelected()) return DynFormSettings.DisplayMode.INLAY_HINTS;
+ return DynFormSettings.DisplayMode.DISABLED;
+ }
+
+ @Override
+ public void reset() {
+ DynFormSettings settings = DynFormSettings.getInstance(project);
+ switch (settings.displayMode) {
+ case FOLDING: foldingBtn.setSelected(true); break;
+ case INLAY_HINTS: inlayBtn.setSelected(true); break;
+ case DISABLED: disabledBtn.setSelected(true); break;
+ }
+ showIconCheck.setSelected(settings.showIcon);
+ xsdFolderField.setText(settings.xsdFolderPath);
+ xsdPrefixField.setText(settings.xsdPrefix);
+ }
+}
diff --git a/src/main/java/com/sdk/dynform/tools/i18n/I18nSettings.java b/src/main/java/com/sdk/dynform/tools/config/DynFormSettings.java
similarity index 51%
rename from src/main/java/com/sdk/dynform/tools/i18n/I18nSettings.java
rename to src/main/java/com/sdk/dynform/tools/config/DynFormSettings.java
index ad77a46..3967f95 100644
--- a/src/main/java/com/sdk/dynform/tools/i18n/I18nSettings.java
+++ b/src/main/java/com/sdk/dynform/tools/config/DynFormSettings.java
@@ -1,18 +1,18 @@
-package com.sdk.dynform.tools.i18n;
+package com.sdk.dynform.tools.config;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
+import com.intellij.openapi.project.Project;
import com.intellij.util.xmlb.XmlSerializerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@State(
- name = "com.sdk.dynform.tools.i18n.I18nSettings",
- storages = @Storage("DynamicFormTools.xml")
+ name = "com.sdk.dynform.tools.config.DynFormSettings",
+ storages = @Storage("DynamicFormToolsProject.xml")
)
-public class I18nSettings implements PersistentStateComponent {
+public class DynFormSettings implements PersistentStateComponent {
public enum DisplayMode {
FOLDING,
@@ -22,19 +22,21 @@ public class I18nSettings implements PersistentStateComponent {
public DisplayMode displayMode = DisplayMode.FOLDING;
public boolean showIcon = true;
+ public String xsdFolderPath = "";
+ public String xsdPrefix = "/dynf";
- public static I18nSettings getInstance() {
- return ApplicationManager.getApplication().getService(I18nSettings.class);
+ public static DynFormSettings getInstance(Project project) {
+ return project.getService(DynFormSettings.class);
}
@Nullable
@Override
- public I18nSettings getState() {
+ public DynFormSettings getState() {
return this;
}
@Override
- public void loadState(@NotNull I18nSettings state) {
+ public void loadState(@NotNull DynFormSettings state) {
XmlSerializerUtil.copyBean(state, this);
}
}
diff --git a/src/main/java/com/sdk/dynform/tools/helper/DynFormCompletionContributor.java b/src/main/java/com/sdk/dynform/tools/dynform/DynFormCompletionContributor.java
similarity index 98%
rename from src/main/java/com/sdk/dynform/tools/helper/DynFormCompletionContributor.java
rename to src/main/java/com/sdk/dynform/tools/dynform/DynFormCompletionContributor.java
index af1acc8..df9b7c9 100644
--- a/src/main/java/com/sdk/dynform/tools/helper/DynFormCompletionContributor.java
+++ b/src/main/java/com/sdk/dynform/tools/dynform/DynFormCompletionContributor.java
@@ -1,4 +1,4 @@
-package com.sdk.dynform.tools.helper;
+package com.sdk.dynform.tools.dynform;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
@@ -76,12 +76,12 @@ public class DynFormCompletionContributor extends CompletionContributor {
while (formContainer != null && !"FORM_ENTRY".equals(formContainer.getName()) && !"FORM_BROWSE".equals(formContainer.getName())) {
formContainer = formContainer.getParentTag();
}
-
+
if (formContainer == null) {
XmlFile file = (XmlFile) parameters.getOriginalFile();
formContainer = file.getRootTag();
}
-
+
if (formContainer != null) {
addFieldsInTagRecursive(formContainer, resultSet);
}
@@ -136,7 +136,7 @@ public class DynFormCompletionContributor extends CompletionContributor {
ajaxOptionTag = ajaxOptionTag.getParentTag();
}
if (ajaxOptionTag == null) return;
-
+
String datasetId = ajaxOptionTag.getAttributeValue("DATASET");
if (datasetId == null) return;
@@ -146,7 +146,7 @@ public class DynFormCompletionContributor extends CompletionContributor {
if (rootTag != null) {
XmlTag datasetsContainer = rootTag.findFirstSubTag("DATASETS");
if (datasetsContainer == null) datasetsContainer = rootTag;
-
+
for (XmlTag datasetTag : datasetsContainer.findSubTags("DATASET")) {
if (datasetId.equals(datasetTag.getAttributeValue("ID"))) {
XmlTag fieldsTag = datasetTag.findFirstSubTag("FIELDS");
@@ -199,7 +199,7 @@ public class DynFormCompletionContributor extends CompletionContributor {
if (!(file instanceof XmlFile xmlFile)) return;
XmlTag rootTag = xmlFile.getRootTag();
if (rootTag == null) return;
-
+
XmlTag datasetsContainer = rootTag.findFirstSubTag("DATASETS");
if (datasetsContainer == null) datasetsContainer = rootTag;
diff --git a/src/main/java/com/sdk/dynform/tools/helper/DynFormPathUtils.java b/src/main/java/com/sdk/dynform/tools/dynform/DynFormPathUtils.java
similarity index 99%
rename from src/main/java/com/sdk/dynform/tools/helper/DynFormPathUtils.java
rename to src/main/java/com/sdk/dynform/tools/dynform/DynFormPathUtils.java
index aebfdf2..5033a22 100644
--- a/src/main/java/com/sdk/dynform/tools/helper/DynFormPathUtils.java
+++ b/src/main/java/com/sdk/dynform/tools/dynform/DynFormPathUtils.java
@@ -1,4 +1,4 @@
-package com.sdk.dynform.tools.helper;
+package com.sdk.dynform.tools.dynform;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -26,7 +26,7 @@ public class DynFormPathUtils {
public static VirtualFile findModuleDir(@NotNull PsiFile file) {
VirtualFile vFile = file.getVirtualFile();
if (vFile == null) return null;
-
+
VirtualFile current = vFile.getParent();
while (current != null) {
if (current.getParent() != null && "module".equals(current.getParent().getName())) {
@@ -53,7 +53,7 @@ public class DynFormPathUtils {
public static PsiFile findIncludedFile(@NotNull PsiFile contextFile, @NotNull String path) {
// จัดการกรณี typo (ิ แทน /)
path = path.replace("ิ", "/");
-
+
VirtualFile moduleBase = getModuleBaseDir(contextFile.getProject());
if (moduleBase == null) return null;
diff --git a/src/main/java/com/sdk/dynform/tools/helper/DynFormReferenceContributor.java b/src/main/java/com/sdk/dynform/tools/dynform/DynFormReferenceContributor.java
similarity index 96%
rename from src/main/java/com/sdk/dynform/tools/helper/DynFormReferenceContributor.java
rename to src/main/java/com/sdk/dynform/tools/dynform/DynFormReferenceContributor.java
index 34f871e..2fe0ef6 100644
--- a/src/main/java/com/sdk/dynform/tools/helper/DynFormReferenceContributor.java
+++ b/src/main/java/com/sdk/dynform/tools/dynform/DynFormReferenceContributor.java
@@ -1,4 +1,4 @@
-package com.sdk.dynform.tools.helper;
+package com.sdk.dynform.tools.dynform;
import com.intellij.openapi.util.TextRange;
import com.intellij.patterns.PlatformPatterns;
@@ -60,25 +60,25 @@ public class DynFormReferenceContributor extends PsiReferenceContributor {
XmlAttributeValue attrValue = (XmlAttributeValue) element;
String value = attrValue.getValue();
if (value == null || value.isEmpty()) return PsiReference.EMPTY_ARRAY;
-
+
XmlAttribute attr = (XmlAttribute) attrValue.getParent();
XmlTag tag = (XmlTag) attr.getParent();
String attrName = attr.getName();
-
+
if ("TARGET".equals(attrName)) {
return new PsiReference[]{new DynFormLocalFieldReference(attrValue, new TextRange(1, value.length() + 1), value)};
}
-
+
// เคส 1: อยู่ใน LAYOUT หรือ TITLES -> ลิงก์ไปหา FIELDS (นิยาม)
if (hasAncestorWithName(tag, "LAYOUT") || hasAncestorWithName(tag, "TITLES")) {
return new PsiReference[]{new DynFormFieldDefinitionReference(attrValue, new TextRange(1, value.length() + 1), value)};
}
-
+
// เคส 2: อยู่ใน FIELDS (นิยาม) -> ลิงก์กลับไปหา LAYOUT หรือ TITLES (การใช้งาน)
if (hasAncestorWithName(tag, "FIELDS")) {
return new PsiReference[]{new DynFormFieldUsageReference(attrValue, new TextRange(1, value.length() + 1), value)};
}
-
+
return PsiReference.EMPTY_ARRAY;
}
});
@@ -180,7 +180,7 @@ public class DynFormReferenceContributor extends PsiReferenceContributor {
private static class DynFormModuleReference extends PsiReferenceBase {
private final String moduleName;
public DynFormModuleReference(@NotNull PsiElement element, TextRange textRange, String moduleName) {
- super(element, textRange);
+ super(element, textRange, true);
this.moduleName = moduleName;
}
@Nullable @Override public PsiElement resolve() {
@@ -192,7 +192,7 @@ public class DynFormReferenceContributor extends PsiReferenceContributor {
private final String moduleName;
private final String frmlName;
public DynFormFrmlReference(@NotNull PsiElement element, TextRange textRange, String moduleName, String frmlName) {
- super(element, textRange);
+ super(element, textRange, true);
this.moduleName = moduleName;
this.frmlName = frmlName;
}
@@ -204,7 +204,7 @@ public class DynFormReferenceContributor extends PsiReferenceContributor {
private static class DynFormLocalFieldReference extends PsiReferenceBase {
private final String fieldName;
public DynFormLocalFieldReference(@NotNull XmlAttributeValue element, TextRange range, String fieldName) {
- super(element, range);
+ super(element, range, true);
this.fieldName = fieldName;
}
@Nullable @Override public PsiElement resolve() {
@@ -227,31 +227,31 @@ public class DynFormReferenceContributor extends PsiReferenceContributor {
private static class DynFormFieldDefinitionReference extends PsiReferenceBase {
private final String fieldName;
public DynFormFieldDefinitionReference(@NotNull XmlAttributeValue element, TextRange range, String fieldName) {
- super(element, range);
+ super(element, range, true);
this.fieldName = fieldName;
}
@Nullable @Override public PsiElement resolve() {
XmlTag tag = PsiTreeUtil.getParentOfType(myElement, XmlTag.class);
if (tag == null) return null;
-
+
// หา container (FORM_ENTRY, FORM_BROWSE, GRID-LIST หรือ FILTERS)
XmlTag container = tag;
- while (container != null &&
- !"LAYOUT".equals(container.getName()) &&
- !"TITLES".equals(container.getName()) &&
- !"FORM_ENTRY".equals(container.getName()) &&
- !"FORM_BROWSE".equals(container.getName()) &&
+ while (container != null &&
+ !"LAYOUT".equals(container.getName()) &&
+ !"TITLES".equals(container.getName()) &&
+ !"FORM_ENTRY".equals(container.getName()) &&
+ !"FORM_BROWSE".equals(container.getName()) &&
!"GRID-LIST".equals(container.getName()) &&
!"FILTERS".equals(container.getName())) {
container = container.getParentTag();
}
-
+
if (container != null && ("LAYOUT".equals(container.getName()) || "TITLES".equals(container.getName()))) {
container = container.getParentTag();
}
-
+
if (container == null) return null;
-
+
XmlTag fieldsTag = container.findFirstSubTag("FIELDS");
if (fieldsTag == null) return null;
@@ -265,30 +265,30 @@ public class DynFormReferenceContributor extends PsiReferenceContributor {
private static class DynFormFieldUsageReference extends PsiReferenceBase {
private final String fieldName;
public DynFormFieldUsageReference(@NotNull XmlAttributeValue element, TextRange range, String fieldName) {
- super(element, range);
+ super(element, range, true);
this.fieldName = fieldName;
}
@Nullable @Override public PsiElement resolve() {
XmlTag tag = PsiTreeUtil.getParentOfType(myElement, XmlTag.class);
if (tag == null) return null;
-
+
// หา FIELDS container
XmlTag fieldsTag = tag;
while (fieldsTag != null && !"FIELDS".equals(fieldsTag.getName())) {
fieldsTag = fieldsTag.getParentTag();
}
if (fieldsTag == null) return null;
-
+
XmlTag containerTag = fieldsTag.getParentTag();
if (containerTag == null) return null;
-
+
// หาใน LAYOUT ก่อน
XmlTag layoutTag = containerTag.findFirstSubTag("LAYOUT");
if (layoutTag != null) {
PsiElement found = findFieldInTag(layoutTag, fieldName);
if (found != null) return found;
}
-
+
// ถ้าไม่เจอใน LAYOUT ให้หาใน TITLES
XmlTag titlesTag = containerTag.findFirstSubTag("TITLES");
if (titlesTag != null) {
@@ -320,7 +320,7 @@ public class DynFormReferenceContributor extends PsiReferenceContributor {
private static class DynFormDatasetReference extends PsiReferenceBase {
private final String datasetId;
public DynFormDatasetReference(@NotNull XmlAttributeValue element, TextRange range, String datasetId) {
- super(element, range);
+ super(element, range, true);
this.datasetId = datasetId;
}
@Nullable @Override public PsiElement resolve() {
@@ -339,7 +339,7 @@ public class DynFormReferenceContributor extends PsiReferenceContributor {
if (!(file instanceof XmlFile xmlFile)) return null;
XmlTag rootTag = xmlFile.getRootTag();
if (rootTag == null) return null;
-
+
XmlTag datasetsContainer = rootTag.findFirstSubTag("DATASETS");
if (datasetsContainer == null) datasetsContainer = rootTag;
@@ -356,7 +356,7 @@ public class DynFormReferenceContributor extends PsiReferenceContributor {
private static class DynFormGridReference extends PsiReferenceBase {
private final String gridId;
public DynFormGridReference(@NotNull XmlAttributeValue element, TextRange range, String gridId) {
- super(element, range);
+ super(element, range, true);
this.gridId = gridId;
}
@Nullable @Override public PsiElement resolve() {
@@ -398,7 +398,7 @@ public class DynFormReferenceContributor extends PsiReferenceContributor {
private static class DynFormAjaxSrcFieldReference extends PsiReferenceBase {
private final String fieldName;
public DynFormAjaxSrcFieldReference(@NotNull XmlAttributeValue element, TextRange range, String fieldName) {
- super(element, range);
+ super(element, range, true);
this.fieldName = fieldName;
}
@Nullable @Override public PsiElement resolve() {
@@ -407,16 +407,16 @@ public class DynFormReferenceContributor extends PsiReferenceContributor {
ajaxOptionTag = ajaxOptionTag.getParentTag();
}
if (ajaxOptionTag == null) return null;
-
+
String datasetId = ajaxOptionTag.getAttributeValue("DATASET");
if (datasetId == null) return null;
PsiFile ajaxFile = DynFormPathUtils.findAjaxXml(myElement.getContainingFile());
if (!(ajaxFile instanceof XmlFile xmlFile)) return null;
-
+
XmlTag rootTag = xmlFile.getRootTag();
if (rootTag == null) return null;
-
+
XmlTag datasetsContainer = rootTag.findFirstSubTag("DATASETS");
if (datasetsContainer == null) datasetsContainer = rootTag;
@@ -436,7 +436,7 @@ public class DynFormReferenceContributor extends PsiReferenceContributor {
private static class DynFormFileIncludeReference extends PsiReferenceBase {
private final String path;
public DynFormFileIncludeReference(@NotNull XmlAttributeValue element, TextRange range, String path) {
- super(element, range);
+ super(element, range, true);
this.path = path;
}
@Nullable @Override public PsiElement resolve() {
diff --git a/src/main/java/com/sdk/dynform/tools/dynform/DynFormXsdScanner.java b/src/main/java/com/sdk/dynform/tools/dynform/DynFormXsdScanner.java
new file mode 100644
index 0000000..d0e3dad
--- /dev/null
+++ b/src/main/java/com/sdk/dynform/tools/dynform/DynFormXsdScanner.java
@@ -0,0 +1,44 @@
+package com.sdk.dynform.tools.dynform;
+
+import com.intellij.javaee.ExternalResourceManagerEx;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+
+import java.io.File;
+
+public class DynFormXsdScanner {
+ private static final Logger LOG = Logger.getInstance(DynFormXsdScanner.class);
+
+ public static void scanAndRegister(Project project, String folderPath, String prefix) {
+ if (project == null || folderPath == null || folderPath.isEmpty()) return;
+
+ File dir = new File(folderPath);
+ if (!dir.exists() || !dir.isDirectory()) return;
+
+ File[] xsdFiles = dir.listFiles((d, name) -> name.toLowerCase().endsWith(".xsd"));
+ if (xsdFiles == null) return;
+
+ ExternalResourceManagerEx manager = ExternalResourceManagerEx.getInstanceEx();
+
+ // Ensure prefix ends with a slash if it's not empty
+ String tempPrefix = prefix != null ? prefix.trim() : "";
+ if (!tempPrefix.isEmpty() && !tempPrefix.endsWith("/")) {
+ tempPrefix += "/";
+ }
+ final String finalPrefix = tempPrefix;
+
+ ApplicationManager.getApplication().runWriteAction(() -> {
+ for (File file : xsdFiles) {
+ VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
+ if (vFile == null) continue;
+
+ String uri = finalPrefix + file.getName();
+ manager.addResource(uri, vFile.getPath(), project);
+ LOG.info("Registered DynForm XSD for project [" + project.getName() + "]: " + uri + " -> " + vFile.getPath());
+ }
+ });
+ }
+}
diff --git a/src/main/java/com/sdk/dynform/tools/helper/FRMLFileType.java b/src/main/java/com/sdk/dynform/tools/dynform/FRMLFileType.java
similarity index 90%
rename from src/main/java/com/sdk/dynform/tools/helper/FRMLFileType.java
rename to src/main/java/com/sdk/dynform/tools/dynform/FRMLFileType.java
index eae1177..480d898 100644
--- a/src/main/java/com/sdk/dynform/tools/helper/FRMLFileType.java
+++ b/src/main/java/com/sdk/dynform/tools/dynform/FRMLFileType.java
@@ -1,6 +1,5 @@
-package com.sdk.dynform.tools.helper;
+package com.sdk.dynform.tools.dynform;
-import com.intellij.ide.highlighter.XmlLikeFileType;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.fileTypes.LanguageFileType;
import org.jetbrains.annotations.NotNull;
diff --git a/src/main/java/com/sdk/dynform/tools/i18n/I18nCompletionContributor.java b/src/main/java/com/sdk/dynform/tools/i18n/I18nCompletionContributor.java
index 5ec98ba..48ed042 100644
--- a/src/main/java/com/sdk/dynform/tools/i18n/I18nCompletionContributor.java
+++ b/src/main/java/com/sdk/dynform/tools/i18n/I18nCompletionContributor.java
@@ -11,7 +11,6 @@ import com.intellij.psi.PsiMethodCallExpression;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
-import com.intellij.psi.xml.XmlToken;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
@@ -31,7 +30,7 @@ public class I18nCompletionContributor extends CompletionContributor {
@NotNull CompletionResultSet resultSet) {
PsiElement position = parameters.getPosition();
PsiLiteralExpression literal = PsiTreeUtil.getParentOfType(position, PsiLiteralExpression.class);
-
+
// ในบางภาษาอาจจะไม่ใช่ PsiLiteralExpression โดยตรง
if (literal != null && isMGetArgument(literal)) {
String value = literal.getValue() instanceof String ? (String) literal.getValue() : "";
@@ -44,7 +43,7 @@ public class I18nCompletionContributor extends CompletionContributor {
String textBefore = parameters.getEditor().getDocument().getText(
new com.intellij.openapi.util.TextRange(Math.max(0, parameters.getOffset() - 100), parameters.getOffset())
);
-
+
java.util.regex.Matcher m = java.util.regex.Pattern.compile("\\$M\\.get\\([\"']([^\"']*)$").matcher(textBefore);
if (m.find()) {
handleMultiKeyCompletion(parameters, resultSet, m.group(1));
@@ -93,9 +92,9 @@ public class I18nCompletionContributor extends CompletionContributor {
String text = position.getText();
int offsetInElement = parameters.getOffset() - position.getTextRange().getStartOffset();
if (offsetInElement < 0 || offsetInElement > text.length()) return;
-
+
String before = text.substring(0, offsetInElement);
-
+
// Find the start of the current @M{ block
int openBracket = before.lastIndexOf("@M{");
if (openBracket != -1) {
@@ -115,9 +114,9 @@ public class I18nCompletionContributor extends CompletionContributor {
int lastPipe = content.lastIndexOf("||");
int lastSpace = content.lastIndexOf(' ');
int lastHash = content.lastIndexOf('#');
-
+
int lastSeparator = Math.max(lastPlus, Math.max(lastPipe != -1 ? lastPipe + 1 : -1, Math.max(lastSpace, lastHash)));
-
+
String currentPrefix;
if (lastSeparator != -1) {
// Handle || which is 2 chars
@@ -129,13 +128,13 @@ public class I18nCompletionContributor extends CompletionContributor {
} else {
currentPrefix = content;
}
-
+
addMessageKeys(parameters, resultSet.withPrefixMatcher(currentPrefix));
}
private void addMessageKeys(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet resultSet) {
Set keys = I18nUtils.findAllMessageKeys(parameters.getEditor().getProject());
-
+
for (String key : keys) {
String translation = I18nUtils.findMessageValue(parameters.getEditor().getProject(), key);
resultSet.addElement(LookupElementBuilder.create(key)
diff --git a/src/main/java/com/sdk/dynform/tools/i18n/I18nConfigurable.java b/src/main/java/com/sdk/dynform/tools/i18n/I18nConfigurable.java
deleted file mode 100644
index 1c6c7e6..0000000
--- a/src/main/java/com/sdk/dynform/tools/i18n/I18nConfigurable.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.sdk.dynform.tools.i18n;
-
-import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.util.NlsContexts;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.awt.*;
-
-public class I18nConfigurable implements Configurable {
-
- private JRadioButton foldingBtn;
- private JRadioButton inlayBtn;
- private JRadioButton disabledBtn;
- private JCheckBox showIconCheck;
-
- @Override
- public @NlsContexts.ConfigurableName String getDisplayName() {
- return "DynForm I18n Tools";
- }
-
- @Override
- public @Nullable JComponent createComponent() {
- JPanel panel = new JPanel();
- panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
-
- panel.add(new JLabel("Message Display Mode:"));
-
- foldingBtn = new JRadioButton("Folding (Hide key, show translation)");
- inlayBtn = new JRadioButton("Inlay Hints (Show translation next to key)");
- disabledBtn = new JRadioButton("Disabled");
-
- ButtonGroup group = new ButtonGroup();
- group.add(foldingBtn);
- group.add(inlayBtn);
- group.add(disabledBtn);
-
- panel.add(foldingBtn);
- panel.add(inlayBtn);
- panel.add(disabledBtn);
-
- panel.add(Box.createVerticalStrut(10));
- showIconCheck = new JCheckBox("Show icon in code completion");
- panel.add(showIconCheck);
-
- panel.add(Box.createVerticalGlue());
-
- return panel;
- }
-
- @Override
- public boolean isModified() {
- I18nSettings settings = I18nSettings.getInstance();
- I18nSettings.DisplayMode currentMode = getCurrentModeFromUI();
- return settings.displayMode != currentMode || settings.showIcon != showIconCheck.isSelected();
- }
-
- @Override
- public void apply() {
- I18nSettings settings = I18nSettings.getInstance();
- settings.displayMode = getCurrentModeFromUI();
- settings.showIcon = showIconCheck.isSelected();
-
- // Refresh all editors to apply changes
- com.intellij.codeInsight.daemon.DaemonCodeAnalyzer.getInstance(
- com.intellij.openapi.project.ProjectManager.getInstance().getOpenProjects()[0]
- ).restart();
- }
-
- private I18nSettings.DisplayMode getCurrentModeFromUI() {
- if (foldingBtn.isSelected()) return I18nSettings.DisplayMode.FOLDING;
- if (inlayBtn.isSelected()) return I18nSettings.DisplayMode.INLAY_HINTS;
- return I18nSettings.DisplayMode.DISABLED;
- }
-
- @Override
- public void reset() {
- I18nSettings settings = I18nSettings.getInstance();
- switch (settings.displayMode) {
- case FOLDING: foldingBtn.setSelected(true); break;
- case INLAY_HINTS: inlayBtn.setSelected(true); break;
- case DISABLED: disabledBtn.setSelected(true); break;
- }
- showIconCheck.setSelected(settings.showIcon);
- }
-}
diff --git a/src/main/java/com/sdk/dynform/tools/i18n/I18nFoldingBuilder.java b/src/main/java/com/sdk/dynform/tools/i18n/I18nFoldingBuilder.java
index 2d2bb54..39305a9 100644
--- a/src/main/java/com/sdk/dynform/tools/i18n/I18nFoldingBuilder.java
+++ b/src/main/java/com/sdk/dynform/tools/i18n/I18nFoldingBuilder.java
@@ -10,6 +10,7 @@ import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
+import com.sdk.dynform.tools.config.DynFormSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -22,7 +23,7 @@ public class I18nFoldingBuilder extends FoldingBuilderEx {
@NotNull
@Override
public FoldingDescriptor @NotNull [] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) {
- if (I18nSettings.getInstance().displayMode != I18nSettings.DisplayMode.FOLDING) {
+ if (DynFormSettings.getInstance(root.getProject()).displayMode != DynFormSettings.DisplayMode.FOLDING) {
return new FoldingDescriptor[0];
}
diff --git a/src/main/java/com/sdk/dynform/tools/i18n/I18nInlayHintsProvider.java b/src/main/java/com/sdk/dynform/tools/i18n/I18nInlayHintsProvider.java
index 3138916..bd024a8 100644
--- a/src/main/java/com/sdk/dynform/tools/i18n/I18nInlayHintsProvider.java
+++ b/src/main/java/com/sdk/dynform/tools/i18n/I18nInlayHintsProvider.java
@@ -3,10 +3,12 @@ package com.sdk.dynform.tools.i18n;
import com.intellij.codeInsight.hints.*;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlToken;
+import com.sdk.dynform.tools.config.DynFormSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -18,7 +20,8 @@ public class I18nInlayHintsProvider implements InlayHintsProvider {
@Nullable
@Override
public InlayHintsCollector getCollectorFor(@NotNull PsiFile file, @NotNull Editor editor, @NotNull NoSettings settings, @NotNull InlayHintsSink sink) {
- if (I18nSettings.getInstance().displayMode != I18nSettings.DisplayMode.INLAY_HINTS) {
+ Project project = file.getProject();
+ if (DynFormSettings.getInstance(project).displayMode != DynFormSettings.DisplayMode.INLAY_HINTS) {
return null;
}
diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
index 661a095..d2b4281 100644
--- a/src/main/resources/META-INF/plugin.xml
+++ b/src/main/resources/META-INF/plugin.xml
@@ -2,11 +2,11 @@
com.sdk.dynform.tools
- Dynamic Form Helper
+ DynamicForm Tools
Sakda Sakprapakorn
Enhance Development with Dynamic Form Tools
+ Enhance Development with DynamicForm Tools
This plugin is a comprehensive suite of tools designed to streamline the development of Java-based web applications (like vrms-system and teddy-taxi-web) that utilize the DynForm framework.
Core Modules:
@@ -29,11 +29,17 @@
Usage:
- Generation: Right-click a table in the Database tool window -> "Generate Action Models".
- - I18n: Type
@M{ in XML or use supported I18n methods in Java/JS to see suggestions. Configure message file paths in Settings -> DynForm I18n Tools.
+ - I18n: Type
@M{ in XML or use supported I18n methods in Java/JS to see suggestions. Configure message file paths in Settings -> DynamicForm Tools.
]]>
[3.2.0]
+
+ - Schema Validation: Introduced project-level automatic XSD registration. Configure a target folder and namespace prefix to seamlessly map
.xsd files to the ExternalResourceManager.
+ - Architecture: Finalized rebranding by standardizing internal packages to
com.sdk.dynform.* for better consistency.
+ - UI Improvement: Streamlined the plugin settings UI into distinct Internationalization and Schema Validation groups.
+
[3.1.0]
- Advanced Navigation: Implemented bidirectional field referencing between
<FIELDS>, <LAYOUT>, and <TITLES> tags in .frml files.
@@ -50,7 +56,7 @@
[3.0.1]
- - Rebranding: Renamed plugin to "Dynamic Form Helper" (DynamicFormTools) to better reflect its expanding capabilities beyond code generation.
+ - Rebranding: Renamed plugin to "DynamicForm Tools" to better reflect its expanding capabilities beyond code generation.
- I18n Support: Added comprehensive tools for internationalization:
- Inlay hints and code folding for i18n keys in Java, XML, and JavaScript.
@@ -96,20 +102,20 @@
JavaScript
-
+
-
-
-
@@ -117,12 +123,13 @@
-
-
+
+
-
+
@@ -140,18 +147,18 @@
-
-
-
+
+
+
-
-
-
+
+
+
-
\ No newline at end of file
+