org.eclipse.emf.ecp.edit.internal.swt.controls.XmlDateControlText.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.emf.ecp.edit.internal.swt.controls.XmlDateControlText.java

Source

/*******************************************************************************
 * Copyright (c) 2011-2013 EclipseSource Muenchen GmbH 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:
 * Eugen Neufeld - initial API and implementation
 *
 *******************************************************************************/
package org.eclipse.emf.ecp.edit.internal.swt.controls;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Pattern;

import javax.xml.datatype.XMLGregorianCalendar;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.ecp.edit.internal.swt.Activator;
import org.eclipse.emf.ecp.edit.internal.swt.util.DateUtil;
import org.eclipse.emf.ecp.edit.spi.swt.util.ECPDialogExecutor;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emfforms.spi.localization.LocalizationServiceHelper;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.dialogs.IDialogLabelKeys;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DateTime;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

/**
 * This is a XMLDateControl. It is used to display values of type {@link XMLGregorianCalendar}. This control only
 * displays a date widget.
 *
 * @author Eugen Neufeld
 *
 *         private Button bDate;
 */
@Deprecated
public class XmlDateControlText extends AbstractTextControl {
    private static final DateFormat CHECK_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); //$NON-NLS-1$
    private static final Pattern CHECK_PATTERN = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}$"); //$NON-NLS-1$
    private Button bDate;

    @Override
    protected String getTextVariantID() {
        return "org_eclipse_emf_ecp_control_xmldate"; //$NON-NLS-1$
    }

    @Override
    protected String getUnsetLabelText() {
        return LocalizationServiceHelper.getString(getClass(),
                DepricatedControlMessageKeys.XmlDateControlText_NoDateSetClickToSetDate);
    }

    @Override
    protected String getUnsetButtonTooltip() {
        return LocalizationServiceHelper.getString(getClass(),
                DepricatedControlMessageKeys.XmlDateControlText_UnsetDate);
    }

    @Override
    protected void customizeText(Text text) {
        super.customizeText(text);
        text.setMessage(((SimpleDateFormat) setupFormat()).toPattern());
    }

    @Override
    public void setEditable(boolean editable) {
        super.setEditable(editable);
        bDate.setVisible(editable);
    }

    @Override
    protected void fillControlComposite(Composite composite) {
        final Composite main = new Composite(composite, SWT.NONE);
        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(main);
        GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.BEGINNING).applyTo(main);
        super.fillControlComposite(main);
        bDate = new Button(main, SWT.PUSH);
        bDate.setImage(Activator.getImage("icons/date.png")); //$NON-NLS-1$
        bDate.setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_control_xmldate"); //$NON-NLS-1$
        bDate.addSelectionListener(new SelectionAdapterExtension());
    }

    @Override
    public Binding bindValue() {
        final IObservableValue value = SWTObservables.observeText(getText(), SWT.FocusOut);
        final DateTargetToModelUpdateStrategy targetToModelUpdateStrategy = new DateTargetToModelUpdateStrategy();
        final DateModelToTargetUpdateStrategy modelToTargetUpdateStrategy = new DateModelToTargetUpdateStrategy();
        final Binding binding = getDataBindingContext().bindValue(value, getModelValue(),
                targetToModelUpdateStrategy, modelToTargetUpdateStrategy);
        createTooltipBinding(targetToModelUpdateStrategy, modelToTargetUpdateStrategy);
        return binding;
    }

    /**
     * @author Jonas
     *
     */
    private final class SelectionAdapterExtension extends SelectionAdapter {
        @Override
        public void widgetSelected(SelectionEvent e) {
            final Shell dialog = new Shell(getText().getShell(), SWT.NONE);
            dialog.setLayout(new GridLayout(1, false));

            final DateTime calendar = new DateTime(dialog, SWT.CALENDAR | SWT.BORDER);
            final XMLGregorianCalendar gregorianCalendar = (XMLGregorianCalendar) getModelValue().getValue();
            final Calendar cal = Calendar.getInstance(getLocale());
            if (gregorianCalendar != null) {
                cal.setTime(gregorianCalendar.toGregorianCalendar().getTime());
            }
            calendar.setDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH));

            final IObservableValue dateObserver = SWTObservables.observeSelection(calendar);
            final Binding binding = getDataBindingContext().bindValue(dateObserver, getModelValue(),
                    new DateTargetToModelUpdateStrategy(), new DateModelToTargetUpdateStrategy());
            binding.updateModelToTarget();

            final Button okButton = new Button(dialog, SWT.PUSH);
            okButton.setText(JFaceResources.getString(IDialogLabelKeys.OK_LABEL_KEY));
            GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).grab(false, false).applyTo(okButton);
            okButton.addSelectionListener(new SelectionAdapter() {
                /**
                 * {@inheritDoc}
                 *
                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                 */
                @Override
                public void widgetSelected(SelectionEvent e) {
                    binding.updateTargetToModel();
                    binding.dispose();
                    dialog.close();
                }
            });

            dialog.pack();
            dialog.layout();
            final Point dialogSize = dialog.getSize();
            final Rectangle displayBounds = dialog.getDisplay().getBounds();
            final Point buttonLocation = okButton.toDisplay(okButton.getSize().x, okButton.getSize().y);

            // TODO what if dialogsize > displaybounds? + some other cases

            int dialogX = buttonLocation.x - dialogSize.x;
            int dialogY = buttonLocation.y;
            if (dialogY + dialogSize.y > displayBounds.height) {
                dialogY = dialogY - okButton.getSize().y - dialogSize.y;
            }
            if (dialogX + dialogSize.x > displayBounds.width) {
                dialogX = dialogX - dialogSize.x;
            } else if (dialogX - dialogSize.x < displayBounds.x) {
                dialogX = buttonLocation.x - okButton.getSize().x;
            }
            dialog.setLocation(dialogX, dialogY);
            dialog.open();
        }
    }

    private class DateModelToTargetUpdateStrategy extends ModelToTargetUpdateStrategy {

        @Override
        public Object convertValue(Object value) {
            // final DecimalFormat format = (DecimalFormat) DecimalFormat
            // .getInstance(getModelElementContext().getLocale());
            // format.setGroupingUsed(false);
            // format.setParseIntegerOnly(isInteger());
            final DateFormat format = setupFormat();
            final XMLGregorianCalendar gregorianCalendar = (XMLGregorianCalendar) value;
            if (gregorianCalendar == null) {
                return null;
            }
            final Date date = gregorianCalendar.toGregorianCalendar().getTime();
            return format.format(date);
        }
    }

    private class DateTargetToModelUpdateStrategy extends TargetToModelUpdateStrategy {

        private final DateFormat format;

        DateTargetToModelUpdateStrategy() {
            super();
            format = setupFormat();

        }

        @Override
        protected Object convertValue(final Object value) {
            try {
                Date date = null;
                if (String.class.isInstance(value)) {
                    date = format.parse((String) value);
                } else if (Date.class.isInstance(value)) {
                    date = (Date) value;
                } else if (value == null) {
                    return value;
                }
                final String xmlFormat = CHECK_FORMAT.format(date);
                if (!CHECK_PATTERN.matcher(xmlFormat).matches()) {
                    return revertToOldValue(value);
                }
                final String formatedDate = format.format(date);
                getText().setText(formatedDate);

                final Calendar targetCal = Calendar.getInstance();
                targetCal.setTime(date);
                return DateUtil.convertOnlyDateToXMLGregorianCalendar(targetCal);
            } catch (final ParseException ex) {
                return revertToOldValue(value);
            }
            // return null;
        }

        private Object revertToOldValue(final Object value) {

            if (getFirstStructuralFeature().getDefaultValue() == null && (value == null || value.equals(""))) { //$NON-NLS-1$
                return null;
            }

            final Object result = getModelValue().getValue();

            final MessageDialog messageDialog = new MessageDialog(getText().getShell(),
                    LocalizationServiceHelper
                            .getString(getClass(), DepricatedControlMessageKeys.XmlDateControlText_InvalidNumber),
                    null,
                    LocalizationServiceHelper.getString(getClass(),
                            DepricatedControlMessageKeys.XmlDateControlText_NumberInvalidValueWillBeUnset),
                    MessageDialog.ERROR, new String[] { JFaceResources.getString(IDialogLabelKeys.OK_LABEL_KEY) },
                    0);

            new ECPDialogExecutor(messageDialog) {
                @Override
                public void handleResult(int codeResult) {

                }
            }.execute();

            if (result == null) {
                getText().setText(""); //$NON-NLS-1$
            } else {
                final XMLGregorianCalendar gregorianCalendar = (XMLGregorianCalendar) result;
                final Date date = gregorianCalendar.toGregorianCalendar().getTime();
                getText().setText(format.format(date));
            }

            if (getFirstStructuralFeature().isUnsettable() && result == null) {
                showUnsetLabel();
                return SetCommand.UNSET_VALUE;
            }
            return result;
        }
    }

    /**
     * Sets up a {@link DateFormat} for the current {@link java.util.Locale}.
     *
     * @return the date format
     */
    protected DateFormat setupFormat() {
        return DateFormat.getDateInstance(DateFormat.MEDIUM, getLocale());
    }
}