/*- * Copyright 2015 Diamond Light Source Ltd. * * 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 */ package uk.ac.diamond.scisoft.xpdf.views; import java.util.ArrayList; import java.util.List; import org.eclipse.dawnsci.nexus.NexusException; import org.eclipse.dawnsci.nexus.builder.NexusFileBuilder; import org.eclipse.dawnsci.nexus.builder.impl.DefaultNexusFileBuilder; import org.eclipse.january.dataset.Dataset; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ViewPart; /** * The view containing the XPDF sample and phase editor. * @author Timothy Spain, timothy.spain@diamond.ac.uk * */ public class XPDFSampleEditorView extends ViewPart { private Button cifButton; private Button eraButton; private Button simButton; private Button savButton; private Button delButton; private Button clrButton; private Button cifPhaseButton; // private Button eraPhaseButton; private Button delPhaseButton; private Action loadTestDataAction; private Action simPDFAction; private Action saveAction; private Action newCifAction; private Action newEraAction; private Action newSampleAction; private Action newContainerAction; private Action pointBreakAction; private Action deleteAction; private Action clearAction; private Action deletePhaseAction; private Action newPhaseAction; private SampleGroupedTable sampleTable; private PhaseGroupedTable phaseTable; public XPDFSampleEditorView() { } /** * Constructs the view within parent * @param parent * {@link Composite} to contain the view. * @param style * style bits to apply to the view (ignored) */ public XPDFSampleEditorView(Composite parent, int style) { createPartControl(parent); } @Override public void createPartControl(Composite parent) { SashForm sampleEditorComposite = new SashForm(parent, SWT.VERTICAL); // Overall composite of the view Composite sampleTableCompo = new Composite(sampleEditorComposite, SWT.BORDER); sampleTableCompo.setLayout(new FormLayout()); Composite phaseTableCompo = new Composite(sampleEditorComposite, SWT.BORDER); phaseTableCompo.setLayout(new FormLayout()); sampleEditorComposite.setWeights(new int[]{1,1}); sampleTable = new SampleGroupedTable(sampleTableCompo, SWT.NONE); Composite buttonCompo = new Composite(sampleTableCompo, SWT.NONE); phaseTable = new PhaseGroupedTable(phaseTableCompo, SWT.NONE); Composite phaseButtonCompo = new Composite(phaseTableCompo, SWT.NONE); sampleTable.setPhaseTable(phaseTable); phaseTable.setSampleTable(sampleTable); FormData formData = new FormData(); formData.left = new FormAttachment(0); formData.right = new FormAttachment(100); formData.top = new FormAttachment(0); formData.bottom = new FormAttachment(buttonCompo); // formData.height = 800; sampleTable.setLayoutData(formData); formData = new FormData(); formData.left = new FormAttachment(0); formData.right = new FormAttachment(100); // formData.top = new FormAttachment(sampleTable); formData.bottom = new FormAttachment(100); buttonCompo.setLayoutData(formData); buttonCompo.setLayout(new FormLayout()); formData = new FormData(); formData.left = new FormAttachment(0); formData.right = new FormAttachment(100); formData.bottom = new FormAttachment(phaseButtonCompo); formData.top = new FormAttachment(0); // formData.top = new FormAttachment(buttonCompo); phaseTable.setLayoutData(formData); formData = new FormData(); formData.left = new FormAttachment(0); formData.right = new FormAttachment(100); formData.bottom = new FormAttachment(100); phaseButtonCompo.setLayoutData(formData); phaseButtonCompo.setLayout(new FormLayout()); createActions(); createLoadButtons(buttonCompo); createCentreButtons(buttonCompo); createRHSButtons(buttonCompo); createPhaseLoadButtons(phaseButtonCompo); createPhaseCentreButtons(phaseButtonCompo); sampleTable.setInput(); phaseTable.setInput(); } private void createActions() { // load the nonsense test data loadTestDataAction = new LoadTestDataAction(); loadTestDataAction.setText("Load test data"); loadTestDataAction.setToolTipText("Load the test data"); loadTestDataAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_FILE)); // do nothing but allow a breakpoint hook pointBreakAction = new Action() { @Override public void run() { sampleTable.get(0).getDensity(); } }; pointBreakAction.setToolTipText("Ze goggles, zey..."); pointBreakAction.setText("...do nothing"); pointBreakAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ETOOL_CLEAR)); // save the data // saveAction = new Action() { // @Override // public void run() { // for (XPDFSampleParameters sample : sampleTable.getAll()) // System.err.println(sample.toString()); // } // }; // saveAction.setToolTipText("Save data to stderr"); saveAction = new WriteNexusAction(); saveAction.setToolTipText("Write to a pre-specified NeXus file"); saveAction.setText("Save"); saveAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ETOOL_SAVE_EDIT)); // add a new entry to the end of the list newSampleAction = new Action() { @Override public void run() { XPDFSampleParameters blankSample = new XPDFSampleParameters(true); // blankSample.setId(generateUniqueID()); sampleTable.add(blankSample); } }; newSampleAction.setText("New sample"); newSampleAction.setToolTipText("Add an empty sample to the table"); newSampleAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_ADD)); newContainerAction = new Action() { @Override public void run() { sampleTable.add(new XPDFSampleParameters(false)); } }; newContainerAction.setText("New container"); newContainerAction.setToolTipText("Add an empty container to the table"); newContainerAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_ADD)); // clear all the data from the list clearAction = new Action() { @Override public void run() { sampleTable.clear(); } }; clearAction.setText("Clear"); clearAction.setToolTipText("Clear all entries"); clearAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ETOOL_CLEAR)); // delete a selected entry deleteAction = new DeleteSampleAction(); deleteAction.setText("Delete"); deleteAction.setToolTipText("Delete selected samples"); deleteAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ETOOL_DELETE)); // simulate a PDF simPDFAction = new SimulatePDFAction(); simPDFAction.setText("Simulate"); simPDFAction.setToolTipText("Simulate a PDF for each of the selected samples"); // Phase Table Actions deletePhaseAction = new DeletePhaseAction(); deletePhaseAction.setText("Delete unused"); deletePhaseAction.setToolTipText("Delete selected (or all) phases not used by a sample."); newPhaseAction = new NewPhaseAction(); newPhaseAction.setText("New"); newPhaseAction.setToolTipText("New blank phase"); hookIntoContextMenu(); hookIntoPhaseContextMenu(); } private void createRHSButtons(Composite parent) { int rightMargin = -10; int topMargin = 10; // Composite stCompo = compoAbove.getParent(); simButton = new Button(parent, SWT.NONE); FormData formData= new FormData(); formData.right = new FormAttachment(100, rightMargin); formData.top = new FormAttachment(0, topMargin); simButton.setLayoutData(formData); simButton.setText("Simulate PDF"); simButton.setToolTipText("Produce a simulated pair distribution function for the selected sample"); simButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { simPDFAction.run(); } }); savButton = new Button(parent, SWT.NONE); formData = new FormData(); formData.right = new FormAttachment(100, rightMargin); formData.top = new FormAttachment(simButton, topMargin); formData.bottom = new FormAttachment(100, -topMargin); savButton.setLayoutData(formData); savButton.setText("Save"); savButton.setToolTipText("Save the sample data to file (or the database?)"); savButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { saveAction.run(); } }); } private void createCentreButtons(Composite parent) { int offset = 10; // int bottomMargin = -10; // Composite stCompo = compoAbove.getParent(); delButton = new Button(parent, SWT.NONE); FormData formData = new FormData(); formData.left = new FormAttachment(50); formData.top = new FormAttachment(0, offset); delButton.setLayoutData(formData); delButton.setText(deleteAction.getText()); delButton.setToolTipText(deleteAction.getToolTipText()); delButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { deleteAction.run(); } }); // clrButton = new Button(parent, SWT.NONE); // formData = new FormData(); // formData.left = new FormAttachment(50); // formData.top = new FormAttachment(delButton, offset); // formData.bottom = new FormAttachment(100, bottomMargin); // clrButton.setLayoutData(formData); // clrButton.setText(clearAction.getText()); // clrButton.setToolTipText(clearAction.getToolTipText()); // clrButton.addSelectionListener(new SelectionAdapter() { // @Override // public void widgetSelected(SelectionEvent event) { // clearAction.run(); // } // }); } private void createLoadButtons(Composite parent) { int leftMargin = 10; int topMargin = 10; // Composite stCompo = compoAbove.getParent(); cifButton = new Button(parent, SWT.NONE); FormData formData = new FormData(); formData.left = new FormAttachment(0, leftMargin); formData.top = new FormAttachment(0, topMargin); cifButton.setLayoutData(formData); cifButton.setText("New sample from CIF file"); cifButton.setToolTipText("Create new sample from the data contained in a specified Crystallographic Information File."); eraButton = new Button(parent, SWT.NONE); formData = new FormData(); formData.left = new FormAttachment(0, leftMargin); formData.top = new FormAttachment(cifButton, topMargin); formData.bottom = new FormAttachment(100, -topMargin); eraButton.setLayoutData(formData); eraButton.setText("New sample from ERA file"); eraButton.setToolTipText("Create a new sample from the data contained in a specified ERA file."); } private void createPhaseLoadButtons(Composite parent) { int leftMargin = 10; int topMargin = 10; // Composite stCompo = compoAbove.getParent(); cifPhaseButton = new Button(parent, SWT.NONE); FormData formData = new FormData(); formData.left = new FormAttachment(0, leftMargin); formData.top = new FormAttachment(0, topMargin); formData.bottom = new FormAttachment(100, -topMargin); cifPhaseButton.setLayoutData(formData); cifPhaseButton.setText("New phase(s) from CIF file"); cifPhaseButton.setToolTipText("Create new phase(s) from the data contained in a specified Crystallographic Information File."); } private void createPhaseCentreButtons(Composite parent) { int offset = 10; // int bottomMargin = -10; // Composite stCompo = compoAbove.getParent(); delPhaseButton = new Button(parent, SWT.NONE); FormData formData = new FormData(); formData.left = new FormAttachment(50); formData.top = new FormAttachment(0, offset); delPhaseButton.setLayoutData(formData); delPhaseButton.setText(deletePhaseAction.getText()); delPhaseButton.setToolTipText(deletePhaseAction.getToolTipText()); delPhaseButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { deletePhaseAction.run(); } }); } @Override public void setFocus() { sampleTable.setFocus(); } // Hook actions into the context menu private void hookIntoContextMenu() { MenuManager menuMan = new MenuManager("#PopupMenu"); menuMan.setRemoveAllWhenShown(true); menuMan.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager manager) { fillContextMenu(manager); } }); sampleTable.createContextMenu(menuMan); } protected void fillContextMenu(IMenuManager manager) { manager.add(loadTestDataAction); manager.add(newSampleAction); manager.add(newContainerAction); manager.add(saveAction); manager.add(deleteAction); manager.add(clearAction); manager.add(new Separator("Data")); manager.add(simPDFAction); manager.add(new Separator("Debug")); manager.add(pointBreakAction); } // Action class that simulates the pair-distribution function of the given sample. // At the moment, this plots the NIST ceria standard PDF private class SimulatePDFAction extends Action { @Override public void run() { List<XPDFSampleParameters> selectedXPDFParameters = sampleTable.getSelectedSamples(); if (selectedXPDFParameters.isEmpty()) return; // Get the pair-distribution function data for each sample List<Dataset> simulatedPDFs = new ArrayList<Dataset>(selectedXPDFParameters.size()); for (int i = 0; i < selectedXPDFParameters.size(); i++) simulatedPDFs.add(i, selectedXPDFParameters.get(i).getSimulatedPDF()); // Because the XPDF Sample View is not necessarily going to be // used in a Perspective containing a plot view, and because there // may be many selected samples, open an new plot window, and plot // the data there. // TODO: Do something with the data // for (Dataset pdf : simulatedPDFs) { // } } } private class DeleteSampleAction extends Action { @Override public void run() { List<XPDFSampleParameters> selectedXPDFParameters = sampleTable.getSelectedSamples(); if (selectedXPDFParameters.isEmpty()) return; sampleTable.removeAll(selectedXPDFParameters); } } private void hookIntoPhaseContextMenu() { MenuManager menuMan = new MenuManager("#PopupMenu"); menuMan.setRemoveAllWhenShown(true); menuMan.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager manager) { fillPhaseContextMenu(manager); } }); phaseTable.createContextMenu(menuMan); } protected void fillPhaseContextMenu(IMenuManager manager) { manager.add(newPhaseAction); manager.add(deletePhaseAction); } private class DeletePhaseAction extends Action { @Override public void run() { List<XPDFPhase> selectedPhases = phaseTable.getSelectedPhases(); if (selectedPhases.isEmpty()) selectedPhases = phaseTable.getAll(); List<XPDFPhase> usedPhases = sampleTable.getAllPhases(); List<XPDFPhase> unusedPhases = new ArrayList<XPDFPhase>(); for (XPDFPhase phase : selectedPhases) if (!usedPhases.contains(phase)) unusedPhases.add(phase); phaseTable.removeAll(unusedPhases); phaseTable.refresh(); } } private class NewPhaseAction extends Action { @Override public void run() { List<XPDFPhase> newPhases = new ArrayList<XPDFPhase>(); newPhases.add(new XPDFPhase()); phaseTable.addPhases(newPhases); } } // // Generate a new id // int generateUniqueID() { // final int lowestID = 154; // if (usedIDs == null) // usedIDs = new TreeSet<Integer>(); // int theID = (usedIDs.isEmpty()) ? lowestID : usedIDs.last()+1; // usedIDs.add(theID); // return theID; // } // Sample data with integer multiplicities private class LoadTestDataAction extends Action { @Override public void run() { // barium titanate sampleTable.add(SampleTestData.createTestSample("Barium Titanate")); // rutile sampleTable.add(SampleTestData.createTestSample("Rutile")); // ceria sampleTable.add(SampleTestData.createTestSample("ceria")); // quartz capillary sampleTable.add(SampleTestData.createTestSample("Quartz Capillary")); } } private class WriteNexusAction extends Action { @Override public void run() { XPDFSampleParameters firstSelectedSample = sampleTable.getSelectedSamples().get(0); String filename = "/home/rkl37156/" + firstSelectedSample.getName() + ".nxs"; NexusFileBuilder builder = new DefaultNexusFileBuilder(filename); firstSelectedSample.getNXsample(builder); try { builder.createFile(false); System.err.println("Success writing NeXus file to " + filename); } catch (NexusException nE) { System.err.println("Error writing NeXus file to " + filename + ": " + nE.toString()); } } } }