/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.extension.ui.editors; import static org.teiid.designer.extension.ui.UiConstants.Form.COMBO_STYLE; import static org.teiid.designer.extension.ui.UiConstants.ImageIds.MED_EDITOR; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Locale; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; 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.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.FormDialog; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.core.designer.util.CoreStringUtil; import org.teiid.designer.extension.ExtensionConstants; import org.teiid.designer.extension.definition.ModelExtensionDefinitionValidator; import org.teiid.designer.extension.properties.Translation; import org.teiid.designer.extension.ui.Activator; import org.teiid.designer.extension.ui.Messages; /** * The <code>EditTranslationDialog</code> is used to create or edit a translation. */ public class EditTranslationDialog extends FormDialog { private Button btnOk; private final List<Translation> existingTranslations; private Locale locale; private ScrolledForm scrolledForm; private final String title; private final String translationType; private final ErrorMessage localeError; private final ErrorMessage translationError; private String translation; /** * The translation being edited or <code>null</code> when creating a translation. */ private Translation translationBeingEdited; /** * @param parentShell the parent shell (may be <code>null</code>) * @param title the dialog title (cannot be <code>null</code> or empty) * @param translationType a word describing what the translation represents (description, display name, etc.) (cannot be * <code>null</code> or empty) * @param existingTranslations the existing translations (can be <code>null</code> or empty) */ public EditTranslationDialog( Shell parentShell, String title, String translationType, Collection<Translation> existingTranslations ) { super(parentShell); CoreArgCheck.isNotNull(title, "title is null"); //$NON-NLS-1$ CoreArgCheck.isNotNull(translationType, "translationType is null"); //$NON-NLS-1$ this.title = title; this.translationType = translationType; this.existingTranslations = ((existingTranslations == null) ? new ArrayList<Translation>() : new ArrayList<Translation>(existingTranslations)); this.localeError = new ErrorMessage(); this.translationError = new ErrorMessage(); } /** * @param parentShell the parent shell (may be <code>null</code>) * @param title the dialog title * @param translationType a word describing what the translation represents (description, display name, etc.) (cannot be * <code>null</code> or empty) * @param existingTranslations the existing translations (can be <code>null</code> or empty) * @param translationBeingEdited the translation being edited (cannot be <code>null</code>) */ public EditTranslationDialog( Shell parentShell, String title, String translationType, Collection<Translation> existingTranslations, Translation translationBeingEdited ) { this(parentShell, title, translationType, existingTranslations); CoreArgCheck.isNotNull(translationBeingEdited, "translationBeingEdited is null"); //$NON-NLS-1$ this.translationBeingEdited = translationBeingEdited; this.locale = this.translationBeingEdited.getLocale(); this.translation = this.translationBeingEdited.getTranslation(); // remove the translation being edited this.existingTranslations.remove(this.translationBeingEdited); } /** * {@inheritDoc} * * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) */ @Override protected void configureShell( Shell newShell ) { super.configureShell(newShell); if (isEditMode()) { newShell.setText(Messages.editMetaclassDialogTitle); } } /** * {@inheritDoc} * * @see org.eclipse.jface.dialogs.MessageDialog#createButton(org.eclipse.swt.widgets.Composite, int, java.lang.String, boolean) */ @Override protected Button createButton( Composite parent, int id, String label, boolean defaultButton ) { Button btn = super.createButton(parent, id, label, defaultButton); if (id == IDialogConstants.OK_ID) { // disable OK button initially this.btnOk = btn; btn.setEnabled(false); } return btn; } /** * {@inheritDoc} * * @see org.eclipse.ui.forms.FormDialog#createFormContent(org.eclipse.ui.forms.IManagedForm) */ @SuppressWarnings("unused") @Override protected void createFormContent( IManagedForm managedForm ) { this.scrolledForm = managedForm.getForm(); this.scrolledForm.setText(this.title); this.scrolledForm.setImage(Activator.getDefault().getImage(MED_EDITOR)); this.scrolledForm.setMessage(Messages.translationDialogMsg, IMessageProvider.NONE); FormToolkit toolkit = managedForm.getToolkit(); toolkit.decorateFormHeading(this.scrolledForm.getForm()); Composite body = this.scrolledForm.getBody(); body.setLayout(new GridLayout(2, false)); final Control cbx; LOCALE: { Label lblLocale = toolkit.createLabel(body, Messages.localeLabel, SWT.NONE); lblLocale.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); CCombo cbxLocales = new CCombo(body, COMBO_STYLE); this.localeError.setControl(cbxLocales); cbx = cbxLocales; toolkit.adapt(cbxLocales, true, false); cbxLocales.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); ((GridData)cbxLocales.getLayoutData()).widthHint = (int)(getParentShell().getSize().x * 0.8); ((GridData)cbxLocales.getLayoutData()).heightHint = cbxLocales.getItemHeight() + 4; // populate locale combo final List<Locale> locales = new ArrayList<Locale>(Arrays.asList(Locale.getAvailableLocales())); Collections.sort(locales, ExtensionConstants.LOCALE_COMPARATOR); for (Locale locale : locales) { cbxLocales.add(locale.getDisplayName()); } if (isEditMode()) { String current = this.translationBeingEdited.getLocale().getDisplayName(); int index = cbxLocales.indexOf(current); if (index != -1) { cbxLocales.select(index); } } cbxLocales.addSelectionListener(new SelectionAdapter() { /** * {@inheritDoc} * * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected( SelectionEvent e ) { int index = ((CCombo)e.widget).getSelectionIndex(); handleLocaleChanged(locales.get(index)); } }); cbxLocales.addKeyListener(new KeyListener() { @Override public void keyReleased(KeyEvent e) { if( e.keyCode == 13) { int index = ((CCombo)e.widget).getSelectionIndex(); handleLocaleChanged(locales.get(index)); } } @Override public void keyPressed(KeyEvent e) { } }); cbxLocales.addFocusListener(new FocusListener() { @Override public void focusLost(FocusEvent e) { int index = ((CCombo)e.widget).getSelectionIndex(); if( ! locales.isEmpty() && index > 0 && index < locales.size()) { handleLocaleChanged(locales.get(index)); } } @Override public void focusGained(FocusEvent e) { } }); final LocaleProposalProvider proposalProvider = new LocaleProposalProvider(cbxLocales); proposalProvider.init(); } TRANSLATION: { Label lblTranslation = toolkit.createLabel(body, Messages.translationLabel, SWT.NONE); lblTranslation.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); Text txtTranslation = toolkit.createText(body, null, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.WRAP); this.translationError.setControl(txtTranslation); txtTranslation.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); ((GridData)txtTranslation.getLayoutData()).verticalIndent += ((GridLayout)body.getLayout()).verticalSpacing; ((GridData)txtTranslation.getLayoutData()).heightHint = txtTranslation.getLineHeight() * 3; ((GridData)txtTranslation.getLayoutData()).widthHint = (int)(getParentShell().getSize().x * 0.8); if (isEditMode()) { txtTranslation.setText(this.translationBeingEdited.getTranslation()); } txtTranslation.addModifyListener(new ModifyListener() { /** * {@inheritDoc} * * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent) */ @Override public void modifyText( ModifyEvent e ) { handleTranslationChanged(((Text)e.widget).getText()); } }); } } /** * <strong>Should only be called after the OK button has been pressed.</strong> * * @return the new or edited translation (never <code>null</code>) */ public Translation getTranslation() { return new Translation(this.locale, this.translation); } void handleLocaleChanged( Locale newLocale ) { this.locale = newLocale; validate(); updateState(); } void handleTranslationChanged( String newTranslation ) { this.translation = newTranslation; validate(); updateState(); } private boolean isEditMode() { return (this.translationBeingEdited != null); } private void updateState() { boolean enable = false; if (!this.localeError.isError() && !this.translationError.isError()) { // valid enable = true; if (isEditMode()) { Locale localeBeingEdited = this.translationBeingEdited.getLocale(); if (this.locale == null) { enable = (localeBeingEdited != null); } else { enable = ((localeBeingEdited == null) || !localeBeingEdited.equals(this.locale)); } if (!enable) { enable = !CoreStringUtil.equals(this.translation, this.translationBeingEdited.getTranslation()); } } // set message if changed if (!CoreStringUtil.equals(Messages.translationDialogMsg, this.scrolledForm.getMessage())) { // a bug in Eclipse doesn't reset the font color going from an error to NONE so first set to INFORMATION to get the // font color to change this.scrolledForm.setMessage(CoreStringUtil.Constants.EMPTY_STRING, IMessageProvider.INFORMATION); this.scrolledForm.setMessage(Messages.translationDialogMsg, IMessageProvider.NONE); } } // set enabled state of OK button if (this.btnOk.getEnabled() != enable) { this.btnOk.setEnabled(enable); } } private void validate() { // validate locale this.localeError.setStatus(ModelExtensionDefinitionValidator.validateTranslationLocale(this.locale)); if (!this.localeError.isError()) { assert (this.locale != null) : "locale is null and should not be"; //$NON-NLS-1$ Translation newTranslation = new Translation(this.locale, this.translation); Collection<Translation> temp = new ArrayList<Translation>(this.existingTranslations); temp.add(newTranslation); this.localeError.setStatus(ModelExtensionDefinitionValidator.validateTranslations(this.translationType, temp, false)); } this.localeError.update(this.scrolledForm.getMessageManager()); // validate translation text this.translationError.setStatus(ModelExtensionDefinitionValidator.validateTranslationText(this.translation)); this.translationError.update(this.scrolledForm.getMessageManager()); } }