package net.sourceforge.pmd.eclipse.ui.preferences.panelmanagers; import java.util.ArrayList; import java.util.List; import net.sourceforge.pmd.Rule; import net.sourceforge.pmd.eclipse.ui.editors.SyntaxManager; import net.sourceforge.pmd.eclipse.ui.nls.StringKeys; import net.sourceforge.pmd.eclipse.ui.preferences.br.ImplementationType; import net.sourceforge.pmd.eclipse.ui.preferences.br.RuleSelection; import net.sourceforge.pmd.eclipse.ui.preferences.br.ValueChangeListener; import net.sourceforge.pmd.eclipse.ui.preferences.editors.EnumerationEditorFactory; import net.sourceforge.pmd.eclipse.ui.preferences.editors.SWTUtil; import net.sourceforge.pmd.lang.rule.RuleReference; import net.sourceforge.pmd.lang.rule.XPathRule; import net.sourceforge.pmd.lang.rule.properties.EnumeratedProperty; import net.sourceforge.pmd.util.StringUtil; import org.eclipse.swt.SWT; 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.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; /** * * @author Brian Remedios */ public class XPathPanelManager extends AbstractRulePanelManager { private StyledText xpathField; private Combo xpathVersionField; private Label versionLabel; private List<String> unknownVariableNames; public static final String ID = "xpath"; public XPathPanelManager(String theTitle, EditorUsageMode theMode, ValueChangeListener theListener) { super(ID, theTitle, theMode, theListener); } protected boolean canManageMultipleRules() { return false; } protected boolean canWorkWith(Rule rule) { return RuleSelection.implementationType(rule) == ImplementationType.XPath; } protected List<String> fieldErrors() { List<String> errors = new ArrayList<String>(2); if (StringUtil.isEmpty(xpathField.getText())) { errors.add("Missing XPATH code"); } if (unknownVariableNames == null || unknownVariableNames.isEmpty()) { return errors; } errors.add("Unknown variables: " + unknownVariableNames); return errors; } protected void clearControls() { xpathField.setText(""); } public void showControls(boolean flag) { xpathField.setVisible(flag); xpathVersionField.setVisible(flag); versionLabel.setVisible(flag); } protected void updateOverridenFields() { Rule rule = soleRule(); if (rule instanceof RuleReference) { RuleReference ruleReference = (RuleReference)rule; xpathField.setBackground(ruleReference.hasOverriddenProperty(XPathRule.XPATH_DESCRIPTOR) ? overridenColour: null); } } public Control setupOn(Composite parent) { GridData gridData; Composite panel = new Composite(parent, 0); GridLayout layout = new GridLayout(2, false); panel.setLayout(layout); xpathField = newCodeField(panel); SyntaxManager.adapt(xpathField, "xpath", null); gridData = new GridData(GridData.FILL_BOTH); gridData.grabExcessHorizontalSpace = true; gridData.horizontalSpan = 2; xpathField.setLayoutData(gridData); xpathField.addModifyListener( new ModifyListener() { public void modifyText(ModifyEvent event) { if (!isActive()) return; Rule soleRule = soleRule(); if (soleRule == null) return; String newValue = xpathField.getText().trim(); String existingValue = soleRule.getProperty(XPathRule.XPATH_DESCRIPTOR).trim(); if (StringUtil.areSemanticEquals(existingValue, newValue)) return; validate(); soleRule.setProperty(XPathRule.XPATH_DESCRIPTOR, newValue); // updateVariablesField(); valueChanged(XPathRule.XPATH_DESCRIPTOR, newValue); } }); versionLabel = new Label(panel, 0); versionLabel.setText(SWTUtil.stringFor(StringKeys.PREF_RULEEDIT_LABEL_XPATH_VERSION)); gridData = new GridData(); gridData.horizontalSpan = 1; gridData.grabExcessHorizontalSpace = false; versionLabel.setLayoutData(gridData); final EnumeratedProperty<String> ep = XPathRule.VERSION_DESCRIPTOR; xpathVersionField = new Combo(panel, SWT.READ_ONLY); gridData = new GridData(); gridData.horizontalSpan = 1; gridData.grabExcessHorizontalSpace = false; xpathVersionField.setLayoutData(gridData); xpathVersionField.setItems(SWTUtil.labelsIn(ep.choices(), 0)); xpathVersionField.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { Rule rule = soleRule(); int selectionIdx = xpathVersionField.getSelectionIndex(); Object newValue = ep.choices()[selectionIdx][1]; if (newValue.equals(rule.getProperty(ep))) return; rule.setProperty(ep, newValue); // adjustRendering(rule, ep, xpathVersionField); TODO - won't compile? } }); return panel; } private void configureVersionFieldFor(Rule rule) { Object value = rule.getProperty(XPathRule.VERSION_DESCRIPTOR); int selectionIdx = EnumerationEditorFactory.indexOf(value, XPathRule.VERSION_DESCRIPTOR.choices()); if (selectionIdx >= 0) xpathVersionField.select(selectionIdx); } // private static StyleRange styleFor(Rule rule, String source, int[] position, List<String> unknownVars) { // // String varName = source.substring(position[0], position[0] + position[1]); // PropertyDescriptor<?> desc = rule.getPropertyDescriptor(varName); // // if (desc == null) unknownVars.add(varName); // // return new StyleRange( // position[0], position[1], // desc == null ? errorColour : null, // null, // SWT.BOLD // ); // } // // private void updateVariablesField() { // // xpathField.setStyleRange(null); // clear all // // Rule rule = soleRule(); // unknownVariableNames = new ArrayList<String>(); // // String xpath = rule.getProperty(XPathRule.XPATH_DESCRIPTOR).trim(); // List<int[]> positions = Util.referencedNamePositionsIn(xpath, '$'); // for (int[] position : positions) { // StyleRange range = styleFor(rule, xpath, position, unknownVariableNames); // xpathField.setStyleRange(range); // } // } public void adapt() { Rule soleRule = soleRule(); if (soleRule == null) { shutdown(xpathField); } else { show(xpathField, soleRule.getProperty(XPathRule.XPATH_DESCRIPTOR).trim()); configureVersionFieldFor(soleRule); // updateVariablesField(); } validate(); } }