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