1 package org.simantics.district.imports.ui;
3 import java.io.IOException;
4 import java.nio.file.Files;
5 import java.nio.file.Path;
6 import java.nio.file.Paths;
7 import java.util.HashMap;
10 import java.util.Map.Entry;
12 import org.apache.commons.csv.CSVRecord;
13 import org.eclipse.jface.dialogs.IPageChangeProvider;
14 import org.eclipse.jface.dialogs.IPageChangedListener;
15 import org.eclipse.jface.dialogs.PageChangedEvent;
16 import org.eclipse.jface.layout.GridDataFactory;
17 import org.eclipse.jface.layout.TableColumnLayout;
18 import org.eclipse.jface.viewers.ColumnWeightData;
19 import org.eclipse.jface.wizard.IWizardContainer;
20 import org.eclipse.jface.wizard.WizardPage;
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.events.SelectionEvent;
23 import org.eclipse.swt.events.SelectionListener;
24 import org.eclipse.swt.layout.GridLayout;
25 import org.eclipse.swt.widgets.Button;
26 import org.eclipse.swt.widgets.Combo;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Group;
29 import org.eclipse.swt.widgets.Table;
30 import org.eclipse.swt.widgets.TableColumn;
31 import org.eclipse.swt.widgets.TableItem;
32 import org.simantics.district.imports.ui.controls.DynamicComboFieldEditor;
33 import org.simantics.utils.ui.widgets.FileOrDirectorySelectionWidget;
34 import org.simantics.utils.ui.widgets.FileSelectionListener;
35 import org.simantics.utils.ui.widgets.FileSelectionWidget;
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;
68 private Group indexMappingGroup;
70 private Composite composite;
72 private Button isVertexImport;
74 protected CSVImportWizardPage(CSVImportModel model) {
75 super("Import CSV Data");
77 setMessage("Select columng index mappings");
81 public void createControl(Composite parent) {
82 composite = new Composite(parent, SWT.NONE);
83 composite.setLayout(new GridLayout(1, false));
84 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(composite);
86 delimiterCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
87 delimiterCombo.setItems(model.getDelimiterFormats());
88 delimiterCombo.addSelectionListener(new SelectionListener() {
91 public void widgetSelected(SelectionEvent e) {
92 model.setDelimiterByLabel(delimiterCombo.getItem(delimiterCombo.getSelectionIndex()));
98 public void widgetDefaultSelected(SelectionEvent e) {
103 firstAsHeader = new Button(composite, SWT.CHECK);
104 firstAsHeader.setText("Read first row as header");
105 firstAsHeader.setSelection(model.getReadFirstAsHeader());
106 firstAsHeader.addSelectionListener(new SelectionListener() {
109 public void widgetSelected(SelectionEvent e) {
110 model.setReadFirstAsHeader(firstAsHeader.getSelection());
116 public void widgetDefaultSelected(SelectionEvent e) {
121 tableComposite = new Composite(composite, SWT.BORDER);
122 tableColumnLayout = new TableColumnLayout();
123 tableComposite.setLayout(tableColumnLayout);
125 wktFileSelection = new FileSelectionWidget(composite, "WKT file", SWT.OPEN);
126 wktFileSelection.addListener(new FileSelectionListener() {
129 public void fileSelected(FileOrDirectorySelectionWidget source, String[] filename) {
130 String[] selection = wktFileSelection.getFilename();
131 if (selection != null && selection.length > 0) {
132 Path wktFile = Paths.get(selection[0]);
133 if (!Files.exists(wktFile)) {
134 setErrorMessage("File " + wktFile.toAbsolutePath() + " does not exist");
136 model.setWKTFile(wktFile);
137 validatePageComplete();
143 isVertexImport = new Button(composite, SWT.CHECK);
144 isVertexImport.setText("File contains vertices");
145 isVertexImport.setSelection(model.isVertexImport());
146 isVertexImport.addSelectionListener(new SelectionListener() {
149 public void widgetSelected(SelectionEvent e) {
150 model.setVertexImport(isVertexImport.getSelection());
151 updateControls(false);
155 public void widgetDefaultSelected(SelectionEvent e) {
160 updateControls(true);
162 setControl(composite);
164 final IWizardContainer container = getContainer();
166 if (container instanceof IPageChangeProvider) {
167 ((IPageChangeProvider) container).addPageChangedListener(new IPageChangedListener() {
170 public void pageChanged(PageChangedEvent event) {
172 CSVImportWizardPage.this.updateControls(false);
177 validatePageComplete();
180 private void updateControls(boolean initial) {
181 createIndexMappingGroup();
184 composite.layout(true, true);
187 private void createIndexMappingGroup() {
188 if (indexMappingGroup != null)
189 indexMappingGroup.dispose();
191 indexMappingGroup = new Group(composite, SWT.NONE);
192 indexMappingGroup.setText("Column index mapping");
193 GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(indexMappingGroup);
195 if (model.isVertexImport())
196 createVertexIndexMappingField(indexMappingGroup);
198 createEdgeIndexMappingField(indexMappingGroup);
200 createCommonIndexMappingField(indexMappingGroup);
203 private void createCommonIndexMappingField(Group parent) {
205 componentMappingSelector = new DynamicComboFieldEditor("componentMapping", "Apros component mapping", parent);
206 componentMappingSelector.addComboListener(new SelectionListener() {
209 public void widgetSelected(SelectionEvent e) {
210 widgetDefaultSelected(e);
214 public void widgetDefaultSelected(SelectionEvent e) {
215 model.setComponentMappingIndex(Integer.parseInt(componentMappingSelector.getValue()));
216 validatePageComplete();
222 private void createVertexIndexMappingField(Group parent) {
223 xCoordSelector = new DynamicComboFieldEditor("xCoord", "X Coordinate", parent);
224 xCoordSelector.addComboListener(new SelectionListener() {
227 public void widgetSelected(SelectionEvent e) {
228 widgetDefaultSelected(e);
232 public void widgetDefaultSelected(SelectionEvent e) {
233 model.setXCoordIndex(Integer.parseInt(xCoordSelector.getValue()));
234 validatePageComplete();
238 yCoordSelector = new DynamicComboFieldEditor("yCoord", "Y Coordinate", parent);
239 yCoordSelector.addComboListener(new SelectionListener() {
242 public void widgetSelected(SelectionEvent e) {
243 widgetDefaultSelected(e);
247 public void widgetDefaultSelected(SelectionEvent e) {
248 model.setYCoordIndex(Integer.parseInt(yCoordSelector.getValue()));
249 validatePageComplete();
252 zValueSelector = new DynamicComboFieldEditor("zValue", "Z Value", parent);
253 zValueSelector.addComboListener(new SelectionListener() {
256 public void widgetSelected(SelectionEvent e) {
257 widgetDefaultSelected(e);
261 public void widgetDefaultSelected(SelectionEvent e) {
262 model.setZCoordIndex(Integer.parseInt(zValueSelector.getValue()));
263 validatePageComplete();
268 private void createEdgeIndexMappingField(Group parent) {
269 startXCoordSelector = new DynamicComboFieldEditor("startxCoord", "Start X Coordinate", parent);
270 startXCoordSelector.addComboListener(new SelectionListener() {
273 public void widgetSelected(SelectionEvent e) {
274 widgetDefaultSelected(e);
278 public void widgetDefaultSelected(SelectionEvent e) {
279 model.setStartXCoordIndex(Integer.parseInt(startXCoordSelector.getValue()));
280 validatePageComplete();
284 startYCoordSelector = new DynamicComboFieldEditor("startyCoord", "Start Y Coordinate", parent);
285 startYCoordSelector.addComboListener(new SelectionListener() {
288 public void widgetSelected(SelectionEvent e) {
289 widgetDefaultSelected(e);
293 public void widgetDefaultSelected(SelectionEvent e) {
294 model.setStartYCoordIndex(Integer.parseInt(startYCoordSelector.getValue()));
295 validatePageComplete();
298 startZValueSelector = new DynamicComboFieldEditor("startzValue", "Start Z Value", parent);
299 startZValueSelector.addComboListener(new SelectionListener() {
302 public void widgetSelected(SelectionEvent e) {
303 widgetDefaultSelected(e);
307 public void widgetDefaultSelected(SelectionEvent e) {
308 model.setStartZCoordIndex(Integer.parseInt(startZValueSelector.getValue()));
309 validatePageComplete();
313 endXCoordSelector = new DynamicComboFieldEditor("endxCoord", "End X Coordinate", parent);
314 endXCoordSelector.addComboListener(new SelectionListener() {
317 public void widgetSelected(SelectionEvent e) {
318 widgetDefaultSelected(e);
322 public void widgetDefaultSelected(SelectionEvent e) {
323 model.setEndXCoordIndex(Integer.parseInt(endXCoordSelector.getValue()));
324 validatePageComplete();
328 endYCoordSelector = new DynamicComboFieldEditor("endyCoord", "End Y Coordinate", parent);
329 endYCoordSelector.addComboListener(new SelectionListener() {
332 public void widgetSelected(SelectionEvent e) {
333 widgetDefaultSelected(e);
337 public void widgetDefaultSelected(SelectionEvent e) {
338 model.setEndYCoordIndex(Integer.parseInt(endYCoordSelector.getValue()));
339 validatePageComplete();
342 endZValueSelector = new DynamicComboFieldEditor("endzValue", "End Z Value", parent);
343 endZValueSelector.addComboListener(new SelectionListener() {
346 public void widgetSelected(SelectionEvent e) {
347 widgetDefaultSelected(e);
351 public void widgetDefaultSelected(SelectionEvent e) {
352 model.setEndZCoordIndex(Integer.parseInt(endZValueSelector.getValue()));
353 validatePageComplete();
358 private void updateCombos() {
359 String[][] namesAndValues = new String[headerIndexAndValues.size()][];
362 for (Entry<Integer, String> entry : headerIndexAndValues.entrySet()) {
363 int key = entry.getKey();
364 String value = entry.getValue();
366 String[] nameAndValue = new String[2];
367 nameAndValue[0] = value;
368 nameAndValue[1] = Integer.toString(key);
369 namesAndValues[i++] = nameAndValue;
372 if (model.isVertexImport())
373 updateVertexcombos(namesAndValues);
375 updateEdgeCombos(namesAndValues);
377 componentMappingSelector.updateCombo(namesAndValues);
380 private void updateEdgeCombos(String[][] namesAndValues) {
381 startXCoordSelector.updateCombo(namesAndValues);
382 endXCoordSelector.updateCombo(namesAndValues);
383 startYCoordSelector.updateCombo(namesAndValues);
384 endYCoordSelector.updateCombo(namesAndValues);
385 startZValueSelector.updateCombo(namesAndValues);
386 endZValueSelector.updateCombo(namesAndValues);
389 private void updateVertexcombos(String[][] namesAndValues) {
390 xCoordSelector.updateCombo(namesAndValues);
391 yCoordSelector.updateCombo(namesAndValues);
392 zValueSelector.updateCombo(namesAndValues);
395 private void updateHeaders() {
396 if (headerTable != null)
397 headerTable.dispose();
398 headerTable = new Table(tableComposite, SWT.NONE);
399 headerTable.setHeaderVisible(true);
400 headerTable.setLinesVisible(true);
401 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(tableComposite);
402 for (int i = 0; i < headerTable.getColumns().length; i++) {
403 TableColumn column = headerTable.getColumns()[i];
406 for (int i = 0; i < headerTable.getItemCount(); i++) {
407 TableItem item = headerTable.getItem(i);
411 headerIndexAndValues.clear();
414 List<CSVRecord> rows = model.getRows(5);
416 for (int k = 0; k < rows.size(); k++) {
417 CSVRecord row = rows.get(k);
419 int columnCount = row.size();
420 for (int i = 0; i < columnCount; i++) {
421 String value = row.get(i);
423 TableColumn headerCol = new TableColumn(headerTable, SWT.NONE);
424 headerCol.setText(value);
426 tableColumnLayout.setColumnData(headerCol, new ColumnWeightData(10));
429 headerIndexAndValues.put(i, value);
433 int itemCount = headerTable.getItemCount();
434 if (actualK >= itemCount) {
435 item = new TableItem(headerTable, SWT.NONE);
437 item = headerTable.getItem(actualK);
439 item.setText(i, value);
444 } catch (IOException e) {
445 setErrorMessage(e.getMessage());
449 protected void validatePageComplete() {
450 if (model.isVertexImport())
451 setPageComplete(model.getXCoordIndex() != -1 && model.getYCoordIndex() != -1 && model.getComponentMappingIndex() != -1);
453 setPageComplete(model.getStartXCoordIndex() != 1 && model.getStartYCoordIndex() != -1 && model.getEndXCoordIndex() != -1 && model.getEndYCoordIndex() != -1 && model.getComponentMappingIndex() != -1);