package edu.ualberta.med.biobank.gui.common.dialogs; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.Date; import org.acegisecurity.AccessDeniedException; import org.eclipse.core.databinding.beans.PojoObservables; import org.eclipse.core.databinding.observable.ChangeEvent; import org.eclipse.core.databinding.observable.IChangeListener; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.databinding.observable.value.WritableValue; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; 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.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.forms.widgets.Section; import org.springframework.remoting.RemoteAccessException; import org.springframework.remoting.RemoteConnectFailureException; import edu.ualberta.med.biobank.gui.common.BgcPlugin; import edu.ualberta.med.biobank.gui.common.validators.AbstractValidator; import edu.ualberta.med.biobank.gui.common.widgets.DateTimeWidget; import edu.ualberta.med.biobank.gui.common.widgets.utils.BgcWidgetCreator; import edu.ualberta.med.biobank.gui.common.widgets.utils.ComboSelectionUpdate; public abstract class BgcBaseDialog extends TitleAreaDialog { protected BgcWidgetCreator widgetCreator; protected Boolean okButtonEnabled; protected boolean setupFinished = false; private boolean closed; public BgcBaseDialog(Shell parentShell) { super(parentShell); widgetCreator = new BgcWidgetCreator(null); widgetCreator.initDataBinding(); } @Override protected void configureShell(Shell shell) { super.configureShell(shell); shell.setText(getDialogShellTitle()); } @Override protected Control createContents(Composite parent) { Control contents = super.createContents(parent); setTitleImage(getTitleAreaImage()); setTitle(getTitleAreaTitle()); setMessage(getTitleAreaMessage(), getTitleAreaMessageType()); return contents; } protected Image getTitleAreaImage() { return BgcPlugin.getDefault().getImageRegistry() .get(BgcPlugin.IMG_DIALOGS); } protected int getTitleAreaMessageType() { return IMessageProvider.NONE; } @Override protected boolean isResizable() { return true; } protected abstract String getTitleAreaMessage(); protected abstract String getTitleAreaTitle(); protected abstract String getDialogShellTitle(); @Override protected Control createButtonBar(Composite parent) { Control contents = super.createButtonBar(parent); if (okButtonEnabled != null) { // in case the binding wanted to modify it before its creation setOkButtonEnabled(okButtonEnabled); } return contents; } @Override protected Control createDialogArea(Composite parent) { // add a separator below the title area (look better that way) Label separator1 = new Label(parent, SWT.HORIZONTAL | SWT.SEPARATOR); separator1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL)); Composite contents = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); contents.setLayout(layout); contents.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); try { createDialogAreaInternal(contents); } catch (final RemoteConnectFailureException exp) { BgcPlugin.openRemoteConnectErrorMessage(exp); } catch (final RemoteAccessException exp) { BgcPlugin.openRemoteAccessErrorMessage(exp); } catch (final AccessDeniedException ade) { BgcPlugin.openAccessDeniedErrorMessage(ade); } catch (Exception e) { throw new RuntimeException(e); } // Build the separator line Label bottomSeparator = new Label(parent, SWT.HORIZONTAL | SWT.SEPARATOR); bottomSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL)); bindChangeListener(); setupFinished = true; return parent; } protected abstract void createDialogAreaInternal(Composite parent) throws Exception; protected AbstractValidator createValidator( Class<? extends AbstractValidator> validatorClass, String validatorErrMsg) { try { Class<?>[] types = new Class[] { String.class }; Constructor<?> cons = validatorClass.getConstructor(types); Object[] args = new Object[] { validatorErrMsg }; return (AbstractValidator) cons.newInstance(args); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } protected void bindChangeListener() { final IObservableValue statusObservable = new WritableValue(); statusObservable.addChangeListener(new IChangeListener() { @Override public void handleChange(ChangeEvent event) { IObservableValue validationStatus = (IObservableValue) event .getSource(); handleStatusChanged((IStatus) validationStatus.getValue()); } }); widgetCreator.addGlobalBindValue(statusObservable); } protected void handleStatusChanged(IStatus status) { if (status.getSeverity() == IStatus.OK) { setErrorMessage(null); setOkButtonEnabled(true); } else { if (setupFinished) { setErrorMessage(status.getMessage()); } setOkButtonEnabled(false); } } @Override public boolean close() { this.closed = true; return super.close(); } @Override public void setErrorMessage(String newErrorMessage) { if (!closed) // test that dialog is not closed to avoid sometimes // NullPointerException or disposed problems. super.setErrorMessage(newErrorMessage); } protected void setOkButtonEnabled(boolean enabled) { Button okButton = getButton(IDialogConstants.OK_ID); if ((okButton != null) && !okButton.isDisposed()) { okButton.setEnabled(enabled); } else { okButtonEnabled = enabled; } } private IObservableValue createPojoObservable(Object pojo, String propertyName) { if (pojo == null) return null; Assert.isNotNull(propertyName); return PojoObservables.observeValue(pojo, propertyName); } public Control createBoundWidget(Composite composite, Class<? extends Widget> widgetClass, int widgetOptions, Label label, String[] widgetValues, Object pojo, String propertyName, AbstractValidator validator) { return widgetCreator.createBoundWidget(composite, widgetClass, widgetOptions, label, widgetValues, createPojoObservable(pojo, propertyName), validator); } protected Control createBoundWidgetWithLabel(Composite composite, Class<? extends Widget> widgetClass, int widgetOptions, String fieldLabel, String[] widgetValues, Object pojo, String propertyName, AbstractValidator validator) { return widgetCreator.createBoundWidgetWithLabel(composite, widgetClass, widgetOptions, fieldLabel, widgetValues, createPojoObservable(pojo, propertyName), validator); } protected <T> ComboViewer createComboViewer(Composite parent, String fieldLabel, Collection<T> input, T selection, String errorMessage, ComboSelectionUpdate csu, IBaseLabelProvider labelProvider) { return widgetCreator.createComboViewer(parent, fieldLabel, input, selection, errorMessage, csu, labelProvider); } public DateTimeWidget createDateTimeWidget(Composite client, Label label, Date date, Object pojo, String propertyName, AbstractValidator validator, int typeShown, String bindingKey) { return widgetCreator.createDateTimeWidget(client, label, date, createPojoObservable(pojo, propertyName), validator, typeShown, bindingKey); } protected DateTimeWidget createDateTimeWidget(Composite client, String nameLabel, Date date, Object pojo, String propertyName, AbstractValidator validator) { return createDateTimeWidget(client, nameLabel, date, pojo, propertyName, validator, SWT.DATE | SWT.TIME); } public DateTimeWidget createDateTimeWidget(Composite client, String nameLabel, Date date, Object pojo, String propertyName, AbstractValidator validator, int typeShown) { return widgetCreator.createDateTimeWidget(client, nameLabel, date, createPojoObservable(pojo, propertyName), validator, typeShown, null); } protected BgcWidgetCreator getWidgetCreator() { return widgetCreator; } protected Section createSection(final Composite contents, String title, String addTooltip, SelectionListener addListener) { Section section = new Section(contents, Section.TWISTIE | Section.TITLE_BAR | Section.EXPANDED); section.setText(title); section.setLayout(new GridLayout(1, false)); GridData gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 2; section.setLayoutData(gd); ToolBar tbar = (ToolBar) section.getTextClient(); if (tbar == null) { tbar = new ToolBar(section, SWT.FLAT | SWT.HORIZONTAL); section.setTextClient(tbar); } if (addListener != null) { ToolItem titem = new ToolItem(tbar, SWT.NULL); titem.setImage(BgcPlugin.getDefault().getImageRegistry() .get(BgcPlugin.IMG_ADD)); titem.setToolTipText(addTooltip); titem.addSelectionListener(addListener); } return section; } }