package edu.ualberta.med.biobank.forms;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
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.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.Section;
import edu.ualberta.med.biobank.SessionManager;
import edu.ualberta.med.biobank.common.action.BooleanResult;
import edu.ualberta.med.biobank.common.action.container.ContainerCreateChildrenAction;
import edu.ualberta.med.biobank.common.action.container.ContainerDeleteChildrenAction;
import edu.ualberta.med.biobank.common.action.container.ContainerGetInfoAction;
import edu.ualberta.med.biobank.common.action.container.ContainerGetInfoAction.ContainerInfo;
import edu.ualberta.med.biobank.common.action.container.ContainerGetSpecimenListInfoAction;
import edu.ualberta.med.biobank.common.action.specimen.SpecimenInfo;
import edu.ualberta.med.biobank.common.permission.container.ContainerCreatePermission;
import edu.ualberta.med.biobank.common.permission.container.ContainerDeletePermission;
import edu.ualberta.med.biobank.common.util.RowColPos;
import edu.ualberta.med.biobank.common.wrappers.CommentWrapper;
import edu.ualberta.med.biobank.common.wrappers.ContainerTypeWrapper;
import edu.ualberta.med.biobank.common.wrappers.ContainerWrapper;
import edu.ualberta.med.biobank.common.wrappers.ModelWrapper;
import edu.ualberta.med.biobank.common.wrappers.SiteWrapper;
import edu.ualberta.med.biobank.common.wrappers.SpecimenWrapper;
import edu.ualberta.med.biobank.forms.input.FormInput;
import edu.ualberta.med.biobank.gui.common.BgcLogger;
import edu.ualberta.med.biobank.gui.common.BgcPlugin;
import edu.ualberta.med.biobank.gui.common.widgets.BgcBaseText;
import edu.ualberta.med.biobank.gui.common.widgets.IInfoTableDoubleClickItemListener;
import edu.ualberta.med.biobank.gui.common.widgets.IInfoTableEditItemListener;
import edu.ualberta.med.biobank.gui.common.widgets.InfoTableEvent;
import edu.ualberta.med.biobank.gui.common.widgets.InfoTableSelection;
import edu.ualberta.med.biobank.model.ContainerPosition;
import edu.ualberta.med.biobank.model.Specimen;
import edu.ualberta.med.biobank.treeview.AdapterBase;
import edu.ualberta.med.biobank.treeview.SpecimenAdapter;
import edu.ualberta.med.biobank.treeview.admin.ContainerAdapter;
import edu.ualberta.med.biobank.widgets.grids.ContainerDisplayWidget;
import edu.ualberta.med.biobank.widgets.grids.cell.AbstractUICell;
import edu.ualberta.med.biobank.widgets.grids.cell.ContainerCell;
import edu.ualberta.med.biobank.widgets.grids.cell.UICellStatus;
import edu.ualberta.med.biobank.widgets.grids.selection.MultiSelectionEvent;
import edu.ualberta.med.biobank.widgets.grids.selection.MultiSelectionListener;
import edu.ualberta.med.biobank.widgets.grids.selection.MultiSelectionSpecificBehaviour;
import edu.ualberta.med.biobank.widgets.infotables.CommentsInfoTable;
import edu.ualberta.med.biobank.widgets.infotables.NewSpecimenInfoTable;
import edu.ualberta.med.biobank.widgets.infotables.NewSpecimenInfoTable.ColumnsShown;
import gov.nih.nci.system.applicationservice.ApplicationException;
public class ContainerViewForm extends BiobankViewForm {
public static final String ID =
"edu.ualberta.med.biobank.forms.ContainerViewForm";
private static BgcLogger logger = BgcLogger
.getLogger(ContainerViewForm.class.getName());
private NewSpecimenInfoTable specimensWidget;
private BgcBaseText siteLabel;
private BgcBaseText containerLabelLabel;
private BgcBaseText productBarcodeLabel;
private BgcBaseText activityStatusLabel;
private BgcBaseText containerTypeLabel;
private BgcBaseText temperatureLabel;
private ContainerDisplayWidget containerWidget;
private Map<RowColPos, ContainerCell> cells;
private boolean childrenOk = true;
private Composite childrenActionSection;
private boolean canCreate;
private boolean canDelete;
private ComboViewer initSelectionCv;
private ComboViewer deleteCv;
private CommentsInfoTable commentTable;
private ContainerInfo containerInfo;
private ContainerAdapter containerAdapter;
private ArrayList<SpecimenInfo> specInfo;
@Override
public void init() throws Exception {
Assert.isTrue(adapter instanceof ContainerAdapter,
"Invalid editor input: object of type "
+ adapter.getClass().getName());
containerAdapter = (ContainerAdapter) adapter;
updateContainerInfo();
setPartName(NLS.bind("Container {0} ({1})",
containerInfo.container.getLabel(), containerInfo.container
.getContainerType().getNameShort()));
initCells();
canCreate =
SessionManager.getAppService().isAllowed(new
ContainerCreatePermission(((ContainerWrapper) containerAdapter
.getModelObject()).getSite().getId()));
canDelete = SessionManager.getAppService().isAllowed(new
ContainerDeletePermission());
}
private void updateContainerInfo() throws ApplicationException {
Assert.isNotNull(adapter.getId());
containerInfo = SessionManager.getAppService().doAction(
new ContainerGetInfoAction(adapter.getId()));
specInfo = SessionManager.getAppService().doAction(
new ContainerGetSpecimenListInfoAction(containerInfo.container
.getId())).getList();
Assert.isNotNull(containerInfo);
Assert.isNotNull(containerInfo.container);
}
@Override
protected void createFormContent() throws Exception {
form.setText(NLS.bind("Container {0} ({1})",
containerInfo.container.getLabel(), containerInfo.container
.getContainerType().getNameShort()));
page.setLayout(new GridLayout(1, false));
createContainerSection();
if (containerInfo.container.getContainerType()
.getSpecimenTypes().size() > 0) {
// only show specimens section this if this container type does not
// have child containers
createSpecimensSection();
}
}
private void createContainerSection() {
Composite client = toolkit.createComposite(page);
GridLayout layout = new GridLayout(2, false);
layout.horizontalSpacing = 10;
client.setLayout(layout);
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
client.setLayoutData(gridData);
toolkit.paintBordersFor(client);
siteLabel =
createReadOnlyLabelledField(client, SWT.NONE,
"Repository Site");
containerLabelLabel =
createReadOnlyLabelledField(client, SWT.NONE,
"Label");
productBarcodeLabel =
createReadOnlyLabelledField(client, SWT.NONE,
"Product Bar Code");
activityStatusLabel =
createReadOnlyLabelledField(client, SWT.NONE,
"Activity status");
containerTypeLabel =
createReadOnlyLabelledField(client, SWT.NONE,
"Container Type");
temperatureLabel =
createReadOnlyLabelledField(client, SWT.NONE,
"Temperature");
createCommentsSection();
setContainerValues();
if (containerInfo.container.getContainerType()
.getChildContainerTypes().size() > 0) {
createVisualizeContainer();
}
}
private void createCommentsSection() {
Composite client = createSectionWithClient("Comments");
commentTable =
new CommentsInfoTable(client,
ModelWrapper.wrapModelCollection(
SessionManager.getAppService(),
containerInfo.container.getComments(),
CommentWrapper.class));
commentTable.adaptToToolkit(toolkit, true);
toolkit.paintBordersFor(commentTable);
}
private void initCells() {
try {
if (containerInfo.container.getContainerType()
.getChildContainerTypes().isEmpty()) return;
Integer rowCap =
containerInfo.container.getContainerType().getCapacity()
.getRowCapacity();
Integer colCap =
containerInfo.container.getContainerType().getCapacity()
.getColCapacity();
Assert.isNotNull(rowCap, "row capacity is null");
Assert.isNotNull(colCap, "column capacity is null");
if (rowCap == 0) rowCap = 1;
if (colCap == 0) colCap = 1;
cells = new TreeMap<RowColPos, ContainerCell>();
Map<RowColPos, ContainerWrapper> childrenMap =
new HashMap<RowColPos, ContainerWrapper>();
for (ContainerPosition position : containerInfo.container
.getChildPositions()) {
childrenMap.put(
new RowColPos(position.getRow(), position.getCol()),
new ContainerWrapper(SessionManager.getAppService(),
position.getContainer()));
}
for (int i = 0; i < rowCap; i++) {
for (int j = 0; j < colCap; j++) {
ContainerCell cell = new ContainerCell(i, j);
cells.put(new RowColPos(i, j), cell);
ContainerWrapper container =
childrenMap.get(new RowColPos(i, j));
if (container == null) {
cell.setStatus(UICellStatus.NOT_INITIALIZED);
} else {
cell.setContainer(container);
cell.setStatus(UICellStatus.INITIALIZED);
}
}
}
} catch (Exception ex) {
BgcPlugin.openAsyncError(
"Positions errors",
"Some child container has wrong position number");
childrenOk = false;
}
}
private void refreshVis() {
initCells();
if (containerWidget == null) {
createVisualizeContainer();
form.layout(true, true);
}
containerWidget.setCells(cells);
}
protected void createVisualizeContainer() {
Section s = createSection("Container Visual");
s.setLayout(new GridLayout(1, false));
Composite containerSection = new Composite(s, SWT.NONE);
containerSection.setLayout(new FillLayout(SWT.VERTICAL));
ScrolledComposite sc =
new ScrolledComposite(containerSection, SWT.H_SCROLL);
sc.setExpandHorizontal(true);
sc.setExpandVertical(true);
Composite client = new Composite(sc, SWT.NONE);
client.setLayout(new GridLayout(1, false));
toolkit.adapt(containerSection);
toolkit.adapt(sc);
toolkit.adapt(client);
sc.setContent(client);
s.setClient(containerSection);
if (!childrenOk) {
Label label =
toolkit
.createLabel(client,
"Error in container children : can't display those initialized");
label.setForeground(Display.getCurrent().getSystemColor(
SWT.COLOR_RED));
}
containerWidget =
new ContainerDisplayWidget(client,
UICellStatus.DEFAULT_CONTAINER_STATUS_LIST);
containerWidget.setContainer(containerInfo.container);
containerWidget.setCells(cells);
toolkit.adapt(containerWidget);
// Set the minimum size
sc.setMinSize(containerWidget.computeSize(SWT.DEFAULT, SWT.DEFAULT));
containerWidget.addMouseListener(new MouseAdapter() {
@Override
public void mouseDoubleClick(MouseEvent e) {
AbstractUICell cell =
((ContainerDisplayWidget) e.widget).getObjectAtCoordinates(
e.x, e.y);
if (cell != null) openFormFor((ContainerCell) cell);
}
});
containerWidget.getMultiSelectionManager().enableMultiSelection(
new MultiSelectionSpecificBehaviour() {
@Override
public void removeSelection(AbstractUICell cell) {
//
}
@Override
public boolean isSelectable(AbstractUICell cell) {
return true;
}
});
containerWidget.getMultiSelectionManager().addMultiSelectionListener(
new MultiSelectionListener() {
@Override
public void selectionChanged(MultiSelectionEvent mse) {
setChildrenActionSectionEnabled(mse.selections > 0);
}
});
containerWidget.displayFullInfoString(true);
createChildrenActionsSection(containerSection);
}
private void createChildrenActionsSection(Composite client) {
childrenActionSection = toolkit.createComposite(client);
childrenActionSection.setLayout(new GridLayout(3, false));
if (canCreate || canDelete) {
List<ContainerTypeWrapper> containerTypes =
getChildContainerTypes();
if (canCreate) {
// Initialisation action for selection
initSelectionCv =
createComboViewer(
childrenActionSection,
"Initialize selection to",
containerTypes, containerTypes.get(0));
initSelectionCv.getCombo()
.setLayoutData(new GridData(SWT.LEFT));
Button initializeSelectionButton =
toolkit
.createButton(
childrenActionSection,
"Initialize",
SWT.PUSH);
initializeSelectionButton
.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
ContainerTypeWrapper type =
(ContainerTypeWrapper) ((IStructuredSelection) initSelectionCv
.getSelection()).getFirstElement();
initSelection(type);
}
});
initializeSelectionButton.setLayoutData(new GridData(SWT.LEFT));
}
if (canDelete) {
// Delete action for selection
List<Object> deleteComboList = new ArrayList<Object>();
deleteComboList
.add("All");
deleteComboList.addAll(containerTypes);
deleteCv =
createComboViewer(
childrenActionSection,
"Delete selected containers of type",
deleteComboList,
"All");
deleteCv.getCombo().setLayoutData(new GridData(SWT.LEFT));
Button deleteButton =
toolkit
.createButton(
childrenActionSection,
"Delete",
SWT.PUSH);
deleteButton.setLayoutData(new GridData(SWT.LEFT));
deleteButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
Boolean confirm =
MessageDialog
.openConfirm(
PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getShell(),
"Confirm Delete",
"Are you sure you want to delete these containers?");
if (confirm) {
Object selection =
((IStructuredSelection) deleteCv.getSelection())
.getFirstElement();
if (selection instanceof ContainerTypeWrapper) {
deleteSelection((ContainerTypeWrapper) selection);
} else {
deleteSelection(null);
}
}
}
});
}
}
setChildrenActionSectionEnabled(false);
}
private void setChildrenActionSectionEnabled(boolean enable) {
// don't use the method seEnabled on the composite because the children
// are not greyed out in this case
for (Control c : childrenActionSection.getChildren()) {
c.setEnabled(enable);
}
}
private void initSelection(final ContainerTypeWrapper type) {
IRunnableContext context =
new ProgressMonitorDialog(Display.getDefault().getActiveShell());
try {
context.run(true, false, new IRunnableWithProgress() {
@Override
public void run(final IProgressMonitor monitor) {
monitor
.beginTask(
"Initializing...",
IProgressMonitor.UNKNOWN);
boolean initDone = true;
try {
final Set<RowColPos> positions =
containerWidget.getMultiSelectionManager()
.getSelectedPositions();
initChildrenWithType(type, positions);
} catch (Exception e) {
initDone = false;
BgcPlugin
.openAsyncError(
"Error while creating children",
e);
}
refresh(initDone, false);
monitor.done();
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
containerWidget.getMultiSelectionManager()
.clearMultiSelection();
}
});
}
});
} catch (Exception e) {
BgcPlugin.openAsyncError(
"Error while creating children", e);
refresh(false, false);
}
}
public boolean initChildrenWithType(ContainerTypeWrapper type,
Set<RowColPos> positions) throws Exception {
ContainerCreateChildrenAction containerCreateChildrenAction =
new ContainerCreateChildrenAction();
containerCreateChildrenAction
.setParentContainerId(containerInfo.container.getId());
containerCreateChildrenAction.setContainerTypeId(type.getId());
containerCreateChildrenAction.setParentPositions(positions);
BooleanResult result =
SessionManager.getAppService().doAction(
containerCreateChildrenAction);
return result.isTrue();
}
private void deleteSelection(final ContainerTypeWrapper type) {
IRunnableContext context =
new ProgressMonitorDialog(Display.getDefault().getActiveShell());
try {
context.run(true, false, new IRunnableWithProgress() {
@Override
public void run(final IProgressMonitor monitor) {
monitor
.beginTask(
"Deleting...",
IProgressMonitor.UNKNOWN);
boolean deleteDones = false;
try {
Set<RowColPos> positions =
containerWidget.getMultiSelectionManager()
.getSelectedPositions();
deleteDones =
deleteChildrenWithType(type, positions);
} catch (Exception ex) {
BgcPlugin
.openAsyncError(
"Can't Delete Containers",
ex);
}
refresh(deleteDones, true);
monitor.done();
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
containerWidget.getMultiSelectionManager()
.clearMultiSelection();
}
});
}
});
} catch (Exception e) {
BgcPlugin.openAsyncError(
"Can't Delete Containers", e);
refresh(false, false);
}
}
protected boolean deleteChildrenWithType(ContainerTypeWrapper type,
Set<RowColPos> positions) throws Exception {
ContainerDeleteChildrenAction containerDeleteChildrenAction =
new ContainerDeleteChildrenAction();
containerDeleteChildrenAction
.setParentContainerId(containerInfo.container.getId());
if (type != null) {
containerDeleteChildrenAction.setContainerTypeId(type.getId());
}
containerDeleteChildrenAction.setParentPositions(positions);
BooleanResult result =
SessionManager.getAppService().doAction(
containerDeleteChildrenAction);
return result.isTrue();
}
private void refresh(boolean initDone, final boolean rebuild) {
if (initDone) {
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
try {
reload();
} catch (Exception e) {
logger.error(
"Error loading", e);
}
if (rebuild) {
containerAdapter.rebuild();
}
containerAdapter.performExpand();
}
});
}
}
private void openFormFor(ContainerCell cell) {
ContainerAdapter newAdapter = null;
if (cell.getStatus() == UICellStatus.NOT_INITIALIZED) {
if (canCreate) {
ContainerWrapper containerToOpen = cell.getContainer();
if (containerToOpen == null) {
containerToOpen =
new ContainerWrapper(SessionManager.getAppService());
}
containerToOpen.setSite(new SiteWrapper(SessionManager
.getAppService(), containerInfo.container.getSite()));
RowColPos pos = new RowColPos(cell.getRow(), cell.getCol());
containerToOpen.setParentInternal(
new ContainerWrapper(SessionManager.getAppService(),
containerInfo.container), pos);
newAdapter =
new ContainerAdapter(containerAdapter, containerToOpen);
newAdapter.openEntryForm(true);
}
} else {
ContainerWrapper child = cell.getContainer();
Assert.isNotNull(child);
SessionManager.openViewForm(child);
}
containerAdapter.performExpand();
}
private void setContainerValues() {
setTextValue(siteLabel, containerInfo.container.getSite().getName());
setTextValue(containerLabelLabel, containerInfo.container.getLabel());
setTextValue(productBarcodeLabel,
containerInfo.container.getProductBarcode());
setTextValue(activityStatusLabel,
containerInfo.container.getActivityStatus().getName());
setTextValue(containerTypeLabel, containerInfo.container
.getContainerType().getName());
setTextValue(temperatureLabel, containerInfo.container
.getTopContainer().getTemperature());
}
List<ContainerTypeWrapper> getChildContainerTypes() {
return ModelWrapper.wrapModelCollection(
SessionManager.getAppService(),
containerInfo.container.getContainerType()
.getChildContainerTypes(),
ContainerTypeWrapper.class);
}
private void createSpecimensSection() {
Composite parent =
createSectionWithClient("Specimens");
specimensWidget =
new NewSpecimenInfoTable(parent, specInfo,
ColumnsShown.CEVENT_SOURCE_SPECIMENS, 20);
specimensWidget.adaptToToolkit(toolkit, true);
specimensWidget
.addClickListener(new IInfoTableDoubleClickItemListener<SpecimenInfo>() {
@Override
public void doubleClick(InfoTableEvent<SpecimenInfo> event) {
Specimen s =
((SpecimenInfo) ((InfoTableSelection) event
.getSelection()).getObject()).specimen;
AdapterBase.openForm(
new FormInput(
new SpecimenAdapter(null,
new SpecimenWrapper(SessionManager
.getAppService(), s))),
SpecimenViewForm.ID);
}
});
specimensWidget
.addEditItemListener(new IInfoTableEditItemListener<SpecimenInfo>() {
@Override
public void editItem(InfoTableEvent<SpecimenInfo> event) {
Specimen s =
((SpecimenInfo) ((InfoTableSelection) event
.getSelection()).getObject()).specimen;
AdapterBase.openForm(
new FormInput(
new SpecimenAdapter(null,
new SpecimenWrapper(SessionManager
.getAppService(), s))),
SpecimenEntryForm.ID);
}
});
}
@Override
public void setValues() throws Exception {
if (form.isDisposed()) return;
form.setText(NLS.bind("Container {0} ({1})",
containerInfo.container
.getLabel(), containerInfo.container.getContainerType()
.getNameShort()));
if (containerInfo.container.getContainerType()
.getChildContainerTypes()
.size() > 0) refreshVis();
setContainerValues();
List<ContainerTypeWrapper> containerTypes = getChildContainerTypes();
List<Object> deleteComboList = new ArrayList<Object>();
deleteComboList
.add("All");
deleteComboList.addAll(containerTypes);
if (initSelectionCv != null) {
initSelectionCv.setInput(containerTypes);
initSelectionCv.getCombo().select(0);
}
if (deleteCv != null) {
deleteCv.setInput(deleteComboList);
deleteCv.getCombo().select(0);
}
if (specimensWidget != null) {
specimensWidget.reloadCollection(specInfo);
}
commentTable.setList(
ModelWrapper.wrapModelCollection(
SessionManager.getAppService(),
containerInfo.container.getComments(),
CommentWrapper.class));
}
}