package net.sourceforge.pmd.eclipse.ui.preferences.panelmanagers; import java.util.Collections; import java.util.List; import net.sourceforge.pmd.PropertyDescriptor; import net.sourceforge.pmd.Rule; import net.sourceforge.pmd.eclipse.ui.PMDUiConstants; 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.TypeText; import net.sourceforge.pmd.eclipse.util.ColourManager; import net.sourceforge.pmd.eclipse.util.ResourceManager; import net.sourceforge.pmd.lang.rule.properties.StringProperty; import net.sourceforge.pmd.util.StringUtil; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.RGB; 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.Event; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.TabItem; import org.eclipse.swt.widgets.Text; /** * Concrete subclasses can also be used as tab folders outside of a wizard dialog via the setupOn(Composite) method. * * @author Brian Remedios */ public abstract class AbstractRulePanelManager extends WizardPage implements RulePropertyManager { private TabItem tab; private String tabText; private boolean isActive; protected RuleSelection rules; protected final ValueChangeListener changeListener; private final EditorUsageMode usageMode; protected static Color textColour; protected static Color errorColour; protected static Color disabledColour; protected static Color overridenColour; private static final String disabledTabText = "-------"; public static final RGB overridenColourValues = new RGB(236, 236, 255); // light blue public AbstractRulePanelManager(String theId, String theTitle, EditorUsageMode theMode, ValueChangeListener theListener) { super(theId, theTitle, null); changeListener = theListener; usageMode = theMode; } public abstract Control setupOn(Composite panel); public EditorUsageMode mode() { return usageMode; } /** * For use by wizards only.. */ public void createControl(Composite panel) { Control childPanel = setupOn(panel); setControl(childPanel); setPageComplete(true); } protected boolean creatingNewRule() { return usageMode == EditorUsageMode.CreateNew; } public void tab(TabItem theTab) { tab = theTab; tabText = theTab.getText(); } public boolean isActive() { return isActive; } protected String asCleanString(String original) { if (original == null) return ""; return original.trim(); } public void manage(RuleSelection theRules) { rules = theRules; isActive = (rules.hasOneRule() && canWorkWith(rules.soleRule())) || (rules.hasMultipleRules() && canManageMultipleRules()); showControls(isActive); if (tab != null) tab.setText(isActive ? tabText : disabledTabText); if (isActive) { adapt(); } else { clearControls(); } updateUI(); } protected void valueChanged(PropertyDescriptor<?> optionalDesc, Object newValue) { changeListener.changed(rules, optionalDesc, newValue); updateUI(); } protected void updateUI() { List<String> warnings = fieldWarnings(); List<String> errors = fieldErrors(); if (tab != null) updateTabUI(warnings, errors); updateOverridenFields(); disableIrrelevantFields(); } protected void updateOverridenFields() { } protected void disableIrrelevantFields() { } protected boolean canWorkWith(Rule rule) { return true; } // override as necessary protected List<String> fieldErrors() { // override as necessary return Collections.emptyList(); } protected List<String> fieldWarnings() { // override as necessary return Collections.emptyList(); } public boolean validate() { List<String> warnings = fieldWarnings(); List<String> errors = fieldErrors(); if (tab != null) { updateTabUI(warnings, errors); } String errorText = errors.isEmpty() ? null : StringUtil.asString(errors.toArray(), ", "); setErrorMessage(errorText); setPageComplete(StringUtil.isEmpty(errorText)); return errorText == null; } protected void updateTabUI(List<String> warnings, List<String> errors) { if (!isActive) { tab.setToolTipText(""); tab.setImage(null); return; } boolean hasIssues = updateTab(errors, PMDUiConstants.ICON_ERROR); if (hasIssues) return; updateTab(fieldWarnings(), PMDUiConstants.ICON_WARN); } private boolean updateTab(List<String> issues, String iconName) { boolean hasIssues = !issues.isEmpty(); tab.setImage( hasIssues ? ResourceManager.imageFor(iconName) : null ); tab.setToolTipText(hasIssues ? issues.toString() : ""); return hasIssues; } protected abstract boolean canManageMultipleRules(); protected abstract void adapt(); protected abstract void clearControls(); public abstract void showControls(boolean flag); protected Rule soleRule() { return rules.soleRule(); } protected void addTextListeners(final Text control, final StringProperty desc) { control.addListener(SWT.FocusOut, new Listener() { public void handleEvent(Event event) { changed(desc, control.getText()); } }); } protected void addTextListeners(final StyledText control, final StringProperty desc) { control.addListener(SWT.FocusOut, new Listener() { public void handleEvent(Event event) { changed(desc, control.getText()); } }); } public void loadValues() { // subclasses to re-implement } protected void initializeOn(Composite parent) { if (errorColour != null) return; ColourManager clrMgr = ColourManager.managerFor(parent.getDisplay()); errorColour = clrMgr.colourFor(new RGB( 255, 0, 0 )); // red textColour = clrMgr.colourFor(new RGB( 0, 0, 0 )); // black disabledColour = clrMgr.colourFor(new RGB( 128, 128, 128)); // grey // overridenColour = clrMgr.colourFor(overridenColourValues); } // protected void valueChanged() { // changeListener.changed(rules, null, ""); // } /** * @param property StringProperty * @param newValue String */ protected void changed(StringProperty property, String newValue) { if (rules == null) return; String cleanValue = newValue.trim(); String existingValue = rules.commonStringValue(property); if (StringUtil.areSemanticEquals(existingValue, cleanValue)) return; rules.setValue(property, cleanValue); valueChanged(property, newValue); } protected void shutdown(Text control) { control.setText(""); control.setEnabled(false); } protected void shutdown(StyledText control) { control.setText(""); control.setEnabled(false); } protected void shutdown(Link control) { control.setText(""); control.setEnabled(false); } protected void show(TypeText control, Class<?> type) { control.setType(type); // control.setEnabled(usageMode == EditorUsageMode.CreateNew); } protected void show(Button checkbox, boolean checked) { checkbox.setSelection(checked); // checkbox.setEnabled(usageMode == EditorUsageMode.CreateNew); } protected void show(Text control, String value) { control.setText(value == null ? "" : value); // control.setEnabled(usageMode == EditorUsageMode.CreateNew); } protected void show(StyledText control, String value) { control.setText(value == null ? "" : value); // control.setEnabled(usageMode == EditorUsageMode.CreateNew); } protected void show(Combo control, String value) { // control.setEnabled(usageMode == EditorUsageMode.CreateNew); if (StringUtil.isEmpty(value)) { control.deselectAll(); return; } String[] choices = control.getItems(); int index = -1; for (int i=0; i<choices.length; i++) { if (StringUtil.areSemanticEquals(choices[i], value)) { index = i; break; } } if (index < 0) { control.deselectAll(); } else { control.select(index); } } protected void show(CCombo control, String value) { // control.setEnabled(usageMode == EditorUsageMode.CreateNew); if (StringUtil.isEmpty(value)) { control.deselectAll(); return; } String[] choices = control.getItems(); int index = -1; for (int i=0; i<choices.length; i++) { if (StringUtil.areSemanticEquals(choices[i], value)) { index = i; break; } } if (index < 0) { control.deselectAll(); } else { control.select(index); } } protected void show(Link control, String value) { control.setText(value == null ? "" : value); // control.setEnabled(true); } /** * Method newTextField. * @param parent Composite * @return Text */ protected Text newTextField(Composite parent) { return new Text(parent, SWT.BORDER | SWT.WRAP | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); } protected StyledText newCodeField(Composite parent) { StyledText st = new StyledText(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); return st; } }