]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardPage.java
5db4581584e6110147a87173b0fa3bb0e6aca5bf
[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.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Map.Entry;
8 import java.util.Set;
9 import java.util.function.Consumer;
10
11 import org.apache.commons.csv.CSVRecord;
12 import org.eclipse.jface.dialogs.IPageChangeProvider;
13 import org.eclipse.jface.dialogs.IPageChangedListener;
14 import org.eclipse.jface.dialogs.PageChangedEvent;
15 import org.eclipse.jface.layout.GridDataFactory;
16 import org.eclipse.jface.layout.TableColumnLayout;
17 import org.eclipse.jface.viewers.ColumnWeightData;
18 import org.eclipse.jface.wizard.IWizardContainer;
19 import org.eclipse.jface.wizard.WizardPage;
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.events.ModifyEvent;
22 import org.eclipse.swt.events.ModifyListener;
23 import org.eclipse.swt.events.SelectionAdapter;
24 import org.eclipse.swt.events.SelectionEvent;
25 import org.eclipse.swt.events.SelectionListener;
26 import org.eclipse.swt.layout.GridLayout;
27 import org.eclipse.swt.widgets.Button;
28 import org.eclipse.swt.widgets.Combo;
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Group;
31 import org.eclipse.swt.widgets.Label;
32 import org.eclipse.swt.widgets.Table;
33 import org.eclipse.swt.widgets.TableColumn;
34 import org.eclipse.swt.widgets.TableItem;
35 import org.eclipse.swt.widgets.Text;
36 import org.geotools.referencing.CRS;
37 import org.simantics.district.imports.CSVImportModel;
38 import org.simantics.district.network.ui.DynamicComboFieldEditor;
39
40 public class CSVImportWizardPage extends WizardPage {
41
42     private CSVImportModel model;
43
44     private Map<Integer, String> headerIndexAndValues = new HashMap<>();
45
46     private Table headerTable;
47 //    private Button firstAsHeader;
48
49     private Combo delimiterCombo;
50     private TableColumnLayout tableColumnLayout;
51     private Composite tableComposite;
52 //    private FileSelectionWidget wktFileSelection;
53
54     // Common for vertex and edge
55     private DynamicComboFieldEditor componentMappingSelector;
56     private DynamicComboFieldEditor idSelector;
57     
58     // For vertex import
59     private DynamicComboFieldEditor xCoordSelector;
60     private DynamicComboFieldEditor yCoordSelector;
61     private DynamicComboFieldEditor zValueSelector;
62     private DynamicComboFieldEditor altElevationValueSelector;
63
64     private DynamicComboFieldEditor supplyTempValueSelector;
65     private DynamicComboFieldEditor returnTempValueSelector;
66     private DynamicComboFieldEditor supplyPressureValueSelector;
67     private DynamicComboFieldEditor returnPressureValueSelector;
68     private DynamicComboFieldEditor dpSelector;
69     private DynamicComboFieldEditor dtSelector;
70     private DynamicComboFieldEditor heatPowerSelector;
71     private DynamicComboFieldEditor peakPowerSelector;
72     private DynamicComboFieldEditor regionSelector;
73     private DynamicComboFieldEditor nominalHeadMSelector;
74     private DynamicComboFieldEditor nominalHeadBSelector;
75     private DynamicComboFieldEditor nominalFlowSelector;
76     private DynamicComboFieldEditor maximumHeadMSelector;
77     private DynamicComboFieldEditor heatLoadDsSelector;
78     private DynamicComboFieldEditor massFlowSelector;
79     private DynamicComboFieldEditor volFlowSelector;
80     private DynamicComboFieldEditor velocitySelector;
81     private DynamicComboFieldEditor flowAreaSelector;
82     private DynamicComboFieldEditor nominalPressureLossSelector;
83     private DynamicComboFieldEditor valvePositionSelector;
84     private DynamicComboFieldEditor addressSelector;
85     private DynamicComboFieldEditor lengthSelector;
86
87     // For edge import
88     private DynamicComboFieldEditor startXCoordSelector;
89     private DynamicComboFieldEditor startYCoordSelector;
90     private DynamicComboFieldEditor startZValueSelector;
91     private DynamicComboFieldEditor endXCoordSelector;
92     private DynamicComboFieldEditor endYCoordSelector;
93     private DynamicComboFieldEditor endZValueSelector;
94     private DynamicComboFieldEditor detailedGeometrySelector;
95     private DynamicComboFieldEditor pipeCodeSelector;
96     private DynamicComboFieldEditor installationYearSelector;
97     private DynamicComboFieldEditor wallThicknessSelector;
98     private DynamicComboFieldEditor insulationConductivitySelector;
99     private DynamicComboFieldEditor pipeSizeDNSelector;
100     private DynamicComboFieldEditor roughnessSelector;
101     private DynamicComboFieldEditor structureSelector;
102
103     private Text edgeConnectionPadding;
104     
105     private DynamicComboFieldEditor outerDiameterSelector;
106     private DynamicComboFieldEditor diameterSelector;
107     private DynamicComboFieldEditor nominalMassFlowSelector;
108
109     private Group indexMappingGroup;
110
111     private Composite composite;
112
113     private Button isVertexImport;
114
115     private Combo sourceCRSCombo;
116
117     private DynamicComboFieldEditor edgeFlowAreaSelector;
118
119     private DynamicComboFieldEditor kReturnSelector;
120
121     private DynamicComboFieldEditor kSupplySelector;
122
123     private DynamicComboFieldEditor tGroundSelector;
124     
125     protected CSVImportWizardPage(CSVImportModel model) {
126         super("Import CSV Data");
127         this.model = model;
128         setMessage("Select column index mappings");
129     }
130
131     @Override
132     public void createControl(Composite parent) {
133         composite = new Composite(parent, SWT.NONE);
134         composite.setLayout(new GridLayout(1, false));
135         GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(composite);
136
137         Label label = new Label(composite, SWT.NONE);
138         label.setText("Select delimiter");
139         
140         delimiterCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
141         delimiterCombo.setToolTipText("Select the delimiter that is used to separate elements in the CSV file");
142         String[] formats = model.getDelimiterFormats();
143         delimiterCombo.setItems(formats);
144         if (formats.length > 0)
145             delimiterCombo.select(0);
146         delimiterCombo.addSelectionListener(new SelectionListener() {
147
148             @Override
149             public void widgetSelected(SelectionEvent e) {
150                 model.setDelimiterByLabel(delimiterCombo.getItem(delimiterCombo.getSelectionIndex()));
151                 updateHeaders();
152                 updateCombos();
153             }
154
155             @Override
156             public void widgetDefaultSelected(SelectionEvent e) {
157                 widgetSelected(e);
158             }
159         });
160
161 //        firstAsHeader = new Button(composite, SWT.CHECK);
162 //        firstAsHeader.setText("Read first row as header");
163 //        firstAsHeader.setSelection(model.getReadFirstAsHeader());
164 //        firstAsHeader.addSelectionListener(new SelectionListener() {
165 //
166 //            @Override
167 //            public void widgetSelected(SelectionEvent e) {
168 //                model.setReadFirstAsHeader(firstAsHeader.getSelection());
169 //                updateHeaders();
170 //                updateCombos();
171 //            }
172 //
173 //            @Override
174 //            public void widgetDefaultSelected(SelectionEvent e) {
175 //                widgetSelected(e);
176 //            }
177 //        });
178
179         tableComposite = new Composite(composite, SWT.BORDER);
180         tableColumnLayout = new TableColumnLayout();
181         tableComposite.setLayout(tableColumnLayout);
182
183         label = new Label(composite, SWT.NONE);
184         label.setText("Select source Coordinate Reference System");
185         
186         sourceCRSCombo = new Combo(composite, SWT.NONE);
187         sourceCRSCombo.setToolTipText("Select the coordinate reference system that is used in the source material for possible transformation to target coordinate reference system (EPSG:4326)");
188         Set<String> codes = CRS.getSupportedCodes("EPSG");
189         sourceCRSCombo.setItems(codes.toArray(new String[codes.size()]));
190         sourceCRSCombo.addSelectionListener(new SelectionAdapter() {
191             
192             @Override
193             public void widgetSelected(SelectionEvent e) {
194                 String current = sourceCRSCombo.getItem(sourceCRSCombo.getSelectionIndex());
195                 model.setSourceCRS("EPSG:" + current);
196             }
197         });
198         
199         sourceCRSCombo.addModifyListener(new ModifyListener() {
200             
201             @Override
202             public void modifyText(ModifyEvent e) {
203                 String currentText = sourceCRSCombo.getText();
204                 if (codes.contains(currentText)) {
205                     // Select this
206                     String[] items = sourceCRSCombo.getItems();
207                     int i;
208                     for (i = 0; i < items.length; i++) {
209                         String item = items[i];
210                         if (currentText.equals(item)) {
211                             break;
212                         }
213                     }
214                     if (i != 0) {
215                         sourceCRSCombo.select(i);
216                         model.setSourceCRS("EPSG:" + currentText);
217                     } else {
218                         System.err.println("this should not happen");
219                     }
220                 }
221             }
222         });
223         
224 //        wktFileSelection = new FileSelectionWidget(composite, "WKT file", SWT.OPEN);
225 //        wktFileSelection.addListener(new FileSelectionListener() {
226 //
227 //            @Override
228 //            public void fileSelected(FileOrDirectorySelectionWidget source, String[] filename) {
229 //                String[] selection = wktFileSelection.getFilename();
230 //                if (selection != null && selection.length > 0) {
231 //                    Path wktFile = Paths.get(selection[0]);
232 //                    if (!Files.exists(wktFile)) {
233 //                        setErrorMessage("File " + wktFile.toAbsolutePath() + " does not exist");
234 //                    } else {
235 //                        model.setWKTFile(wktFile);
236 //                        validatePageComplete();
237 //                    }
238 //                }
239 //            }
240 //        });
241
242         isVertexImport = new Button(composite, SWT.CHECK);
243         isVertexImport.setText("File contains vertices");
244         isVertexImport.setToolTipText("Enable this if the file contains vertices, i.e. points");
245         isVertexImport.setSelection(model.isVertexImport());
246         isVertexImport.addSelectionListener(new SelectionListener() {
247
248             @Override
249             public void widgetSelected(SelectionEvent e) {
250                 model.setVertexImport(isVertexImport.getSelection());
251                 updateControls(false);
252             }
253
254             @Override
255             public void widgetDefaultSelected(SelectionEvent e) {
256                 widgetSelected(e);
257             }
258         });
259         
260         updateControls(true);
261         updateHeaders();
262         setControl(composite);
263
264         final IWizardContainer container = getContainer();
265         
266         if (container instanceof IPageChangeProvider) {
267             ((IPageChangeProvider) container).addPageChangedListener(new IPageChangedListener() {
268
269                 @Override
270                 public void pageChanged(PageChangedEvent event) {
271                     if (isCurrentPage())
272                         CSVImportWizardPage.this.updateControls(false);
273                 }
274             });
275         }
276
277         validatePageComplete();
278     }
279     
280     private void updateControls(boolean initial) {
281         createIndexMappingGroup();
282         updateCombos();
283         if (!initial)
284             composite.layout(true, true);
285     }
286     
287     private void createIndexMappingGroup() {
288         if (indexMappingGroup != null)
289             indexMappingGroup.dispose();
290         
291         indexMappingGroup = new Group(composite, SWT.NONE);
292         indexMappingGroup.setText("Column index mapping");
293         GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(indexMappingGroup);
294         
295         if (model.isVertexImport())
296             createVertexIndexMappingField(indexMappingGroup);
297         else
298             createEdgeIndexMappingField(indexMappingGroup);
299         
300         createCommonIndexMappingField(indexMappingGroup);
301         
302         if (!model.isVertexImport()) {
303             Label label = new Label(indexMappingGroup, SWT.NONE);
304             label.setText("Connection point padding");
305             GridDataFactory.fillDefaults().applyTo(label);
306             edgeConnectionPadding = new Text(indexMappingGroup, SWT.BORDER);
307             GridDataFactory.fillDefaults().applyTo(edgeConnectionPadding);
308             edgeConnectionPadding.setText("0.0001"); // default
309             edgeConnectionPadding.addModifyListener(new ModifyListener() {
310                 
311                 @Override
312                 public void modifyText(ModifyEvent e) {
313                     try {
314                         double padding = Double.parseDouble(edgeConnectionPadding.getText());
315                         model.setEdgePadding(padding);
316                     } catch (NumberFormatException ee) {
317                         // ignore
318                     }
319                 }
320             });
321         }
322     }
323
324     private void createCommonIndexMappingField(Group parent) {
325         
326         componentMappingSelector = createComboField("componentMapping", "Apros component mapping", model::setComponentMappingIndex, parent);
327         
328         idSelector = createComboField("id", "ID", model::setIdIndex, parent);
329         regionSelector = createComboField("regionValue", "Region", model::setRegionIndex, parent);
330     }
331
332     private DynamicComboFieldEditor createComboField(String name, String label, Consumer<Integer> setter, Group parent) {
333         DynamicComboFieldEditor selector = new DynamicComboFieldEditor(name, label, parent);
334         createSelectionListener(selector, setter);
335         return selector;
336     }
337     
338     private void createSelectionListener(DynamicComboFieldEditor editor, Consumer<Integer> setter) {
339         editor.addComboListener(new SelectionListener() {
340     
341             @Override
342             public void widgetSelected(SelectionEvent e) {
343                 widgetDefaultSelected(e);
344             }
345     
346             @Override
347             public void widgetDefaultSelected(SelectionEvent e) {
348                 setter.accept(Integer.parseInt(editor.getValue()));
349                 validatePageComplete();
350             }
351         });
352     }
353
354     private void createVertexIndexMappingField(Group parent) {
355         xCoordSelector = createComboField("xCoord", "X Coordinate", model::setXCoordIndex, parent);
356
357         yCoordSelector = createComboField("yCoord", "Y Coordinate", model::setYCoordIndex, parent);
358         zValueSelector = createComboField("zValue", "Z Value", model::setZCoordIndex, parent);
359
360         altElevationValueSelector = createComboField("altElevation", "Alternative Elevation", model::setAltElevationIndex, parent);
361         
362         supplyTempValueSelector = createComboField("tempValue", "Supply Temperature value", model::setSupplyTempIndex, parent);
363         returnTempValueSelector = createComboField("returnTempValue", "Return Temperature value", model::setReturnTempIndex, parent);
364         supplyPressureValueSelector = createComboField("pressureValue", "Supply Pressure value", model::setSupplyPressureIndex, parent);
365         returnPressureValueSelector = createComboField("returnPressureValue", "Return Pressure value", model::setReturnPressureIndex, parent);
366         dpSelector = createComboField("dpValue", "Delta pressure ", model::setDeltaPressureIndex, parent);
367         dtSelector = createComboField("dtValue", "Delta temperature ", model::setDeltaTemperatureIndex, parent);
368         heatPowerSelector = createComboField("heatPowerValue", "Heat Power", model::setHeatPowerIndex, parent);
369         peakPowerSelector = createComboField("peakPowerValue", "Peak Power", model::setPeakPowerIndex, parent);
370         
371         nominalHeadMSelector = createComboField("nominalHeadMValue", "nominalHeadM", model::setNominalHeadMIndex, parent);
372         nominalHeadBSelector = createComboField("nominalHeadBValue", "nominalHeadB", model::setNominalHeadBIndex, parent);
373         nominalFlowSelector = createComboField("nominalFlowValue", "nominalFlow", model::setNominalFlowIndex, parent);
374
375         maximumHeadMSelector = createComboField("maximumHeadMValue", "maximumHeadM", model::setMaximumHeadMIndex, parent);
376         heatLoadDsSelector = createComboField("heatLoadDsValue", "heatLoadDs", model::setHeatLoadDsIndex, parent);
377         massFlowSelector = createComboField("massFlowValue", "massFlow", model::setMassFlowIndex, parent);
378         volFlowSelector = createComboField("volFlowValue", "volFlow", model::setVolFlowIndex, parent);
379         velocitySelector = createComboField("velocityValue", "velocity", model::setVelocityIndex, parent);
380         flowAreaSelector = createComboField("flowAreaValue", "flowArea", model::setFlowAreaIndex, parent);
381         nominalPressureLossSelector = createComboField("nominalPressureLossValue", "nominalPressureLoss", model::setNominalPressureLossIndex, parent);
382         valvePositionSelector = createComboField("valvePositionSelectorValue", "valvePositionSelector", model::setValvePositionIndex, parent);
383         addressSelector = createComboField("addressValue", "addressSelector", model::setAddressIndex, parent);
384         
385
386     }
387     
388     private void createEdgeIndexMappingField(Group parent) {
389         
390 //        Composite paddingComposite = new Composite(parent, SWT.NONE);
391 //        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(paddingComposite);
392         startXCoordSelector = createComboField("startxCoord", "Start X Coordinate", model::setStartXCoordIndex, parent);
393         startYCoordSelector = createComboField("startyCoord", "Start Y Coordinate", model::setStartYCoordIndex, parent);
394         startZValueSelector = createComboField("startzValue", "Start Z Value", model::setStartZCoordIndex, parent);
395         
396         endXCoordSelector = createComboField("endxCoord", "End X Coordinate", model::setEndXCoordIndex, parent);
397         endYCoordSelector = createComboField("endyCoord", "End Y Coordinate", model::setEndYCoordIndex, parent);
398         endZValueSelector = createComboField("endzValue", "End Z Value", model::setEndZCoordIndex, parent);
399         
400         pipeCodeSelector = createComboField("pipeCodeValue", "Pipe Code", model::setPipeCodeIndex, parent);
401         
402         detailedGeometrySelector = createComboField("detailedGeometryValue", "Geometry", model::detailedGeometryIndex, parent);
403         diameterSelector = createComboField("diameterValue", "Diameter value", model::setDiameterIndex, parent);
404         outerDiameterSelector = createComboField("outerDiameterValue", "Outer Diameter value", model::setOuterDiameterIndex, parent);
405         nominalMassFlowSelector = createComboField("nominalMassFlowValue", "Nominal Mass Flow", model::setNominalMassFlowIndex, parent);
406         edgeFlowAreaSelector = createComboField("edgeFlowAreaValue", "Flow Area", model::setEdgeFlowAreaIndex, parent);
407         kReturnSelector = createComboField("kReturnValue", "K Return", model::setKReturnIndex, parent);
408         kSupplySelector = createComboField("kSupplyValue", "K Supply", model::setKSupplyIndex, parent);
409         tGroundSelector = createComboField("tGroundValue", "Temperature Ground", model::setTGroundIndex, parent);
410         lengthSelector = createComboField("lengthValue", "lengthSelector", model::setLengthIndex, parent);
411         
412         pipeSizeDNSelector = createComboField("pipeSizeDNValue", "Pipe Size DN", model::setPipeSizeDNIndex, parent);
413         structureSelector = createComboField("structureValue", "Structure", model::setStructureIndex, parent);
414         installationYearSelector = createComboField("installationYearValue", "Installation Year", model::setInstallationYearIndex, parent);
415         wallThicknessSelector = createComboField("wallThicknessValue", "Wall Thickness", model::setWallThicknessIndex, parent);
416         insulationConductivitySelector = createComboField("insulationConductivityValue", "Insulation Conductivity", model::setInsulationConductivityIndex, parent);
417         roughnessSelector = createComboField("roughnessValue", "Roughness", model::setRoughnessIndex, parent);
418     }
419
420     private void updateCombos() {
421         String[][] namesAndValues = new String[headerIndexAndValues.size() + 1][];
422
423         namesAndValues[0] = new String[] {"", "-1"};
424         int i = 1;
425         for (Entry<Integer, String> entry : headerIndexAndValues.entrySet()) {
426             int key = entry.getKey();
427             String value = entry.getValue();
428
429             String[] nameAndValue = new String[2];
430             nameAndValue[0] = value;
431             nameAndValue[1] = Integer.toString(key);
432             namesAndValues[i++] = nameAndValue;
433         }
434
435         if (model.isVertexImport())
436             updateVertexCombos(namesAndValues);
437         else
438             updateEdgeCombos(namesAndValues);
439
440         componentMappingSelector.updateCombo(namesAndValues);
441         idSelector.updateCombo(namesAndValues);
442     }
443
444     private void updateEdgeCombos(String[][] namesAndValues) {
445         startXCoordSelector.updateCombo(namesAndValues);
446         endXCoordSelector.updateCombo(namesAndValues);
447         startYCoordSelector.updateCombo(namesAndValues);
448         endYCoordSelector.updateCombo(namesAndValues);
449         startZValueSelector.updateCombo(namesAndValues);
450         endZValueSelector.updateCombo(namesAndValues);
451         pipeCodeSelector.updateCombo(namesAndValues);
452         detailedGeometrySelector.updateCombo(namesAndValues);
453         diameterSelector.updateCombo(namesAndValues);
454         outerDiameterSelector.updateCombo(namesAndValues);
455         nominalMassFlowSelector.updateCombo(namesAndValues);
456         edgeFlowAreaSelector.updateCombo(namesAndValues);
457         kReturnSelector.updateCombo(namesAndValues);
458         kSupplySelector.updateCombo(namesAndValues);
459         tGroundSelector.updateCombo(namesAndValues);
460         lengthSelector.updateCombo(namesAndValues);
461         pipeSizeDNSelector.updateCombo(namesAndValues);
462         structureSelector.updateCombo(namesAndValues);
463         installationYearSelector.updateCombo(namesAndValues);
464         wallThicknessSelector.updateCombo(namesAndValues);
465         insulationConductivitySelector.updateCombo(namesAndValues);
466         roughnessSelector.updateCombo(namesAndValues);
467     }
468
469     private void updateVertexCombos(String[][] namesAndValues) {
470         xCoordSelector.updateCombo(namesAndValues);
471         yCoordSelector.updateCombo(namesAndValues);
472         zValueSelector.updateCombo(namesAndValues);
473         altElevationValueSelector.updateCombo(namesAndValues);
474         supplyTempValueSelector.updateCombo(namesAndValues);       
475         returnTempValueSelector.updateCombo(namesAndValues);       
476         supplyPressureValueSelector.updateCombo(namesAndValues);   
477         returnPressureValueSelector.updateCombo(namesAndValues);   
478         dpSelector.updateCombo(namesAndValues);                    
479         dtSelector.updateCombo(namesAndValues);                    
480         heatPowerSelector.updateCombo(namesAndValues);             
481         valvePositionSelector.updateCombo(namesAndValues);             
482         nominalHeadMSelector.updateCombo(namesAndValues);          
483         nominalHeadBSelector.updateCombo(namesAndValues);          
484         nominalFlowSelector.updateCombo(namesAndValues);           
485         maximumHeadMSelector.updateCombo(namesAndValues);          
486         heatLoadDsSelector.updateCombo(namesAndValues);            
487         massFlowSelector.updateCombo(namesAndValues);              
488         volFlowSelector.updateCombo(namesAndValues);               
489         velocitySelector.updateCombo(namesAndValues);              
490         flowAreaSelector.updateCombo(namesAndValues);              
491         nominalPressureLossSelector.updateCombo(namesAndValues);   
492         addressSelector.updateCombo(namesAndValues);
493     }
494     
495     
496
497     private void updateHeaders() {
498         if (headerTable != null)
499             headerTable.dispose();
500         headerTable = new Table(tableComposite, SWT.NONE);
501         headerTable.setHeaderVisible(true);
502         headerTable.setLinesVisible(true);
503         GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(tableComposite);
504         for (int i = 0; i < headerTable.getColumns().length; i++) {
505             TableColumn column = headerTable.getColumns()[i];
506             column.dispose();
507         }
508         for (int i = 0; i < headerTable.getItemCount(); i++) {
509             TableItem item = headerTable.getItem(i);
510             item.dispose();
511         }
512
513         headerIndexAndValues.clear();
514
515         try {
516             List<CSVRecord> rows = model.getRows(5, false);
517
518             for (int k = 0; k < rows.size(); k++) {
519                 CSVRecord row = rows.get(k);
520
521                 int columnCount = row.size();
522                 for (int i = 0; i < columnCount; i++) {
523                     String value = row.get(i);
524                     if (k == 0) {
525                         TableColumn headerCol = new TableColumn(headerTable, SWT.NONE);
526                         headerCol.setText(value);
527
528                         tableColumnLayout.setColumnData(headerCol, new ColumnWeightData(10));
529                         headerCol.pack();
530
531                         headerIndexAndValues.put(i, value);
532                     } else {
533                         int actualK = k - 1;
534                         TableItem item;
535                         int itemCount = headerTable.getItemCount();
536                         if (actualK >= itemCount) {
537                             item = new TableItem(headerTable, SWT.NONE);
538                         } else {
539                             item = headerTable.getItem(actualK);
540                         }
541                         item.setText(i, value);
542                     }
543                 }
544             }
545
546         } catch (IOException e) {
547             setErrorMessage(e.getMessage());
548         }
549     }
550
551     protected void validatePageComplete() {
552         if (model.isVertexImport())
553             setPageComplete(model.getXCoordIndex() != -1 && model.getYCoordIndex() != -1 && model.getComponentMappingIndex() != -1);
554         else
555             setPageComplete(model.getStartXCoordIndex() != -1 && model.getStartYCoordIndex() != -1 && model.getEndXCoordIndex() != -1 && model.getEndYCoordIndex() != -1 && model.getComponentMappingIndex() != -1);
556     }
557
558 }