1 package org.simantics.district.imports.ui;
3 import java.io.IOException;
4 import java.util.HashMap;
7 import java.util.Map.Entry;
10 import org.apache.commons.csv.CSVRecord;
11 import org.eclipse.jface.dialogs.IPageChangeProvider;
12 import org.eclipse.jface.dialogs.IPageChangedListener;
13 import org.eclipse.jface.dialogs.PageChangedEvent;
14 import org.eclipse.jface.layout.GridDataFactory;
15 import org.eclipse.jface.layout.TableColumnLayout;
16 import org.eclipse.jface.viewers.ColumnWeightData;
17 import org.eclipse.jface.wizard.IWizardContainer;
18 import org.eclipse.jface.wizard.WizardPage;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.ModifyEvent;
21 import org.eclipse.swt.events.ModifyListener;
22 import org.eclipse.swt.events.SelectionAdapter;
23 import org.eclipse.swt.events.SelectionEvent;
24 import org.eclipse.swt.events.SelectionListener;
25 import org.eclipse.swt.layout.GridLayout;
26 import org.eclipse.swt.widgets.Button;
27 import org.eclipse.swt.widgets.Combo;
28 import org.eclipse.swt.widgets.Composite;
29 import org.eclipse.swt.widgets.Group;
30 import org.eclipse.swt.widgets.Label;
31 import org.eclipse.swt.widgets.Table;
32 import org.eclipse.swt.widgets.TableColumn;
33 import org.eclipse.swt.widgets.TableItem;
34 import org.geotools.referencing.CRS;
35 import org.simantics.district.imports.ui.controls.DynamicComboFieldEditor;
37 public class CSVImportWizardPage extends WizardPage {
39 private CSVImportModel model;
41 private Map<Integer, String> headerIndexAndValues = new HashMap<>();
43 private Table headerTable;
44 // private Button firstAsHeader;
46 private Combo delimiterCombo;
47 private TableColumnLayout tableColumnLayout;
48 private Composite tableComposite;
49 // private FileSelectionWidget wktFileSelection;
51 // Common for vertex and edge
52 private DynamicComboFieldEditor componentMappingSelector;
53 private DynamicComboFieldEditor labelSelector;
56 private DynamicComboFieldEditor xCoordSelector;
57 private DynamicComboFieldEditor yCoordSelector;
58 private DynamicComboFieldEditor zValueSelector;
61 private DynamicComboFieldEditor startXCoordSelector;
62 private DynamicComboFieldEditor startYCoordSelector;
63 private DynamicComboFieldEditor startZValueSelector;
64 private DynamicComboFieldEditor endXCoordSelector;
65 private DynamicComboFieldEditor endYCoordSelector;
66 private DynamicComboFieldEditor endZValueSelector;
67 private DynamicComboFieldEditor tempValueSelector;
68 private DynamicComboFieldEditor pressureValueSelector;
70 private DynamicComboFieldEditor outerDiameterSelector;
71 private DynamicComboFieldEditor diameterSelector;
72 private DynamicComboFieldEditor nominalMassFlowSelector;
74 private Group indexMappingGroup;
76 private Composite composite;
78 private Button isVertexImport;
80 private Combo sourceCRSCombo;
82 protected CSVImportWizardPage(CSVImportModel model) {
83 super("Import CSV Data");
85 setMessage("Select column index mappings");
89 public void createControl(Composite parent) {
90 composite = new Composite(parent, SWT.NONE);
91 composite.setLayout(new GridLayout(1, false));
92 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(composite);
94 Label label = new Label(composite, SWT.NONE);
95 label.setText("Select delimiter");
97 delimiterCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
98 delimiterCombo.setToolTipText("Select the delimiter that is used to separate elements in the CSV file");
99 delimiterCombo.setItems(model.getDelimiterFormats());
100 delimiterCombo.addSelectionListener(new SelectionListener() {
103 public void widgetSelected(SelectionEvent e) {
104 model.setDelimiterByLabel(delimiterCombo.getItem(delimiterCombo.getSelectionIndex()));
110 public void widgetDefaultSelected(SelectionEvent e) {
115 // firstAsHeader = new Button(composite, SWT.CHECK);
116 // firstAsHeader.setText("Read first row as header");
117 // firstAsHeader.setSelection(model.getReadFirstAsHeader());
118 // firstAsHeader.addSelectionListener(new SelectionListener() {
121 // public void widgetSelected(SelectionEvent e) {
122 // model.setReadFirstAsHeader(firstAsHeader.getSelection());
128 // public void widgetDefaultSelected(SelectionEvent e) {
129 // widgetSelected(e);
133 tableComposite = new Composite(composite, SWT.BORDER);
134 tableColumnLayout = new TableColumnLayout();
135 tableComposite.setLayout(tableColumnLayout);
137 label = new Label(composite, SWT.NONE);
138 label.setText("Select source Coordinate Reference System");
140 sourceCRSCombo = new Combo(composite, SWT.NONE);
141 sourceCRSCombo.setToolTipText("Select the coordinate reference system that is used in the source material for possible transformation to target coordinate reference system (EPSG:4326)");
142 Set<String> codes = CRS.getSupportedCodes("EPSG");
143 sourceCRSCombo.setItems(codes.toArray(new String[codes.size()]));
144 sourceCRSCombo.addSelectionListener(new SelectionAdapter() {
147 public void widgetSelected(SelectionEvent e) {
148 String current = sourceCRSCombo.getItem(sourceCRSCombo.getSelectionIndex());
149 model.setSourceCRS("EPSG:" + current);
153 sourceCRSCombo.addModifyListener(new ModifyListener() {
156 public void modifyText(ModifyEvent e) {
157 String currentText = sourceCRSCombo.getText();
158 if (codes.contains(currentText)) {
160 String[] items = sourceCRSCombo.getItems();
162 for (i = 0; i < items.length; i++) {
163 String item = items[i];
164 if (currentText.equals(item)) {
169 sourceCRSCombo.select(i);
170 model.setSourceCRS("EPSG:" + currentText);
172 System.err.println("this should not happen");
178 // wktFileSelection = new FileSelectionWidget(composite, "WKT file", SWT.OPEN);
179 // wktFileSelection.addListener(new FileSelectionListener() {
182 // public void fileSelected(FileOrDirectorySelectionWidget source, String[] filename) {
183 // String[] selection = wktFileSelection.getFilename();
184 // if (selection != null && selection.length > 0) {
185 // Path wktFile = Paths.get(selection[0]);
186 // if (!Files.exists(wktFile)) {
187 // setErrorMessage("File " + wktFile.toAbsolutePath() + " does not exist");
189 // model.setWKTFile(wktFile);
190 // validatePageComplete();
196 isVertexImport = new Button(composite, SWT.CHECK);
197 isVertexImport.setText("File contains vertices");
198 isVertexImport.setToolTipText("Enable this if the file contains vertices, i.e. points");
199 isVertexImport.setSelection(model.isVertexImport());
200 isVertexImport.addSelectionListener(new SelectionListener() {
203 public void widgetSelected(SelectionEvent e) {
204 model.setVertexImport(isVertexImport.getSelection());
205 updateControls(false);
209 public void widgetDefaultSelected(SelectionEvent e) {
214 updateControls(true);
216 setControl(composite);
218 final IWizardContainer container = getContainer();
220 if (container instanceof IPageChangeProvider) {
221 ((IPageChangeProvider) container).addPageChangedListener(new IPageChangedListener() {
224 public void pageChanged(PageChangedEvent event) {
226 CSVImportWizardPage.this.updateControls(false);
231 validatePageComplete();
234 private void updateControls(boolean initial) {
235 createIndexMappingGroup();
238 composite.layout(true, true);
241 private void createIndexMappingGroup() {
242 if (indexMappingGroup != null)
243 indexMappingGroup.dispose();
245 indexMappingGroup = new Group(composite, SWT.NONE);
246 indexMappingGroup.setText("Column index mapping");
247 GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(indexMappingGroup);
249 if (model.isVertexImport())
250 createVertexIndexMappingField(indexMappingGroup);
252 createEdgeIndexMappingField(indexMappingGroup);
254 createCommonIndexMappingField(indexMappingGroup);
257 private void createCommonIndexMappingField(Group parent) {
259 componentMappingSelector = new DynamicComboFieldEditor("componentMapping", "Apros component mapping", parent);
260 componentMappingSelector.addComboListener(new SelectionListener() {
263 public void widgetSelected(SelectionEvent e) {
264 widgetDefaultSelected(e);
268 public void widgetDefaultSelected(SelectionEvent e) {
269 model.setComponentMappingIndex(Integer.parseInt(componentMappingSelector.getValue()));
270 validatePageComplete();
276 private void createVertexIndexMappingField(Group parent) {
277 xCoordSelector = new DynamicComboFieldEditor("xCoord", "X Coordinate", parent);
278 xCoordSelector.addComboListener(new SelectionListener() {
281 public void widgetSelected(SelectionEvent e) {
282 widgetDefaultSelected(e);
286 public void widgetDefaultSelected(SelectionEvent e) {
287 model.setXCoordIndex(Integer.parseInt(xCoordSelector.getValue()));
288 validatePageComplete();
292 yCoordSelector = new DynamicComboFieldEditor("yCoord", "Y Coordinate", parent);
293 yCoordSelector.addComboListener(new SelectionListener() {
296 public void widgetSelected(SelectionEvent e) {
297 widgetDefaultSelected(e);
301 public void widgetDefaultSelected(SelectionEvent e) {
302 model.setYCoordIndex(Integer.parseInt(yCoordSelector.getValue()));
303 validatePageComplete();
306 zValueSelector = new DynamicComboFieldEditor("zValue", "Z Value", parent);
307 zValueSelector.addComboListener(new SelectionListener() {
310 public void widgetSelected(SelectionEvent e) {
311 widgetDefaultSelected(e);
315 public void widgetDefaultSelected(SelectionEvent e) {
316 model.setZCoordIndex(Integer.parseInt(zValueSelector.getValue()));
317 validatePageComplete();
320 tempValueSelector = new DynamicComboFieldEditor("tempValue", "Temperature value", parent);
321 tempValueSelector.addComboListener(new SelectionListener() {
324 public void widgetSelected(SelectionEvent e) {
325 widgetDefaultSelected(e);
329 public void widgetDefaultSelected(SelectionEvent e) {
330 model.setTempIndex(Integer.parseInt(tempValueSelector.getValue()));
331 validatePageComplete();
334 pressureValueSelector = new DynamicComboFieldEditor("pressureValue", "Pressure value", parent);
335 pressureValueSelector.addComboListener(new SelectionListener() {
338 public void widgetSelected(SelectionEvent e) {
339 widgetDefaultSelected(e);
343 public void widgetDefaultSelected(SelectionEvent e) {
344 model.setPressureIndex(Integer.parseInt(pressureValueSelector.getValue()));
345 validatePageComplete();
350 private void createEdgeIndexMappingField(Group parent) {
351 startXCoordSelector = new DynamicComboFieldEditor("startxCoord", "Start X Coordinate", parent);
352 startXCoordSelector.addComboListener(new SelectionListener() {
355 public void widgetSelected(SelectionEvent e) {
356 widgetDefaultSelected(e);
360 public void widgetDefaultSelected(SelectionEvent e) {
361 model.setStartXCoordIndex(Integer.parseInt(startXCoordSelector.getValue()));
362 validatePageComplete();
366 startYCoordSelector = new DynamicComboFieldEditor("startyCoord", "Start Y Coordinate", parent);
367 startYCoordSelector.addComboListener(new SelectionListener() {
370 public void widgetSelected(SelectionEvent e) {
371 widgetDefaultSelected(e);
375 public void widgetDefaultSelected(SelectionEvent e) {
376 model.setStartYCoordIndex(Integer.parseInt(startYCoordSelector.getValue()));
377 validatePageComplete();
380 startZValueSelector = new DynamicComboFieldEditor("startzValue", "Start Z Value", parent);
381 startZValueSelector.addComboListener(new SelectionListener() {
384 public void widgetSelected(SelectionEvent e) {
385 widgetDefaultSelected(e);
389 public void widgetDefaultSelected(SelectionEvent e) {
390 model.setStartZCoordIndex(Integer.parseInt(startZValueSelector.getValue()));
391 validatePageComplete();
395 endXCoordSelector = new DynamicComboFieldEditor("endxCoord", "End X Coordinate", parent);
396 endXCoordSelector.addComboListener(new SelectionListener() {
399 public void widgetSelected(SelectionEvent e) {
400 widgetDefaultSelected(e);
404 public void widgetDefaultSelected(SelectionEvent e) {
405 model.setEndXCoordIndex(Integer.parseInt(endXCoordSelector.getValue()));
406 validatePageComplete();
410 endYCoordSelector = new DynamicComboFieldEditor("endyCoord", "End Y Coordinate", parent);
411 endYCoordSelector.addComboListener(new SelectionListener() {
414 public void widgetSelected(SelectionEvent e) {
415 widgetDefaultSelected(e);
419 public void widgetDefaultSelected(SelectionEvent e) {
420 model.setEndYCoordIndex(Integer.parseInt(endYCoordSelector.getValue()));
421 validatePageComplete();
424 endZValueSelector = new DynamicComboFieldEditor("endzValue", "End Z Value", parent);
425 endZValueSelector.addComboListener(new SelectionListener() {
428 public void widgetSelected(SelectionEvent e) {
429 widgetDefaultSelected(e);
433 public void widgetDefaultSelected(SelectionEvent e) {
434 model.setEndZCoordIndex(Integer.parseInt(endZValueSelector.getValue()));
435 validatePageComplete();
438 diameterSelector = new DynamicComboFieldEditor("diameterValue", "Diameter value", parent);
439 diameterSelector.addComboListener(new SelectionListener() {
442 public void widgetSelected(SelectionEvent e) {
443 widgetDefaultSelected(e);
447 public void widgetDefaultSelected(SelectionEvent e) {
448 model.setDiameterIndex(Integer.parseInt(diameterSelector.getValue()));
449 validatePageComplete();
452 outerDiameterSelector = new DynamicComboFieldEditor("outerDiameterValue", "Outer Diameter value", parent);
453 outerDiameterSelector.addComboListener(new SelectionListener() {
456 public void widgetSelected(SelectionEvent e) {
457 widgetDefaultSelected(e);
461 public void widgetDefaultSelected(SelectionEvent e) {
462 model.setOuterDiameterIndex(Integer.parseInt(outerDiameterSelector.getValue()));
463 validatePageComplete();
466 nominalMassFlowSelector = new DynamicComboFieldEditor("nominalMassFlowValue", "Nominal Mass Flow", parent);
467 nominalMassFlowSelector.addComboListener(new SelectionListener() {
470 public void widgetSelected(SelectionEvent e) {
471 widgetDefaultSelected(e);
475 public void widgetDefaultSelected(SelectionEvent e) {
476 model.setNominalMassFlowIndex(Integer.parseInt(nominalMassFlowSelector.getValue()));
477 validatePageComplete();
482 private void updateCombos() {
483 String[][] namesAndValues = new String[headerIndexAndValues.size()][];
486 for (Entry<Integer, String> entry : headerIndexAndValues.entrySet()) {
487 int key = entry.getKey();
488 String value = entry.getValue();
490 String[] nameAndValue = new String[2];
491 nameAndValue[0] = value;
492 nameAndValue[1] = Integer.toString(key);
493 namesAndValues[i++] = nameAndValue;
496 if (model.isVertexImport())
497 updateVertexCombos(namesAndValues);
499 updateEdgeCombos(namesAndValues);
501 componentMappingSelector.updateCombo(namesAndValues);
504 private void updateEdgeCombos(String[][] namesAndValues) {
505 startXCoordSelector.updateCombo(namesAndValues);
506 endXCoordSelector.updateCombo(namesAndValues);
507 startYCoordSelector.updateCombo(namesAndValues);
508 endYCoordSelector.updateCombo(namesAndValues);
509 startZValueSelector.updateCombo(namesAndValues);
510 endZValueSelector.updateCombo(namesAndValues);
511 diameterSelector.updateCombo(namesAndValues);
512 outerDiameterSelector.updateCombo(namesAndValues);
513 nominalMassFlowSelector.updateCombo(namesAndValues);
516 private void updateVertexCombos(String[][] namesAndValues) {
517 xCoordSelector.updateCombo(namesAndValues);
518 yCoordSelector.updateCombo(namesAndValues);
519 zValueSelector.updateCombo(namesAndValues);
520 pressureValueSelector.updateCombo(namesAndValues);
521 tempValueSelector.updateCombo(namesAndValues);
524 private void updateHeaders() {
525 if (headerTable != null)
526 headerTable.dispose();
527 headerTable = new Table(tableComposite, SWT.NONE);
528 headerTable.setHeaderVisible(true);
529 headerTable.setLinesVisible(true);
530 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(tableComposite);
531 for (int i = 0; i < headerTable.getColumns().length; i++) {
532 TableColumn column = headerTable.getColumns()[i];
535 for (int i = 0; i < headerTable.getItemCount(); i++) {
536 TableItem item = headerTable.getItem(i);
540 headerIndexAndValues.clear();
543 List<CSVRecord> rows = model.getRows(5);
545 for (int k = 0; k < rows.size(); k++) {
546 CSVRecord row = rows.get(k);
548 int columnCount = row.size();
549 for (int i = 0; i < columnCount; i++) {
550 String value = row.get(i);
552 TableColumn headerCol = new TableColumn(headerTable, SWT.NONE);
553 headerCol.setText(value);
555 tableColumnLayout.setColumnData(headerCol, new ColumnWeightData(10));
558 headerIndexAndValues.put(i, value);
562 int itemCount = headerTable.getItemCount();
563 if (actualK >= itemCount) {
564 item = new TableItem(headerTable, SWT.NONE);
566 item = headerTable.getItem(actualK);
568 item.setText(i, value);
573 } catch (IOException e) {
574 setErrorMessage(e.getMessage());
578 protected void validatePageComplete() {
579 if (model.isVertexImport())
580 setPageComplete(model.getXCoordIndex() != -1 && model.getYCoordIndex() != -1 && model.getComponentMappingIndex() != -1);
582 setPageComplete(model.getStartXCoordIndex() != 1 && model.getStartYCoordIndex() != -1 && model.getEndXCoordIndex() != -1 && model.getEndYCoordIndex() != -1 && model.getComponentMappingIndex() != -1);