]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardPage.java
Enhancements to district functionalities and code
[simantics/district.git] / org.simantics.district.imports.ui / src / org / simantics / district / imports / ui / CSVImportWizardPage.java
1 package org.simantics.district.imports.ui;
2
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;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Map.Entry;
11
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;
36
37 public class CSVImportWizardPage extends WizardPage {
38
39     private CSVImportModel model;
40
41     private Map<Integer, String> headerIndexAndValues = new HashMap<>();
42
43     private Table headerTable;
44     private Button firstAsHeader;
45
46     private Combo delimiterCombo;
47     private TableColumnLayout tableColumnLayout;
48     private Composite tableComposite;
49     private FileSelectionWidget wktFileSelection;
50
51     // Common for vertex and edge
52     private DynamicComboFieldEditor componentMappingSelector;
53     private DynamicComboFieldEditor labelSelector;
54     
55     // For vertex import
56     private DynamicComboFieldEditor xCoordSelector;
57     private DynamicComboFieldEditor yCoordSelector;
58     private DynamicComboFieldEditor zValueSelector;
59
60     // For edge import
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
68     private Group indexMappingGroup;
69
70     private Composite composite;
71
72     private Button isVertexImport;
73     
74     protected CSVImportWizardPage(CSVImportModel model) {
75         super("Import CSV Data");
76         this.model = model;
77         setMessage("Select columng index mappings");
78     }
79
80     @Override
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);
85
86         delimiterCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
87         delimiterCombo.setItems(model.getDelimiterFormats());
88         delimiterCombo.addSelectionListener(new SelectionListener() {
89
90             @Override
91             public void widgetSelected(SelectionEvent e) {
92                 model.setDelimiterByLabel(delimiterCombo.getItem(delimiterCombo.getSelectionIndex()));
93                 updateHeaders();
94                 updateCombos();
95             }
96
97             @Override
98             public void widgetDefaultSelected(SelectionEvent e) {
99                 widgetSelected(e);
100             }
101         });
102
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() {
107
108             @Override
109             public void widgetSelected(SelectionEvent e) {
110                 model.setReadFirstAsHeader(firstAsHeader.getSelection());
111                 updateHeaders();
112                 updateCombos();
113             }
114
115             @Override
116             public void widgetDefaultSelected(SelectionEvent e) {
117
118             }
119         });
120
121         tableComposite = new Composite(composite, SWT.BORDER);
122         tableColumnLayout = new TableColumnLayout();
123         tableComposite.setLayout(tableColumnLayout);
124
125         wktFileSelection = new FileSelectionWidget(composite, "WKT file", SWT.OPEN);
126         wktFileSelection.addListener(new FileSelectionListener() {
127
128             @Override
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");
135                     } else {
136                         model.setWKTFile(wktFile);
137                         validatePageComplete();
138                     }
139                 }
140             }
141         });
142
143         isVertexImport = new Button(composite, SWT.CHECK);
144         isVertexImport.setText("File contains vertices");
145         isVertexImport.setSelection(model.isVertexImport());
146         isVertexImport.addSelectionListener(new SelectionListener() {
147
148             @Override
149             public void widgetSelected(SelectionEvent e) {
150                 model.setVertexImport(isVertexImport.getSelection());
151                 updateControls(false);
152             }
153
154             @Override
155             public void widgetDefaultSelected(SelectionEvent e) {
156                 widgetSelected(e);
157             }
158         });
159         
160         updateControls(true);
161         updateHeaders();
162         setControl(composite);
163
164         final IWizardContainer container = getContainer();
165         
166         if (container instanceof IPageChangeProvider) {
167             ((IPageChangeProvider) container).addPageChangedListener(new IPageChangedListener() {
168
169                 @Override
170                 public void pageChanged(PageChangedEvent event) {
171                     if (isCurrentPage())
172                         CSVImportWizardPage.this.updateControls(false);
173                 }
174             });
175         }
176
177         validatePageComplete();
178     }
179     
180     private void updateControls(boolean initial) {
181         createIndexMappingGroup();
182         updateCombos();
183         if (!initial)
184             composite.layout(true, true);
185     }
186     
187     private void createIndexMappingGroup() {
188         if (indexMappingGroup != null)
189             indexMappingGroup.dispose();
190         
191         indexMappingGroup = new Group(composite, SWT.NONE);
192         indexMappingGroup.setText("Column index mapping");
193         GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(indexMappingGroup);
194         
195         if (model.isVertexImport())
196             createVertexIndexMappingField(indexMappingGroup);
197         else
198             createEdgeIndexMappingField(indexMappingGroup);
199         
200         createCommonIndexMappingField(indexMappingGroup);
201     }
202
203     private void createCommonIndexMappingField(Group parent) {
204         
205         componentMappingSelector = new DynamicComboFieldEditor("componentMapping", "Apros component mapping", parent);
206         componentMappingSelector.addComboListener(new SelectionListener() {
207
208             @Override
209             public void widgetSelected(SelectionEvent e) {
210                 widgetDefaultSelected(e);
211             }
212
213             @Override
214             public void widgetDefaultSelected(SelectionEvent e) {
215                 model.setComponentMappingIndex(Integer.parseInt(componentMappingSelector.getValue()));
216                 validatePageComplete();
217             }
218         });
219         
220     }
221
222     private void createVertexIndexMappingField(Group parent) {
223         xCoordSelector = new DynamicComboFieldEditor("xCoord", "X Coordinate", parent);
224         xCoordSelector.addComboListener(new SelectionListener() {
225
226             @Override
227             public void widgetSelected(SelectionEvent e) {
228                 widgetDefaultSelected(e);
229             }
230
231             @Override
232             public void widgetDefaultSelected(SelectionEvent e) {
233                 model.setXCoordIndex(Integer.parseInt(xCoordSelector.getValue()));
234                 validatePageComplete();
235             }
236         });
237
238         yCoordSelector = new DynamicComboFieldEditor("yCoord", "Y Coordinate", parent);
239         yCoordSelector.addComboListener(new SelectionListener() {
240
241             @Override
242             public void widgetSelected(SelectionEvent e) {
243                 widgetDefaultSelected(e);
244             }
245
246             @Override
247             public void widgetDefaultSelected(SelectionEvent e) {
248                 model.setYCoordIndex(Integer.parseInt(yCoordSelector.getValue()));
249                 validatePageComplete();
250             }
251         });
252         zValueSelector = new DynamicComboFieldEditor("zValue", "Z Value", parent);
253         zValueSelector.addComboListener(new SelectionListener() {
254
255             @Override
256             public void widgetSelected(SelectionEvent e) {
257                 widgetDefaultSelected(e);
258             }
259
260             @Override
261             public void widgetDefaultSelected(SelectionEvent e) {
262                 model.setZCoordIndex(Integer.parseInt(zValueSelector.getValue()));
263                 validatePageComplete();
264             }
265         });
266     }
267
268     private void createEdgeIndexMappingField(Group parent) {
269         startXCoordSelector = new DynamicComboFieldEditor("startxCoord", "Start X Coordinate", parent);
270         startXCoordSelector.addComboListener(new SelectionListener() {
271
272             @Override
273             public void widgetSelected(SelectionEvent e) {
274                 widgetDefaultSelected(e);
275             }
276
277             @Override
278             public void widgetDefaultSelected(SelectionEvent e) {
279                 model.setStartXCoordIndex(Integer.parseInt(startXCoordSelector.getValue()));
280                 validatePageComplete();
281             }
282         });
283
284         startYCoordSelector = new DynamicComboFieldEditor("startyCoord", "Start Y Coordinate", parent);
285         startYCoordSelector.addComboListener(new SelectionListener() {
286
287             @Override
288             public void widgetSelected(SelectionEvent e) {
289                 widgetDefaultSelected(e);
290             }
291
292             @Override
293             public void widgetDefaultSelected(SelectionEvent e) {
294                 model.setStartYCoordIndex(Integer.parseInt(startYCoordSelector.getValue()));
295                 validatePageComplete();
296             }
297         });
298         startZValueSelector = new DynamicComboFieldEditor("startzValue", "Start Z Value", parent);
299         startZValueSelector.addComboListener(new SelectionListener() {
300
301             @Override
302             public void widgetSelected(SelectionEvent e) {
303                 widgetDefaultSelected(e);
304             }
305
306             @Override
307             public void widgetDefaultSelected(SelectionEvent e) {
308                 model.setStartZCoordIndex(Integer.parseInt(startZValueSelector.getValue()));
309                 validatePageComplete();
310             }
311         });
312         
313         endXCoordSelector = new DynamicComboFieldEditor("endxCoord", "End X Coordinate", parent);
314         endXCoordSelector.addComboListener(new SelectionListener() {
315
316             @Override
317             public void widgetSelected(SelectionEvent e) {
318                 widgetDefaultSelected(e);
319             }
320
321             @Override
322             public void widgetDefaultSelected(SelectionEvent e) {
323                 model.setEndXCoordIndex(Integer.parseInt(endXCoordSelector.getValue()));
324                 validatePageComplete();
325             }
326         });
327
328         endYCoordSelector = new DynamicComboFieldEditor("endyCoord", "End Y Coordinate", parent);
329         endYCoordSelector.addComboListener(new SelectionListener() {
330
331             @Override
332             public void widgetSelected(SelectionEvent e) {
333                 widgetDefaultSelected(e);
334             }
335
336             @Override
337             public void widgetDefaultSelected(SelectionEvent e) {
338                 model.setEndYCoordIndex(Integer.parseInt(endYCoordSelector.getValue()));
339                 validatePageComplete();
340             }
341         });
342         endZValueSelector = new DynamicComboFieldEditor("endzValue", "End Z Value", parent);
343         endZValueSelector.addComboListener(new SelectionListener() {
344
345             @Override
346             public void widgetSelected(SelectionEvent e) {
347                 widgetDefaultSelected(e);
348             }
349
350             @Override
351             public void widgetDefaultSelected(SelectionEvent e) {
352                 model.setEndZCoordIndex(Integer.parseInt(endZValueSelector.getValue()));
353                 validatePageComplete();
354             }
355         });
356     }
357
358     private void updateCombos() {
359         String[][] namesAndValues = new String[headerIndexAndValues.size()][];
360
361         int i = 0;
362         for (Entry<Integer, String> entry : headerIndexAndValues.entrySet()) {
363             int key = entry.getKey();
364             String value = entry.getValue();
365
366             String[] nameAndValue = new String[2];
367             nameAndValue[0] = value;
368             nameAndValue[1] = Integer.toString(key);
369             namesAndValues[i++] = nameAndValue;
370         }
371
372         if (model.isVertexImport())
373             updateVertexcombos(namesAndValues);
374         else
375             updateEdgeCombos(namesAndValues);
376
377         componentMappingSelector.updateCombo(namesAndValues);
378     }
379
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);
387     }
388
389     private void updateVertexcombos(String[][] namesAndValues) {
390         xCoordSelector.updateCombo(namesAndValues);
391         yCoordSelector.updateCombo(namesAndValues);
392         zValueSelector.updateCombo(namesAndValues);
393     }
394
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];
404             column.dispose();
405         }
406         for (int i = 0; i < headerTable.getItemCount(); i++) {
407             TableItem item = headerTable.getItem(i);
408             item.dispose();
409         }
410
411         headerIndexAndValues.clear();
412
413         try {
414             List<CSVRecord> rows = model.getRows(5);
415
416             for (int k = 0; k < rows.size(); k++) {
417                 CSVRecord row = rows.get(k);
418
419                 int columnCount = row.size();
420                 for (int i = 0; i < columnCount; i++) {
421                     String value = row.get(i);
422                     if (k == 0) {
423                         TableColumn headerCol = new TableColumn(headerTable, SWT.NONE);
424                         headerCol.setText(value);
425
426                         tableColumnLayout.setColumnData(headerCol, new ColumnWeightData(10));
427                         headerCol.pack();
428
429                         headerIndexAndValues.put(i, value);
430                     } else {
431                         int actualK = k - 1;
432                         TableItem item;
433                         int itemCount = headerTable.getItemCount();
434                         if (actualK >= itemCount) {
435                             item = new TableItem(headerTable, SWT.NONE);
436                         } else {
437                             item = headerTable.getItem(actualK);
438                         }
439                         item.setText(i, value);
440                     }
441                 }
442             }
443
444         } catch (IOException e) {
445             setErrorMessage(e.getMessage());
446         }
447     }
448
449     protected void validatePageComplete() {
450         if (model.isVertexImport())
451             setPageComplete(model.getXCoordIndex() != -1 && model.getYCoordIndex() != -1 && model.getComponentMappingIndex() != -1);
452         else
453             setPageComplete(model.getStartXCoordIndex() != 1 && model.getStartYCoordIndex() != -1 && model.getEndXCoordIndex() != -1 && model.getEndYCoordIndex() != -1 && model.getComponentMappingIndex() != -1);
454     }
455
456 }