Revision: 7051
http://pmd.svn.sourceforge.net/pmd/?rev=7051&view=rev
Author: hooperbloob
Date: 2010-01-03 04:32:29 +0000 (Sun, 03 Jan 2010)
Log Message:
-----------
I18L updates, better explanatory tooltips for rule aspect column headings, initial MultiEnumerationEditor (read-only for now), bugfixes for spinner widget updates
Modified Paths:
--------------
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/messages.properties
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/nls/StringKeys.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/AbstractRuleColumnDescriptor.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/CellPainterBuilder.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/ImageColumnDescriptor.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/PMDPreferencePage.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/RuleFieldAccessor.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/RuleLabelProvider.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/RuleSelection.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/RuleSetTreeItemProvider.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/RuleSortListener.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/TextColumnDescriptor.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/editors/AbstractNumericEditorFactory.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/editors/DoubleEditorFactory.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/editors/FloatEditorFactory.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/editors/IntegerEditorFactory.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/editors/MethodEditorFactory.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/editors/MethodPicker.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/editors/MultiIntegerEditorFactory.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/editors/SWTUtil.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/editors/StringEditorFactory.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/editors/TypeEditorFactory.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/panelmanagers/DescriptionPanelManager.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/panelmanagers/FormArranger.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/panelmanagers/PerRulePropertyPanelManager.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/util/ColourManager.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/util/Util.java
Added Paths:
-----------
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/NewPropertyDialog.java
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/editors/MultiEnumerationEditorFactory.java
Removed Paths:
-------------
trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/PropertyDialog.java
Modified: trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/messages.properties
===================================================================
--- trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/messages.properties 2010-01-02 20:25:50 UTC (rev 7050)
+++ trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/messages.properties 2010-01-03 04:32:29 UTC (rev 7051)
@@ -45,16 +45,36 @@
preference.ruleset.label.rulepropstable = Rule properties
preference.ruleset.label.exclude_patterns_table = Exclude patterns
preference.ruleset.label.include_patterns_table = Include patterns
+preference.ruleset.label.rules_grouped_by = Rules grouped by
preference.ruleset.column.language = Language
+preference.ruleset.column.language.tooltip = Target language
+preference.ruleset.column.dataflow = DFA
+preference.ruleset.column.dataflow.tooltip = Dataflow analysis
+preference.ruleset.column.ruleset = Rule set
+preference.ruleset.column.ruleset.tooltip = Current rule set
preference.ruleset.column.ruleset_name = Rule set name
preference.ruleset.column.rule_name = Rule name
+preference.ruleset.column.rule_type = Type
+preference.ruleset.column.rule_type.tooltip = Rule type:\n X = XPath\n D = dataflow\n T = type resolving
+preference.ruleset.column.min_ver = Min ver
+preference.ruleset.column.min_ver.tooltip = Minimum applicable language version
+preference.ruleset.column.filters = Filters
+preference.ruleset.column.filters.tooltip = Filters by color code
preference.ruleset.column.since = Since
+preference.ruleset.column.since.tooltip = Incorporation within PMD
preference.ruleset.column.priority = Priority
+preference.ruleset.column.priority.tooltip = Relative priority
preference.ruleset.column.description = Description
preference.ruleset.column.property = Property
+preference.ruleset.column.properties = Properties
+preference.ruleset.column.properties.tooltip = Current rule properties in short form
preference.ruleset.column.value = Value
+preference.ruleset.column.url = URL
preference.ruleset.column.exclude_pattern = Exclude Pattern
preference.ruleset.column.include_pattern = Include Pattern
+preference.ruleset.grouping.none = <no grouping>
+preference.ruleset.grouping.pmd_version = PMD version
+preference.ruleset.grouping.regex = Regex filter
preference.ruleset.button.addrule = Add rule...
preference.ruleset.button.removerule = Remove rule
preference.ruleset.button.editrule = Edit rule...
@@ -75,6 +95,16 @@
preference.rulesetselection.button.reference = Import by Reference
preference.rulesetselection.button.copy = Import by Copy
+preference.ruleedit.tab.properties = Properties
+preference.ruleedit.tab.description = Description
+preference.ruleedit.tab.filters = Filters
+preference.ruleedit.tab.xpath = XPath
+preference.ruleedit.tab.examples = Examples
+
+preference.ruleedit.label.exclusion_regex = Exclusion regular expression
+preference.ruleedit.label.xpath_exclusion = XPath exclusion expression
+preference.ruleedit.label.colour_code = Color code
+
preference.ruleedit.label.ruleset_name = RuleSet name :
preference.ruleedit.label.since = Since :
preference.ruleedit.label.name = Rule name :
@@ -190,6 +220,8 @@
dialog.cpd.no_results.header = Copy/Paste detection results
dialog.cpd.no_results.body = CPD has now finished with no results.
+dialog.preferences.add_new_property = Add new property
+
# Monitor messages
monitor.job_title = Checking Code with PMD
monitor.begintask = PMD Processing...
Modified: trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/nls/StringKeys.java
===================================================================
--- trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/nls/StringKeys.java 2010-01-02 20:25:50 UTC (rev 7050)
+++ trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/nls/StringKeys.java 2010-01-03 04:32:29 UTC (rev 7051)
@@ -75,6 +75,7 @@
public static final String MSGKEY_PREF_GENERAL_DIALOG_BROWSE = "preference.pmd.dialog.browse";
public static final String MSGKEY_PREF_GENERAL_LABEL_LOG_LEVEL = "preference.pmd.label.log_level";
+ // TOOLTIP keys are not shown here...just append ".tooltip" to an existing key to see if you have one :)
public static final String MSGKEY_PREF_RULESET_TITLE = "preference.ruleset.title";
public static final String MSGKEY_PREF_RULESET_LIST = "preference.ruleset.list";
public static final String MSGKEY_PREF_RULESET_ADD = "preference.ruleset.add";
@@ -83,16 +84,26 @@
public static final String MSGKEY_PREF_RULESET_LABEL_RULEPROPSTABLE = "preference.ruleset.label.rulepropstable";
public static final String MSGKEY_PREF_RULESET_LABEL_EXCLUDE_PATTERNS_TABLE = "preference.ruleset.label.exclude_patterns_table";
public static final String MSGKEY_PREF_RULESET_LABEL_INCLUDE_PATTERNS_TABLE = "preference.ruleset.label.include_patterns_table";
+ public static final String MSGKEY_PREF_RULESET_COLUMN_DATAFLOW = "preference.ruleset.column.dataflow";
public static final String MSGKEY_PREF_RULESET_COLUMN_LANGUAGE = "preference.ruleset.column.language";
+ public static final String MSGKEY_PREF_RULESET_COLUMN_RULESET = "preference.ruleset.column.ruleset";
public static final String MSGKEY_PREF_RULESET_COLUMN_RULESET_NAME = "preference.ruleset.column.ruleset_name";
public static final String MSGKEY_PREF_RULESET_COLUMN_RULE_NAME = "preference.ruleset.column.rule_name";
+ public static final String MSGKEY_PREF_RULESET_COLUMN_RULE_TYPE = "preference.ruleset.column.rule_type";
public static final String MSGKEY_PREF_RULESET_COLUMN_SINCE = "preference.ruleset.column.since";
+ public static final String MSGKEY_PREF_RULESET_COLUMN_FILTERS = "preference.ruleset.column.filters";
+ public static final String MSGKEY_PREF_RULESET_COLUMN_MIN_VER = "preference.ruleset.column.minimum_version";
public static final String MSGKEY_PREF_RULESET_COLUMN_PRIORITY = "preference.ruleset.column.priority";
+ public static final String MSGKEY_PREF_RULESET_COLUMN_PROPERTIES = "preference.ruleset.column.properties";
public static final String MSGKEY_PREF_RULESET_COLUMN_DESCRIPTION = "preference.ruleset.column.description";
public static final String MSGKEY_PREF_RULESET_COLUMN_PROPERTY = "preference.ruleset.column.property";
public static final String MSGKEY_PREF_RULESET_COLUMN_VALUE = "preference.ruleset.column.value";
+ public static final String MSGKEY_PREF_RULESET_COLUMN_URL = "preference.ruleset.column.url";
public static final String MSGKEY_PREF_RULESET_COLUMN_EXCLUDE_PATTERN = "preference.ruleset.column.exclude_pattern";
public static final String MSGKEY_PREF_RULESET_COLUMN_INCLUDE_PATTERN = "preference.ruleset.column.include_pattern";
+ public static final String MSGKEY_PREF_RULESET_GROUPING_NONE = "preference.ruleset.grouping.none";
+ public static final String MSGKEY_PREF_RULESET_GROUPING_PMD_VERSION = "preference.ruleset.grouping.pmd_version";
+ public static final String MSGKEY_PREF_RULESET_GROUPING_REGEX = "preference.ruleset.grouping.regex";
public static final String MSGKEY_PREF_RULESET_BUTTON_ADDRULE = "preference.ruleset.button.addrule";
public static final String MSGKEY_PREF_RULESET_BUTTON_REMOVERULE = "preference.ruleset.button.removerule";
public static final String MSGKEY_PREF_RULESET_BUTTON_EDITRULE = "preference.ruleset.button.editrule";
@@ -106,6 +117,18 @@
public static final String MSGKEY_PREF_RULESET_DIALOG_TITLE = "preference.ruleset.dialog.title";
public static final String MSGKEY_PREF_RULESET_DIALOG_RULESET_DESCRIPTION = "preference.ruleset.dialog.ruleset_description";
public static final String MSGKEY_PREF_RULESET_DIALOG_PROPERTY_NAME = "preference.ruleset.dialog.property_name";
+
+ public static final String MSGKEY_PREF_RULESET_RULES_GROUPED_BY = "preference.ruleset.label.rules_grouped_by";
+
+ public static final String MSGKEY_PREF_RULESET_TAB_PROPERTIES = "preference.ruleedit.tab.properties";
+ public static final String MSGKEY_PREF_RULESET_TAB_DESCRIPTION = "preference.ruleedit.tab.description";
+ public static final String MSGKEY_PREF_RULESET_TAB_FILTERS = "preference.ruleedit.tab.filters";
+ public static final String MSGKEY_PREF_RULESET_TAB_XPATH = "preference.ruleedit.tab.xpath";
+ public static final String MSGKEY_PREF_RULESET_TAB_EXAMPLES = "preference.ruleedit.tab.examples";
+
+ public static final String MSGKEY_LABEL_XPATH_EXCLUSION = "preference.ruleedit.label.xpath_exclusion";
+ public static final String MSGKEY_LABEL_EXCLUSION_REGEX = "preference.ruleedit.label.exclusion_regex";
+ public static final String MSGKEY_LABEL_COLOUR_CODE = "preference.ruleedit.label.colour_code";
public static final String MSGKEY_PREF_RULESETSELECTION_LABEL_ENTER_RULESET = "preference.rulesetselection.label.enter_ruleset";
public static final String MSGKEY_PREF_RULESETSELECTION_TOOLTIP_RULESET = "preference.rulesetselection.tooltip.ruleset";
@@ -212,6 +235,9 @@
public static final String MSGKEY_VIEW_MENU_PACKFILES = "view.menu.show_pack_files";
public static final String MSGKEY_VIEW_MENU_PRESENTATION_TYPE = "view.menu.show_type";
+ public static final String MSGKEY_DIALOG_PREFS_ADD_NEW_PROPERTY = "dialog.preferences.add_new_property";
+
+
public static final String MSGKEY_DIALOG_CPD_TITLE = "dialog.cpd.title";
public static final String MSGKEY_DIALOG_CPD_MIN_TILESIZE_LABEL = "dialog.cpd.min_tilesize.label";
public static final String MSGKEY_DIALOG_CPD_CREATEREPORT = "dialog.cpd.create_report";
Modified: trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/AbstractRuleColumnDescriptor.java
===================================================================
--- trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/AbstractRuleColumnDescriptor.java 2010-01-02 20:25:50 UTC (rev 7050)
+++ trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/AbstractRuleColumnDescriptor.java 2010-01-03 04:32:29 UTC (rev 7051)
@@ -1,7 +1,7 @@
package net.sourceforge.pmd.eclipse.ui.preferences.br;
import net.sourceforge.pmd.Rule;
-import net.sourceforge.pmd.eclipse.plugin.PMDPlugin;
+import net.sourceforge.pmd.eclipse.ui.preferences.editors.SWTUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Event;
@@ -9,9 +9,16 @@
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
+/**
+ * Retains all values necessary to hydrate a table column for holding a set of rules. Invoke the buildTreeColumn()
+ * method to constitute one. As descriptors they can be held as static items since they they're immutable.
+ *
+ * @author Brian Remedios
+ */
public abstract class AbstractRuleColumnDescriptor implements RuleColumnDescriptor {
private String label;
+ private String tooltip;
private int alignment;
private int width;
private RuleFieldAccessor accessor;
@@ -20,17 +27,14 @@
protected AbstractRuleColumnDescriptor(String labelKey, int theAlignment, int theWidth, RuleFieldAccessor theAccessor, boolean resizableFlag) {
super();
- label = stringFor(labelKey);
+ label = SWTUtil.stringFor(labelKey);
+ tooltip = SWTUtil.tooltipFor(labelKey);
alignment = theAlignment;
width = theWidth;
accessor = theAccessor;
isResizable = resizableFlag;
}
- protected static String stringFor(String key) {
- return PMDPlugin.getDefault().getStringTable().getString(key);
- }
-
protected TreeColumn buildTreeColumn(Tree parent, final RuleSortListener sortListener) {
final TreeColumn tc = new TreeColumn(parent, alignment);
@@ -53,5 +57,7 @@
public String label() { return label; }
+ public String tooltip() { return tooltip; }
+
public RuleFieldAccessor accessor() { return accessor; }
}
\ No newline at end of file
Modified: trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/CellPainterBuilder.java
===================================================================
--- trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/CellPainterBuilder.java 2010-01-02 20:25:50 UTC (rev 7050)
+++ trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/CellPainterBuilder.java 2010-01-03 04:32:29 UTC (rev 7051)
@@ -5,7 +5,10 @@
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Tree;
-
+/**
+ *
+ * @author Brian Remedios
+ */
public interface CellPainterBuilder {
void addPainterFor(Tree tree, int columnIndex, RuleFieldAccessor getter, Map<Integer, List<Listener>> listenersByEventCode);
Modified: trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/ImageColumnDescriptor.java
===================================================================
--- trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/ImageColumnDescriptor.java 2010-01-02 20:25:50 UTC (rev 7050)
+++ trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/ImageColumnDescriptor.java 2010-01-03 04:32:29 UTC (rev 7051)
@@ -5,6 +5,7 @@
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.eclipse.ui.PMDUiConstants;
+import net.sourceforge.pmd.eclipse.ui.nls.StringKeys;
import net.sourceforge.pmd.eclipse.util.ResourceManager;
import net.sourceforge.pmd.eclipse.util.Util;
@@ -22,9 +23,9 @@
private String imagePath;
private CellPainterBuilder painterBuilder;
-
- public static final RuleColumnDescriptor filterExpression = new ImageColumnDescriptor("Filters", SWT.LEFT, 25, RuleFieldAccessor.violationRegex, false, PMDUiConstants.ICON_FILTER, Util.regexBuilderFor(16, 16));
+ public static final RuleColumnDescriptor filterExpression = new ImageColumnDescriptor(StringKeys.MSGKEY_PREF_RULESET_COLUMN_FILTERS, SWT.LEFT, 25, RuleFieldAccessor.violationRegex, false, PMDUiConstants.ICON_FILTER, Util.regexBuilderFor(16, 16));
+
public ImageColumnDescriptor(String labelKey, int theAlignment, int theWidth, RuleFieldAccessor theAccessor, boolean resizableFlag, String theImagePath, CellPainterBuilder thePainterBuilder) {
super(labelKey, theAlignment, theWidth, theAccessor, resizableFlag);
@@ -38,7 +39,7 @@
*/
public TreeColumn newTreeColumnFor(Tree parent, int columnIndex, final RuleSortListener sortListener, Map<Integer, List<Listener>> paintListeners) {
TreeColumn tc = buildTreeColumn(parent, sortListener);
- tc.setToolTipText(label());
+ tc.setToolTipText(tooltip());
if (imagePath != null) tc.setImage(ResourceManager.imageFor(imagePath));
if (painterBuilder != null) painterBuilder.addPainterFor(tc.getParent(), columnIndex, accessor(), paintListeners);
return tc;
Copied: trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/NewPropertyDialog.java (from rev 7049, trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/PropertyDialog.java)
===================================================================
--- trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/NewPropertyDialog.java (rev 0)
+++ trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/NewPropertyDialog.java 2010-01-03 04:32:29 UTC (rev 7051)
@@ -0,0 +1,457 @@
+package net.sourceforge.pmd.eclipse.ui.preferences.br;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import net.sourceforge.pmd.PropertyDescriptor;
+import net.sourceforge.pmd.Rule;
+import net.sourceforge.pmd.eclipse.plugin.PMDPlugin;
+import net.sourceforge.pmd.eclipse.ui.nls.StringKeys;
+import net.sourceforge.pmd.eclipse.ui.preferences.editors.MethodEditorFactory;
+import net.sourceforge.pmd.eclipse.ui.preferences.editors.SWTUtil;
+import net.sourceforge.pmd.eclipse.util.Util;
+import net.sourceforge.pmd.lang.rule.XPathRule;
+import net.sourceforge.pmd.util.StringUtil;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+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.graphics.Color;
+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.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Implements a dialog for adding or editing a rule property. As the user changes the specified
+ * type, each type's associated editor factory will provide additional labels & widgets intended
+ * to capture other metadata.
+ *
+ * @author Brian Remedios
+ */
+public class NewPropertyDialog extends Dialog implements SizeChangeListener {
+
+ private Text nameField;
+ private Text labelField;
+ private Combo typeField;
+ private Control[] factoryControls;
+ private Composite dlgArea;
+ private EditorFactory factory;
+ private ValueChangeListener changeListener;
+
+ private Rule rule;
+ private PropertyDescriptor<?> descriptor;
+ private Map<Class<?>, EditorFactory> editorFactoriesByValueType;
+
+ private Color textColour = new Color(null, 0, 0, 0);
+ private Color textErrorColour = new Color(null, 255, 0, 0);
+
+ // these are the ones we've tested, the others may work but might not make sense in the xpath source context...
+ private static final Class<?>[] validEditorTypes = new Class[] { String.class, Integer.class, Boolean.class };
+ private static final Class<?> defaultEditorType = validEditorTypes[0]; // first one
+
+ private static final String INITIAL_NAME = "a unique name"; //
+ private static final String INITIAL_DESC = "a description"; //
+
+ public static Map<Class<?>, EditorFactory> withOnly(Map<Class<?>, EditorFactory> factoriesByType, Class<?>[] legalTypeKeys) {
+ Map<Class<?>, EditorFactory> results = new HashMap<Class<?>, EditorFactory>(legalTypeKeys.length);
+
+ for (Class<?> type : legalTypeKeys) {
+ if (factoriesByType.containsKey(type)) {
+ results.put(type, factoriesByType.get(type));
+ }
+ }
+ return results;
+ }
+
+ /**
+ * Constructor for RuleDialog. Supply a working descriptor with name & description values we expect the user to change.
+ *
+ * @param parentdlgArea
+ */
+ public NewPropertyDialog(Shell parent, Map<Class<?>, EditorFactory> theEditorFactoriesByValueType, Rule theRule, ValueChangeListener theChangeListener) {
+ super(parent);
+
+ setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX | SWT.APPLICATION_MODAL);
+
+ rule = theRule;
+ changeListener = theChangeListener;
+ editorFactoriesByValueType = withOnly(theEditorFactoriesByValueType, validEditorTypes);
+ }
+
+ /**
+ * Constructor for RuleDialog.
+ *
+ * @param parentdlgArea
+ */
+ public NewPropertyDialog(Shell parent, Map<Class<?>, EditorFactory> theEditorFactoriesByValueType, Rule theRule, PropertyDescriptor<?> theDescriptor, ValueChangeListener theChangeListener) {
+ this(parent, theEditorFactoriesByValueType, theRule, theChangeListener);
+
+ descriptor = theDescriptor;
+ }
+
+ public boolean close() {
+
+ textColour.dispose();
+ textErrorColour.dispose();
+
+ return super.close();
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite)
+ */
+ @Override
+ protected Control createDialogArea(Composite parent) {
+
+ parent.setLayoutData(new GridData(GridData.FILL_BOTH));
+ getShell().setText(SWTUtil.stringFor(StringKeys.MSGKEY_DIALOG_PREFS_ADD_NEW_PROPERTY));
+
+ dlgArea = new Composite(parent, SWT.NULL);
+ GridLayout layout = new GridLayout(2, false);
+ layout.verticalSpacing = 2;
+ layout.marginTop = 1;
+ dlgArea.setLayout(layout);
+ dlgArea.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ buildLabel(dlgArea, "Name:"); nameField = buildNameText(dlgArea); // TODO i18l label
+ buildLabel(dlgArea, "Datatype:"); typeField = buildTypeField(dlgArea); // TODO i18l label
+ buildLabel(dlgArea, "Label:"); labelField = buildLabelField(dlgArea); // TODO i18l label
+
+ setPreferredName();
+ setInitialType();
+
+ validateForm(false);
+
+ dlgArea.pack();
+
+ return dlgArea;
+ }
+
+ /**
+ * Build a label
+ */
+ private Label buildLabel(Composite parent, String msgKey) {
+ Label label = new Label(parent, SWT.NONE);
+ label.setText(msgKey == null ? "" : SWTUtil.stringFor(msgKey));
+ return label;
+ }
+
+ /**
+ * Build the rule name text
+ */
+ private Text buildNameText(Composite parent) {
+
+ final Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
+ GridData data = new GridData();
+ data.horizontalSpan = 1;
+ data.horizontalAlignment = GridData.FILL;
+ data.grabExcessHorizontalSpace = true;
+ text.setLayoutData(data);
+
+ text.addListener(SWT.Modify, new Listener() {
+ public void handleEvent(Event event) {
+ nameChanged(text);
+ }
+ });
+
+ return text;
+ }
+
+ private boolean isValidNewName(String nameCandidate) {
+ if (StringUtil.isEmpty(nameCandidate)) return false;
+ return rule.getPropertyDescriptor(nameCandidate) == null;
+ }
+
+ private static boolean isValidJavaIdentifier(String candidateName) {
+
+ if (!Character.isJavaIdentifierStart(candidateName.charAt(0))) {
+ return false;
+ }
+
+ for (int i=1; i<candidateName.length(); i++) {
+ char ch = candidateName.charAt(i);
+ if (Character.isJavaIdentifierPart(ch)) continue;
+ return false;
+ }
+ return true;
+ }
+
+ private boolean isValidNewLabel(String labelCandidate) {
+
+ if (StringUtil.isEmpty(labelCandidate)) return false;
+ if (!isValidJavaIdentifier(labelCandidate)) return false;
+
+ for (PropertyDescriptor<?> desc : rule.getPropertyDescriptors()) {
+ if (desc.description().equalsIgnoreCase(labelCandidate)) return false;
+ }
+ return true;
+ }
+
+ private void nameChanged(Text textField) {
+ String newName = textField.getText().trim();
+ textField.setForeground(
+ isValidNewName(newName) ? textColour : textErrorColour
+ );
+ validateForm(false);
+ }
+
+ /**
+ * Build the rule name text
+ */
+ private Text buildLabelField(Composite parent) {
+
+ final Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
+ GridData data = new GridData();
+ data.horizontalSpan = 1;
+ data.horizontalAlignment = GridData.FILL;
+ data.grabExcessHorizontalSpace = true;
+ text.setLayoutData(data);
+
+ text.addListener(SWT.Modify, new Listener() {
+ public void handleEvent(Event event) {
+ labelChanged(text);
+ }
+ });
+
+ return text;
+ }
+
+ private void labelChanged(Text textField) {
+ String newLabel = textField.getText().trim();
+ textField.setForeground(
+ isValidNewLabel(newLabel) ? textColour : textErrorColour
+ );
+ validateForm(false);
+ }
+
+ private static String labelFor(Class<?> type) {
+ return Util.signatureFor(type, MethodEditorFactory.UnwantedPrefixes);
+ }
+
+ /**
+ * A bit of a hack but this avoids the need to create an alternate lookup structure
+ *
+ * @param label
+ * @return
+ */
+ private EditorFactory factoryFor(String label) {
+
+ for (Entry<Class<?>, EditorFactory> entry : editorFactoriesByValueType.entrySet()) {
+ if (label.equals(
+ labelFor(entry.getKey())
+ )) return entry.getValue();
+ }
+
+ return null;
+ }
+
+ /**
+ * Build the rule name text
+ */
+ private Combo buildTypeField(final Composite parent) {
+
+ final Combo combo = new Combo(parent, SWT.READ_ONLY);
+ GridData data = new GridData();
+ data.grabExcessHorizontalSpace = true;
+ data.horizontalAlignment = GridData.FILL;
+ combo.setLayoutData(data);
+
+ String[] labels = new String[editorFactoriesByValueType.size()];
+ int i=0;
+ for (Entry<Class<?>, EditorFactory> entry : editorFactoriesByValueType.entrySet()) {
+ labels[i++] = labelFor(entry.getKey());
+ }
+ Arrays.sort(labels);
+ combo.setItems(labels);
+
+ combo.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ int selectionIdx = combo.getSelectionIndex();
+ EditorFactory factory = factoryFor(combo.getItem(selectionIdx));
+
+ factory( factory );
+ }
+ });
+
+ return combo;
+ }
+
+ private boolean ruleHasPropertyName(String name) {
+ return rule.getPropertyDescriptor(name) != null;
+ }
+
+ /**
+ * Pick the first name in the xpath source the rule doesn't know about
+ */
+ private void setPreferredName() {
+
+ String xpath = rule.getProperty(XPathRule.XPATH_DESCRIPTOR).trim();
+ List<int[]> positions = Util.referencedNamePositionsIn(xpath, '$');
+ List<String> names = Util.fragmentsWithin(xpath, positions);
+
+ for (String name : names) {
+ if (ruleHasPropertyName(name)) continue;
+ nameField.setText(name);
+ return;
+ }
+ nameField.setText(INITIAL_NAME);
+ }
+
+ private void setInitialType() {
+
+ String editorLabel = labelFor(defaultEditorType);
+ typeField.select( Util.indexOf(typeField.getItems(), editorLabel) );
+ factory( factoryFor(editorLabel));
+ }
+
+ private void cleanFactoryStuff() {
+ if (factoryControls != null) for (Control control : factoryControls) control.dispose();
+ }
+
+ private void factory(EditorFactory theFactory) {
+
+ factory = theFactory;
+
+ descriptor = factory.createDescriptor("??", INITIAL_DESC, null);
+ labelField.setText(descriptor.description());
+ cleanFactoryStuff();
+
+ factoryControls = factory.createOtherControlsOn(dlgArea, descriptor, rule, changeListener, this);
+
+ dlgArea.pack();
+ dlgArea.getParent().pack();
+ }
+
+// /**
+// * Helper method to shorten message access
+// *
+// * @param key a message key
+// * @return requested message
+// */
+// private String getMessage(String key) {
+// return PMDPlugin.getDefault().getStringTable().getString(key);
+// }
+
+ /**
+ * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+ */
+ @Override
+ protected void okPressed() {
+ if (validateForm(true) ) {
+ descriptor = newDescriptor();
+ super.okPressed();
+ }
+ }
+
+ /**
+ * Perform the form validation
+ */
+ private boolean validateForm(boolean showErrorMessages) {
+ boolean isOk = validateName(showErrorMessages) && validateLabel(showErrorMessages);
+ Control button = getButton(IDialogConstants.OK_ID);
+ // if (button != null) button.setEnabled(isOk);
+ return isOk;
+ }
+
+ /**
+ * Perform the name validation
+ */
+ private boolean validateName(boolean showErrorMessages) {
+
+ String name = nameField.getText().trim();
+
+ if (StringUtil.isEmpty(name)) {
+ if (showErrorMessages) MessageDialog.openWarning(getShell(),
+ SWTUtil.stringFor(StringKeys.MSGKEY_WARNING_TITLE),
+ SWTUtil.stringFor(StringKeys.MSGKEY_WARNING_NAME_MANDATORY));
+ nameField.setFocus();
+ return false;
+ }
+
+ if (ruleHasPropertyName(name)) {
+ if (showErrorMessages) MessageDialog.openWarning(getShell(),
+ SWTUtil.stringFor(StringKeys.MSGKEY_WARNING_TITLE),
+ "'" + name + "' is already used by another property"
+ );
+ nameField.setFocus();
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Perform the label validation
+ */
+ private boolean validateLabel(boolean showErrorMessages) {
+
+ String label = labelField.getText().trim();
+
+ if (StringUtil.isEmpty(label)) {
+ if (showErrorMessages) MessageDialog.openWarning(getShell(),
+ SWTUtil.stringFor(StringKeys.MSGKEY_WARNING_TITLE),
+ "A proper label is required"
+ );
+ labelField.setFocus();
+ return false;
+ }
+
+ if (!isValidNewLabel(label)) {
+ if (showErrorMessages) MessageDialog.openWarning(getShell(),
+ SWTUtil.stringFor(StringKeys.MSGKEY_WARNING_TITLE),
+ "Label text must differ from other label text"
+ );
+ labelField.setFocus();
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the descriptor.
+ *
+ * @return PropertyDescriptor
+ */
+ public PropertyDescriptor<?> descriptor() {
+ return descriptor;
+ }
+
+ private PropertyDescriptor<?> newDescriptor() {
+
+ return factory.createDescriptor(
+ nameField.getText().trim(),
+ labelField.getText().trim(),
+ factoryControls
+ );
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
+ */
+ @Override
+ protected void cancelPressed() {
+ // courierFont.dispose();
+ super.cancelPressed();
+ }
+
+ public void addedRows(int newRowCount) {
+ dlgArea.pack();
+ dlgArea.getParent().pack();
+
+ System.out.println("rows added: " + newRowCount);
+ }
+}
Modified: trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/PMDPreferencePage.java
===================================================================
--- trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/PMDPreferencePage.java 2010-01-02 20:25:50 UTC (rev 7050)
+++ trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/PMDPreferencePage.java 2010-01-03 04:32:29 UTC (rev 7051)
@@ -105,19 +105,19 @@
TextColumnDescriptor.ruleType,
TextColumnDescriptor.minLangVers,
TextColumnDescriptor.language,
- ImageColumnDescriptor.filterExpression, // regex text -> compact color dots (for comparison)
+ ImageColumnDescriptor.filterExpression, // regex text -> compact color squares (for comparison)
TextColumnDescriptor.properties,
};
// last item in this list is the grouping used at startup
private static final Object[][] groupingChoices = new Object[][] {
- { TextColumnDescriptor.ruleSetName, "Rule set" }, // TODO i18l
- { TextColumnDescriptor.since, "PMD version" },
- { TextColumnDescriptor.priorityName, "Priority" },
- { TextColumnDescriptor.ruleType, "Type" },
- { TextColumnDescriptor.language, "Language" },
- { ImageColumnDescriptor.filterExpression, "Regex filter" },
- { null, "<no grouping>" }
+ { TextColumnDescriptor.ruleSetName, StringKeys.MSGKEY_PREF_RULESET_COLUMN_RULESET},
+ { TextColumnDescriptor.since, StringKeys.MSGKEY_PREF_RULESET_GROUPING_PMD_VERSION },
+ { TextColumnDescriptor.priorityName, StringKeys.MSGKEY_PREF_RULESET_COLUMN_PRIORITY },
+ { TextColumnDescriptor.ruleType, StringKeys.MSGKEY_PREF_RULESET_COLUMN_RULE_TYPE },
+ { TextColumnDescriptor.language, StringKeys.MSGKEY_PREF_RULESET_COLUMN_LANGUAGE },
+ { ImageColumnDescriptor.filterExpression, StringKeys.MSGKEY_PREF_RULESET_GROUPING_REGEX },
+ { null, StringKeys.MSGKEY_PREF_RULESET_GROUPING_NONE }
};
// properties that should not be shown in the PerRuleProperty page
@@ -177,12 +177,8 @@
private Map<String, MenuItem> rulesetMenusByName;
private boolean modified = false;
- private static PMDPlugin plugin = PMDPlugin.getDefault();
+ private static PMDPlugin plugin = PMDPlugin.getDefault();
- private static String stringFor(String key) {
- return plugin.getStringTable().getString(key);
- }
-
/**
* @see IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
*/
@@ -235,7 +231,7 @@
Composite ruleSection = new Composite(parent, SWT.NULL);
// Create the controls (order is important !)
- Composite groupCombo = buildGroupCombo(ruleSection, "Rules grouped by ");
+ Composite groupCombo = buildGroupCombo(ruleSection, StringKeys.MSGKEY_PREF_RULESET_RULES_GROUPED_BY);
Tree ruleTree = buildRuleTreeViewer(ruleSection);
groupBy(null);
@@ -374,7 +370,7 @@
groupBy(groupingColumn);
}
- private Composite buildGroupCombo(Composite parent, String comboLabel) {
+ private Composite buildGroupCombo(Composite parent, String comboLabelKey) {
Composite panel = new Composite(parent, 0);
GridLayout layout = new GridLayout(2, false);
@@ -385,10 +381,10 @@
data.horizontalAlignment = SWT.LEFT;
data.verticalAlignment = SWT.CENTER;
label.setLayoutData(data);
- label.setText(comboLabel);
+ label.setText(SWTUtil.stringFor(comboLabelKey));
final Combo combo = new Combo(panel, SWT.READ_ONLY);
- combo.setItems(SWTUtil.labelsIn(groupingChoices, 1));
+ combo.setItems(SWTUtil.i18lLabelsIn(groupingChoices, 1));
combo.select(groupingChoices.length - 1); // picks last one by default TODO make it a persistent preference
combo.addSelectionListener(new SelectionAdapter() {
@@ -413,11 +409,11 @@
tabFolder = new TabFolder(parent, SWT.TOP);
rulePropertyManagers = new RulePropertyManager[] {
- buildPropertyTab(tabFolder, 0, "Properties"),
- buildDescriptionTab(tabFolder, 1, stringFor(StringKeys.MSGKEY_PREF_RULESET_COLUMN_DESCRIPTION)),
- buildUsageTab(tabFolder, 2, "Filters"),
- buildXPathTab(tabFolder, 3, "XPath"),
- buildExampleTab(tabFolder, 4, "Examples")
+ buildPropertyTab(tabFolder, 0, SWTUtil.stringFor(StringKeys.MSGKEY_PREF_RULESET_TAB_PROPERTIES)),
+ buildDescriptionTab(tabFolder, 1, SWTUtil.stringFor(StringKeys.MSGKEY_PREF_RULESET_TAB_DESCRIPTION)),
+ buildUsageTab(tabFolder, 2, SWTUtil.stringFor(StringKeys.MSGKEY_PREF_RULESET_TAB_FILTERS)),
+ buildXPathTab(tabFolder, 3, SWTUtil.stringFor(StringKeys.MSGKEY_PREF_RULESET_TAB_XPATH)),
+ buildExampleTab(tabFolder, 4, SWTUtil.stringFor(StringKeys.MSGKEY_PREF_RULESET_TAB_EXAMPLES)),
};
tabFolder.pack();
@@ -507,15 +503,15 @@
tab.setControl(
manager.setupOn(
parent,
- "Exclusion regular expression",
- "XPath exclusion expression",
- "Color code "
+ SWTUtil.stringFor(StringKeys.MSGKEY_LABEL_EXCLUSION_REGEX),
+ SWTUtil.stringFor(StringKeys.MSGKEY_LABEL_XPATH_EXCLUSION),
+ SWTUtil.stringFor(StringKeys.MSGKEY_LABEL_COLOUR_CODE)
)
);
manager.tab(tab);
return manager;
}
-
+
/**
* Create buttons for rule table management
* @param parent Composite
@@ -641,7 +637,7 @@
Menu menu = new Menu(control);
MenuItem priorityMenu = new MenuItem (menu, SWT.CASCADE);
- priorityMenu.setText(stringFor(StringKeys.MSGKEY_PREF_RULESET_COLUMN_PRIORITY));
+ priorityMenu.setText(SWTUtil.stringFor(StringKeys.MSGKEY_PREF_RULESET_COLUMN_PRIORITY));
Menu subMenu = new Menu(menu);
priorityMenu.setMenu (subMenu);
priorityMenusByPriority = new HashMap<RulePriority, MenuItem>();
Deleted: trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/PropertyDialog.java
===================================================================
--- trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/PropertyDialog.java 2010-01-02 20:25:50 UTC (rev 7050)
+++ trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/PropertyDialog.java 2010-01-03 04:32:29 UTC (rev 7051)
@@ -1,438 +0,0 @@
-package net.sourceforge.pmd.eclipse.ui.preferences.br;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import net.sourceforge.pmd.PropertyDescriptor;
-import net.sourceforge.pmd.Rule;
-import net.sourceforge.pmd.eclipse.plugin.PMDPlugin;
-import net.sourceforge.pmd.eclipse.ui.nls.StringKeys;
-import net.sourceforge.pmd.eclipse.ui.preferences.editors.MethodEditorFactory;
-import net.sourceforge.pmd.eclipse.util.Util;
-import net.sourceforge.pmd.lang.rule.XPathRule;
-import net.sourceforge.pmd.util.StringUtil;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-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.graphics.Color;
-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.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Implements a dialog for adding or editing a rule property. As the user changes the specified
- * type, each type's associated editor factory will provide additional labels & widgets intended
- * to capture other metadata.
- *
- * @author Brian Remedios
- */
-public class PropertyDialog extends Dialog implements SizeChangeListener {
-
- private Text nameField;
- private Text labelField;
- private Combo typeField;
- private Control[] factoryControls;
- private Composite dlgArea;
- private EditorFactory factory;
- private ValueChangeListener changeListener;
-
- private Rule rule;
- private PropertyDescriptor<?> descriptor;
- private Map<Class<?>, EditorFactory> editorFactoriesByValueType;
-
- private Color textColour = new Color(null, 0, 0, 0);
- private Color textErrorColour = new Color(null, 255, 0, 0);
-
-
- // these are the ones we've tested, the others may work but might not make sense in the xpath source context...
- private static final Class<?>[] validEditorTypes = new Class[] { String.class, Integer.class, Boolean.class };
- private static final Class<?> defaultEditorType = validEditorTypes[0]; // first one
-
- public static Map<Class<?>, EditorFactory> withOnly(Map<Class<?>, EditorFactory> factoriesByType, Class<?>[] legalTypeKeys) {
- Map<Class<?>, EditorFactory> results = new HashMap<Class<?>, EditorFactory>(legalTypeKeys.length);
-
- for (Class<?> type : legalTypeKeys) {
- if (factoriesByType.containsKey(type)) {
- results.put(type, factoriesByType.get(type));
- }
- }
- return results;
- }
-
- /**
- * Constructor for RuleDialog.
- *
- * @param parentdlgArea
- */
- public PropertyDialog(Shell parent, Map<Class<?>, EditorFactory> theEditorFactoriesByValueType, Rule theRule, ValueChangeListener theChangeListener) {
- super(parent);
-
- setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX | SWT.APPLICATION_MODAL);
-
- rule = theRule;
- changeListener = theChangeListener;
- editorFactoriesByValueType = withOnly(theEditorFactoriesByValueType, validEditorTypes);
- }
-
- /**
- * Constructor for RuleDialog.
- *
- * @param parentdlgArea
- */
- public PropertyDialog(Shell parent, Map<Class<?>, EditorFactory> theEditorFactoriesByValueType, Rule theRule, PropertyDescriptor<?> theDescriptor, ValueChangeListener theChangeListener) {
- this(parent, theEditorFactoriesByValueType, theRule, theChangeListener);
-
- descriptor = theDescriptor;
- }
-
- public boolean close() {
-
- textColour.dispose();
- textErrorColour.dispose();
-
- return super.close();
- }
-
- /**
- * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite)
- */
- @Override
- protected Control createDialogArea(Composite parent) {
-
- parent.setLayoutData(new GridData(GridData.FILL_BOTH));
- // Set the window title
- getShell().setText("Add new property");
-
- dlgArea = new Composite(parent, SWT.NULL);
- GridLayout layout = new GridLayout(2, false);
- layout.verticalSpacing = 2;
- layout.marginTop = 1;
- dlgArea.setLayout(layout);
- dlgArea.setLayoutData(new GridData(GridData.FILL_BOTH));
-
- buildLabel(dlgArea, "Name:"); nameField = buildNameText(dlgArea);
- buildLabel(dlgArea, "Datatype:"); typeField = buildTypeField(dlgArea);
- buildLabel(dlgArea, "Label:"); labelField = buildLabelField(dlgArea);
-
- setPreferredName();
- setInitialType();
-
- validateForm(false);
-
- dlgArea.pack();
-
- return dlgArea;
- }
-
- /**
- * Build a label
- */
- private Label buildLabel(Composite parent, String msgKey) {
- Label label = new Label(parent, SWT.NONE);
- label.setText(msgKey == null ? "" : getMessage(msgKey));
- return label;
- }
-
- /**
- * Build the rule name text
- */
- private Text buildNameText(Composite parent) {
-
- final Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
- GridData data = new GridData();
- data.horizontalSpan = 1;
- data.horizontalAlignment = GridData.FILL;
- data.grabExcessHorizontalSpace = true;
- text.setLayoutData(data);
-
- text.addListener(SWT.Modify, new Listener() {
- public void handleEvent(Event event) {
- nameChanged(text);
- }
- });
-
- return text;
- }
-
- private boolean isValidNewName(String nameCandidate) {
- if (StringUtil.isEmpty(nameCandidate)) return false;
- return rule.getPropertyDescriptor(nameCandidate) == null;
- }
-
- private boolean isValidNewLabel(String labelCandidate) {
- if (StringUtil.isEmpty(labelCandidate)) return false;
- for (PropertyDescriptor<?> desc : rule.getPropertyDescriptors()) {
- if (desc.description().equalsIgnoreCase(labelCandidate)) return false;
- }
- return true;
- }
-
- private void nameChanged(Text textField) {
- String newName = textField.getText().trim();
- textField.setForeground(
- isValidNewName(newName) ? textColour : textErrorColour
- );
- validateForm(false);
- }
-
- /**
- * Build the rule name text
- */
- private Text buildLabelField(Composite parent) {
-
- final Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
- GridData data = new GridData();
- data.horizontalSpan = 1;
- data.horizontalAlignment = GridData.FILL;
- data.grabExcessHorizontalSpace = true;
- text.setLayoutData(data);
-
- text.addListener(SWT.Modify, new Listener() {
- public void handleEvent(Event event) {
- labelChanged(text);
- }
- });
-
- return text;
- }
-
- private void labelChanged(Text textField) {
- String newLabel = textField.getText().trim();
- textField.setForeground(
- isValidNewLabel(newLabel) ? textColour : textErrorColour
- );
- validateForm(false);
- }
-
- private static String labelFor(Class<?> type) {
- return Util.signatureFor(type, MethodEditorFactory.UnwantedPrefixes);
- }
-
- /**
- * A bit of a hack but this avoids the need to create an alternate lookup structure
- *
- * @param label
- * @return
- */
- private EditorFactory factoryFor(String label) {
-
- for (Entry<Class<?>, EditorFactory> entry : editorFactoriesByValueType.entrySet()) {
- if (label.equals(
- labelFor(entry.getKey())
- )) return entry.getValue();
- }
-
- return null;
- }
-
- /**
- * Build the rule name text
- */
- private Combo buildTypeField(final Composite parent) {
-
- final Combo combo = new Combo(parent, SWT.READ_ONLY);
- GridData data = new GridData();
- data.grabExcessHorizontalSpace = true;
- data.horizontalAlignment = GridData.FILL;
- combo.setLayoutData(data);
-
- String[] labels = new String[editorFactoriesByValueType.size()];
- int i=0;
- for (Entry<Class<?>, EditorFactory> entry : editorFactoriesByValueType.entrySet()) {
- labels[i++] = labelFor(entry.getKey());
- }
- Arrays.sort(labels);
- combo.setItems(labels);
-
- combo.addSelectionListener(new SelectionAdapter() {
- public void widgetSelected(SelectionEvent e) {
- int selectionIdx = combo.getSelectionIndex();
- EditorFactory factory = factoryFor(combo.getItem(selectionIdx));
-
- factory( factory );
- }
- });
-
- return combo;
- }
-
- private boolean ruleHasPropertyName(String name) {
- return rule.getPropertyDescriptor(name) != null;
- }
-
- /**
- * Pick the first name in the xpath source the rule doesn't know about
- */
- private void setPreferredName() {
-
- String xpath = rule.getProperty(XPathRule.XPATH_DESCRIPTOR).trim();
- List<int[]> positions = Util.referencedNamePositionsIn(xpath, '$');
- List<String> names = Util.fragmentsWithin(xpath, positions);
-
- for (String name : names) {
- if (ruleHasPropertyName(name)) continue;
- nameField.setText(name);
- return;
- }
- nameField.setText("a unique name");
- }
-
- private void setInitialType() {
-
- String editorLabel = labelFor(defaultEditorType);
- typeField.select( Util.indexOf(typeField.getItems(), editorLabel) );
- factory( factoryFor(editorLabel));
- }
-
- private void cleanFactoryStuff() {
- if (factoryControls != null) for (Control control : factoryControls) control.dispose();
- }
-
- private void factory(EditorFactory theFactory) {
-
- factory = theFactory;
-
- descriptor = factory.createDescriptor("??", "a description", null);
- labelField.setText(descriptor.description());
- cleanFactoryStuff();
-
- factoryControls = factory.createOtherControlsOn(dlgArea, descriptor, rule, changeListener, this);
-
- dlgArea.pack();
- dlgArea.getParent().pack();
- }
-
- /**
- * Helper method to shorten message access
- *
- * @param key a message key
- * @return requested message
- */
- private String getMessage(String key) {
- return PMDPlugin.getDefault().getStringTable().getString(key);
- }
-
- /**
- * @see org.eclipse.jface.dialogs.Dialog#okPressed()
- */
- @Override
- protected void okPressed() {
- if (validateForm(true) ) {
- descriptor = newDescriptor();
- super.okPressed();
- }
- }
-
- /**
- * Perform the form validation
- */
- private boolean validateForm(boolean showErrorMessages) {
- boolean isOk = validateName(showErrorMessages) && validateLabel(showErrorMessages);
- Control button = getButton(IDialogConstants.OK_ID);
- // if (button != null) button.setEnabled(isOk);
- return isOk;
- }
-
- /**
- * Perform the name validation
- */
- private boolean validateName(boolean showErrorMessages) {
-
- String name = nameField.getText().trim();
-
- if (StringUtil.isEmpty(name)) {
- if (showErrorMessages) MessageDialog.openWarning(getShell(),
- getMessage(StringKeys.MSGKEY_WARNING_TITLE),
- getMessage(StringKeys.MSGKEY_WARNING_NAME_MANDATORY));
- nameField.setFocus();
- return false;
- }
-
- if (ruleHasPropertyName(name)) {
- if (showErrorMessages) MessageDialog.openWarning(getShell(),
- getMessage(StringKeys.MSGKEY_WARNING_TITLE),
- "'" + name + "' is already used by another property"
- );
- nameField.setFocus();
- return false;
- }
-
- return true;
- }
-
- /**
- * Perform the label validation
- */
- private boolean validateLabel(boolean showErrorMessages) {
-
- String label = labelField.getText().trim();
-
- if (StringUtil.isEmpty(label)) {
- if (showErrorMessages) MessageDialog.openWarning(getShell(),
- getMessage(StringKeys.MSGKEY_WARNING_TITLE),
- "A proper label is required"
- );
- labelField.setFocus();
- return false;
- }
-
- if (!isValidNewLabel(label)) {
- if (showErrorMessages) MessageDialog.openWarning(getShell(),
- getMessage(StringKeys.MSGKEY_WARNING_TITLE),
- "Label text must differ from other label text"
- );
- labelField.setFocus();
- return false;
- }
-
- return true;
- }
-
- /**
- * Returns the descriptor.
- *
- * @return PropertyDescriptor
- */
- public PropertyDescriptor<?> descriptor() {
- return descriptor;
- }
-
- private PropertyDescriptor<?> newDescriptor() {
-
- return factory.createDescriptor(
- nameField.getText().trim(),
- labelField.getText().trim(),
- factoryControls
- );
- }
-
- /**
- * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
- */
- @Override
- protected void cancelPressed() {
- // courierFont.dispose();
- super.cancelPressed();
- }
-
- public void addedRows(int newRowCount) {
- dlgArea.pack();
- dlgArea.getParent().pack();
-
- System.out.println("rows added: " + newRowCount);
- }
-}
Modified: trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/RuleFieldAccessor.java
===================================================================
--- trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/RuleFieldAccessor.java 2010-01-02 20:25:50 UTC (rev 7050)
+++ trunk/pmd-eclipse-plugin/plugins/net.sourceforge.pmd.eclipse.plugin/src/net/sourceforge/pmd/eclipse/ui/preferences/br/RuleFieldAccessor.java 2010-01-03 04:32:29 UTC (rev 7051)
@@ -16,12 +16,17 @@
* Value returned are typed as comparable to facilitate sorting. Never return null,
* return an empty string instead.
*
- * TODO - move this to PMD proper, nothing UI-specific here
- *
* @author Brian Remedios
*/
public interface RuleFieldAccessor {
+ // NOTE: If you update these values then you also need to update
+ // the tooltip that references them: 'preference.ruleset.column.rule_type.tooltip'
+
+ String ruleTypeXPath[] = new String[] { "X", "XPath" };
+ String ruleTypeDFlow[] = new String[] { "D", "Dataflow" };
+ String ruleTypeTypeRes[]= new String[] { "T", "Type resolving" };
+
/**
* @param rule Rule
* @return Comparable
@@ -87,16 +92,16 @@
RuleFieldAccessor ruleType = new BasicRuleFieldAccessor() {
public Comparable<?> valueFor(Rule rule) {
StringBuilder sb = new StringBuilder(3);
- if (rule.hasDescriptor(XPathRule.XPATH_DESCRIPTOR)) sb.append('X');
- if (rule.usesDFA()) sb.append('D');
- if (rule.usesTypeResolution()) sb.append('T');
+ if (rule.hasDescriptor(XPathRule.XPATH_DESCRIPTOR)) sb.append(ruleTypeXPath[0]);
+ if (rule.usesDFA()) sb.append(ruleTypeDFlow[0]);
+ if (rule.usesTypeResolution()) sb.append(ruleTypeTypeRes[0]);
return sb.toString();
}
public String labelFor(Rule rule) {
List<String> types = new ArrayList<String>(3);
- if (rule.hasDescriptor(XPathRule.XPATH_DESCRIPTOR)) types.add("XPath");
- if (rule.usesDFA()) types.add("Dataflow");
- if (rule.usesTypeResolution()) types.add("Type resolving");
+ if (rule.hasDescriptor(XPathRule.XPATH_DESCRIPTOR)) types.add(ruleTypeXPath[1]);
+ if (rule.usesDFA()) types.add(ruleTypeDFlow[1]);
+ if (rule.usesTypeResolution()) types.add(ruleTypeTypeRes[1]);
return Util.asString(types, ", ");
}...
[truncated message content] |