/******************************************************************************* * Copyright (c) 2010 SAP AG. * 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: * Emil Simeonov - initial API and implementation. * Dimitar Donchev - initial API and implementation. * Dimitar Tenev - initial API and implementation. * Nevena Manova - initial API and implementation. * Georgi Konstantinov - initial API and implementation. *******************************************************************************/ package org.eclipse.wst.sse.sieditor.ui.v2.newtypedialog; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.fieldassist.ControlDecoration; import org.eclipse.jface.fieldassist.FieldDecoration; import org.eclipse.jface.fieldassist.FieldDecorationRegistry; import org.eclipse.swt.SWT; 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.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.wst.sse.sieditor.model.utils.EmfXsdUtils; import org.eclipse.wst.sse.sieditor.ui.Activator; import org.eclipse.wst.sse.sieditor.ui.i18n.Messages; public class NewTypeDialog extends Dialog { public static final String RADIO_SELECTION_NONE = "no.selection"; //$NON-NLS-1$ public static final String RADIO_SELECTION_ELEMENT = "element"; //$NON-NLS-1$ public static final String RADIO_SELECTION_SIMPLE_TYPE = "simple.type"; //$NON-NLS-1$ public static final String RADIO_SELECTION_FAULT_ELEMENT = "fault.element"; //$NON-NLS-1$ public static final String RADIO_SELECTION_STRUCTURE_TYPE = "structure.type"; //$NON-NLS-1$ /** * Status returned on ok button press. */ protected IStatus finishStatus; protected final ITypeDialogStrategy strategy; protected Text nameControl; protected ControlDecoration decoration; protected Button simpleTypeButton; protected Button structureTypeButton; protected Button elementButton; /** * the new type element type to create - element, simple.type, * structure.type */ private String newTypeType; /** * the new type name to create */ private String newTypeName; /** * flag determining if the user has modified the name field and if it is * being modified via the API not the user */ protected boolean cleanFlag; /** * flag determining if the user has modified the name field and if it is * being modified via the API not the user */ protected boolean externalNameModifyFlag; public NewTypeDialog(final Shell parentShell, final ITypeDialogStrategy strategy) { super(parentShell); setShellStyle(getShellStyle() | SWT.RESIZE); this.strategy = strategy; finishStatus = Status.CANCEL_STATUS; cleanFlag = true; externalNameModifyFlag = true; } public IStatus createAndOpen() { create(); getShell().setText(strategy.getDialogTitle()); setBlockOnOpen(true); setDefaultName(); final int dialogResult = open(); if (OK == dialogResult) { return finishStatus; } return Status.CANCEL_STATUS; } @Override protected Control createDialogArea(final Composite parent) { final Composite dialogAreaComposite = (Composite) super.createDialogArea(parent); createRadioComposite(dialogAreaComposite); createNameComposite(dialogAreaComposite); return dialogAreaComposite; } /** * Code creating and the composite above the name - allowing the user to * chose * * @param parent */ protected void createRadioComposite(final Composite parent) { final Group radioGroup = new Group(parent, SWT.NONE); final GridData gridData = new GridData(); gridData.grabExcessHorizontalSpace = true; gridData.horizontalAlignment = SWT.FILL; radioGroup.setLayoutData(gridData); radioGroup.setLayout(new GridLayout()); radioGroup.setText(Messages.NewTypeDialog_group_title_type_category); elementButton = new Button(radioGroup, SWT.RADIO); structureTypeButton = new Button(radioGroup, SWT.RADIO); simpleTypeButton = new Button(radioGroup, SWT.RADIO); elementButton.setEnabled(strategy.isElementEnabled()); structureTypeButton.setEnabled(strategy.isStructureTypeEnabled()); simpleTypeButton.setEnabled(strategy.isSimpleTypeEnabled()); final SelectionAdapter selectionListener = new SelectionAdapter() { @Override public void widgetSelected(final SelectionEvent e) { radioSelected(); } }; simpleTypeButton.addSelectionListener(selectionListener); structureTypeButton.addSelectionListener(selectionListener); elementButton.addSelectionListener(selectionListener); simpleTypeButton.setText(Messages.NewTypeDialog_simple_type_radio_button); structureTypeButton.setText(Messages.NewTypeDialog_structure_type_radio_button); elementButton.setText(Messages.NewTypeDialog_element_radio_button); if (strategy.isElementEnabled()) { elementButton.setSelection(true); elementButton.setFocus(); } else if (strategy.isStructureTypeEnabled()) { structureTypeButton.setSelection(true); structureTypeButton.setFocus(); } else { simpleTypeButton.setSelection(true); simpleTypeButton.setFocus(); } } /** * Code creating the composite containing the name control * * @param parent */ protected void createNameComposite(final Composite parent) { // create a composite to place the name text and label controls final Composite nameComposit = new Composite(parent, SWT.NONE); final GridData gridData = new GridData(); gridData.grabExcessHorizontalSpace = true; gridData.grabExcessVerticalSpace = true; gridData.horizontalAlignment = GridData.FILL; gridData.verticalAlignment = GridData.FILL; nameComposit.setLayoutData(gridData); // set up the layout of the composite final GridLayout layout = new GridLayout(2, false); layout.horizontalSpacing = 7; nameComposit.setLayout(layout); // create the label before the name text control final Label nameLabel = new Label(nameComposit, SWT.NONE); nameLabel.setText(Messages.NewTypeDialog_label_name); // create and set up the name text control nameControl = new Text(nameComposit, SWT.SINGLE | SWT.BORDER); final GridData NameGridData = new GridData(); NameGridData.horizontalAlignment = GridData.FILL; NameGridData.grabExcessHorizontalSpace = true; NameGridData.widthHint = 200; nameControl.setLayoutData(NameGridData); nameControl.addModifyListener(new ModifyListener() { public void modifyText(final ModifyEvent e) { nameModified(); } }); // create the decoration for the name control decoration = new ControlDecoration(nameControl, SWT.LEFT | SWT.TOP); final FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault().getFieldDecoration( FieldDecorationRegistry.DEC_ERROR); decoration.setImage(fieldDecoration.getImage()); decoration.hide();// just in case } protected void setDefaultName() { externalNameModifyFlag = false; nameControl.setText(strategy.getDefaultName(getSelectedComboType())); externalNameModifyFlag = true; } protected String getSelectedComboType() { if (elementButton.getSelection()) { return RADIO_SELECTION_ELEMENT; } if (structureTypeButton.getSelection()) { return RADIO_SELECTION_STRUCTURE_TYPE; } if (simpleTypeButton.getSelection()) { return RADIO_SELECTION_SIMPLE_TYPE; } return RADIO_SELECTION_NONE; } public void nameModified() { if (cleanFlag && externalNameModifyFlag) { cleanFlag = false; } validateAndMark(); } protected void radioSelected() { if (cleanFlag) { // this will call the validation anyway setDefaultName(); } else { validateAndMark(); } } /** * Validates the text in the name control according to the strategy and xml * NCName rules. <br> * Sets the error marker and text if invalid, removes them if valid. */ // TODO split this into two methods: validate() && mark() protected void validateAndMark() { // put code checking the selected radio button and validating name // controll content final List<String> errorMsgList = new ArrayList<String>(); final String name = nameControl.getText(); if (!EmfXsdUtils.isValidNCName(name)) { if (EmfXsdUtils.isValidNCName(name.trim())) { errorMsgList.add(Messages.NewTypeDialog_msg_error_invalid_name_whitespace); } else { errorMsgList.add(Messages.NewTypeDialog_msg_error_invalid_name); } } if (strategy.isDuplicateName(name, getSelectedComboType())) { errorMsgList.add(strategy.getDuplicateNameErrorMessage(getSelectedComboType())); } if (errorMsgList.isEmpty()) { decoration.hide(); getButton(IDialogConstants.OK_ID).setEnabled(true); } else { final StringBuffer message = new StringBuffer(Messages.NewTypeDialog_msg_error_header_invalid_name); for (final String string : errorMsgList) { message.append(Messages.NewTypeDialog_error_message_new_line); message.append(string); } decoration.setDescriptionText(message.toString()); decoration.show(); getButton(IDialogConstants.OK_ID).setEnabled(false); } } @Override protected void okPressed() { newTypeName = nameControl.getText(); newTypeType = getSelectedComboType(); finishStatus = new Status(IStatus.OK, Activator.PLUGIN_ID, null); super.okPressed(); } @Override protected void cancelPressed() { newTypeName = null; newTypeType = null; super.cancelPressed(); } // =========================================================== // getters // =========================================================== /** * @return the name of the type to create or <code>null</code> if the dialog * was cancelled */ public String getNewTypeName() { return newTypeName; } /** * @return the type of the type({@link #RADIO_SELECTION_ELEMENT}, * {@link #RADIO_SELECTION_SIMPLE_TYPE}, etc.) to create or * <code>null</code> if the dialog was cancelled */ public String getNewTypeType() { return newTypeType; } }