From 6f18c4a7c47839526ea781cef1ef0e7457b62cdd Mon Sep 17 00:00:00 2001 From: Denys Almazov Date: Mon, 6 Apr 2026 12:47:34 +0300 Subject: [PATCH 1/7] feat: adding support for kconfig 3.0 --- .../sdk/config/core/IJsonServerConfig.java | 2 + .../idf/sdk/config/core/KConfigMenuItem.java | 19 +- .../sdk/config/core/server/CommandType.java | 2 + .../config/core/server/IJsonConfigOutput.java | 4 + .../config/core/server/JsonConfigOutput.java | 20 ++ .../config/core/server/JsonConfigServer.java | 18 ++ .../core/server/JsonConfigServerRunnable.java | 12 +- .../icons/reset.png | Bin 0 -> 1075 bytes .../sdk/config/ui/SDKConfigurationEditor.java | 211 ++++++++++++++++-- 9 files changed, 258 insertions(+), 30 deletions(-) create mode 100644 bundles/com.espressif.idf.sdk.config.ui/icons/reset.png diff --git a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/IJsonServerConfig.java b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/IJsonServerConfig.java index 213d66200..ec6d3e10a 100644 --- a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/IJsonServerConfig.java +++ b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/IJsonServerConfig.java @@ -16,6 +16,7 @@ public interface IJsonServerConfig String VISIBLE = "visible"; //$NON-NLS-1$ String RANGES = "ranges"; //$NON-NLS-1$ String VERSION = "version"; //$NON-NLS-1$ + String DEFAULTS = "defaults"; //$NON-NLS-1$ // data types String HEX_TYPE = "hex"; //$NON-NLS-1$ @@ -29,6 +30,7 @@ public interface IJsonServerConfig String SET = "set"; //$NON-NLS-1$ String SAVE = "save"; //$NON-NLS-1$ String LOAD = "load"; //$NON-NLS-1$ + String RESET = "reset"; //$NON-NLS-1$ String COMPONENT_CONFIG_TITLE = "Component config"; //$NON-NLS-1$ diff --git a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/KConfigMenuItem.java b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/KConfigMenuItem.java index ee469912b..a117af4a5 100644 --- a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/KConfigMenuItem.java +++ b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/KConfigMenuItem.java @@ -23,6 +23,7 @@ public class KConfigMenuItem private String type; private String id; private boolean isMenuConfig; + private boolean isDefault; public KConfigMenuItem(KConfigMenuItem parent) { @@ -173,5 +174,21 @@ private boolean isVisible(JSONObject visibleJsonMap, String configKey) return visibleJsonMap.get(configKey) != null ? (boolean) visibleJsonMap.get(configKey) : false; } + public boolean isDefault() + { + return isDefault; + } + + public void setDefault(boolean isDefault) + { + this.isDefault = isDefault; + } -} \ No newline at end of file + public void updateDefaultState(JSONObject defaultsJsonMap) + { + if (defaultsJsonMap != null && defaultsJsonMap.containsKey(getId())) + { + this.isDefault = (boolean) defaultsJsonMap.get(getId()); + } + } +} diff --git a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/CommandType.java b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/CommandType.java index 7feea31d6..f86b53269 100644 --- a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/CommandType.java +++ b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/CommandType.java @@ -29,6 +29,8 @@ public enum CommandType */ SET, + RESET, + /** * To represent server connection is closed */ diff --git a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/IJsonConfigOutput.java b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/IJsonConfigOutput.java index 350a777b6..f8e072307 100644 --- a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/IJsonConfigOutput.java +++ b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/IJsonConfigOutput.java @@ -27,4 +27,8 @@ public interface IJsonConfigOutput */ public JSONObject getRangesJsonMap(); + public JSONObject getDefaultsJsonMap(); + + public long getVersion(); + } diff --git a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigOutput.java b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigOutput.java index 23bcb9cc4..5a640d1e0 100644 --- a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigOutput.java +++ b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigOutput.java @@ -24,6 +24,14 @@ public class JsonConfigOutput implements IJsonConfigOutput private JSONObject valuesJsonMap; private JSONObject visibleJsonMap; private JSONObject rangesJsonMap; + private JSONObject defaultsJsonMap; + private long version = 1; + + @Override + public long getVersion() + { + return version; + } @Override public JSONObject getValuesJsonMap() @@ -56,12 +64,18 @@ public void parse(String response, boolean isUpdate) throws ParseException JSONObject jsonObj = (JSONObject) parser.parse(response); if (jsonObj != null) { + if (jsonObj.containsKey(IJsonServerConfig.VERSION)) + { + version = (long) jsonObj.get(IJsonServerConfig.VERSION); + } + if (isUpdate) { // newly updated values and visible items JSONObject visibleJson = (JSONObject) jsonObj.get(IJsonServerConfig.VISIBLE); JSONObject valuesJson = (JSONObject) jsonObj.get(IJsonServerConfig.VALUES); JSONObject rangesJson = (JSONObject) jsonObj.get(IJsonServerConfig.RANGES); + JSONObject defaultsJson = (JSONObject) jsonObj.get(IJsonServerConfig.DEFAULTS); // Updated visible items Set newVisibleKeyset = visibleJson.keySet(); @@ -89,9 +103,15 @@ public void parse(String response, boolean isUpdate) throws ParseException valuesJsonMap = (JSONObject) jsonObj.get(IJsonServerConfig.VALUES); visibleJsonMap = (JSONObject) jsonObj.get(IJsonServerConfig.VISIBLE); rangesJsonMap = (JSONObject) jsonObj.get(IJsonServerConfig.RANGES); + defaultsJsonMap = (JSONObject) jsonObj.get(IJsonServerConfig.DEFAULTS); } } } + public JSONObject getDefaultsJsonMap() + { + return defaultsJsonMap; + } + } diff --git a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigServer.java b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigServer.java index fa7f20468..fa5d050ff 100644 --- a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigServer.java +++ b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigServer.java @@ -53,6 +53,24 @@ public JsonConfigServer(IProject project, IFile file) this.file = file; } + public void resetElementById(String id) + { + String resetRequest = String.format("{\"version\": 3, \"reset\": [\"%s\"]}", id); + execute(resetRequest, CommandType.RESET); + } + + public void resetElementChildren(List children) + { + if (children == null || children.isEmpty()) + { + return; + } + + String joinedIds = String.join("\", \"", children); + String resetRequest = String.format("{\"version\": 3, \"reset\": [\"%s\"]}", joinedIds); + execute(resetRequest, CommandType.RESET); + } + @Override public void addListener(IMessageHandlerListener listener) { diff --git a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigServerRunnable.java b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigServerRunnable.java index ebb5eb566..bee20d265 100644 --- a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigServerRunnable.java +++ b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigServerRunnable.java @@ -200,26 +200,22 @@ protected boolean isValidJson(String output) { String jsonOutput = new JsonConfigProcessor().getInitialOutput(output); if (StringUtil.isEmpty(jsonOutput)) - { return false; - } + try { JSONObject jsonObj = (JSONObject) new JSONParser().parse(jsonOutput); if (jsonObj != null) { - if (jsonObj.get(IJsonServerConfig.VISIBLE) != null && jsonObj.get(IJsonServerConfig.VALUES) != null - && jsonObj.get(IJsonServerConfig.RANGES) != null) - { - return true; - } + // Check for the new version key and the mandatory data maps + return jsonObj.containsKey(IJsonServerConfig.VERSION) && jsonObj.containsKey(IJsonServerConfig.VALUES) + && jsonObj.containsKey("defaults"); //$NON-NLS-1$ } } catch (ParseException e) { return false; } - return false; } diff --git a/bundles/com.espressif.idf.sdk.config.ui/icons/reset.png b/bundles/com.espressif.idf.sdk.config.ui/icons/reset.png new file mode 100644 index 0000000000000000000000000000000000000000..69a4d72f2d0a087f017c872a8ef148616c49674d GIT binary patch literal 1075 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc4egmB5hW46K32*3xq68y`AMmI6}bgK)eHls47YguJQ{>uF6ifOi{PD zbs{}UK3djZt>nqvW6s4qD1-ZCERRDRmN*N_31y=g{ z<>lpi<;HsXMd|v6mX?v90`zGE;%B09k2gXakl<5wp<;IRwdJb`TMuUx6%m z$bfA^18>v`48TQt*ggKNPHg|6;^o^IdGFBUZ& zF*B*(dvfP<3)MSqd`)(jE#Ft}pU%JUJ;Q&Fty~NjYQHA3XI{%)dB;&elOd8#r@qo= zZr;~VVT=rinA4qmX0t6h!TiG5smxx&{{B7dqD8q6uDts8Yu4ot?`}6vpVxWQ;V#$x z)HX@=b&KQl*5tmsp&YUA#iM*CsS?*nGAWq7Afx9DG<%TaLu5nSNG$&j791G zQ`z-ge7MrXHCY9G&AuLUoM$unNm%qHJF736^DF0OhcR{dEdO;<-byX|s$-JQf+ZYs zR&_tCcckA)Vi1_=b@$=E3#B`p)DOpWxybWWGb>E>4YGUQ_P=3G=s}asb6?(4QZJpL z6udIK>cTwXsZ3L}5AetQ5I1c#2yK?*;`3T)h;cCp$mgXJyX{ z5q;0_DKirtudTW-QlJ;F^Y??<#)*AvJp<+0AGM=WN%<9_*H_wq)44QJ`ulB@<5df1HU_5sc=+beEu{ydjrCyy-Z#~a z?f2Gg`PaI(KYz}jU$2aJ=bLC}i!Pk9r6W5r=v}_z7yjs(Q@gJJkN?3e_v7OJptlo1 Pr2vDctDnm{r-UW|(EF`6 literal 0 HcmV?d00001 diff --git a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java index ebff2c161..c846edfc2 100644 --- a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java +++ b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; +import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -66,6 +67,7 @@ import org.eclipse.ui.part.MultiPageEditorPart; import org.eclipse.ui.progress.IProgressService; import org.eclipse.ui.texteditor.AbstractTextEditor; +import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.ParseException; @@ -90,7 +92,6 @@ * SDK Configuration editor which represents the UI for the all sdkconfig fields * * @author Kondal Kolipaka - * */ @SuppressWarnings("unchecked") public class SDKConfigurationEditor extends MultiPageEditorPart @@ -103,6 +104,8 @@ public class SDKConfigurationEditor extends MultiPageEditorPart private static final String ICONS_SDK_TOOL_CONFIG_PNG = "icons/sdk_tool_config.png"; //$NON-NLS-1$ + private static final String ICONS_SDK_RESET_ACTION_PNG = "icons/reset.png"; //$NON-NLS-1$ + private TreeViewer treeViewer; private Group updateUIComposite; @@ -471,8 +474,23 @@ public void doSave(IProgressMonitor monitor) { JSONObject jsonObject = new JSONObject(); jsonObject.put(IJsonServerConfig.VERSION, 2); - jsonObject.put(IJsonServerConfig.SET, modifiedJsonMap); - jsonObject.put(IJsonServerConfig.SAVE, null); + + if (!modifiedJsonMap.isEmpty()) + { + jsonObject.put(IJsonServerConfig.SET, modifiedJsonMap); + + for (Object key : modifiedJsonMap.keySet()) + { + valuesJsonMap.put(key, modifiedJsonMap.get(key)); + } + } + else + { + jsonObject.put(IJsonServerConfig.SET, new JSONObject()); + } + + String filePath = getFile().getLocation().toOSString(); + jsonObject.put(IJsonServerConfig.SAVE, filePath); String command = jsonObject.toJSONString(); configServer.execute(command, CommandType.SAVE); @@ -590,12 +608,44 @@ private void updateUI(KConfigMenuItem selectedElement) control.dispose(); } - updateUIComposite.setLayout((new GridLayout(3, false))); + updateUIComposite.setLayout((new GridLayout(4, false))); updateUIComposite.setText(selectedElement.getTitle()); GridData updateCompsiteGD = new GridData(SWT.FILL, SWT.FILL, true, true); updateCompsiteGD.verticalIndent = 10; updateUIComposite.setLayoutData(updateCompsiteGD); + + Button resetGroupButton = new Button(updateUIComposite, SWT.PUSH); + resetGroupButton.setText("Reset Menu Defaults"); + + GridData resetGD = new GridData(SWT.END, SWT.CENTER, false, false, 4, 1); + resetGroupButton.setLayoutData(resetGD); + resetGroupButton.addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + boolean confirm = MessageDialog.openConfirm(Display.getDefault().getActiveShell(), + "Reset Menu Configurations", "This action will reset all configurations under '" + + selectedElement.getTitle() + "' to their default values. Continue?"); + + if (confirm) + { + List childIds = new ArrayList<>(); + collectAllChildIds(selectedElement, childIds); + + if (!childIds.isEmpty()) + { + executeResetChildrenCommand(childIds); + } + else if (selectedElement.getId() != null) + { + executeResetCommand(selectedElement.getId()); + } + } + } + }); + renderMenuItems(selectedElement); sc.setContent(updateUIComposite); @@ -607,6 +657,48 @@ private void updateUI(KConfigMenuItem selectedElement) updateUIComposite.layout(true); } + /** + * Recursively collects all configuration IDs for a menu and its sub-menus + */ + private void collectAllChildIds(KConfigMenuItem item, List childIds) + { + if (item == null || item.getChildren() == null) + { + return; + } + for (KConfigMenuItem child : item.getChildren()) + { + if (child.getId() != null && !child.getId().isEmpty()) + { + childIds.add(child.getId()); + } + collectAllChildIds(child, childIds); + } + } + + protected void addResetButton(KConfigMenuItem kConfigMenuItem) + { + Label resetIcon = new Label(updateUIComposite, SWT.NONE); + + resetIcon.setImage(SDKConfigUIPlugin.getImage(ICONS_SDK_RESET_ACTION_PNG)); + resetIcon.setToolTipText("Reset '" + kConfigMenuItem.getTitle() + "' to default value"); + + GridData gridData = new GridData(SWT.END, SWT.CENTER, false, false); + resetIcon.setLayoutData(gridData); + + resetIcon.addListener(SWT.MouseUp, new Listener() + { + @Override + public void handleEvent(Event event) + { + if (kConfigMenuItem.getId() != null) + { + executeResetCommand(kConfigMenuItem.getId()); + } + } + }); + } + protected void renderMenuItems(KConfigMenuItem selectedElement) { // add children here @@ -635,7 +727,9 @@ protected void renderMenuItems(KConfigMenuItem selectedElement) textControl.setText(newConfigValue != null ? (String) newConfigValue : (String) configValue); } textControl.addModifyListener(addModifyListener(configKey, textControl)); + addTooltipImage(kConfigMenuItem); + addResetButton(kConfigMenuItem); } else if (isVisible && type.equals(IJsonServerConfig.HEX_TYPE)) @@ -656,7 +750,9 @@ else if (isVisible && type.equals(IJsonServerConfig.HEX_TYPE)) } textControl.addModifyListener(addModifyListener(configKey, textControl)); + addTooltipImage(kConfigMenuItem); + addResetButton(kConfigMenuItem); } else if (kConfigMenuItem.isMenuConfig()) { @@ -703,7 +799,9 @@ else if (isVisible && type.equals(IJsonServerConfig.INT_TYPE)) } text.addModifyListener(addModifyListener(configKey, text)); + addTooltipImage(kConfigMenuItem); + addResetButton(kConfigMenuItem); } else if (isVisible && type.equals(IJsonServerConfig.MENU_TYPE)) @@ -722,8 +820,6 @@ else if (type.equals(IJsonServerConfig.CHOICE_TYPE)) labelName.setText(kConfigMenuItem.getTitle()); Combo choiceCombo = new Combo(updateUIComposite, SWT.DROP_DOWN | SWT.READ_ONLY); - choiceCombo.setLayoutData(new GridData(SWT.NONE, SWT.NONE, false, false, 1, 1)); - GridData gridData = new GridData(); gridData.widthHint = 250; choiceCombo.setLayoutData(gridData); @@ -762,7 +858,9 @@ public void widgetSelected(SelectionEvent e) } } }); + addTooltipImage(kConfigMenuItem); + addResetButton(kConfigMenuItem); } } @@ -780,7 +878,8 @@ private Button createCheckBox(KConfigMenuItem kConfigMenuItem, String configKey, { Button button = new Button(updateUIComposite, SWT.CHECK); button.setText(kConfigMenuItem.getTitle()); - button.setLayoutData(new GridData(SWT.NONE, SWT.NONE, false, false, 2, 1)); + + button.setLayoutData(new GridData(SWT.NONE, SWT.CENTER, false, false, 2, 1)); button.setToolTipText(helpInfo); if (configValue != null) { @@ -797,7 +896,10 @@ public void widgetSelected(SelectionEvent e) } }); + addTooltipImage(kConfigMenuItem); + addResetButton(kConfigMenuItem); + return button; } @@ -882,6 +984,11 @@ protected void executeCommand(JSONObject jsonObj) isDirty = true; editorDirtyStateChanged(); + for (Object key : jsonObj.keySet()) + { + valuesJsonMap.put(key, jsonObj.get(key)); + } + JSONObject jsonObject = new JSONObject(); jsonObject.put(IJsonServerConfig.VERSION, 2); jsonObject.put(IJsonServerConfig.SET, jsonObj); @@ -890,6 +997,59 @@ protected void executeCommand(JSONObject jsonObj) configServer.execute(command, CommandType.SET); } + protected void executeResetCommand(String idToReset) + { + long version = configServer.getOutput().getVersion(); + if (version >= 3) + { + isDirty = true; + editorDirtyStateChanged(); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put(IJsonServerConfig.VERSION, 3); + + JSONArray resetArray = new JSONArray(); + resetArray.add(idToReset); + jsonObject.put(IJsonServerConfig.RESET, resetArray); + + String command = jsonObject.toJSONString(); + configServer.execute(command, CommandType.RESET); + } + else + { + MessageDialog.openWarning(Display.getDefault().getActiveShell(), "Unsupported Operation", + "Your current ESP-IDF version does not support partial SDK reset."); + } + } + + protected void executeResetChildrenCommand(List idsToReset) + { + long version = configServer.getOutput().getVersion(); + if (version >= 3) + { + if (idsToReset == null || idsToReset.isEmpty()) + return; + + isDirty = true; + editorDirtyStateChanged(); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put(IJsonServerConfig.VERSION, 3); + + JSONArray resetArray = new JSONArray(); + resetArray.addAll(idsToReset); + jsonObject.put(IJsonServerConfig.RESET, resetArray); + + String command = jsonObject.toJSONString(); + configServer.execute(command, CommandType.RESET); + } + else + { + MessageDialog.openWarning(Display.getDefault().getActiveShell(), "Unsupported Operation", + "Your current ESP-IDF version does not support partial SDK reset."); + } + } + @Override public boolean isDirty() { @@ -905,9 +1065,8 @@ public void editorDirtyStateChanged() } /* - * (non-Javadoc) - * - * @see com.espressif.idf.sdk.config.core.server.IMessageHandlerListener#notifyRequestServed(java.lang.String) + * (non-Javadoc) * @see + * com.espressif.idf.sdk.config.core.server.IMessageHandlerListener#notifyRequestServed(java.lang.String) */ @Override public void notifyRequestServed(String message, CommandType type) @@ -920,22 +1079,33 @@ public void notifyRequestServed(String message, CommandType type) { try { - // reset the modified map - if (type == CommandType.LOAD) + if (type == CommandType.LOAD || type == CommandType.RESET) { modifiedJsonMap.clear(); - isDirty = false; - editorDirtyStateChanged(); + isDirty = (type == CommandType.RESET); + + Display.getDefault().asyncExec(this::editorDirtyStateChanged); + } + + if (type == CommandType.SAVE) + { + Display.getDefault().asyncExec(() -> { + try + { + getFile().refreshLocal(org.eclipse.core.resources.IResource.DEPTH_ZERO, + new NullProgressMonitor()); + } + catch (CoreException e) + { + Logger.log(SDKConfigUIPlugin.getDefault(), e); + } + }); } - // fetch the latest values update(); - // Update in UI thread - Display.getDefault().asyncExec(new Runnable() + Display.getDefault().asyncExec(() -> { - @Override - public void run() { if (!treeViewer.getControl().isDisposed()) { @@ -991,7 +1161,7 @@ private String getCurrentBuildFolder() String buildFolder = StringUtil.EMPTY; try { - buildFolder = IDFUtil.getBuildDir(project); + IDFUtil.getBuildDir(project); } catch (CoreException e) { @@ -1028,5 +1198,4 @@ private Optional getSdkConfigParentFolderOpt() } return Optional.empty(); } - } From 6991e33554308ba6b65bba1d72489a8e44013a9b Mon Sep 17 00:00:00 2001 From: Denys Almazov Date: Mon, 6 Apr 2026 20:59:20 +0300 Subject: [PATCH 2/7] fix: make reset UI version-aware; use server version --- .../core/server/JsonConfigServerRunnable.java | 4 +- .../sdk/config/ui/SDKConfigurationEditor.java | 150 ++++++++++-------- 2 files changed, 89 insertions(+), 65 deletions(-) diff --git a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigServerRunnable.java b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigServerRunnable.java index bee20d265..057e85609 100644 --- a/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigServerRunnable.java +++ b/bundles/com.espressif.idf.sdk.config.core/src/com/espressif/idf/sdk/config/core/server/JsonConfigServerRunnable.java @@ -207,9 +207,7 @@ protected boolean isValidJson(String output) JSONObject jsonObj = (JSONObject) new JSONParser().parse(jsonOutput); if (jsonObj != null) { - // Check for the new version key and the mandatory data maps - return jsonObj.containsKey(IJsonServerConfig.VERSION) && jsonObj.containsKey(IJsonServerConfig.VALUES) - && jsonObj.containsKey("defaults"); //$NON-NLS-1$ + return jsonObj.containsKey(IJsonServerConfig.VERSION) && jsonObj.containsKey(IJsonServerConfig.VALUES); } } catch (ParseException e) diff --git a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java index c846edfc2..c3d227d05 100644 --- a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java +++ b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java @@ -37,6 +37,7 @@ import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; @@ -473,7 +474,8 @@ public void dispose() public void doSave(IProgressMonitor monitor) { JSONObject jsonObject = new JSONObject(); - jsonObject.put(IJsonServerConfig.VERSION, 2); + var version = configServer.getOutput().getVersion(); + jsonObject.put(IJsonServerConfig.VERSION, version); if (!modifiedJsonMap.isEmpty()) { @@ -615,46 +617,101 @@ private void updateUI(KConfigMenuItem selectedElement) updateUIComposite.setLayoutData(updateCompsiteGD); - Button resetGroupButton = new Button(updateUIComposite, SWT.PUSH); + addResetMenuButton(selectedElement); + + renderMenuItems(selectedElement); + + sc.setContent(updateUIComposite); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + sc.setMinSize(updateUIComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + sc.setShowFocusedControl(true); + + updateUIComposite.layout(true); + } + + private boolean isResetSupported() + { + return configServer.getOutput().getVersion() >= 3; + } + + private void addResetMenuButton(KConfigMenuItem selectedElement) + { + Composite resetGroupBtnComposite = new Composite(updateUIComposite, SWT.NONE); + resetGroupBtnComposite.setLayout(new FillLayout()); + resetGroupBtnComposite.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false, 4, 1)); + + Button resetGroupButton = new Button(resetGroupBtnComposite, SWT.PUSH); resetGroupButton.setText("Reset Menu Defaults"); - GridData resetGD = new GridData(SWT.END, SWT.CENTER, false, false, 4, 1); - resetGroupButton.setLayoutData(resetGD); resetGroupButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - boolean confirm = MessageDialog.openConfirm(Display.getDefault().getActiveShell(), - "Reset Menu Configurations", "This action will reset all configurations under '" - + selectedElement.getTitle() + "' to their default values. Continue?"); + handleResetMenuAction(selectedElement); + } + }); - if (confirm) - { - List childIds = new ArrayList<>(); - collectAllChildIds(selectedElement, childIds); + applyResetSupportState(resetGroupBtnComposite, resetGroupButton, null); + } - if (!childIds.isEmpty()) - { - executeResetChildrenCommand(childIds); - } - else if (selectedElement.getId() != null) - { - executeResetCommand(selectedElement.getId()); - } - } + private void handleResetMenuAction(KConfigMenuItem selectedElement) + { + boolean confirm = MessageDialog.openConfirm(Display.getDefault().getActiveShell(), "Reset Menu Configurations", + "This action will reset all configurations under '" + selectedElement.getTitle() + + "' to their default values. Continue?"); + + if (!confirm) + return; + + List childIds = new ArrayList<>(); + collectAllChildIds(selectedElement, childIds); + + if (!childIds.isEmpty()) + { + executeResetChildrenCommand(childIds); + } + else if (selectedElement.getId() != null) + { + executeResetCommand(selectedElement.getId()); + } + } + + protected void addResetButton(KConfigMenuItem kConfigMenuItem) + { + Composite resetIconComposite = new Composite(updateUIComposite, SWT.NONE); + resetIconComposite.setLayout(new FillLayout()); + + resetIconComposite.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); + + Label resetIcon = new Label(resetIconComposite, SWT.NONE); + resetIcon.setImage(SDKConfigUIPlugin.getImage(ICONS_SDK_RESET_ACTION_PNG)); + + resetIcon.addListener(SWT.MouseUp, event -> { + if (kConfigMenuItem.getId() != null) + { + executeResetCommand(kConfigMenuItem.getId()); } }); - renderMenuItems(selectedElement); - - sc.setContent(updateUIComposite); - sc.setExpandHorizontal(true); - sc.setExpandVertical(true); - sc.setMinSize(updateUIComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - sc.setShowFocusedControl(true); + String activeTooltip = "Reset '" + kConfigMenuItem.getTitle() + "' to default value"; + applyResetSupportState(resetIconComposite, resetIcon, activeTooltip); + } - updateUIComposite.layout(true); + private void applyResetSupportState(Composite wrapper, Control innerControl, String activeTooltip) + { + if (!isResetSupported()) + { + innerControl.setEnabled(false); + innerControl.setToolTipText(null); + wrapper.setToolTipText("Reset action is not available for this esp-idf version"); + } + else + { + innerControl.setEnabled(true); + innerControl.setToolTipText(activeTooltip); + } } /** @@ -676,29 +733,6 @@ private void collectAllChildIds(KConfigMenuItem item, List childIds) } } - protected void addResetButton(KConfigMenuItem kConfigMenuItem) - { - Label resetIcon = new Label(updateUIComposite, SWT.NONE); - - resetIcon.setImage(SDKConfigUIPlugin.getImage(ICONS_SDK_RESET_ACTION_PNG)); - resetIcon.setToolTipText("Reset '" + kConfigMenuItem.getTitle() + "' to default value"); - - GridData gridData = new GridData(SWT.END, SWT.CENTER, false, false); - resetIcon.setLayoutData(gridData); - - resetIcon.addListener(SWT.MouseUp, new Listener() - { - @Override - public void handleEvent(Event event) - { - if (kConfigMenuItem.getId() != null) - { - executeResetCommand(kConfigMenuItem.getId()); - } - } - }); - } - protected void renderMenuItems(KConfigMenuItem selectedElement) { // add children here @@ -990,7 +1024,8 @@ protected void executeCommand(JSONObject jsonObj) } JSONObject jsonObject = new JSONObject(); - jsonObject.put(IJsonServerConfig.VERSION, 2); + var version = configServer.getOutput().getVersion(); + jsonObject.put(IJsonServerConfig.VERSION, version); jsonObject.put(IJsonServerConfig.SET, jsonObj); String command = jsonObject.toJSONString(); @@ -1015,11 +1050,7 @@ protected void executeResetCommand(String idToReset) String command = jsonObject.toJSONString(); configServer.execute(command, CommandType.RESET); } - else - { - MessageDialog.openWarning(Display.getDefault().getActiveShell(), "Unsupported Operation", - "Your current ESP-IDF version does not support partial SDK reset."); - } + } protected void executeResetChildrenCommand(List idsToReset) @@ -1043,11 +1074,6 @@ protected void executeResetChildrenCommand(List idsToReset) String command = jsonObject.toJSONString(); configServer.execute(command, CommandType.RESET); } - else - { - MessageDialog.openWarning(Display.getDefault().getActiveShell(), "Unsupported Operation", - "Your current ESP-IDF version does not support partial SDK reset."); - } } @Override From 6859a6accbb47f665679593f08388ee10ef1addf Mon Sep 17 00:00:00 2001 From: Denys Almazov Date: Tue, 7 Apr 2026 20:50:34 +0300 Subject: [PATCH 3/7] feat: refactoring and moving UI rendering to separate class --- .../sdk/config/ui/ConfigActionHandler.java | 16 + .../idf/sdk/config/ui/ConfigUIRenderer.java | 349 +++++++++++++ .../sdk/config/ui/SDKConfigurationEditor.java | 477 +++--------------- 3 files changed, 422 insertions(+), 420 deletions(-) create mode 100644 bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/ConfigActionHandler.java create mode 100644 bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/ConfigUIRenderer.java diff --git a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/ConfigActionHandler.java b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/ConfigActionHandler.java new file mode 100644 index 000000000..6146d81a9 --- /dev/null +++ b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/ConfigActionHandler.java @@ -0,0 +1,16 @@ +package com.espressif.idf.sdk.config.ui; + +import org.json.simple.JSONObject; + +import com.espressif.idf.sdk.config.core.KConfigMenuItem; + +public interface ConfigActionHandler +{ + void onCommandExecuted(JSONObject jsonMap); + + void onTextModified(String key, Object value); + + void onResetRequested(String key); + + void onMenuResetRequested(KConfigMenuItem menu); +} diff --git a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/ConfigUIRenderer.java b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/ConfigUIRenderer.java new file mode 100644 index 000000000..09bbe5719 --- /dev/null +++ b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/ConfigUIRenderer.java @@ -0,0 +1,349 @@ +package com.espressif.idf.sdk.config.ui; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; +import org.json.simple.JSONObject; + +import com.espressif.idf.core.logging.Logger; +import com.espressif.idf.sdk.config.core.IJsonServerConfig; +import com.espressif.idf.sdk.config.core.KConfigMenuItem; +import com.espressif.idf.ui.dialogs.HelpPopupDialog; + +public class ConfigUIRenderer +{ + + private static final String ICONS_INFO_OBJ_GIF = "icons/help.gif"; //$NON-NLS-1$ + private static final String ICONS_SDK_RESET_ACTION_PNG = "icons/reset.png"; //$NON-NLS-1$ + + private final Composite parent; + private final JSONObject valuesMap; + private final JSONObject visibleMap; + private final JSONObject modifiedMap; + private final JSONObject rangesMap; + private final ConfigActionHandler actionHandler; + private final boolean isResetSupported; + private HelpPopupDialog infoDialog; + + private record RenderContext(KConfigMenuItem item, String configKey, Object configValue, Object modifiedValue, + boolean isVisible, String helpInfo) + { + public RenderContext(KConfigMenuItem item, JSONObject visibleMap, JSONObject valuesMap, JSONObject modifiedMap) + { + this(item, item.getId(), valuesMap.get(item.getId()), modifiedMap.get(item.getId()), + Boolean.TRUE.equals(visibleMap.get(item.getId())), + item.getHelp()); + } + } + + public ConfigUIRenderer(Composite parent, JSONObject valuesMap, JSONObject visibleMap, JSONObject modifiedMap, + JSONObject rangesMap, boolean isResetSupported, ConfigActionHandler actionHandler) + { + this.parent = parent; + this.valuesMap = valuesMap; + this.visibleMap = visibleMap; + this.modifiedMap = modifiedMap; + this.rangesMap = rangesMap; + this.isResetSupported = isResetSupported; + this.actionHandler = actionHandler; + } + + public void renderMenuItems(KConfigMenuItem selectedElement) + { + if (selectedElement == null || selectedElement.getChildren() == null) + return; + + for (KConfigMenuItem item : selectedElement.getChildren()) + { + var ctx = new RenderContext(item, visibleMap, valuesMap, modifiedMap); + String type = item.getType(); + + if (!ctx.isVisible() && !type.equals(IJsonServerConfig.MENU_TYPE)) + { + continue; + } + + switch (type) + { + case IJsonServerConfig.STRING_TYPE -> renderString(ctx); + case IJsonServerConfig.HEX_TYPE -> renderHex(ctx); + case IJsonServerConfig.INT_TYPE -> renderInt(ctx); + case IJsonServerConfig.BOOL_TYPE -> renderBool(ctx); + case IJsonServerConfig.CHOICE_TYPE -> renderChoice(ctx); + case IJsonServerConfig.MENU_TYPE -> renderMenuItems(item); + default -> Logger.log("Unhandled config type: " + type); + } + + if (!type.equals(IJsonServerConfig.MENU_TYPE) && !type.equals(IJsonServerConfig.CHOICE_TYPE)) + { + addTooltipImage(ctx); + addResetButton(ctx); + } + + if (item.hasChildren() && !type.equals(IJsonServerConfig.MENU_TYPE) + && !type.equals(IJsonServerConfig.CHOICE_TYPE) && !item.isMenuConfig()) + { + renderMenuItems(item); + } + } + } + + + private void renderString(RenderContext ctx) + { + var labelName = new Label(parent, SWT.NONE); + labelName.setText(ctx.item().getTitle()); + + var textControl = new Text(parent, SWT.SINGLE | SWT.BORDER); + var gridData = new GridData(); + gridData.widthHint = 250; + textControl.setLayoutData(gridData); + textControl.setToolTipText(ctx.helpInfo()); + + if (ctx.configValue() != null) + { + textControl + .setText(ctx.modifiedValue() != null ? (String) ctx.modifiedValue() : (String) ctx.configValue()); + } + + textControl.addModifyListener(e -> { + String text = textControl.getText(); + actionHandler.onTextModified(ctx.configKey(), text.trim()); + }); + } + + private void renderHex(RenderContext ctx) + { + var labelName = new Label(parent, SWT.NONE); + labelName.setText(ctx.item().getTitle().concat(" (hex)")); + + var textControl = new Text(parent, SWT.SINGLE | SWT.BORDER); + var gridData = new GridData(); + gridData.widthHint = 250; + textControl.setLayoutData(gridData); + textControl.setToolTipText(ctx.helpInfo()); + + if (ctx.configValue() != null) + { + long valToFormat = ctx.modifiedValue() != null ? (long) ctx.modifiedValue() : (long) ctx.configValue(); + textControl.setText("0x" + Long.toHexString(valToFormat).toUpperCase()); + } + + textControl.addModifyListener(e -> { + String text = textControl.getText().toLowerCase(); + if (text.startsWith("0x") && text.length() > 2) + { + try + { + long hexVal = Long.parseLong(text.substring(2), 16); + actionHandler.onTextModified(ctx.configKey(), hexVal); + } + catch (NumberFormatException ignored) + { + } + } + }); + } + + private void renderInt(RenderContext ctx) + { + var labelName = new Label(parent, SWT.NONE); + labelName.setText(ctx.item().getTitle()); + + var textControl = new Text(parent, SWT.SINGLE | SWT.BORDER); + var gridData = new GridData(); + gridData.widthHint = 250; + textControl.setLayoutData(gridData); + textControl.setToolTipText(ctx.helpInfo()); + + if (ctx.configValue() != null) + { + textControl.setText(ctx.modifiedValue() != null ? String.valueOf(ctx.modifiedValue()) + : String.valueOf(ctx.configValue())); + } + + textControl.addModifyListener(e -> actionHandler.onTextModified(ctx.configKey(), textControl.getText().trim())); + } + + private void renderBool(RenderContext ctx) + { + var button = new Button(parent, SWT.CHECK); + button.setText(ctx.item().getTitle()); + button.setLayoutData(new GridData(SWT.NONE, SWT.CENTER, false, false, 2, 1)); + button.setToolTipText(ctx.helpInfo()); + + if (ctx.configValue() != null) + { + button.setSelection((boolean) ctx.configValue()); + } + + button.addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + var jsonObj = new JSONObject(); + jsonObj.put(ctx.configKey(), button.getSelection()); + actionHandler.onCommandExecuted(jsonObj); + } + }); + } + + private void renderChoice(RenderContext ctx) + { + var labelName = new Label(parent, SWT.NONE); + labelName.setText(ctx.item().getTitle()); + + var choiceCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY); + var gridData = new GridData(); + gridData.widthHint = 250; + choiceCombo.setLayoutData(gridData); + + int index = 0; + for (KConfigMenuItem child : ctx.item().getChildren()) + { + String localConfigKey = child.getId(); + if (Boolean.TRUE.equals(visibleMap.get(localConfigKey))) + { + choiceCombo.add(child.getTitle()); + choiceCombo.setData(child.getTitle(), localConfigKey); + + if (Boolean.TRUE.equals(valuesMap.get(localConfigKey))) + { + choiceCombo.select(index); + } + index++; + } + } + + choiceCombo.addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + String key = (String) choiceCombo.getData(choiceCombo.getText()); + if (key != null) + { + var jsonObj = new JSONObject(); + jsonObj.put(key, true); + actionHandler.onCommandExecuted(jsonObj); + } + } + }); + + addTooltipImage(ctx); + addResetButton(ctx); + } + + private void addTooltipImage(RenderContext ctx) + { + var labelName = new Label(parent, SWT.NONE); + labelName.setImage(SDKConfigUIPlugin.getImage(ICONS_INFO_OBJ_GIF)); + labelName.setToolTipText("Help"); + + labelName.addListener(SWT.MouseUp, event -> { + String message = """ + %s + + %s + """.formatted(ctx.item().getTitle(), ctx.helpInfo()); //$NON-NLS-1$ + + Object range = rangesMap.get(ctx.configKey()); + if (range != null) + { + message += """ + + Range Information: + %s + """.formatted(range.toString()); //$NON-NLS-1$ + } + + var activeShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + if (infoDialog != null) + infoDialog.close(); + + infoDialog = new HelpPopupDialog(activeShell, "Help > " + ctx.configKey(), message); + infoDialog.open(); + }); + } + + private void addResetButton(RenderContext ctx) + { + var resetIconComposite = new Composite(parent, SWT.NONE); + resetIconComposite.setLayout(new FillLayout()); + resetIconComposite.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); + + var resetIcon = new Label(resetIconComposite, SWT.NONE); + resetIcon.setImage(SDKConfigUIPlugin.getImage(ICONS_SDK_RESET_ACTION_PNG)); + + resetIcon.addListener(SWT.MouseUp, event -> { + if (ctx.configKey() != null) + { + actionHandler.onResetRequested(ctx.configKey()); + } + }); + + if (!isResetSupported) + { + resetIcon.setEnabled(false); + resetIcon.setToolTipText(null); + resetIconComposite.setToolTipText("Reset action is not available for this esp-idf version"); + } + else + { + resetIcon.setEnabled(true); + resetIcon.setToolTipText("Reset '" + ctx.item().getTitle() + "' to default value"); + } + } + + public void renderFullMenu(KConfigMenuItem selectedElement) + { + addResetMenuButton(selectedElement); + renderMenuItems(selectedElement); + } + + private void addResetMenuButton(KConfigMenuItem selectedElement) + { + var resetGroupBtnComposite = new Composite(parent, SWT.NONE); + resetGroupBtnComposite.setLayout(new FillLayout()); + resetGroupBtnComposite.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false, 4, 1)); + + var resetGroupButton = new Button(resetGroupBtnComposite, SWT.PUSH); + resetGroupButton.setText("Reset Menu Defaults"); + + resetGroupButton.addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + boolean confirm = MessageDialog.openConfirm(parent.getShell(), + "Reset Menu Configurations", "This action will reset all configurations under '" + + selectedElement.getTitle() + "' to their default values. Continue?"); + + if (confirm) + { + actionHandler.onMenuResetRequested(selectedElement); + } + } + }); + + if (!isResetSupported) + { + resetGroupBtnComposite.setToolTipText("Reset action is not available for this esp-idf version"); + resetGroupButton.setEnabled(false); + } + else + { + resetGroupButton.setToolTipText("Reset all settings in this menu"); + } + } +} diff --git a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java index c3d227d05..00e05def1 100644 --- a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java +++ b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java @@ -26,31 +26,18 @@ import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.PageChangedEvent; import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorSite; @@ -67,7 +54,6 @@ import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.part.MultiPageEditorPart; import org.eclipse.ui.progress.IProgressService; -import org.eclipse.ui.texteditor.AbstractTextEditor; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.ParseException; @@ -87,7 +73,6 @@ import com.espressif.idf.sdk.config.core.server.JsonConfigProcessor; import com.espressif.idf.sdk.config.core.server.JsonConfigServer; import com.espressif.idf.ui.IDFConsole; -import com.espressif.idf.ui.dialogs.HelpPopupDialog; /** * SDK Configuration editor which represents the UI for the all sdkconfig fields @@ -101,12 +86,6 @@ public class SDKConfigurationEditor extends MultiPageEditorPart public static String EDITOR_ID = "com.espressif.idf.sdk.config.ui.editor"; //$NON-NLS-1$ - private static final String ICONS_INFO_OBJ_GIF = "icons/help.gif"; //$NON-NLS-1$ - - private static final String ICONS_SDK_TOOL_CONFIG_PNG = "icons/sdk_tool_config.png"; //$NON-NLS-1$ - - private static final String ICONS_SDK_RESET_ACTION_PNG = "icons/reset.png"; //$NON-NLS-1$ - private TreeViewer treeViewer; private Group updateUIComposite; @@ -132,8 +111,6 @@ public class SDKConfigurationEditor extends MultiPageEditorPart */ private JSONObject modifiedJsonMap = new JSONObject(); - private HelpPopupDialog infoDialog; - private CommandType type; private ScrolledComposite sc; @@ -228,7 +205,7 @@ private void createSourcePage() try { TextEditor editor = new TextEditor(); - Object control = ((AbstractTextEditor) editor).getAdapter(Control.class); + Object control = (editor).getAdapter(Control.class); if (control instanceof StyledText) { ((StyledText) control).setEditable(false); @@ -374,7 +351,7 @@ protected IProject getProject() * @throws IOException * @throws ParseException */ - protected void initConfigServer(IProject project) throws IOException, ParseException + protected void initConfigServer(IProject project) throws IOException { // Create console @@ -406,7 +383,7 @@ protected void initConfigServer(IProject project) throws IOException, ParseExcep } } - protected void update() throws ParseException + protected void update() { JsonConfigProcessor jsonProcessor = new JsonConfigProcessor(); String response = jsonProcessor.getInitialOutput(serverMessage); @@ -429,7 +406,7 @@ protected void update() throws ParseException * @return * @throws IOException */ - private boolean isReady(int maxAttempts, long sleepInterval, JsonConfigProcessor jsonProcessor) throws IOException + private boolean isReady(int maxAttempts, long sleepInterval, JsonConfigProcessor jsonProcessor) { int waitCount = 0; while (serverMessage == null || jsonProcessor.getInitialOutput(serverMessage) == null) @@ -481,7 +458,7 @@ public void doSave(IProgressMonitor monitor) { jsonObject.put(IJsonServerConfig.SET, modifiedJsonMap); - for (Object key : modifiedJsonMap.keySet()) + for (Object key : modifiedJsonMap.entrySet()) { valuesJsonMap.put(key, modifiedJsonMap.get(key)); } @@ -560,20 +537,14 @@ public KConfigMenuItem getInitalInput() protected void hookListeners() { - treeViewer.addSelectionChangedListener(new ISelectionChangedListener() + treeViewer.addSelectionChangedListener(event -> { - @Override - public void selectionChanged(SelectionChangedEvent event) + if (event.getSelection() instanceof IStructuredSelection) { - if (event.getSelection() instanceof IStructuredSelection) - { - KConfigMenuItem selectedElement = (KConfigMenuItem) event.getStructuredSelection() - .getFirstElement(); - updateUI(selectedElement); + KConfigMenuItem selectedElement = (KConfigMenuItem) event.getStructuredSelection().getFirstElement(); + updateUI(selectedElement); - } } - }); } @@ -582,7 +553,7 @@ private FilteredTree createFilteredTree(Group group) { PatternFilter patternFilter = new SDKConfigurationFilter(); int style = SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER; - FilteredTree transfersTree = new FilteredTree(group, style, patternFilter, true) + return new FilteredTree(group, style, patternFilter, true) { @Override protected TreeViewer doCreateTreeViewer(Composite parent, int style) @@ -590,7 +561,6 @@ protected TreeViewer doCreateTreeViewer(Composite parent, int style) return new TreeViewer(parent, style); } }; - return transfersTree; } private void updateUI(KConfigMenuItem selectedElement) @@ -603,115 +573,73 @@ private void updateUI(KConfigMenuItem selectedElement) this.selectedElement = selectedElement; - // dispose old elements - Control[] updateUICompositeControls = updateUIComposite.getChildren(); - for (Control control : updateUICompositeControls) + for (Control control : updateUIComposite.getChildren()) { control.dispose(); } updateUIComposite.setLayout((new GridLayout(4, false))); updateUIComposite.setText(selectedElement.getTitle()); + GridData updateCompsiteGD = new GridData(SWT.FILL, SWT.FILL, true, true); updateCompsiteGD.verticalIndent = 10; updateUIComposite.setLayoutData(updateCompsiteGD); - - addResetMenuButton(selectedElement); - - renderMenuItems(selectedElement); - - sc.setContent(updateUIComposite); - sc.setExpandHorizontal(true); - sc.setExpandVertical(true); - sc.setMinSize(updateUIComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - sc.setShowFocusedControl(true); - - updateUIComposite.layout(true); - } - - private boolean isResetSupported() - { - return configServer.getOutput().getVersion() >= 3; - } - - private void addResetMenuButton(KConfigMenuItem selectedElement) - { - Composite resetGroupBtnComposite = new Composite(updateUIComposite, SWT.NONE); - resetGroupBtnComposite.setLayout(new FillLayout()); - resetGroupBtnComposite.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false, 4, 1)); - - Button resetGroupButton = new Button(resetGroupBtnComposite, SWT.PUSH); - resetGroupButton.setText("Reset Menu Defaults"); - - resetGroupButton.addSelectionListener(new SelectionAdapter() + ConfigActionHandler handler = new ConfigActionHandler() { @Override - public void widgetSelected(SelectionEvent e) + public void onCommandExecuted(JSONObject jsonMap) { - handleResetMenuAction(selectedElement); + executeCommand(jsonMap); } - }); - - applyResetSupportState(resetGroupBtnComposite, resetGroupButton, null); - } - - private void handleResetMenuAction(KConfigMenuItem selectedElement) - { - boolean confirm = MessageDialog.openConfirm(Display.getDefault().getActiveShell(), "Reset Menu Configurations", - "This action will reset all configurations under '" + selectedElement.getTitle() - + "' to their default values. Continue?"); - if (!confirm) - return; + @Override + public void onTextModified(String key, Object value) + { + isDirty = true; + editorDirtyStateChanged(); + modifiedJsonMap.put(key, value); + } - List childIds = new ArrayList<>(); - collectAllChildIds(selectedElement, childIds); + @Override + public void onResetRequested(String key) + { + executeResetCommand(key); + } - if (!childIds.isEmpty()) - { - executeResetChildrenCommand(childIds); - } - else if (selectedElement.getId() != null) + @Override + public void onMenuResetRequested(KConfigMenuItem menu) { - executeResetCommand(selectedElement.getId()); - } - } + List childIds = new ArrayList<>(); + collectAllChildIds(menu, childIds); - protected void addResetButton(KConfigMenuItem kConfigMenuItem) - { - Composite resetIconComposite = new Composite(updateUIComposite, SWT.NONE); - resetIconComposite.setLayout(new FillLayout()); + if (!childIds.isEmpty()) + { + executeResetChildrenCommand(childIds); + } + else if (menu.getId() != null) + { + executeResetCommand(menu.getId()); + } + } + }; - resetIconComposite.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); + ConfigUIRenderer renderer = new ConfigUIRenderer(updateUIComposite, valuesJsonMap, visibleJsonMap, + modifiedJsonMap, rangesJsonMap, isResetSupported(), handler); - Label resetIcon = new Label(resetIconComposite, SWT.NONE); - resetIcon.setImage(SDKConfigUIPlugin.getImage(ICONS_SDK_RESET_ACTION_PNG)); + renderer.renderFullMenu(selectedElement); - resetIcon.addListener(SWT.MouseUp, event -> { - if (kConfigMenuItem.getId() != null) - { - executeResetCommand(kConfigMenuItem.getId()); - } - }); + sc.setContent(updateUIComposite); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + sc.setMinSize(updateUIComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + sc.setShowFocusedControl(true); - String activeTooltip = "Reset '" + kConfigMenuItem.getTitle() + "' to default value"; - applyResetSupportState(resetIconComposite, resetIcon, activeTooltip); + updateUIComposite.layout(true); } - - private void applyResetSupportState(Composite wrapper, Control innerControl, String activeTooltip) + private boolean isResetSupported() { - if (!isResetSupported()) - { - innerControl.setEnabled(false); - innerControl.setToolTipText(null); - wrapper.setToolTipText("Reset action is not available for this esp-idf version"); - } - else - { - innerControl.setEnabled(true); - innerControl.setToolTipText(activeTooltip); - } + return configServer.getOutput().getVersion() >= 3; } /** @@ -733,292 +661,12 @@ private void collectAllChildIds(KConfigMenuItem item, List childIds) } } - protected void renderMenuItems(KConfigMenuItem selectedElement) - { - // add children here - List children = selectedElement.getChildren(); - for (KConfigMenuItem kConfigMenuItem : children) - { - String type = kConfigMenuItem.getType(); - String configKey = kConfigMenuItem.getId(); - Object configValue = valuesJsonMap.get(configKey); - boolean isVisible = (visibleJsonMap.get(configKey) != null ? (boolean) visibleJsonMap.get(configKey) - : false); - Object newConfigValue = modifiedJsonMap.get(configKey); - String helpInfo = kConfigMenuItem.getHelp(); - if (isVisible && type.equals(IJsonServerConfig.STRING_TYPE)) - { - Label labelName = new Label(updateUIComposite, SWT.NONE); - labelName.setText(kConfigMenuItem.getTitle()); - - Text textControl = new Text(updateUIComposite, SWT.SINGLE | SWT.BORDER); - GridData gridData = new GridData(); - gridData.widthHint = 250; - textControl.setLayoutData(gridData); - textControl.setToolTipText(helpInfo); - if (configValue != null) - { - textControl.setText(newConfigValue != null ? (String) newConfigValue : (String) configValue); - } - textControl.addModifyListener(addModifyListener(configKey, textControl)); - - addTooltipImage(kConfigMenuItem); - addResetButton(kConfigMenuItem); - - } - else if (isVisible && type.equals(IJsonServerConfig.HEX_TYPE)) - { - Label labelName = new Label(updateUIComposite, SWT.NONE); - labelName.setText(kConfigMenuItem.getTitle().concat(" (hex)")); - - Text textControl = new Text(updateUIComposite, SWT.SINGLE | SWT.BORDER); - GridData gridData = new GridData(); - gridData.widthHint = 250; - textControl.setLayoutData(gridData); - textControl.setToolTipText(helpInfo); - if (configValue != null) - { - String hexText = newConfigValue != null ? Long.toHexString((long) newConfigValue) - : Long.toHexString((long) configValue); - textControl.setText("0x" + hexText.toUpperCase()); - - } - textControl.addModifyListener(addModifyListener(configKey, textControl)); - - addTooltipImage(kConfigMenuItem); - addResetButton(kConfigMenuItem); - } - else if (kConfigMenuItem.isMenuConfig()) - { - Button button = createCheckBox(kConfigMenuItem, configKey, configValue, helpInfo); - button.addSelectionListener(new SelectionAdapter() - { - @Override - public void widgetSelected(SelectionEvent e) - { - renderMenuItems(kConfigMenuItem); - } - - }); - if (kConfigMenuItem.hasChildren()) - { - button.setImage(SDKConfigUIPlugin.getImage(ICONS_SDK_TOOL_CONFIG_PNG)); - } - - if (button.getSelection()) - { - renderMenuItems(kConfigMenuItem); - } - - } - else if (isVisible && type.equals(IJsonServerConfig.BOOL_TYPE)) - { - createCheckBox(kConfigMenuItem, configKey, configValue, helpInfo); - } - - else if (isVisible && type.equals(IJsonServerConfig.INT_TYPE)) - { - Label labelName = new Label(updateUIComposite, SWT.NONE); - labelName.setText(kConfigMenuItem.getTitle()); - - Text text = new Text(updateUIComposite, SWT.SINGLE | SWT.BORDER); - GridData gridData = new GridData(); - gridData.widthHint = 250; - text.setLayoutData(gridData); - text.setToolTipText(helpInfo); - - if (configValue != null) - { - text.setText(newConfigValue != null ? String.valueOf(newConfigValue) : String.valueOf(configValue)); - - } - text.addModifyListener(addModifyListener(configKey, text)); - - addTooltipImage(kConfigMenuItem); - addResetButton(kConfigMenuItem); - - } - else if (isVisible && type.equals(IJsonServerConfig.MENU_TYPE)) - { - renderMenuItems(kConfigMenuItem); - } - else if (type.equals(IJsonServerConfig.CHOICE_TYPE)) - { - Logger.logTrace(SDKConfigUIPlugin.getDefault(), - "Config key >" + configKey + " visiblity status >" + isVisible); //$NON-NLS-1$ //$NON-NLS-2$ - - if (isExist(visibleJsonMap, configKey)) - { - List choiceItems = kConfigMenuItem.getChildren(); - Label labelName = new Label(updateUIComposite, SWT.NONE); - labelName.setText(kConfigMenuItem.getTitle()); - - Combo choiceCombo = new Combo(updateUIComposite, SWT.DROP_DOWN | SWT.READ_ONLY); - GridData gridData = new GridData(); - gridData.widthHint = 250; - choiceCombo.setLayoutData(gridData); - - int index = 0; - for (KConfigMenuItem item : choiceItems) - { - String localConfigKey = item.getId(); - if (isExist(visibleJsonMap, localConfigKey)) - { - choiceCombo.add(item.getTitle()); - choiceCombo.setData(item.getTitle(), localConfigKey); - - // Check if this selected? - if (isExist(valuesJsonMap, localConfigKey)) - { - choiceCombo.select(index); - } - index++; - } - - } - - choiceCombo.addSelectionListener(new SelectionAdapter() - { - @Override - public void widgetSelected(SelectionEvent e) - { - Object key = choiceCombo.getData(choiceCombo.getText()); - if (key != null) - { - JSONObject jsonObj = new JSONObject(); - jsonObj.put(key, true); - executeCommand(jsonObj); - - } - } - }); - - addTooltipImage(kConfigMenuItem); - addResetButton(kConfigMenuItem); - } - } - - // kConfigMenuItem has children? - if (!type.equals(IJsonServerConfig.CHOICE_TYPE) && !type.equals(IJsonServerConfig.MENU_TYPE) - && kConfigMenuItem.hasChildren()) - { - renderMenuItems(kConfigMenuItem); - } - } - } - - private Button createCheckBox(KConfigMenuItem kConfigMenuItem, String configKey, Object configValue, - String helpInfo) - { - Button button = new Button(updateUIComposite, SWT.CHECK); - button.setText(kConfigMenuItem.getTitle()); - - button.setLayoutData(new GridData(SWT.NONE, SWT.CENTER, false, false, 2, 1)); - button.setToolTipText(helpInfo); - if (configValue != null) - { - button.setSelection((boolean) configValue); - } - button.addSelectionListener(new SelectionAdapter() - { - @Override - public void widgetSelected(SelectionEvent e) - { - JSONObject jsonObj = new JSONObject(); - jsonObj.put(configKey, button.getSelection()); - executeCommand(jsonObj); - } - - }); - - addTooltipImage(kConfigMenuItem); - addResetButton(kConfigMenuItem); - - return button; - } - - protected boolean isExist(JSONObject jsonMap, String key) - { - return jsonMap.get(key) != null ? (boolean) jsonMap.get(key) : false; - } - - protected void addTooltipImage(KConfigMenuItem kConfigMenuItem) - { - Label labelName = new Label(updateUIComposite, SWT.NONE); - labelName.setImage(SDKConfigUIPlugin.getImage(ICONS_INFO_OBJ_GIF)); - labelName.addListener(SWT.MouseUp, getMouseClickListener(kConfigMenuItem)); - labelName.setToolTipText(Messages.SDKConfigurationEditor_Help); - } - - private Listener getMouseClickListener(KConfigMenuItem kConfigMenuItem) - { - return new Listener() - { - @Override - public void handleEvent(Event event) - { - String help = kConfigMenuItem.getHelp(); - String title = kConfigMenuItem.getTitle(); - String configKey = kConfigMenuItem.getId(); - - // frame message - StringBuilder message = new StringBuilder(); - message.append(title); - message.append("\n\n"); //$NON-NLS-1$ - message.append(help); - - // get range info - Object range = rangesJsonMap.get(configKey); - if (range != null) - { - message.append("\n\n"); //$NON-NLS-1$ - message.append("Range Information:"); //$NON-NLS-1$ - message.append("\n"); //$NON-NLS-1$ - message.append(range.toString()); - } - - if (StringUtil.isEmpty(help)) - { - String msg = MessageFormat.format(Messages.SDKConfigurationEditor_NoHelpAvailable, configKey); - Logger.log(SDKConfigUIPlugin.getDefault(), msg); - return; - } - Shell activeShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); - if (infoDialog != null) - { - infoDialog.close(); - } - infoDialog = new HelpPopupDialog(activeShell, Messages.SDKConfigurationEditor_Help + " > " + configKey, //$NON-NLS-1$ - message.toString()); // $NON-NLS-2$ - infoDialog.open(); - - } - }; - } - - protected ModifyListener addModifyListener(String configKey, Text textControl) - { - return new ModifyListener() - { - @Override - public void modifyText(ModifyEvent e) - { - String text = textControl.getText().toLowerCase(); - boolean isHex = text.startsWith("0x"); - isDirty = true; - editorDirtyStateChanged(); - modifiedJsonMap.put(configKey, - isHex ? Long.parseLong(text.substring(2), 16) : textControl.getText().trim()); - } - }; - } - protected void executeCommand(JSONObject jsonObj) { isDirty = true; editorDirtyStateChanged(); - for (Object key : jsonObj.keySet()) + for (Object key : jsonObj.entrySet()) { valuesJsonMap.put(key, jsonObj.get(key)); } @@ -1103,9 +751,7 @@ public void notifyRequestServed(String message, CommandType type) if (selectedElement != null) { - try - { - if (type == CommandType.LOAD || type == CommandType.RESET) + if (type == CommandType.LOAD || type == CommandType.RESET) { modifiedJsonMap.clear(); isDirty = (type == CommandType.RESET); @@ -1132,20 +778,12 @@ public void notifyRequestServed(String message, CommandType type) Display.getDefault().asyncExec(() -> { + if (!treeViewer.getControl().isDisposed()) { - if (!treeViewer.getControl().isDisposed()) - { - treeViewer.refresh(); - updateUI(selectedElement); - } + treeViewer.refresh(); + updateUI(selectedElement); } }); - } - catch (ParseException e1) - { - Logger.log(SDKConfigUIPlugin.getDefault(), e1); - } - } } @@ -1167,7 +805,6 @@ public void pageChanged(PageChangedEvent event) { doSave(new NullProgressMonitor()); } - return; } } From 2816cc915c541a1957cbbc91546d82d5bee074aa Mon Sep 17 00:00:00 2001 From: Denys Almazov Date: Wed, 8 Apr 2026 10:32:01 +0300 Subject: [PATCH 4/7] fix: replaced loop iteration with putAll --- .../idf/sdk/config/ui/SDKConfigurationEditor.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java index 00e05def1..0c4c5bf73 100644 --- a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java +++ b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java @@ -458,10 +458,7 @@ public void doSave(IProgressMonitor monitor) { jsonObject.put(IJsonServerConfig.SET, modifiedJsonMap); - for (Object key : modifiedJsonMap.entrySet()) - { - valuesJsonMap.put(key, modifiedJsonMap.get(key)); - } + valuesJsonMap.putAll(modifiedJsonMap); } else { @@ -666,10 +663,7 @@ protected void executeCommand(JSONObject jsonObj) isDirty = true; editorDirtyStateChanged(); - for (Object key : jsonObj.entrySet()) - { - valuesJsonMap.put(key, jsonObj.get(key)); - } + valuesJsonMap.putAll(jsonObj); JSONObject jsonObject = new JSONObject(); var version = configServer.getOutput().getVersion(); From b4f1feca0f8180537b484bbb8829e950d7456881 Mon Sep 17 00:00:00 2001 From: Denys Almazov Date: Wed, 8 Apr 2026 11:00:33 +0300 Subject: [PATCH 5/7] feat: use constant and dynamic version for reset --- .../idf/sdk/config/ui/SDKConfigurationEditor.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java index 0c4c5bf73..ea4871579 100644 --- a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java +++ b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java @@ -115,6 +115,8 @@ public class SDKConfigurationEditor extends MultiPageEditorPart private ScrolledComposite sc; + private static final int MIN_VERSION_FOR_RESET = 3; + public SDKConfigurationEditor() { super(); @@ -636,7 +638,7 @@ else if (menu.getId() != null) } private boolean isResetSupported() { - return configServer.getOutput().getVersion() >= 3; + return configServer.getOutput().getVersion() >= MIN_VERSION_FOR_RESET; } /** @@ -677,13 +679,13 @@ protected void executeCommand(JSONObject jsonObj) protected void executeResetCommand(String idToReset) { long version = configServer.getOutput().getVersion(); - if (version >= 3) + if (version >= MIN_VERSION_FOR_RESET) { isDirty = true; editorDirtyStateChanged(); JSONObject jsonObject = new JSONObject(); - jsonObject.put(IJsonServerConfig.VERSION, 3); + jsonObject.put(IJsonServerConfig.VERSION, version); JSONArray resetArray = new JSONArray(); resetArray.add(idToReset); @@ -698,7 +700,7 @@ protected void executeResetCommand(String idToReset) protected void executeResetChildrenCommand(List idsToReset) { long version = configServer.getOutput().getVersion(); - if (version >= 3) + if (version >= MIN_VERSION_FOR_RESET) { if (idsToReset == null || idsToReset.isEmpty()) return; @@ -707,7 +709,7 @@ protected void executeResetChildrenCommand(List idsToReset) editorDirtyStateChanged(); JSONObject jsonObject = new JSONObject(); - jsonObject.put(IJsonServerConfig.VERSION, 3); + jsonObject.put(IJsonServerConfig.VERSION, version); JSONArray resetArray = new JSONArray(); resetArray.addAll(idsToReset); From 94429328bdb7ac9a232a4c9379e3ff7b27a93222 Mon Sep 17 00:00:00 2001 From: Denys Almazov Date: Wed, 8 Apr 2026 12:47:16 +0300 Subject: [PATCH 6/7] fix: don't clear all edits on server reset --- .../sdk/config/ui/SDKConfigurationEditor.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java index ea4871579..c093b3241 100644 --- a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java +++ b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/SDKConfigurationEditor.java @@ -11,6 +11,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; @@ -747,15 +749,26 @@ public void notifyRequestServed(String message, CommandType type) if (selectedElement != null) { - if (type == CommandType.LOAD || type == CommandType.RESET) + if (type == CommandType.LOAD) + { + modifiedJsonMap.clear(); + Display.getDefault().asyncExec(this::editorDirtyStateChanged); + } + else if (type == CommandType.RESET) + { + Pattern pattern = Pattern.compile("Reset\\s+([A-Za-z0-9_]+)\\s+to default value"); + Matcher matcher = pattern.matcher(serverMessage); + while (matcher.find()) { - modifiedJsonMap.clear(); - isDirty = (type == CommandType.RESET); - - Display.getDefault().asyncExec(this::editorDirtyStateChanged); + String resetKey = matcher.group(1); + modifiedJsonMap.remove(resetKey); } - if (type == CommandType.SAVE) + isDirty = true; + Display.getDefault().asyncExec(this::editorDirtyStateChanged); + } + + else if (type == CommandType.SAVE) { Display.getDefault().asyncExec(() -> { try From b70500921fae6902b3a53a3a5ef5ea021d63ac49 Mon Sep 17 00:00:00 2001 From: Denys Almazov Date: Tue, 14 Apr 2026 17:44:31 +0300 Subject: [PATCH 7/7] fix: do not show reset buttons if not supported --- .../idf/sdk/config/ui/ConfigUIRenderer.java | 51 +++++++------------ 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/ConfigUIRenderer.java b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/ConfigUIRenderer.java index 09bbe5719..2822aee59 100644 --- a/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/ConfigUIRenderer.java +++ b/bundles/com.espressif.idf.sdk.config.ui/src/com/espressif/idf/sdk/config/ui/ConfigUIRenderer.java @@ -40,8 +40,7 @@ private record RenderContext(KConfigMenuItem item, String configKey, Object conf public RenderContext(KConfigMenuItem item, JSONObject visibleMap, JSONObject valuesMap, JSONObject modifiedMap) { this(item, item.getId(), valuesMap.get(item.getId()), modifiedMap.get(item.getId()), - Boolean.TRUE.equals(visibleMap.get(item.getId())), - item.getHelp()); + Boolean.TRUE.equals(visibleMap.get(item.getId())), item.getHelp()); } } @@ -97,7 +96,6 @@ public void renderMenuItems(KConfigMenuItem selectedElement) } } - private void renderString(RenderContext ctx) { var labelName = new Label(parent, SWT.NONE); @@ -278,12 +276,19 @@ private void addTooltipImage(RenderContext ctx) private void addResetButton(RenderContext ctx) { + if (!isResetSupported) + { + new Label(parent, SWT.NONE).setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); + return; + } + var resetIconComposite = new Composite(parent, SWT.NONE); resetIconComposite.setLayout(new FillLayout()); resetIconComposite.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); var resetIcon = new Label(resetIconComposite, SWT.NONE); resetIcon.setImage(SDKConfigUIPlugin.getImage(ICONS_SDK_RESET_ACTION_PNG)); + resetIcon.setToolTipText("Reset '" + ctx.item().getTitle() + "' to default value"); resetIcon.addListener(SWT.MouseUp, event -> { if (ctx.configKey() != null) @@ -291,18 +296,6 @@ private void addResetButton(RenderContext ctx) actionHandler.onResetRequested(ctx.configKey()); } }); - - if (!isResetSupported) - { - resetIcon.setEnabled(false); - resetIcon.setToolTipText(null); - resetIconComposite.setToolTipText("Reset action is not available for this esp-idf version"); - } - else - { - resetIcon.setEnabled(true); - resetIcon.setToolTipText("Reset '" + ctx.item().getTitle() + "' to default value"); - } } public void renderFullMenu(KConfigMenuItem selectedElement) @@ -313,21 +306,25 @@ public void renderFullMenu(KConfigMenuItem selectedElement) private void addResetMenuButton(KConfigMenuItem selectedElement) { - var resetGroupBtnComposite = new Composite(parent, SWT.NONE); - resetGroupBtnComposite.setLayout(new FillLayout()); - resetGroupBtnComposite.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false, 4, 1)); + if (!isResetSupported) + { + return; + } - var resetGroupButton = new Button(resetGroupBtnComposite, SWT.PUSH); + var resetGroupButton = new Button(parent, SWT.PUSH); resetGroupButton.setText("Reset Menu Defaults"); + resetGroupButton.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false, 4, 1)); + resetGroupButton.setToolTipText("Reset all settings in this menu"); resetGroupButton.addSelectionListener(new SelectionAdapter() + { @Override public void widgetSelected(SelectionEvent e) { - boolean confirm = MessageDialog.openConfirm(parent.getShell(), - "Reset Menu Configurations", "This action will reset all configurations under '" - + selectedElement.getTitle() + "' to their default values. Continue?"); + boolean confirm = MessageDialog.openConfirm(parent.getShell(), "Reset Menu Configurations", + "This action will reset all configurations under '" + selectedElement.getTitle() + + "' to their default values. Continue?"); if (confirm) { @@ -335,15 +332,5 @@ public void widgetSelected(SelectionEvent e) } } }); - - if (!isResetSupported) - { - resetGroupBtnComposite.setToolTipText("Reset action is not available for this esp-idf version"); - resetGroupButton.setEnabled(false); - } - else - { - resetGroupButton.setToolTipText("Reset all settings in this menu"); - } } }