blob: 75ea9ae23797935fd6cc28a52d5ae13364df65bf [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
// Based on version 1.12 of original xsdeditor
package org.eclipse.wst.xsd.ui.internal.wizards;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
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.Text;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.wst.xsd.ui.internal.XSDEditorContextIds;
import org.eclipse.wst.xsd.ui.internal.XSDEditorPlugin;
import org.eclipse.wst.xsd.ui.internal.util.ViewUtility;
import org.eclipse.xsd.XSDPatternFacet;
/*
-other regex features (eg case sensitivity, ^ or $, |, etc etc)
-smarter model
-better keyboard navigation
-update list of tokens
*/
public class RegexCompositionPage extends WizardPage
{
private static final boolean debug = false;
/* The text representation of our pattern. */
private StyledText value;
/* The StyleRange used to color code the current parse error. */
private StyleRange currentError;
/* The regex terms we can form tokens from. */
private Combo terms;
/* The checkbox for activating auto-escape mode. */
private Button escapeCheckbox;
/* On/off status of auto-escape mode. */
private boolean autoEscapeStatus;
/* The Add Token button. */
private Button add;
// The following controls are used in the occurrence selection group
private Text repeatValue;
private Text rangeMinValue;
private Text rangeMaxValue;
private Label rangeToLabel;
private Button singleRadio;
private Button starRadio;
private Button plusRadio;
private Button optionalRadio;
private Button repeatRadio;
private Button rangeRadio;
// The following variables used as part of the model.
/* Our pattern. */
private XSDPatternFacet pattern;
/* Model used to store the current token. */
private RegexNode node;
/* Validator from the xerces regex package. */
//private RegularExpression validator;
private Pattern validator;
/* The flags passed to the new RegularExpression object. Default value includes:
X = XMLSchema mode */
private String regexFlags = "X";
/* Is the current regex token valid? */
private boolean isValidToken;
/* The label used to indicate the value's caret position when it looses focus. */
private Label caretLabel;
/* The pixel offsets needed to align the label icon with the caret location.
These are dependent on the icon used. */
private static final int CARET_LABEL_X_OFFSET = -3;
private static final int CARET_LABEL_Y_OFFSET = 19;
/* Enumerated constants for specifying the type of an error message. */
private static final int TOKEN = 0;
private static final int SELECTION = 1;
private static final int PARSE = 2;
private static final int NUM_ERROR_MESSAGE_TYPES = 3;
/* The current error message for each type of error. A value of null indicates no message.
The array is indexed according to the above constants.
*/
private String[] currentErrorMessages;
public RegexCompositionPage(XSDPatternFacet pattern)
{
super(XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_COMPOSITION_PAGE_TITLE"));
this.pattern = pattern;
setTitle(XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_COMPOSITION_PAGE_TITLE"));
setDescription(XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_COMPOSITION_PAGE_DESCRIPTION"));
}
public void createControl(Composite parent)
{
// Set up our model and validator
node = new RegexNode();
// validator = new RegularExpression("", regexFlags);
isValidToken = true;
currentErrorMessages = new String[NUM_ERROR_MESSAGE_TYPES];
// The main composite
Composite composite= new Composite(parent, SWT.NONE);
WorkbenchHelp.setHelp(composite, XSDEditorContextIds.XSDR_COMPOSITION_PAGE);
composite.setLayout(new GridLayout());
// The composite for the token combo box, label, and auto-escape checkbox
Composite tokenComposite = new Composite (composite, SWT.NONE);
GridLayout tokenCompositeLayout = new GridLayout();
tokenCompositeLayout.numColumns = 3;
tokenCompositeLayout.marginWidth = 0;
tokenComposite.setLayout(tokenCompositeLayout);
new Label(tokenComposite, SWT.LEFT).setText(XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_TOKEN_LABEL"));
terms = new Combo(tokenComposite, SWT.DROP_DOWN);
WorkbenchHelp.setHelp(terms, XSDEditorContextIds.XSDR_COMPOSITION_TOKEN);
for (int i = 0; i < RegexNode.getNumRegexTerms(); i++)
{
terms.add(RegexNode.getRegexTermText(i));
}
terms.addListener(SWT.Modify, new ComboListener());
terms.setToolTipText(XSDEditorPlugin.getXSDString("_UI_TOOLTIP_REGEX_WIZARD_TERMS"));
escapeCheckbox = new Button(tokenComposite, SWT.CHECK);
escapeCheckbox.setText(XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_AUTO_ESCAPE_CHECKBOX_LABEL"));
escapeCheckbox.setToolTipText(XSDEditorPlugin.getXSDString("_UI_TOOLTIP_REGEX_WIZARD_AUTO_ESCAPE_CHECKBOX"));
escapeCheckbox.addSelectionListener(new CheckboxListener());
autoEscapeStatus = false;
tokenComposite.pack();
// Set up the composites pertaining to the selection of occurrence quantifiers
Group occurrenceSelectionArea = new Group(composite, SWT.NONE);
occurrenceSelectionArea.setText(XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_OCCURENCE_LABEL"));
WorkbenchHelp.setHelp(occurrenceSelectionArea, XSDEditorContextIds.XSDR_COMPOSITION_OCCURRENCE_GROUP);
GridLayout selectionAreaLayout = new GridLayout();
selectionAreaLayout.numColumns = 2;
occurrenceSelectionArea.setLayout(selectionAreaLayout);
// Listener used for all of the text fields
TextListener textListener = new TextListener();
// Add the radio buttons
RadioSelectListener radioSelectListener = new RadioSelectListener();
singleRadio = addOccurenceRadioButton(RegexNode.SINGLE, occurrenceSelectionArea, radioSelectListener);
WorkbenchHelp.setHelp(singleRadio, XSDEditorContextIds.XSDR_COMPOSITION_JUST_ONCE);
ViewUtility.createHorizontalFiller(occurrenceSelectionArea, 1);
starRadio = addOccurenceRadioButton(RegexNode.STAR, occurrenceSelectionArea, radioSelectListener);
WorkbenchHelp.setHelp(starRadio, XSDEditorContextIds.XSDR_COMPOSITION_ZERO_OR_MORE);
ViewUtility.createHorizontalFiller(occurrenceSelectionArea, 1);
plusRadio = addOccurenceRadioButton(RegexNode.PLUS, occurrenceSelectionArea, radioSelectListener);
WorkbenchHelp.setHelp(plusRadio, XSDEditorContextIds.XSDR_COMPOSITION_ONE_OR_MORE);
ViewUtility.createHorizontalFiller(occurrenceSelectionArea, 1);
optionalRadio = addOccurenceRadioButton(RegexNode.OPTIONAL, occurrenceSelectionArea, radioSelectListener);
WorkbenchHelp.setHelp(optionalRadio, XSDEditorContextIds.XSDR_COMPOSITION_OPTIONAL);
ViewUtility.createHorizontalFiller(occurrenceSelectionArea, 1);
repeatRadio = addOccurenceRadioButton(RegexNode.REPEAT, occurrenceSelectionArea, radioSelectListener);
WorkbenchHelp.setHelp(repeatRadio, XSDEditorContextIds.XSDR_COMPOSITION_REPEAT);
// Add text field for specifying number of repeats
Composite repeatWidgets = new Composite(occurrenceSelectionArea, SWT.NONE);
RowLayout repeatWidgetsLayout = new RowLayout();
repeatWidgetsLayout.marginTop = 0;
repeatWidgetsLayout.marginBottom = 0;
repeatWidgetsLayout.marginLeft = 0;
repeatWidgetsLayout.marginRight = 0;
repeatWidgets.setLayout(repeatWidgetsLayout);
repeatValue = new Text(repeatWidgets, SWT.SINGLE | SWT.BORDER);
repeatValue.addListener(SWT.Modify, textListener);
WorkbenchHelp.setHelp(repeatValue, XSDEditorContextIds.XSDR_COMPOSITION_REPEAT_TEXT);
repeatValue.setToolTipText(XSDEditorPlugin.getXSDString("_UI_TOOLTIP_REGEX_WIZARD_REPEAT"));
setEnabledStatus(RegexNode.REPEAT, false);
repeatWidgets.pack();
rangeRadio = addOccurenceRadioButton(RegexNode.RANGE, occurrenceSelectionArea, radioSelectListener);
WorkbenchHelp.setHelp(rangeRadio, XSDEditorContextIds.XSDR_COMPOSITION_RANGE);
// Add text fields and labels for specifying the range
Composite rangeWidgets = new Composite(occurrenceSelectionArea, SWT.NONE);
RowLayout rangeWidgetsLayout = new RowLayout();
rangeWidgetsLayout.marginTop = 0;
rangeWidgetsLayout.marginBottom = 0;
rangeWidgetsLayout.marginLeft = 0;
rangeWidgetsLayout.marginRight = 0;
rangeWidgets.setLayout(rangeWidgetsLayout);
rangeMinValue = new Text(rangeWidgets, SWT.SINGLE | SWT.BORDER);
rangeMinValue.addListener(SWT.Modify, textListener);
WorkbenchHelp.setHelp(rangeMinValue, XSDEditorContextIds.XSDR_COMPOSITION_RANGE_MIN);
rangeMinValue.setToolTipText(XSDEditorPlugin.getXSDString("_UI_TOOLTIP_REGEX_WIZARD_MIN"));
rangeToLabel = new Label(rangeWidgets, SWT.NONE);
rangeToLabel.setText(XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_TO_LABEL"));
rangeMaxValue = new Text(rangeWidgets, SWT.SINGLE | SWT.BORDER);
rangeMaxValue.addListener(SWT.Modify, textListener);
rangeMaxValue.setToolTipText(XSDEditorPlugin.getXSDString("_UI_TOOLTIP_REGEX_WIZARD_MAX"));
WorkbenchHelp.setHelp(rangeMaxValue, XSDEditorContextIds.XSDR_COMPOSITION_RANGE_MAX);
setEnabledStatus(RegexNode.RANGE, false);
rangeWidgets.pack();
singleRadio.setSelection(true);
occurrenceSelectionArea.pack();
// The add button
add = new Button(composite, SWT.PUSH);
add.addSelectionListener(new ButtonSelectListener());
add.setText(XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_ADD_BUTTON_LABEL"));
WorkbenchHelp.setHelp(add, XSDEditorContextIds.XSDR_COMPOSITION_ADD);
add.setToolTipText(XSDEditorPlugin.getXSDString("_UI_TOOLTIP_REGEX_WIZARD_ADD_BUTTON"));
Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
// Our main text box
Label valueLabel= new Label(composite, SWT.LEFT);
valueLabel.setText(XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_CURRENT_REGEX_LABEL"));
value = new StyledText(composite, SWT.SINGLE | SWT.BORDER);
value.addListener(SWT.Modify, textListener);
value.addListener(SWT.Selection, textListener);
WorkbenchHelp.setHelp(value, XSDEditorContextIds.XSDR_COMPOSITION_CURRENT);
value.setToolTipText(XSDEditorPlugin.getXSDString("_UI_TOOLTIP_REGEX_WIZARD_CURRENT_REGEX"));
value.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
value.setFocus();
// StyleRange used for highlighting parse errors
currentError = new StyleRange();
currentError.length = 1;
currentError.foreground = parent.getDisplay().getSystemColor(SWT.COLOR_RED);
// The caret label
caretLabel = new Label(composite, SWT.LEFT);
caretLabel.setImage(XSDEditorPlugin.getXSDImage("icons/RegexWizardArrow.gif"));
caretLabel.setToolTipText(XSDEditorPlugin.getXSDString("_UI_TOOLTIP_REGEX_WIZARD_CARET_LABEL"));
setShowCaretLabel(true);
value.addFocusListener(new TextFocusListener());
terms.select(0);
setControl(composite);
}
public void setVisible(boolean visible)
{
super.setVisible(visible);
value.setText(pattern.getLexicalValue());
value.setCaretOffset(value.getCharCount());
}
public void dispose()
{
super.dispose();
}
/**
* Sets the visible status of caretLabel to status. If status is true, then we also update the position
* of caretLabel in one of two ways. If there is no active selection in value, we set caretLabel's
* position to correspond with the position of the actual caret. Alternatively, if there is an active selection
* in value, we set caretLabel's position to the beginning of the selection.
*
* @param The new visibility status of caretLabel.
*/
private void setShowCaretLabel(boolean status)
{
if (status)
{
int offset;
if (value.getSelectionText().equals(""))
{
offset = value.getCaretOffset();
}
else
{
offset = value.getSelection().x;
}
Point p = value.getLocationAtOffset(offset);
p.x += value.getLocation().x;
p.y = value.getLocation().y;
// Place the label under value, and make sure it is aligned with the caret.
// The offsets are dependent on the icon used.
p.x += CARET_LABEL_X_OFFSET;
p.y += CARET_LABEL_Y_OFFSET;
if (debug)
{
System.out.println("POINT: " + p);
}
caretLabel.setLocation(p);
caretLabel.setVisible(true);
}
else
{
caretLabel.setVisible(false);
}
}
/**
* Adds a new radio button to Composite c with SelectionListener l. The text of the button is the String associated with
* quantifier.
*
* @param quantifier The desired quantifier, as enumerated in RegexNode.
* @param c The Composite to add the buttons to (normally occurrenceRadioButtons).
* @param l The SelectionListener (normally radioSelectionListener).
* @return The newly created button.
*/
private Button addOccurenceRadioButton(int quantifier, Composite c, SelectionListener l)
{
Button result = new Button(c, SWT.RADIO);
result.setText(RegexNode.getQuantifierText(quantifier));
result.addSelectionListener(l);
return result;
}
/**
* Validates the regex in value. If the regex is valid, clears the Wizard's error message. If it's not valid,
* sets the Wizard's error message accordingly.
*
* @return Whether the regex is valid.
*/
private boolean validateRegex()
{
boolean isValid;
try
{
// We validate the regex by checking whether we get a ParseException.
// By default, we assume that it's valid unless we determine otherwise.
isValid = true;
displayRegexErrorMessage(null);
value.setStyleRange(null);
// validator.setPattern(value.getText());
validator = Pattern.compile(value.getText());
}
// catch (ParseException pe)
catch (PatternSyntaxException pe)
{
isValid = false;
displayRegexErrorMessage(pe.getMessage());
// An off-by-one bug in the xerces regex parser will sometimes return a location for the parseError that
// is off the end of the string. If this is the case, then we want to highlight the last character.
if (pe.getIndex() >= value.getText().length())
{
currentError.start = value.getText().length() - 1;
}
else
{
currentError.start = pe.getIndex();
}
if (debug)
{
System.out.println("Parse Error location: " + pe.getIndex());
System.out.println("currentError.start: " + currentError.start);
}
value.setStyleRange(currentError);
}
// Another bug in the xerces parser will sometimes throw a RuntimeException instead of a ParseException.
// When we get a RuntimeException, we aren't provided with the additional information we need to highlight
// the parse error. So, we merely report that there is an error.
catch (RuntimeException re)
{
displayRegexErrorMessage("");
value.setStyleRange(null);
isValid = false;
}
setPageComplete(isValid);
return isValid;
}
/**
* Manages the display of error messages.
* Sets the error message for type to errorMessage. If errorMessage != null, then we set the Wizard's error message
* to errorMessage. If errorMessage == null, then we check whether we have a pending message of another type.
* If we do, then it is displayed as the Wizard's error message. If we don't, then the Wizard's error message field
* is cleared.
*
* @param errorMessage The text of the new error message. A value of null indicates that the error message should
* be cleared.
* @param type The error type, one of PARSE, TOKEN, or SELECTION.
*/
private void displayErrorMessage(String errorMessage, int type)
{
String messageToDisplay = null;
currentErrorMessages[type] = errorMessage;
messageToDisplay = errorMessage;
for (int i = 0; i < NUM_ERROR_MESSAGE_TYPES; i++)
{
if (messageToDisplay != null)
{
break;
}
messageToDisplay = currentErrorMessages[i];
}
setErrorMessage(messageToDisplay);
}
/**
* Sets the Wizard's error message to message, preceded by a standard prefix.
*
* @param message The new error message (or null to clear it).
*/
private void displayRegexErrorMessage (String errorMessage)
{
if (errorMessage == null)
{
displayErrorMessage(null, PARSE);
}
else
{
if (errorMessage.trim().equals("")) // when there is no error message available.
{
displayErrorMessage(XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_INVALID_REGEX_ERROR"),
PARSE);
}
else
{
displayErrorMessage(errorMessage, PARSE);
}
}
}
/**
* Updates the token status. Sets isValidToken to status && the status of the other error type.
* If status is true, we clear the wizard's error message for this type; if it is false, we set it to errorMessage.
*
* @param status The new isValidToken value.
* @param errorMessage The new error message.
* @param type The type of the error (either TOKEN or SELECTION).
*/
private void setTokenStatus (boolean status, String errorMessage, int type)
{
boolean otherTypeStatus = (type == TOKEN) ?
currentErrorMessages[SELECTION] == null :
currentErrorMessages[TOKEN] == null;
isValidToken = status && otherTypeStatus;
add.setEnabled(isValidToken);
if (status)
{
displayErrorMessage(null, type);
}
else
{
if (errorMessage != null && errorMessage.trim().equals("")) // when there is no error message available.
{
displayErrorMessage(XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_INVALID_TOKEN_ERROR"),
type);
}
else
{
displayErrorMessage(errorMessage, type);
}
}
}
/**
* Updates the token status. Sets isValidToken to status && the status of the other error type.
* Also clears the wizard's error message for this type.
* Usually used to set isValidToken to true.
*
* @param status The new isValidToken value.
* @param type The type of the error (either TOKEN or SELECTION).
*/
private void setTokenStatus(boolean status, int type)
{
setTokenStatus(status, null, type);
}
/**
* Sets the enabled status of the text fields and labels associated with the specified quantifier.
* If status is true, then fields and labels associated with other quantifiers are disabled.
* @param quantifier The quantifier whose elements' enabled status we wish to change
* (as enumerated in RegexNode).
* @param status The new status of the elements. If true, then all elements associated with other buttons
* are disabled.
*/
private void setEnabledStatus(int quantifier, boolean status)
{
switch (quantifier)
{
case RegexNode.REPEAT:
repeatValue.setEnabled(status);
if (status)
{
rangeMinValue.setEnabled(false);
rangeMaxValue.setEnabled(false);
rangeToLabel.setEnabled(false);
}
break;
case RegexNode.RANGE:
rangeMinValue.setEnabled(status);
rangeMaxValue.setEnabled(status);
rangeToLabel.setEnabled(status);
if (status)
{
repeatValue.setEnabled(false);
}
break;
}
}
/**
* Checks to see if there is a selection in value. If there is not, we set the Wizard's error message accordingly.
* If there is, we update the contents of node. If "Current Selection" is not the current token, then
* we clear the Selection error message.
*/
private void updateCurrentSelectionStatus()
{
if (terms.getSelectionIndex() == RegexNode.SELECTION)
{
String selection = value.getSelectionText();
if (selection.equals(""))
{
setTokenStatus(false, XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_INVALID_SELECTION_ERROR"), SELECTION);
}
else
{
setTokenStatus(true, SELECTION);
node.setContents(selection);
node.setHasParens(true);
}
}
else
{
setTokenStatus(true, SELECTION);
}
}
/**
* Updates the enabled status of the auto-escape checkbox. If status is true, we enable the checkbox, and
* set its selection status and node's auto-escape status to the value of autoEscapeStatus. If status is
* false, then we disable and deselect the checkbox, and set node's status to false.
*
* @param status The new enabled status.
*/
private void setEscapeCheckboxEnabledStatus(boolean status)
{
if (status)
{
escapeCheckbox.setEnabled(true);
escapeCheckbox.setSelection(autoEscapeStatus);
node.setAutoEscapeStatus(autoEscapeStatus);
}
else
{
escapeCheckbox.setEnabled(false);
escapeCheckbox.setSelection(false);
node.setAutoEscapeStatus(false);
}
}
/**
* Returns the current regex flags.
*/
String getFlags()
{
return regexFlags;
}
/**
* Returns the current XSDPattern model.
*/
XSDPatternFacet getPattern()
{
return pattern;
}
/**
* Returns a string consisting of the values of min, max, and repeat stored in node.
* Used for debugging purposes only.
*/
private String getAllFieldValues()
{
String result = "";
result += "Min: " + node.getMin() + "\n";
result += "Max: " + node.getMax() + "\n";
result += "Repeat: " + node.getRepeat() + "\n";
result += "\n";
return result;
}
/* Listener for the add button. */
class ButtonSelectListener implements SelectionListener
{
public void widgetDefaultSelected(SelectionEvent e)
{
}
// Precondition: isValidToken == true
public void widgetSelected(SelectionEvent e)
{
if (!isValidToken) // should never happen
{
System.out.println("Attempted to add an invalid token.");
System.out.println(node.toString());
System.out.println(getAllFieldValues());
return;
}
// Whether there is anything selected in value.
boolean isActiveSelection = value.getSelectionCount() != 0;
value.insert(node.toString());
if (terms.getSelectionIndex() == RegexNode.SELECTION)
{
updateCurrentSelectionStatus();
}
// If nothing is selected, then we need to advance the caret location.
if (!isActiveSelection)
{
value.setCaretOffset(value.getCaretOffset() + node.toString().length());
}
value.setFocus();
}
}
/* Listener for the terms combo box. */
class ComboListener implements Listener
{
public void handleEvent(Event e)
{
updateCurrentSelectionStatus();
// If the user has typed in a token
if (terms.getSelectionIndex() == -1)
{
setEscapeCheckboxEnabledStatus(true);
node.setContents(terms.getText());
node.setHasParens(true);
if (debug)
{
System.out.println(terms.getText());
}
}
else if (terms.getSelectionIndex() == RegexNode.SELECTION)
{
setEscapeCheckboxEnabledStatus(false);
}
else
{
node.setContents(RegexNode.getRegexTermValue(terms.getSelectionIndex()));
node.setHasParens(false);
setEscapeCheckboxEnabledStatus(false);
}
}
}
/* Listener for enabling/disabling caretLabel. */
class TextFocusListener implements FocusListener
{
public void focusGained(FocusEvent e)
{
setShowCaretLabel(false);
}
public void focusLost(FocusEvent e)
{
setShowCaretLabel(true);
}
}
/* Listener for the text fields. */
class TextListener implements Listener
{
public void handleEvent (Event e)
{
if (debug)
{
System.out.println("Inside TextListener handler");
System.out.println(e);
System.out.println(getAllFieldValues());
}
if ( (e.widget == value) && (e.type == SWT.Modify) )
{
pattern.setLexicalValue(value.getText());
validateRegex();
}
else if (e.widget == value && e.type == SWT.Selection)
{
if (terms.getSelectionIndex() == RegexNode.SELECTION)
{
updateCurrentSelectionStatus();
}
}
else if (e.widget == rangeMinValue)
{
boolean isValid = node.setMin(rangeMinValue.getText());
if (isValid)
{
setTokenStatus(true, null, TOKEN);
}
else
{
setTokenStatus(false, XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_INVALID_MIN_ERROR_SUFFIX"), TOKEN);
}
}
else if (e.widget == rangeMaxValue)
{
boolean isValid = node.setMax(rangeMaxValue.getText());
if (node.getMin() == RegexNode.EMPTY)
{
setTokenStatus(false, XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_MISSING_MIN_ERROR_SUFFIX"), TOKEN);
}
else if (isValid)
{
setTokenStatus(true, null, TOKEN);
}
else
{
setTokenStatus(false, XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_INVALID_MAX_ERROR_SUFFIX"), TOKEN);
}
}
else // (e.widget == repeatValue)
{
boolean isValid = node.setRepeat(repeatValue.getText());
if (isValid)
{
setTokenStatus(true, null, TOKEN);
}
else
{
setTokenStatus(false, XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_INVALID_REPEAT_ERROR_SUFFIX"), TOKEN);
}
}
}
}
/* Listener for the auto-escape checkbox. */
class CheckboxListener implements SelectionListener
{
public void widgetDefaultSelected(SelectionEvent e)
{
}
public void widgetSelected(SelectionEvent e)
{
boolean newStatus = !autoEscapeStatus;
node.setAutoEscapeStatus(newStatus);
autoEscapeStatus = newStatus;
if (debug)
{
System.out.println("AutoEscape Status: " + node.getAutoEscapeStatus());
}
}
}
/* Listener for the radio buttons. */
class RadioSelectListener implements SelectionListener
{
public void widgetDefaultSelected(SelectionEvent e)
{
}
public void widgetSelected(SelectionEvent e)
{
if (debug)
{
System.out.println(getAllFieldValues());
}
int currentQuantifier = getQuantifier(e);
node.setQuantifier(currentQuantifier);
switch (currentQuantifier)
{
case RegexNode.SINGLE:
case RegexNode.STAR:
case RegexNode.PLUS:
case RegexNode.OPTIONAL:
setEnabledStatus(RegexNode.REPEAT, false);
setEnabledStatus(RegexNode.RANGE, false);
setTokenStatus(true, TOKEN);
break;
case RegexNode.REPEAT:
setEnabledStatus(RegexNode.REPEAT, true);
setTokenStatus(node.hasValidRepeat(), XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_INVALID_REPEAT_ERROR_SUFFIX"), TOKEN);
repeatValue.setFocus();
break;
case RegexNode.RANGE:
setEnabledStatus(RegexNode.RANGE, true);
String error = (node.hasValidMin()) ?
XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_INVALID_MAX_ERROR_SUFFIX") :
XSDEditorPlugin.getXSDString("_UI_REGEX_WIZARD_INVALID_MIN_ERROR_SUFFIX");
setTokenStatus( node.hasValidMin() && node.hasValidMax(), error, TOKEN);
rangeMinValue.setFocus();
break;
}
}
private int getQuantifier(SelectionEvent e)
{
if (e.widget == singleRadio)
{
return RegexNode.SINGLE;
}
else if (e.widget == starRadio)
{
return RegexNode.STAR;
}
else if (e.widget == plusRadio)
{
return RegexNode.PLUS;
}
else if (e.widget == optionalRadio)
{
return RegexNode.OPTIONAL;
}
else if (e.widget == repeatRadio)
{
return RegexNode.REPEAT;
}
else if (e.widget == rangeRadio)
{
return RegexNode.RANGE;
}
else // can't get here
{
return RegexNode.EMPTY;
}
}
}
}