]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/NatTableGraphExplorer.java
Sync git svn branch with SVN repository r33334.
[simantics/platform.git] / bundles / org.simantics.browsing.ui.nattable / src / org / simantics / browsing / ui / nattable / NatTableGraphExplorer.java
index aa2c5b21e568485fdfdd709534a2619cf252b711..f38f5fd9350bae2d3b5f4ecf338eb396afb2527b 100644 (file)
@@ -28,8 +28,6 @@ import org.eclipse.core.runtime.MultiStatus;
 import org.eclipse.core.runtime.Platform;\r
 import org.eclipse.core.runtime.Status;\r
 import org.eclipse.core.runtime.jobs.Job;\r
-import org.eclipse.jface.layout.GridDataFactory;\r
-import org.eclipse.jface.layout.TreeColumnLayout;\r
 import org.eclipse.jface.resource.ColorDescriptor;\r
 import org.eclipse.jface.resource.DeviceResourceException;\r
 import org.eclipse.jface.resource.DeviceResourceManager;\r
@@ -55,11 +53,13 @@ import org.eclipse.nebula.widgets.nattable.coordinate.Range;
 import org.eclipse.nebula.widgets.nattable.data.IDataProvider;\r
 import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;\r
 import org.eclipse.nebula.widgets.nattable.data.convert.DefaultDisplayConverter;\r
+import org.eclipse.nebula.widgets.nattable.data.validate.IDataValidator;\r
+import org.eclipse.nebula.widgets.nattable.data.validate.ValidationFailedException;\r
 import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes;\r
 import org.eclipse.nebula.widgets.nattable.edit.EditConfigHelper;\r
 import org.eclipse.nebula.widgets.nattable.edit.ICellEditHandler;\r
-import org.eclipse.nebula.widgets.nattable.edit.config.DefaultEditBindings;\r
 import org.eclipse.nebula.widgets.nattable.edit.config.DefaultEditConfiguration;\r
+import org.eclipse.nebula.widgets.nattable.edit.config.DialogErrorHandling;\r
 import org.eclipse.nebula.widgets.nattable.edit.editor.AbstractCellEditor;\r
 import org.eclipse.nebula.widgets.nattable.edit.editor.ComboBoxCellEditor;\r
 import org.eclipse.nebula.widgets.nattable.edit.editor.ICellEditor;\r
@@ -85,14 +85,18 @@ import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
 import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnOverrideLabelAccumulator;\r
 import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;\r
 import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEvent;\r
-import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter;\r
+import org.eclipse.nebula.widgets.nattable.painter.NatTableBorderOverlayPainter;\r
 import org.eclipse.nebula.widgets.nattable.reorder.ColumnReorderLayer;\r
 import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;\r
 import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.MoveDirectionEnum;\r
+import org.eclipse.nebula.widgets.nattable.selection.command.SelectCellCommand;\r
 import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration;\r
+import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;\r
 import org.eclipse.nebula.widgets.nattable.style.DisplayMode;\r
+import org.eclipse.nebula.widgets.nattable.style.Style;\r
 import org.eclipse.nebula.widgets.nattable.ui.menu.AbstractHeaderMenuConfiguration;\r
 import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder;\r
+import org.eclipse.nebula.widgets.nattable.util.GUIHelper;\r
 import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;\r
 import org.eclipse.nebula.widgets.nattable.widget.EditModeEnum;\r
 import org.eclipse.swt.SWT;\r
@@ -106,7 +110,6 @@ import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.MouseListener;\r
 import org.eclipse.swt.events.SelectionListener;\r
 import org.eclipse.swt.graphics.Color;\r
-import org.eclipse.swt.graphics.GC;\r
 import org.eclipse.swt.graphics.Point;\r
 import org.eclipse.swt.graphics.RGB;\r
 import org.eclipse.swt.graphics.Rectangle;\r
@@ -202,11 +205,13 @@ import gnu.trove.map.hash.THashMap;
 import gnu.trove.map.hash.TObjectIntHashMap;\r
 \r
 /**\r
- * NatTable base GraphExplorer\r
+ * NatTable based GraphExplorer\r
+ * \r
+ * This GraphExplorer is not fully compatible with the other implementations, since it is not based on SWT.Tree. \r
+ * \r
+ * This implementation is useful in scenarios, where there are a lot of data to be displayed, the performance of NatTable is much better to SWT.Tree based implementations.\r
  * \r
  * \r
- * FIXME : asynchronous node loading does not work properly + check expanded/collapsed sate handling\r
- * TODO: InputValidators + input errors\r
  * TODO: ability to hide headers\r
  * TODO: code cleanup (copied from GraphExplorerImpl2) \r
  * \r
@@ -214,7 +219,7 @@ import gnu.trove.map.hash.TObjectIntHashMap;
  *\r
  */\r
 public class NatTableGraphExplorer extends GraphExplorerImplBase implements GraphExplorer{\r
-    public static final int      DEFAULT_MAX_CHILDREN                    = 1000;\r
+    public static final int      DEFAULT_MAX_CHILDREN                    = 10000;\r
        private static final boolean DEBUG_SELECTION_LISTENERS = false;\r
        private static final boolean DEBUG = false;\r
        \r
@@ -349,7 +354,7 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                originalFont = JFaceResources.getDefaultFontDescriptor();\r
 \r
                columns = new Column[0];\r
-               createNatTable();\r
+               createNatTable(style);\r
                layout = new NatTableColumnLayout(natTable, columnHeaderDataProvider, rowHeaderDataLayer);\r
                this.composite.setLayout(layout);\r
                                \r
@@ -531,8 +536,6 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
         //refreshColumnSizes();\r
         rootNode = new TreeNode(rootContext, explorerContext);\r
         if (DEBUG) System.out.println("setRoot " + rootNode);\r
-      \r
-       // viewer.setInput(rootNode);\r
         \r
         // Delay content reading.\r
         \r
@@ -545,8 +548,8 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                        public void run() {\r
                                if (rootNode != null) {\r
                                    rootNode.updateChildren();\r
+                                   rootNode.setExpanded(true);\r
                                    listReIndex();\r
-                                   natTable.refresh(true);\r
                                }\r
                        }\r
                });\r
@@ -554,9 +557,13 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
     }\r
     \r
     private synchronized void listReIndex() {\r
+       for (TreeNode n : list) {\r
+               n.setListIndex(-2);\r
+       }\r
        list.clear();\r
        for (TreeNode c : rootNode.getChildren())\r
                _insertToList(c);\r
+       natTable.refresh();\r
     }\r
     \r
     private void _insertToList(TreeNode n) {\r
@@ -567,6 +574,10 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
        }\r
     }\r
     \r
+    public List<TreeNode> getItems() {\r
+       return Collections.unmodifiableList(list);\r
+    }\r
+    \r
     private void initializeState() {\r
         if (persistor == null)\r
             return;\r
@@ -689,7 +700,7 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                     if (natTable.isDisposed())\r
                         return;\r
                     doSetColumns(columns, callback);\r
-                    natTable.refresh(true);\r
+                    natTable.refresh();\r
                     natTable.getParent().layout();\r
                 }\r
             });\r
@@ -1065,6 +1076,30 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
         \r
     }\r
     \r
+       public boolean select(TreeNode node) {\r
+               assertNotDisposed();\r
+\r
+               if (!list.contains(node)) {\r
+                       StructuredSelection s = new StructuredSelection();\r
+            selectionAdaptor.setSelection(s);\r
+            selectionProvider.setAndFireNonEqualSelection(s);\r
+                       return true;\r
+               }\r
+               selectionAdaptor.setSelection(new StructuredSelection(node));\r
+               return false;\r
+       }\r
+       \r
+       public void show(TreeNode node) {\r
+               int index = node.getListIndex();\r
+               \r
+               int position = treeLayer.getRowPositionByIndex(index);\r
+               if (position < 0) {\r
+                       treeLayer.expandToTreeRow(index);\r
+                       position = treeLayer.getRowPositionByIndex(index);\r
+               }\r
+               viewportLayer.moveRowPositionIntoViewport(position);\r
+       }\r
+    \r
     @Override\r
     public boolean selectPath(Collection<NodeContext> contexts) {\r
        \r
@@ -1171,7 +1206,6 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                else\r
                        treeLayer.collapseTreeRow(n.getListIndex());\r
        }\r
-       //viewer.setExpandedState(context, expanded);\r
        \r
     }\r
     \r
@@ -1179,7 +1213,6 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
     public void setAutoExpandLevel(int level) {\r
         this.autoExpandLevel = level;\r
         treeLayer.expandAllToLevel(level);\r
-        //viewer.setAutoExpandLevel(level);\r
     }\r
     \r
     int maxChildren = DEFAULT_MAX_CHILDREN;\r
@@ -1244,22 +1277,51 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                                if (element.isDisposed()) {\r
                                return;\r
                                }\r
-                       if (((TreeNode)element).updateChildren()) {\r
+                       if (element.updateChildren()) {\r
+                               if (DEBUG) {\r
+                                       System.out.println("Update Item updateChildren " + element.listIndex + " " + element);\r
+                                       printDebug(NatTableGraphExplorer.this);\r
+                               }\r
                                listReIndex();\r
-                               natTable.refresh(true);\r
-                               //viewer.refresh(element,true);\r
+                               if (!element.isHidden()) { \r
+                                       if (!element.isExpanded()) {\r
+                                               if (element.listIndex >= 0)\r
+                                                       treeLayer.collapseTreeRow(element.listIndex);\r
+                                               if (DEBUG) {\r
+                                                       System.out.println("Update Item collapse " + element.listIndex);\r
+                                                       printDebug(NatTableGraphExplorer.this);\r
+                                               }\r
+                                       } else {\r
+                                               for (TreeNode c : element.getChildren())\r
+                                                       c.initData();\r
+                                       }\r
+                               } else {\r
+                                       TreeNode p = element.getCollapsedAncestor();\r
+                                       if (p != null) {\r
+                                               if (element.listIndex >= 0)\r
+                                                       treeLayer.collapseTreeRow(element.listIndex);\r
+                                               if (p.listIndex >= 0) \r
+                                                       treeLayer.collapseTreeRow(p.listIndex);\r
+                                               if (DEBUG) {\r
+                                                       System.out.println("Update Item ancetor collapse " + p.listIndex);\r
+                                                       printDebug(NatTableGraphExplorer.this);\r
+                                               }\r
+                                       }\r
+                               }\r
                        } else {\r
-                               if (columnIndex >= 0) {\r
-                                       natTable.redraw();\r
-                                       //viewer.update(element, new String[]{columns[columnIndex].getKey()});\r
-                               } else {\r
-                                       natTable.redraw();\r
-                                       //viewer.refresh(element,true);\r
-                               }\r
+//                             if (columnIndex >= 0) {\r
+//                                     viewer.update(element, new String[]{columns[columnIndex].getKey()});\r
+//                             } else {\r
+//                                     viewer.refresh(element,true);\r
+//                             }\r
+                               natTable.redraw();\r
                        }\r
                        \r
-                       if (!element.isDisposed() && autoExpandLevel > 1 && !element.isExpanded() && element.getDepth() <= autoExpandLevel) {\r
+                       if (!element.autoExpanded && !element.isDisposed() && autoExpandLevel > 1 && !element.isExpanded() && element.getDepth() <= autoExpandLevel) {\r
                                expand = true;\r
+                               element.autoExpanded = true;\r
+                               element.initData();\r
+                               if (DEBUG) System.out.println("Update Item expand " + element.listIndex);\r
                                treeLayer.expandTreeRow(element.getListIndex());\r
                                //viewer.setExpandedState(element, true);\r
                                expand = false;\r
@@ -1267,8 +1329,6 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                        } else {\r
                                if (rootNode.updateChildren()) {\r
                                        listReIndex();\r
-                               natTable.refresh(true);\r
-                                       //viewer.refresh(rootNode,true);\r
                                }\r
                        }\r
        }\r
@@ -1296,11 +1356,13 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
     }\r
     \r
     private void update(final TreeNode element, final int columnIndex) {\r
-       if (DEBUG)System.out.println("update " + element + " " + columnIndex);\r
        if (natTable.isDisposed())\r
                return;\r
+       if (element != null && element.isDisposed())\r
+               return;\r
+       if (DEBUG) System.out.println("update " + element + " " + columnIndex);\r
        synchronized (pendingItems) {\r
-                       pendingItems.add(new UpdateItem(element, columnIndex));\r
+               pendingItems.add(new UpdateItem(element, columnIndex));\r
                        if (updating) return;\r
                        updateCounter++;\r
                        scheduleUpdater();\r
@@ -1308,14 +1370,14 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
     }\r
 \r
     private void update(final TreeNode element) {\r
-       if (DEBUG)System.out.println("update " + element);\r
+       \r
        if (natTable.isDisposed())\r
                return;\r
        if (element != null && element.isDisposed())\r
                return;\r
+       if (DEBUG) System.out.println("update " + element);\r
        synchronized (pendingItems) {\r
-               \r
-                       pendingItems.add(new UpdateItem(element));\r
+               pendingItems.add(new UpdateItem(element));\r
                        if (updating) return;\r
                        updateCounter++;\r
                        scheduleUpdater();\r
@@ -1449,7 +1511,7 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                return (double)dpi.x/96.0;\r
        }\r
     \r
-    private void createNatTable() {\r
+    private void createNatTable(int style) {\r
        GETreeData treeData = new GETreeData(list);\r
                GETreeRowModel<TreeNode> treeRowModel = new GETreeRowModel<TreeNode>(treeData);\r
                columnAccessor = new GEColumnAccessor(this);\r
@@ -1529,7 +1591,7 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                natTable.addConfiguration(new SingleClickSortConfiguration());\r
                //natTable.addLayerListener(this);\r
                \r
-               natTable.addConfiguration(new GENatTableThemeConfiguration(treeData));\r
+               natTable.addConfiguration(new GENatTableThemeConfiguration(treeData, style));\r
                natTable.addConfiguration(new NatTableHeaderMenuConfiguration(natTable));\r
                \r
                natTable.addConfiguration(new AbstractRegistryConfiguration() {\r
@@ -1559,13 +1621,25 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
 \r
                                });\r
                                  configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, new AdaptableCellEditor());\r
+                                 configRegistry.registerConfigAttribute(EditConfigAttributes.CONVERSION_ERROR_HANDLER, new DialogErrorHandling(), DisplayMode.EDIT);\r
+                                 configRegistry.registerConfigAttribute(EditConfigAttributes.VALIDATION_ERROR_HANDLER, new DialogErrorHandling(), DisplayMode.EDIT);\r
+                                 configRegistry.registerConfigAttribute(EditConfigAttributes.DATA_VALIDATOR, new AdaptableDataValidator(),DisplayMode.EDIT);\r
+                                 \r
+                                 Style conversionErrorStyle = new Style();\r
+                                 conversionErrorStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, GUIHelper.COLOR_RED);\r
+                                 conversionErrorStyle.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR, GUIHelper.COLOR_WHITE);\r
+                                 configRegistry.registerConfigAttribute(EditConfigAttributes.CONVERSION_ERROR_STYLE, conversionErrorStyle, DisplayMode.EDIT);\r
+                                 \r
                                  configRegistry.registerConfigAttribute(CellConfigAttributes.DISPLAY_CONVERTER, new DefaultDisplayConverter(),DisplayMode.EDIT);\r
-                                // configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, new GECellPainter(),DisplayMode.NORMAL);\r
-\r
-                               \r
+                                 \r
+                                 \r
                        }\r
                });\r
                \r
+               if ((style & SWT.BORDER) > 0) {\r
+                       natTable.addOverlayPainter(new NatTableBorderOverlayPainter());\r
+               }\r
+               \r
                natTable.configure();\r
                \r
 //             natTable.addListener(SWT.MenuDetect, new NatTableMenuListener());\r
@@ -1764,8 +1838,29 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                public Rectangle calculateControlBounds(Rectangle cellBounds) {\r
                        return editor.calculateControlBounds(cellBounds);\r
                }\r
+    }\r
+    \r
+    private class AdaptableDataValidator implements IDataValidator {\r
+       @Override\r
+       public boolean validate(ILayerCell cell, IConfigRegistry configRegistry, Object newValue) {\r
+               int col = cell.getColumnIndex();\r
+                       int row = cell.getRowIndex();\r
+                       return validate(col, row, newValue);\r
+       }\r
        \r
-       \r
+       @Override\r
+       public boolean validate(int col, int row, Object newValue) {\r
+               TreeNode node = list.get(row);\r
+                       Modifier modifier = getModifier(node, col);\r
+                       if (modifier == null)\r
+                               return false;\r
+                       \r
+                       String err =  modifier.isValid(newValue.toString());\r
+                       if (err == null)\r
+                               return true;\r
+                       modifier.isValid(newValue.toString());\r
+                       throw new ValidationFailedException(err);\r
+       }\r
     }\r
     \r
     private class CustomCellEditor extends AbstractCellEditor {\r
@@ -2079,7 +2174,7 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                }\r
                if (DEBUG) System.out.println("UpdateRunner.doRun() " + items.size());\r
 \r
-               ge.natTable.setRedraw(false);\r
+               //ge.natTable.setRedraw(false);\r
             for (UpdateItem item : items) {\r
                 item.update(ge.natTable);\r
             }\r
@@ -2091,7 +2186,7 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                ge.natTable.getParent().layout();\r
             }\r
             \r
-            ge.natTable.setRedraw(true);\r
+            //ge.natTable.setRedraw(true);\r
             \r
                synchronized (ge.pendingItems) {\r
                    if (!ge.scheduleUpdater()) {\r
@@ -2100,13 +2195,36 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                }\r
                if (DEBUG) {\r
                        if (!ge.updating) {\r
-                                ge.printTree(ge.rootNode, 0);\r
+                                printDebug(ge); \r
                        }\r
                }\r
            }\r
 \r
        }\r
     \r
+       private static void printDebug(NatTableGraphExplorer ge) {\r
+                ge.printTree(ge.rootNode, 0);\r
+                System.out.println("Expanded");\r
+                for (TreeNode n : ge.treeLayer.expanded)\r
+                        System.out.println(n);\r
+                System.out.println("Expanded end");\r
+                System.out.println("Hidden ");\r
+                for (int i : ge.treeLayer.getHiddenRowIndexes()) {\r
+                        System.out.print(i + " ");\r
+                }\r
+                System.out.println();\r
+//              Display.getCurrent().timerExec(1000, new Runnable() {\r
+//                     \r
+//                     @Override\r
+//                     public void run() {\r
+//                              System.out.println("Hidden delayed ");\r
+//                              for (int i : ge.treeLayer.getHiddenRowIndexes()) {\r
+//                                      System.out.print(i + " ");\r
+//                              }\r
+//                              System.out.println();\r
+//                     }\r
+//             });\r
+       }\r
     \r
     \r
     public static class GeViewerContext extends AbstractDisposable implements IGraphExplorerContext {\r
@@ -2348,23 +2466,22 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                        \r
                        @Override\r
                        public void handleLayerEvent(ILayerEvent event) {\r
-                               // TODO Auto-generated method stub\r
                                if (event instanceof ShowRowPositionsEvent) {\r
                                        ShowRowPositionsEvent e = (ShowRowPositionsEvent)event;\r
                                        for (Range r : e.getRowPositionRanges()) {\r
                                                int expanded = viewportLayer.getRowIndexByPosition(r.start-2)+1;\r
-                                               //System.out.println("ex " + expanded);\r
-                                               if (expanded < 0) {\r
+                                               if (DEBUG)System.out.println("IsExpandedProcessor expand " + expanded);\r
+                                               if (expanded < 0 || expanded >= list.size()) {\r
                                                        return;\r
                                                }\r
-                                               nodeStatusChanged(list.get(expanded).getContext(), false);\r
+                                               nodeStatusChanged(list.get(expanded).getContext(), true);\r
                                        }\r
                                } else if (event instanceof HideRowPositionsEvent) {\r
                                        HideRowPositionsEvent e = (HideRowPositionsEvent)event;\r
                                        for (Range r : e.getRowPositionRanges()) {\r
-                                               int collapsed = viewportLayer.getRowIndexByPosition(r.start-2)+1;\r
-                                               //System.out.println("col " + collapsed);\r
-                                               if (collapsed < 0) {\r
+                                               int collapsed = viewportLayer.getRowIndexByPosition(r.start-2);\r
+                                               if (DEBUG)System.out.println("IsExpandedProcessor collapse " + collapsed);\r
+                                               if (collapsed < 0 || collapsed >= list.size()) {\r
                                                        return;\r
                                                }\r
                                                nodeStatusChanged(list.get(collapsed).getContext(), false);\r
@@ -2714,7 +2831,7 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
                }\r
     }\r
     \r
-private class NatTableHeaderMenuConfiguration extends AbstractHeaderMenuConfiguration {\r
+    private class NatTableHeaderMenuConfiguration extends AbstractHeaderMenuConfiguration {\r
                \r
                \r
                public NatTableHeaderMenuConfiguration(NatTable natTable) {\r
@@ -2755,8 +2872,8 @@ private class NatTableHeaderMenuConfiguration extends AbstractHeaderMenuConfigur
         Point point = new Point(e.x, e.y);\r
         int y = natTable.getRowPositionByY(point.y);\r
         int x = natTable.getColumnPositionByX(point.x);\r
-        if (x < 0 | y < 0)\r
+        if (x < 0 | y <= 0)\r
                return null;\r
-        return list.get(y); \r
+        return list.get(y-1); \r
     }\r
 }\r