]> gerrit.simantics Code Review - simantics/district.git/commitdiff
First testing version of TechTypeTable 78/4378/1 release/1.45.0
authorjsimomaa <jani.simomaa@gmail.com>
Wed, 12 Aug 2020 14:35:56 +0000 (17:35 +0300)
committerjsimomaa <jani.simomaa@gmail.com>
Wed, 12 Aug 2020 14:35:56 +0000 (17:35 +0300)
gitlab #93

Change-Id: I341d7a7735ee8dbc954a53492563f46a18cb3bb7

org.simantics.district.network.ui/src/org/simantics/district/network/ui/table/ImportTechTypeCSVHandler.java [new file with mode: 0644]
org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeColumnHeaderTableDataProvider.java [new file with mode: 0644]
org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeRowHeaderTableDataProvider.java [new file with mode: 0644]
org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTable.java [new file with mode: 0644]
org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableDataProvider.java [new file with mode: 0644]
org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableSortModel.java [new file with mode: 0644]
org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableUI.java [new file with mode: 0644]
org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableView.java [new file with mode: 0644]

diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/table/ImportTechTypeCSVHandler.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/table/ImportTechTypeCSVHandler.java
new file mode 100644 (file)
index 0000000..7ee841b
--- /dev/null
@@ -0,0 +1,53 @@
+package org.simantics.district.network.ui.table;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.simantics.district.imports.DistrictImportUtils;
+import org.simantics.district.network.ui.techtype.table.TechTypeTableView;
+import org.simantics.utils.ui.ExceptionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ImportTechTypeCSVHandler {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ImportTechTypeCSVHandler.class);
+
+    @Inject
+    EPartService partService;
+
+    @Execute
+    public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell s) {
+        // here we can import based on the current CSV table data
+
+        FileDialog dialog = new FileDialog(s);
+        String path = dialog.open();
+        try {
+            if (path != null) {
+                
+                Path p = Paths.get(path);
+                if (Files.exists(p)) {
+                    Map<String, Integer> readCSVHeader = DistrictImportUtils.readCSVHeader(p, ';', true);
+                    TechTypeTableView.table.setTechTypePath(path);
+                } else {
+                    LOGGER.warn("Path does not exist even though path != null: {}", p);
+                }
+            } else {
+                LOGGER.error("Invalid file path given {}", path);
+            }
+        } catch (Exception e) {
+            LOGGER.error("Could not read file {}", path, e);
+            ExceptionUtils.logAndShowError("Could not read file " + path + " : " + e.getMessage(), e);
+        }
+    }
+}
diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeColumnHeaderTableDataProvider.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeColumnHeaderTableDataProvider.java
new file mode 100644 (file)
index 0000000..9b63219
--- /dev/null
@@ -0,0 +1,33 @@
+package org.simantics.district.network.ui.techtype.table;
+
+import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
+
+public class TechTypeColumnHeaderTableDataProvider implements IDataProvider {
+
+       private TechTypeTableDataProvider bodyDataProvider;
+
+    public TechTypeColumnHeaderTableDataProvider(TechTypeTableDataProvider bodyDataProvider) {
+           this.bodyDataProvider = bodyDataProvider;
+    }
+
+    @Override
+       public Object getDataValue(int columnIndex, int rowIndex) {
+               return bodyDataProvider.getHeaderValue(columnIndex);
+       }
+
+       @Override
+       public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
+               
+       }
+
+       @Override
+       public int getColumnCount() {
+               return bodyDataProvider.getColumnCount();
+       }
+
+       @Override
+       public int getRowCount() {
+               return 1;
+       }
+
+}
diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeRowHeaderTableDataProvider.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeRowHeaderTableDataProvider.java
new file mode 100644 (file)
index 0000000..4d21bd5
--- /dev/null
@@ -0,0 +1,33 @@
+package org.simantics.district.network.ui.techtype.table;
+
+import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
+
+public class TechTypeRowHeaderTableDataProvider implements IDataProvider {
+
+    protected final IDataProvider bodyDataProvider;
+
+    public TechTypeRowHeaderTableDataProvider(IDataProvider bodyDataProvider) {
+        this.bodyDataProvider = bodyDataProvider;
+    }
+
+    @Override
+    public int getColumnCount() {
+        return 1;
+    }
+
+    @Override
+    public int getRowCount() {
+        return this.bodyDataProvider.getRowCount();
+    }
+
+    @Override
+    public Object getDataValue(int columnIndex, int rowIndex) {
+        return Integer.valueOf(rowIndex + 1);
+    }
+
+    @Override
+    public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTable.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTable.java
new file mode 100644 (file)
index 0000000..725700f
--- /dev/null
@@ -0,0 +1,181 @@
+package org.simantics.district.network.ui.techtype.table;
+
+import java.io.Serializable;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.nebula.widgets.nattable.NatTable;
+import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
+import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
+import org.eclipse.nebula.widgets.nattable.copy.command.CopyDataCommandHandler;
+import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
+import org.eclipse.nebula.widgets.nattable.data.IRowIdAccessor;
+import org.eclipse.nebula.widgets.nattable.freeze.CompositeFreezeLayer;
+import org.eclipse.nebula.widgets.nattable.freeze.FreezeLayer;
+import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
+import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
+import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultColumnHeaderDataLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.group.ColumnGroupHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.group.ColumnGroupModel;
+import org.eclipse.nebula.widgets.nattable.hideshow.ColumnHideShowLayer;
+import org.eclipse.nebula.widgets.nattable.hover.HoverLayer;
+import org.eclipse.nebula.widgets.nattable.hover.config.BodyHoverStylingBindings;
+import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
+import org.eclipse.nebula.widgets.nattable.layer.ILayer;
+import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer;
+import org.eclipse.nebula.widgets.nattable.reorder.RowReorderLayer;
+import org.eclipse.nebula.widgets.nattable.selection.RowSelectionModel;
+import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
+import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+public class TechTypeTable extends Composite {
+
+       NatTable table;
+       private TechTypeTableDataProvider bodyDataProvider;
+       DataLayer bodyDataLayer;
+       private IConfigRegistry summaryConfigRegistry;
+       private IUniqueIndexLayer summaryRowLayer;
+       private ViewportLayer viewportLayer;
+       private CompositeFreezeLayer compositeFreezeLayer;
+       private FreezeLayer freezeLayer;
+       //private TableDataSortModel sortModel;
+       private ColumnHideShowLayer columnHideShowLayer;
+       private ColumnGroupModel columnGroupModel = new ColumnGroupModel();
+       private TechTypeColumnHeaderTableDataProvider columnHeaderDataProvider;
+       Clipboard cpb;
+       public SelectionLayer selectionLayer;
+    private TechTypeTableSortModel sortModel;
+
+       public TechTypeTable(Composite parent, int style) {
+               super(parent, style);
+               defaultInitializeUI();
+       }
+
+       private void defaultInitializeUI() {
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(this);
+               GridLayoutFactory.fillDefaults().numColumns(1).applyTo(this);
+               
+               Composite filterComposite = new Composite(this, SWT.NONE);
+               GridDataFactory.fillDefaults().grab(true, false).applyTo(filterComposite);
+        GridLayoutFactory.fillDefaults().numColumns(1).applyTo(filterComposite);
+        
+
+        createFilterBar(filterComposite);
+        
+               Composite tableComposite = new Composite(this, SWT.NONE);
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(tableComposite);
+        GridLayoutFactory.fillDefaults().numColumns(1).applyTo(tableComposite);
+               createTable(tableComposite);
+       }
+
+       private void createFilterBar(Composite filterComposite) {
+           
+        Text filterText = new Text(filterComposite, SWT.BORDER);
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(filterText);
+        filterText.addModifyListener(new ModifyListener() {
+            
+            @Override
+            public void modifyText(ModifyEvent e) {
+                System.out.println("text modified");
+                bodyDataProvider.setFilter(filterText.getText());
+                table.refresh(true);
+            }
+        });
+        
+    }
+
+    private void createTable(Composite parent) {
+
+               // build the body layer stack 
+               // Usually you would create a new layer stack by extending AbstractIndexLayerTransform and
+               // setting the ViewportLayer as underlying layer. But in this case using the ViewportLayer
+               // directly as body layer is also working.
+               bodyDataProvider = new TechTypeTableDataProvider();
+               bodyDataLayer = new DataLayer(bodyDataProvider);
+
+               RowReorderLayer rowReorderLayer =
+                               new RowReorderLayer(columnHideShowLayer = new ColumnHideShowLayer(bodyDataLayer));
+
+               HoverLayer hoverLayer = new HoverLayer(rowReorderLayer, false);
+               // we need to ensure that the hover styling is removed when the mouse
+               // cursor moves out of the cell area
+               hoverLayer.addConfiguration(new BodyHoverStylingBindings(hoverLayer));
+
+               selectionLayer = new SelectionLayer(hoverLayer);
+               
+               viewportLayer = new ViewportLayer(selectionLayer);
+               viewportLayer.setRegionName(GridRegion.BODY);
+               freezeLayer = new FreezeLayer(selectionLayer);
+               compositeFreezeLayer = new CompositeFreezeLayer(freezeLayer, viewportLayer, selectionLayer);
+
+               // build the column header layer
+               columnHeaderDataProvider = new TechTypeColumnHeaderTableDataProvider(bodyDataProvider);
+               DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
+               columnHeaderDataLayer.setRowsResizableByDefault(false);
+               columnHeaderDataLayer.setColumnsResizableByDefault(true);
+               ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, compositeFreezeLayer, selectionLayer);
+               ColumnGroupHeaderLayer columnGroupHeaderLayer = new ColumnGroupHeaderLayer(columnHeaderLayer, selectionLayer, columnGroupModel);
+               columnGroupHeaderLayer.setCalculateHeight(true);
+               SortHeaderLayer<String> columnSortHeaderLayer = new SortHeaderLayer<>(columnGroupHeaderLayer, sortModel = new TechTypeTableSortModel(bodyDataProvider));
+
+               // build the row header layer
+               IDataProvider rowHeaderDataProvider = new TechTypeRowHeaderTableDataProvider(bodyDataProvider);
+               DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
+               rowHeaderDataLayer.setRowsResizableByDefault(false);
+               rowHeaderDataLayer.setColumnsResizableByDefault(false);
+               RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, compositeFreezeLayer, selectionLayer);
+
+               // build the corner layer
+               IDataProvider cornerDataProvider = new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider);
+               DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
+               ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, columnSortHeaderLayer);
+
+               // build the grid layer
+               GridLayer gridLayer = new GridLayer(compositeFreezeLayer, columnSortHeaderLayer, rowHeaderLayer, cornerLayer);
+               
+               table = new NatTable(parent, NatTable.DEFAULT_STYLE_OPTIONS | SWT.BORDER, gridLayer, false);
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(table);
+               
+               // Register a CopyDataCommandHandler that also copies the headers and
+               // uses the configured IDisplayConverters
+               CopyDataCommandHandler copyHandler = new CopyDataCommandHandler(
+                               selectionLayer,
+                               columnHeaderDataLayer,
+                               rowHeaderDataLayer);
+               copyHandler.setCopyFormattedText(true);
+               gridLayer.registerCommandHandler(copyHandler);
+               
+               // initialize paste handler with SWT clipboard
+               cpb = new Clipboard(getDisplay());
+               //PasteDataCommandHandler pasteHandler = new PasteDataCommandHandler(bodyDataProvider, bodyDataLayer, selectionLayer, cpb);
+               //bodyDataLayer.registerCommandHandler(pasteHandler);
+               
+               table.addConfiguration(new DefaultNatTableStyleConfiguration());
+               //table.addConfiguration(new EditingSupportConfiguration(bodyDataProvider));
+               table.configure();
+       }
+       
+       @Override
+       public void dispose() {
+               cpb.dispose();
+               super.dispose();
+       }
+
+    public void setTechTypePath(String path) {
+        bodyDataProvider.setPath(path);
+        table.refresh(true);
+    }
+
+}
diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableDataProvider.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableDataProvider.java
new file mode 100644 (file)
index 0000000..534be1d
--- /dev/null
@@ -0,0 +1,90 @@
+package org.simantics.district.network.ui.techtype.table;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.commons.csv.CSVRecord;
+import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
+import org.simantics.district.imports.DistrictImportUtils;
+
+public class TechTypeTableDataProvider implements IDataProvider {
+
+    private List<CSVRecord> records = new ArrayList<>();
+    private List<CSVRecord> filteredRecords = new ArrayList<>();
+    private String filter = "";
+
+    public TechTypeTableDataProvider() {
+        // load csv
+
+        setPath("C:\\projektit\\apros\\Semantum_VTT_Fortum portaali 2018-17-12\\järvenpää\\qgis\\TechTypeData.csv");
+    }
+
+    public Object getHeaderValue(int columnIndex) {
+        if (records.isEmpty()) {
+            return "<empty>";
+        }
+        return records.get(0).get(columnIndex);
+    }
+
+    @Override
+    public Object getDataValue(int columnIndex, int rowIndex) {
+        return filteredRecords.get(rowIndex + 1).get(columnIndex);
+    }
+
+    @Override
+    public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
+
+    }
+
+    @Override
+    public int getColumnCount() {
+        if (records.isEmpty()) {
+            return 0;
+        }
+        return records.get(0).size();
+    }
+
+    @Override
+    public int getRowCount() {
+        return filteredRecords.size() - 1;
+    }
+
+    public boolean isEditable(int columnIndex, int rowIndex) {
+        return false;
+    }
+
+    public void setFilter(String text) {
+        this.filter = text.toLowerCase();
+
+        filteredRecords = records.stream().filter(record -> {
+            for (int i = 0; i < record.size(); i++) {
+                String columnContent = record.get(i);
+                if (columnContent.toLowerCase().contains(filter)) {
+                    return true;
+                }
+            }
+            return false;
+        }).collect(Collectors.toList());
+    }
+
+    public void setPath(String path) {
+        records.clear();
+        filteredRecords.clear();
+        Path techTypeCsv = Paths.get(path);
+        try {
+            DistrictImportUtils.consumeCSV(techTypeCsv, ';', false, record -> {
+                records.add(record);
+                return true;
+            });
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        setFilter("");
+    }
+
+}
diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableSortModel.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableSortModel.java
new file mode 100644 (file)
index 0000000..f6a02f4
--- /dev/null
@@ -0,0 +1,127 @@
+package org.simantics.district.network.ui.techtype.table;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.nebula.widgets.nattable.sort.ISortModel;
+import org.eclipse.nebula.widgets.nattable.sort.SortDirectionEnum;
+import org.simantics.utils.strings.AlphanumComparator;
+
+public class TechTypeTableSortModel implements ISortModel  {
+
+    private static final SortDirectionEnum[] NO_DIRECTIONS = {};
+    private static final boolean[] NO_BOOLEANS = {};
+
+    /**
+     * Array that contains the sort direction for every column.
+     * Needed to access the current sort state of a column.
+     */
+    protected SortDirectionEnum[] sortDirections = NO_DIRECTIONS;
+
+    /**
+     * Array that contains the sorted flags for every column.
+     * Needed to access the current sort state of a column.
+     */
+    protected boolean[] sorted = NO_BOOLEANS;
+
+    /**
+     * As this implementation only supports single column sorting,
+     * this property contains the the column index of the column that
+     * is currently used for sorting.
+     * Initial value = -1 for no sort column
+     */
+    protected int currentSortColumn = -1;
+
+    /**
+     * As this implementation only supports single column sorting,
+     * this property contains the current sort direction of the column that
+     * is currently used for sorting.
+     */
+    protected SortDirectionEnum currentSortDirection = SortDirectionEnum.ASC;
+    
+    private TechTypeTableDataProvider bodyDataProvider;
+
+    public TechTypeTableSortModel(TechTypeTableDataProvider bodyDataProvider) {
+        this.bodyDataProvider = bodyDataProvider;
+    }
+    
+    
+    @Override
+    public List<Integer> getSortedColumnIndexes() {
+        List<Integer> indexes = new ArrayList<Integer>();
+        if (currentSortColumn > -1) {
+            indexes.add(Integer.valueOf(currentSortColumn));
+        }
+        return indexes;
+    }
+
+    @Override
+    public boolean isColumnIndexSorted(int columnIndex) {
+        if (sorted.length <= columnIndex)
+            return false;
+        return sorted[columnIndex];
+    }
+
+    @Override
+    public SortDirectionEnum getSortDirection(int columnIndex) {
+        if (sortDirections.length <= columnIndex)
+            return SortDirectionEnum.NONE;
+        return sortDirections[columnIndex];
+    }
+
+    @Override
+    public int getSortOrder(int columnIndex) {
+        return 0;
+    }
+
+    @Override
+    public List<Comparator> getComparatorsForColumnIndex(int columnIndex) {
+        return Collections.singletonList(AlphanumComparator.COMPARATOR);
+    }
+
+    @Override
+    public Comparator<?> getColumnComparator(int columnIndex) {
+        return AlphanumComparator.COMPARATOR;
+    }
+
+    @Override
+    public void sort(int columnIndex, SortDirectionEnum sortDirection, boolean accumulate) {
+        
+        if (!isColumnIndexSorted(columnIndex)) {
+            clear();
+        }
+        int columnCount = bodyDataProvider.getColumnCount();
+        sortDirections = ensureArraySize(sortDirections, columnCount, SortDirectionEnum.class, SortDirectionEnum.NONE);
+        
+        
+        sortDirections[columnIndex] = sortDirection;
+        sorted[columnIndex] = !sortDirection.equals(SortDirectionEnum.NONE);
+        currentSortColumn = columnIndex;
+        currentSortDirection = sortDirection;
+    }
+
+    @Override
+    public void clear() {
+        Arrays.fill(this.sortDirections, SortDirectionEnum.NONE);
+        Arrays.fill(this.sorted, false);
+        this.currentSortColumn = -1;
+        this.currentSortDirection = SortDirectionEnum.NONE;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T[] ensureArraySize(T[] array, int l, Class<T> clazz, T defaultValue) {
+        boolean fill = true;
+        if (array == null || array.length != l) {
+            array = (T[]) Array.newInstance(clazz, l);
+            fill = defaultValue != null;
+        }
+        if (fill)
+            Arrays.fill(array, defaultValue);
+        return array;
+    }
+
+}
diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableUI.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableUI.java
new file mode 100644 (file)
index 0000000..7cfa44d
--- /dev/null
@@ -0,0 +1,11 @@
+package org.simantics.district.network.ui.techtype.table;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class TechTypeTableUI extends Composite {
+
+       public TechTypeTableUI(Composite parent, int style) {
+               super(parent, style);
+       }
+
+}
diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableView.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableView.java
new file mode 100644 (file)
index 0000000..cdb502c
--- /dev/null
@@ -0,0 +1,53 @@
+package org.simantics.district.network.ui.techtype.table;
+
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.commands.MCommand;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.model.application.ui.menu.MHandledToolItem;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory;
+import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
+import org.eclipse.swt.widgets.Composite;
+
+public class TechTypeTableView {
+
+       @Inject ESelectionService selectionService;
+
+       public static TechTypeTable table;
+
+       @Inject
+       public void init(MPart part, MApplication app) {
+               MToolBar toolBar = MMenuFactory.INSTANCE.createToolBar();
+               toolBar.setToBeRendered(true);
+               toolBar.getChildren().add(createImportCSVDataToolItem(app));
+               part.setToolbar(toolBar);
+       }
+
+       private MHandledToolItem createImportCSVDataToolItem(MApplication app) {
+               MHandledToolItem createHandledToolItem = MMenuFactory.INSTANCE.createHandledToolItem();
+               // Command is contributed via fragment
+               MCommand command = app.getCommand("org.simantics.district.network.ui.command.importtechtypecsv");
+               createHandledToolItem.setCommand(command); //$NON-NLS-1$
+               createHandledToolItem.setLabel("Import Tech Type");
+               createHandledToolItem.setIconURI("platform:/plugin/com.famfamfam.silk/icons/table_edit.png"); //$NON-NLS-1$
+               return createHandledToolItem;
+       }
+
+       @PostConstruct
+       public void postConstruct(Composite parent) {
+               table = new TechTypeTable(parent, 0);
+               
+       }
+       
+       @PreDestroy
+       public void dispose() {
+               table.dispose();
+               table = null;
+       }
+
+}