/** * */ package eu.quanticol.carma.core.ui.views; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; 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.Text; /** * @author loreti * */ public class MeasureParametersDialog extends TitleAreaDialog { private static final String RANGE_INDICATOR = ".."; private static final String SEPARATOR = ","; private Composite area; private Composite container; private String[] parameters; private Map<String, Class<?>> types; private Text[] parametersFields; private boolean withError = false; private List<Map<String, Object>> data; public MeasureParametersDialog(Shell parentShell, String[] parameters, Map<String, Class<?>> types) { super(parentShell); this.parameters = parameters; this.types = types; } @Override public void create() { super.create(); setTitle("Set measure parameters..."); setMessage("Insert measure parameters", IMessageProvider.INFORMATION); } @Override protected Control createDialogArea(Composite parent) { area = (Composite) super.createDialogArea(parent); container = new Composite(area, SWT.NONE); container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); GridLayout layout = new GridLayout(2, false); container.setLayout(layout); parametersFields = new Text[parameters.length]; for( int i=0 ; i<parameters.length ; i++ ) { Label lbtSimulationTime = new Label(container, SWT.NONE); lbtSimulationTime.setText("Parameter "+parameters[i]+" ("+getTypeOf(i)+"):"); GridData dataSimulationTime = new GridData(); dataSimulationTime.grabExcessHorizontalSpace = true; dataSimulationTime.horizontalAlignment = GridData.FILL; parametersFields[i] = new Text(container, SWT.BORDER | SWT.LEFT);; parametersFields[i].setLayoutData(dataSimulationTime); parametersFields[i].addModifyListener( new ModifyListener() { @Override public void modifyText(ModifyEvent e) { checkParameterType(); } }); } Label descriptionLabel = new Label(container, SWT.NONE); descriptionLabel.setText("You can provide multiple comma-separated values as well as " + "(for integer parameters) ranges, such as 2, 5..8, 10"); GridData descriptionLabelData = new GridData(); //descriptionLabelData.verticalAlignment = GridData.FILL; descriptionLabelData.horizontalSpan = 2; descriptionLabelData.verticalIndent = 10; descriptionLabel.setLayoutData(descriptionLabelData); return area; } private String getTypeOf(int i) { Class<?> type = types.get(parameters[i]); if (Integer.class.equals( type )) { return "int"; } if (Double.class.equals( type )) { return "real"; } return "?"; } protected void checkParameterType() { for( int i=0 ; i<parametersFields.length ; i++ ) { String txt = parametersFields[i].getText(); if (!txt.isEmpty()) { try { if ("int".equals(getTypeOf(i))) { for (String seg : txt.split(SEPARATOR)) { int idx = seg.indexOf(RANGE_INDICATOR); if (idx < 0) { Integer.parseInt(seg.trim()); } else { // check that range does not have repeated separators eg 1-5-10 int lastIdx = seg.lastIndexOf(RANGE_INDICATOR); if (lastIdx != idx) { setMessage("Malformed range for parameter " + parameters[i] +".", IMessageProvider.ERROR); withError = true; return; } else { Integer.parseInt(seg.substring(0, idx).trim()); Integer.parseInt(seg.substring(idx+RANGE_INDICATOR.length()).trim()); } } } } else if ("real".equals(getTypeOf(i))) { for (String seg : txt.split(SEPARATOR)) { if (seg.contains(RANGE_INDICATOR)) { setMessage("Ranges cannot be given for real-valued parameters.", IMessageProvider.ERROR); withError = true; return; } else { Double.parseDouble(seg); } } } } catch (NumberFormatException e) { setMessage("Wrong type for parameter "+parameters[i]+"!",IMessageProvider.ERROR); withError = true; return; } } } withError = false; setMessage(""); } public boolean isValid() { if (withError) { return false; } for (Text text : parametersFields) { if (text.getText().isEmpty()) { return false; } } return true; } public List<Map<String,Object>> getParameters() { return data; } /* private Object getValue(int i) { if ("int".equals(getTypeOf(i))) { return Integer.parseInt(parametersFields[i].getText()); } if ("real".equals(getTypeOf(i))) { return Double.parseDouble(parametersFields[i].getText()); } return null; } */ private List<? extends Object> getValues(int i) { if ("int".equals(getTypeOf(i))) { return parseTextForInteger(parametersFields[i].getText()); } if ("real".equals(getTypeOf(i))) { return parseTextForDouble(parametersFields[i].getText()); } return null; } private List<Integer> parseTextForInteger(String txt) { List<Integer> values = new ArrayList<Integer>(); for (String seg : txt.split(SEPARATOR)) { int idx = seg.indexOf(RANGE_INDICATOR); if (idx < 0) { values.add(Integer.parseInt(seg.trim())); } else { int low = Integer.parseInt(seg.substring(0, idx).trim()); int high = Integer.parseInt(seg.substring(idx+RANGE_INDICATOR.length()).trim()); while (low <= high) { values.add(low++); } } } return values; } private List<Double> parseTextForDouble(String txt) { List<Double> values = new ArrayList<Double>(); for (String seg : txt.split(SEPARATOR)) { values.add(Double.parseDouble(seg.trim())); } return values; } /* (non-Javadoc) * @see org.eclipse.jface.dialogs.Dialog#okPressed() */ @Override protected void okPressed() { if (isValid()) { saveInput(); super.okPressed(); } else { if (withError) { MessageDialog.openError(this.getShell(), "Error...", "Provided data are not correct!"); } else { MessageDialog.openError(this.getShell(), "Error...", "Fill all the required data!"); } } } /* private void saveInput() { data = new ArrayList<Map<String,Object>>(); data.add(new HashMap<String, Object>()); for( int i=0 ; i<parameters.length ; i++ ) { data.get(0).put(parameters[i], getValue(i)); } } */ private void saveInput() { data = new ArrayList<Map<String,Object>>(combineEntries()); } private List<Map<String,Object>> combineEntries() { List<Map<String,Object>> combs = new ArrayList<Map<String,Object>>(); combs.add(new HashMap<String,Object>()); for( int i=0 ; i<parameters.length ; i++ ) { List<Map<String,Object>> newCombs = new ArrayList<Map<String,Object>>(); for (Map<String,Object> previous : combs) { for (Object val : getValues(i)) { Map<String,Object> updated = new HashMap<String,Object>(previous); updated.put(parameters[i], val); newCombs.add(updated); } } combs = newCombs; } return combs; } }