package edu.ualberta.med.biobank.dialogs;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
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.Label;
import org.eclipse.swt.widgets.Shell;
import edu.ualberta.med.biobank.SessionManager;
import edu.ualberta.med.biobank.common.action.specimen.SpecimenInfo;
import edu.ualberta.med.biobank.common.peer.SpecimenPeer;
import edu.ualberta.med.biobank.common.wrappers.CommentWrapper;
import edu.ualberta.med.biobank.gui.common.widgets.BgcBaseText;
import edu.ualberta.med.biobank.gui.common.widgets.DateTimeWidget;
import edu.ualberta.med.biobank.gui.common.widgets.utils.ComboSelectionUpdate;
import edu.ualberta.med.biobank.model.ActivityStatus;
import edu.ualberta.med.biobank.model.SourceSpecimen;
import edu.ualberta.med.biobank.model.Specimen;
import edu.ualberta.med.biobank.model.SpecimenType;
import edu.ualberta.med.biobank.validators.DoubleNumberValidator;
import edu.ualberta.med.biobank.validators.InventoryIdValidator;
import edu.ualberta.med.biobank.validators.NotNullValidator;
import edu.ualberta.med.biobank.widgets.BiobankLabelProvider;
import edu.ualberta.med.biobank.widgets.infotables.entry.CommentedSpecimenInfo;
public class CEventSourceSpecimenDialog extends PagedDialog {
private CommentedSpecimenInfo editedSpecimen;
private ComboViewer specimenTypeComboViewer;
private Map<String, SourceSpecimen> mapStudySourceSpecimen;
private List<SpecimenType> allSpecimenTypes;
private String currentTitle;
private boolean dialogCreated = false;
private DateTimeWidget timeDrawnWidget;
private Label timeDrawnLabel;
private Label quantityLabel;
private BgcBaseText inventoryIdWidget;
private BgcBaseText quantityText;
private DoubleNumberValidator quantityTextValidator;
private ComboViewer activityStatusComboViewer;
private Date defaultTimeDrawn;
private CommentedSpecimenInfo internalSpecimen;
private List<String> inventoryIdExcludeList;
private CommentWrapper commentWrapper = new CommentWrapper(
SessionManager.getAppService());
private BgcBaseText commentWidget;
public CEventSourceSpecimenDialog(Shell parent, CommentedSpecimenInfo spec,
Set<SourceSpecimen> studySourceSpecimen,
List<SpecimenType> allSpecimenTypes,
List<String> inventoryIdExcludeList, NewListener listener,
Date defaultTimeDrawn) {
super(parent, listener, spec == null);
this.defaultTimeDrawn = defaultTimeDrawn;
this.inventoryIdExcludeList = inventoryIdExcludeList;
Assert.isNotNull(studySourceSpecimen);
internalSpecimen = new CommentedSpecimenInfo(new SpecimenInfo());
internalSpecimen.specimen = new Specimen();
if (spec == null) {
// FIXME ugly
internalSpecimen.specimen.setActivityStatus(ActivityStatus.ACTIVE);
internalSpecimen.specimen.setCreatedAt(defaultTimeDrawn);
} else {
internalSpecimen.specimen.setId(spec.specimen.getId());
internalSpecimen.specimen.setSpecimenType(spec.specimen
.getSpecimenType());
internalSpecimen.specimen.setInventoryId(spec.specimen
.getInventoryId());
internalSpecimen.specimen.setQuantity(spec.specimen.getQuantity());
internalSpecimen.specimen
.setCreatedAt(spec.specimen.getCreatedAt());
internalSpecimen.specimen.setActivityStatus(spec.specimen
.getActivityStatus());
// comments is special
internalSpecimen.comments = spec.comments;
editedSpecimen = spec;
}
mapStudySourceSpecimen = new HashMap<String, SourceSpecimen>();
for (SourceSpecimen ss : studySourceSpecimen) {
mapStudySourceSpecimen.put(ss.getSpecimenType().getName(), ss);
}
this.allSpecimenTypes = allSpecimenTypes;
if (addMode) {
currentTitle = "Add specimen";
} else {
currentTitle = "Edit specimen";
}
}
@Override
protected String getDialogShellTitle() {
return currentTitle;
}
@Override
protected String getTitleAreaMessage() {
if (addMode) {
return "Add a specimen to a collection event";
}
return "Edit a specimen in a collection event";
}
@Override
protected String getTitleAreaTitle() {
return currentTitle;
}
@Override
protected void createDialogAreaInternal(Composite parent) {
Composite contents = new Composite(parent, SWT.NONE);
contents.setLayout(new GridLayout(3, false));
contents.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
inventoryIdWidget =
(BgcBaseText) createBoundWidgetWithLabel(
contents,
BgcBaseText.class,
SWT.NONE,
"Inventory Id",
null,
internalSpecimen.specimen,
SpecimenPeer.INVENTORY_ID.getName(),
new InventoryIdValidator(
inventoryIdExcludeList,
"Inventory ID is empty or already present",
internalSpecimen.specimen));
GridData gd = (GridData) inventoryIdWidget.getLayoutData();
gd.horizontalSpan = 2;
addSpecimenTypeWidgets(contents);
timeDrawnLabel =
widgetCreator.createLabel(contents,
"Time drawn");
timeDrawnLabel
.setToolTipText("If the study doesn't require a specific time drawn, then the default time drawn is used");
timeDrawnWidget =
createDateTimeWidget(
contents,
timeDrawnLabel,
internalSpecimen.specimen.getCreatedAt(),
internalSpecimen.specimen,
SpecimenPeer.CREATED_AT.getName(),
new NotNullValidator(
"Time drawn should be set"),
SWT.DATE | SWT.TIME, null);
gd = (GridData) timeDrawnWidget.getLayoutData();
gd.horizontalSpan = 2;
activityStatusComboViewer =
widgetCreator.createComboViewer(contents,
"Activity status",
ActivityStatus.valuesList(),
internalSpecimen.specimen.getActivityStatus(),
"An activity status should be selected",
new ComboSelectionUpdate() {
@Override
public void doSelection(Object selectedObject) {
internalSpecimen.specimen
.setActivityStatus((ActivityStatus) selectedObject);
}
}, new BiobankLabelProvider() {
@Override
public String getText(Object element) {
return ((ActivityStatus) element).getName();
}
});
gd = (GridData) activityStatusComboViewer.getControl().getLayoutData();
gd.horizontalSpan = 2;
createCommentSection(contents);
quantityLabel =
widgetCreator.createLabel(contents,
"Quantity (ml)");
quantityLabel.setLayoutData(new GridData(
GridData.VERTICAL_ALIGN_BEGINNING));
quantityTextValidator =
new DoubleNumberValidator(
"Quantity is required.");
quantityText =
(BgcBaseText) createBoundWidget(contents, BgcBaseText.class,
SWT.BORDER, quantityLabel, new String[0],
internalSpecimen.specimen,
SpecimenPeer.QUANTITY.getName(), quantityTextValidator);
gd = (GridData) quantityText.getLayoutData();
gd.horizontalSpan = 2;
dialogCreated = true;
updateWidgetVisibilityAndValues();
}
private void createCommentSection(Composite contents) {
commentWidget =
(BgcBaseText) createBoundWidgetWithLabel(contents,
BgcBaseText.class, SWT.MULTI,
"Add a comment", null,
commentWrapper, "message",
null);
GridData gd = new GridData();
gd = (GridData) commentWidget.getLayoutData();
gd.horizontalSpan = 2;
gd.widthHint = 400;
commentWidget.setLayoutData(gd);
}
private void addSpecimenTypeWidgets(Composite contents) {
boolean useStudyOnlySourceSpecimens = true;
SourceSpecimen ss = null;
SpecimenType type = internalSpecimen.specimen.getSpecimenType();
if (type != null) {
ss = mapStudySourceSpecimen.get(type.getName());
}
if (ss == null && type != null
&& allSpecimenTypes.contains(type)) {
useStudyOnlySourceSpecimens = false;
}
specimenTypeComboViewer =
getWidgetCreator().createComboViewer(contents,
"Type",
mapStudySourceSpecimen.values(), ss,
"A specimen type should be selected",
new ComboSelectionUpdate() {
@Override
public void doSelection(Object selectedObject) {
if (selectedObject instanceof SourceSpecimen) {
internalSpecimen
.specimen
.setSpecimenType(((SourceSpecimen) selectedObject)
.getSpecimenType());
} else {
internalSpecimen
.specimen
.setSpecimenType(((SpecimenType) selectedObject));
}
updateWidgetVisibilityAndValuesNoTimeReset();
}
}, new BiobankLabelProvider() {
@Override
public String getText(Object element) {
if (element instanceof SourceSpecimen) {
return ((SourceSpecimen) element).getSpecimenType()
.getNameShort();
}
return ((SpecimenType) element).getNameShort();
}
});
if (!useStudyOnlySourceSpecimens) {
specimenTypeComboViewer.setInput(allSpecimenTypes);
specimenTypeComboViewer.setSelection(new StructuredSelection(
type));
}
final Button allSpecimenTypesCheckBox = new Button(contents, SWT.CHECK);
allSpecimenTypesCheckBox
.setText("Show only study source specimens");
allSpecimenTypesCheckBox.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (allSpecimenTypesCheckBox.getSelection()) {
specimenTypeComboViewer.setInput(mapStudySourceSpecimen
.values());
} else {
specimenTypeComboViewer.setInput(allSpecimenTypes);
}
}
});
allSpecimenTypesCheckBox.setSelection(useStudyOnlySourceSpecimens);
}
public void updateWidgetVisibilityAndValues() {
if (!dialogCreated) return;
SourceSpecimen ss = null;
SpecimenType type = internalSpecimen.specimen.getSpecimenType();
if (type != null) {
ss = mapStudySourceSpecimen.get(type.getName());
}
boolean enableVolume =
(type != null)
&& (ss == null || Boolean.TRUE.equals(ss
.getNeedOriginalVolume()));
boolean isVolumeRequired =
ss != null && Boolean.TRUE.equals(ss.getNeedOriginalVolume());
if (defaultTimeDrawn != null) {
timeDrawnWidget.setDate(defaultTimeDrawn);
}
quantityLabel.setVisible(enableVolume);
quantityText.setVisible(enableVolume);
quantityTextValidator.setAllowEmpty(!enableVolume || !isVolumeRequired);
String originalText = quantityText.getText();
quantityText.setText(originalText + "*");
quantityText.setText(originalText);
if (!enableVolume) {
internalSpecimen.specimen.setQuantity(null);
}
}
public void updateWidgetVisibilityAndValuesNoTimeReset() {
if (!dialogCreated) return;
SourceSpecimen ss = null;
SpecimenType type = internalSpecimen.specimen.getSpecimenType();
if (type != null) {
ss = mapStudySourceSpecimen.get(type.getName());
}
boolean enableVolume =
(type != null)
&& (ss == null || Boolean.TRUE.equals(ss
.getNeedOriginalVolume()));
boolean isVolumeRequired =
ss != null && Boolean.TRUE.equals(ss.getNeedOriginalVolume());
quantityLabel.setVisible(enableVolume);
quantityText.setVisible(enableVolume);
quantityTextValidator.setAllowEmpty(!enableVolume || !isVolumeRequired);
String originalText = quantityText.getText();
quantityText.setText(originalText + "*");
quantityText.setText(originalText);
if (!enableVolume) {
internalSpecimen.specimen.setQuantity(null);
}
}
/**
* Used only when editing
*/
@Override
protected void okPressed() {
copy(editedSpecimen);
super.okPressed();
}
@Override
protected CommentedSpecimenInfo getNew() {
return new CommentedSpecimenInfo(new SpecimenInfo());
}
@Override
protected void resetFields() {
inventoryIdWidget.setText("");
inventoryIdWidget.setFocus();
quantityText.setText("");
timeDrawnWidget.setDate(null);
specimenTypeComboViewer.getCombo().deselectAll();
activityStatusComboViewer.setSelection(
new StructuredSelection(ActivityStatus.ACTIVE));
commentWidget.setText("");
updateWidgetVisibilityAndValues();
}
@Override
protected void copy(Object newModelObject) {
CommentedSpecimenInfo spec =
(CommentedSpecimenInfo) newModelObject;
spec.specimen
.setInventoryId(internalSpecimen.specimen.getInventoryId());
spec.specimen.setSpecimenType(internalSpecimen.specimen
.getSpecimenType());
spec.specimen.setQuantity(internalSpecimen.specimen.getQuantity());
spec.specimen.setCreatedAt(internalSpecimen.specimen.getCreatedAt());
if (commentWrapper.getMessage() != null
&& !commentWrapper.getMessage().equals("")) {
spec.comments.add(commentWrapper.getMessage());
}
if (spec.comments.size() > 0)
spec.comment = "Y";
else
spec.comment = "N";
spec.specimen.setActivityStatus(internalSpecimen.specimen
.getActivityStatus());
inventoryIdExcludeList.add(internalSpecimen.specimen.getInventoryId());
}
}