X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.interop.update%2Fsrc%2Forg%2Fsimantics%2Finterop%2Fupdate%2Feditor%2FModelUpdateEditor.java;h=ea14039eecb0bbe3fc1c65f5c45cdf8a6c225d60;hb=HEAD;hp=94b24619675049ff0bf1489fd4c4fcbd4935a1eb;hpb=6af8d67b9d34bb9e8cc4b4c8bd5e95e70c16f104;p=simantics%2Finterop.git diff --git a/org.simantics.interop.update/src/org/simantics/interop/update/editor/ModelUpdateEditor.java b/org.simantics.interop.update/src/org/simantics/interop/update/editor/ModelUpdateEditor.java index 94b2461..ea14039 100644 --- a/org.simantics.interop.update/src/org/simantics/interop/update/editor/ModelUpdateEditor.java +++ b/org.simantics.interop.update/src/org/simantics/interop/update/editor/ModelUpdateEditor.java @@ -40,28 +40,26 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.IEditorInput; +import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; +import org.simantics.db.Session; import org.simantics.db.Statement; import org.simantics.db.WriteGraph; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; -import org.simantics.db.exception.DoesNotContainValueException; -import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; -import org.simantics.db.exception.ServiceException; -import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.db.request.Read; import org.simantics.interop.test.GraphChanges; -import org.simantics.interop.test.GraphComparator; import org.simantics.interop.update.Activator; +import org.simantics.interop.update.model.ModelUpdate; +import org.simantics.interop.update.model.ModelUpdate.WarningListener; +import org.simantics.interop.update.model.PropertyChange; +import org.simantics.interop.update.model.UpdateList; import org.simantics.interop.update.model.UpdateNode; -import org.simantics.interop.update.model.UpdateNode.Status; import org.simantics.interop.update.model.UpdateOp; +import org.simantics.interop.update.model.UpdateStatus; import org.simantics.interop.update.model.UpdateTree; import org.simantics.interop.utils.TableUtils; -import org.simantics.ui.workbench.ResourceEditorPart2; -import org.simantics.utils.datastructures.Callback; import org.simantics.utils.datastructures.Pair; import org.simantics.utils.ui.ExceptionUtils; @@ -72,18 +70,13 @@ import org.simantics.utils.ui.ExceptionUtils; * @author Marko Luukkainen * */ -public abstract class ModelUpdateEditor extends ResourceEditorPart2 { +public abstract class ModelUpdateEditor extends Composite implements WarningListener{ - - private Composite composite; private Composite errorComposite; private CheckboxTreeViewer changeBrowser; private TableViewer changeViewer; - private GraphChanges changes; - private UpdateTree updateTree; - private Button updateAllButton; private Button updateSelectedButton; @@ -96,30 +89,29 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { private Color containsColor; private Color deletedColor; private Color addedColor; + private Color disabledColor; + + private ModelUpdate update; - private HashSet> selected = new HashSet>(); private HashSet selectedStructure = new HashSet(); - private List filters = new ArrayList(); - - public ModelUpdateEditor() { + public ModelUpdateEditor(Composite parent) { + super(parent,SWT.NONE); checked = manager.createImage(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/tick.png")); unchecked = manager.createImage(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/cross.png")); + unchecked = manager.createImage(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/cross.png")); warning = manager.createImage(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/error.png")); - } - - @Override - public void createPartControl(Composite parent) { + containsColor = new Color(parent.getDisplay(), new RGB(255,255,220)); deletedColor = new Color(parent.getDisplay(), new RGB(255,220,220)); addedColor = new Color(parent.getDisplay(), new RGB(220,255,220)); + disabledColor = new Color(parent.getDisplay(), new RGB(128,128,128)); - composite = new Composite(parent, SWT.NONE); - composite.setLayout(new GridLayout(1,false)); + this.setLayout(new GridLayout(1,false)); - errorComposite = new Composite(composite, SWT.BORDER); + errorComposite = new Composite(this, SWT.BORDER); GridData data = new GridData(); data.grabExcessHorizontalSpace = true; data.grabExcessVerticalSpace = false; @@ -130,14 +122,14 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { errorComposite.setVisible(false); - IEditorInput input = getEditorInput(); - if (!(input instanceof UpdateEditorInput)) { - Label label = new Label(composite, SWT.NONE); - label.setText("Unknown input."); - return; - } - - Composite fillComposite = new Composite(composite, SWT.NONE); +// IEditorInput input = getEditorInput(); +// if (!(input instanceof UpdateEditorInput)) { +// Label label = new Label(composite, SWT.NONE); +// label.setText("Unknown input."); +// return; +// } + + Composite fillComposite = new Composite(this, SWT.NONE); data = new GridData(); data.grabExcessHorizontalSpace = true; data.grabExcessVerticalSpace = true; @@ -169,7 +161,7 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { node.getOp().select(Boolean.TRUE.equals(event.getChecked())); } - updateSelection(); + refreshChecked(); } }); @@ -181,7 +173,8 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { @Override public void run() { - updateSelection(); + // TreeViewer uses lazy load, checked states must be updated when the tree is expanded. + refreshChecked(); } }); @@ -205,39 +198,35 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { changeViewer.setUseHashlookup(true); - TableViewerColumn selection = TableUtils.addColumn(changeViewer, getColumntTitle(0), false, false, 20); - TableViewerColumn diagram = TableUtils.addColumn(changeViewer, getColumntTitle(1), true, true, 100); - TableViewerColumn symbol = TableUtils.addColumn(changeViewer, getColumntTitle(2), true, true, 100); - TableViewerColumn property = TableUtils.addColumn(changeViewer, getColumntTitle(3), true, true, 100); - TableViewerColumn oldValue = TableUtils.addColumn(changeViewer, getColumntTitle(4), true, true, 100); - TableViewerColumn newValue = TableUtils.addColumn(changeViewer, getColumntTitle(5), true, true, 100); - - diagram.setLabelProvider(getLabelProvider(1)); - symbol.setLabelProvider(getLabelProvider(2)); - property.setLabelProvider(getLabelProvider(3)); - oldValue.setLabelProvider(getLabelProvider(4)); - newValue.setLabelProvider(getLabelProvider(5)); + TableViewerColumn cols[] = new TableViewerColumn[getChangeListColumnCount()]; + TableViewerColumn selection = TableUtils.addColumn(changeViewer, getColumntTitle(0), false, false, getChangeListColumnWidth(0)); + cols[0] = selection; + for (int i = 1 ; i < getChangeListColumnCount(); i++) { + TableViewerColumn column = TableUtils.addColumn(changeViewer, getColumntTitle(i), true, getChangeListColumnSortable(i), getChangeListColumnWidth(i)); + cols[i] = column; + column.setLabelProvider(getLabelProvider(i)); + configureChangeListColumn(i, column); + } - selection.setLabelProvider(new SelectionLabelProvider(selected)); + selection.setLabelProvider(new SelectionLabelProvider()); selection.getColumn().addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - if (changes.getModifications().size() > 0) { - if (selected.contains(changes.getModifications().get(0))) { - for (Pair nr : changes.getModifications()) - selected.remove(nr); + if (update.getUpdateList().getChanges().size() > 0) { + if (update.getUpdateList().getSelected().size() > 0) { + update.getUpdateList().clearSelected(); } else { - for (Pair nr : changes.getModifications()) - selected.add(nr); + for (PropertyChange nr : update.getUpdateList().getChanges()) + nr.select(true); } changeViewer.refresh(); } } }); - selection.setEditingSupport(new SelectionEditingSupport(changeViewer, selected)); + selection.setEditingSupport(new SelectionEditingSupport(changeViewer)); } - Composite buttonComposite = new Composite(composite, SWT.NONE); + Composite buttonComposite = new Composite(this, SWT.NONE); data = new GridData(); data.grabExcessHorizontalSpace = true; @@ -262,7 +251,7 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { updateAllButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - updateAll(); + applyAll(); } }); updateSelectedButton = new Button(buttonComposite, SWT.PUSH); @@ -270,14 +259,35 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { updateSelectedButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - updateSelected(); + applySelected(); } }); - - load(); + } + + protected int getChangeListColumnCount() { + return 6; + } + + protected int getChangeListColumnWidth(int col) { + if (col == 0) + return 20; + return 100; + } + + protected boolean getChangeListColumnSortable(int col) { + if (col == 0) + return false; + return true; + } + + protected void configureChangeListColumn(int col, TableViewerColumn column) { } + protected Session getSession() { + return Simantics.getSession(); + } + protected String getColumntTitle(int i) { switch (i) { case 0: @@ -299,18 +309,28 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { } protected abstract ColumnLabelProvider getLabelProvider(int i); - protected abstract Pair getChanges(Resource r1, Resource r2) throws DatabaseException; - protected abstract UpdateTree getUpdateTree(GraphChanges changes) throws DatabaseException; - protected void addFilters(List filters) { - + public GraphChanges getChanges() { + return update.getChanges(); } - public GraphChanges getChanges() { - return changes; + public UpdateTree getUpdateTree() { + return update.getUpdateTree(); + } + + public UpdateList getUpdateList() { + return update.getUpdateList(); + } + + public CheckboxTreeViewer getChangeBrowser() { + return changeBrowser; } - private void showWarning(String text) { + public TableViewer getChangeViewer() { + return changeViewer; + } + + public void showWarning(ModelUpdate update, String text) { errorComposite.setVisible(true); Label label = new Label(errorComposite, SWT.NONE); @@ -318,18 +338,29 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { label = new Label(errorComposite, SWT.NONE); label.setText(text); //this.setStatusMessage("Update contains structural changes (new or deleted symbols), please create a new model."); - composite.layout(true); + this.layout(true); + } + + + private List checkStateListeners = new ArrayList<>(); + + + public void addCheckStateListener(ICheckStateListener listener) { + checkStateListeners.add(listener); + } + public void removeCheckStateListener(ICheckStateListener listener) { + checkStateListeners.remove(listener); } - private void updateSelection() { + public void refreshChecked() { Stack nodeStack = new Stack(); - nodeStack.push((UpdateNode)updateTree.getRootNode()); + nodeStack.push((UpdateNode)update.getUpdateTree().getRootNode()); while (!nodeStack.isEmpty()) { UpdateNode n = nodeStack.pop(); if (n.getOp() != null) { UpdateOp op = n.getOp(); - if (!op.isAdd() && !op.isDelete()) { + if (!op.isChange()) { changeBrowser.setGrayed(n, true); changeBrowser.setChecked(n, true); } else { @@ -347,7 +378,7 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { selectedStructure.remove(n); } changeBrowser.setChecked(n, sel); - changeBrowser.setGrayed(n, false); + changeBrowser.setGrayed(n, !op.enabled()); } } } else { @@ -360,60 +391,54 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { } changeBrowser.refresh(); + for (ICheckStateListener l : checkStateListeners) { + l.checkStateChanged(new CheckStateChangedEvent(changeBrowser, null, false)); + } + changeViewer.refresh(); } + protected abstract ModelUpdate createUpdate(); - private void load() { - - addFilters(filters); - - UpdateEditorInput uei = (UpdateEditorInput)getEditorInput(); - Resource r1 = uei.getR1(); - Resource r2 = uei.getR2(); - + + public void load(UpdateEditorInput uei) { + Resource oldModel = uei.getR1(); // old model that is being updated, contains user made changes + Resource newModel = uei.getR2(); // new model, + Resource originalModel = uei.getR3(); // original old model without user made changes + boolean newDistinct = uei.isNewDistinct(); try { - - Pair result = getChanges(r1,r2); - GraphComparator comparator = result.first; - if (result.second) - showWarning("Structural symbols have been changed. Model update is not able to update these, please create a new model."); - comparator.test(getSession()); - changes = comparator.getChanges(); - changes = getSession().syncRequest(new FilterChangesRead(changes)); - updateTree = getUpdateTree(changes); + if (update != null) + update.removeListener(this); + update = createUpdate(); + update.addListener(this); + update.setInput(oldModel, newModel, originalModel, newDistinct); } catch (DatabaseException e) { - Text text = new Text(composite, SWT.MULTI); + Text text = new Text(this, SWT.MULTI); text.setText(e.getMessage()); e.printStackTrace(); return; } - - - changeViewer.setInput(changes.getModifications()); - changeBrowser.setInput(updateTree); - updateSelection(); + setInputs(); + + refreshChecked(); } + protected void setInputs() { + changeViewer.setInput(update.getUpdateList().getChanges()); + changeBrowser.setInput(update.getUpdateTree()); + updateAllButton.setEnabled(true); + updateSelectedButton.setEnabled(true); + } - - private void updateAll() { + private void applyAll() { updateAllButton.setEnabled(false); updateSelectedButton.setEnabled(false); getSession().asyncRequest(new WriteRequest(){ @Override public void perform(WriteGraph graph) throws DatabaseException { - Layer0Utils.addCommentMetadata(graph, "Apply all model updates"); - graph.markUndoPoint(); - for (Pair mod : changes.getModifications()) { - applyLiteralChange(graph, mod); - } - selected.clear(); - changes.getModifications().clear(); - - updateTree.getUpdateOps().applyAll(graph); + update.applyAll(graph); Display.getDefault().asyncExec(new Runnable() { @@ -422,51 +447,26 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { updateAllButton.setEnabled(true); updateSelectedButton.setEnabled(true); - updateSelection(); + refreshChecked(); changeViewer.refresh(); } }); } - }, new Callback() { - @Override - public void run(DatabaseException parameter) { - if (parameter != null) - ExceptionUtils.logAndShowError("Cannot update model", parameter); - } + }, e -> { + if (e != null) + ExceptionUtils.logAndShowError("Cannot update model", e); }); } - private void applyLiteralChange(WriteGraph graph, Pair mod) throws DoesNotContainValueException, ServiceException, ManyObjectsForFunctionalRelationException { - - Resource s = changes.getComparable().getLeft(mod.second.getSubject()); - Resource pred = mod.first.getPredicate(); - if (graph.hasValue(mod.second.getObject())) { - Object value = graph.getValue(mod.second.getObject()); - graph.claimLiteral(s, pred, value); - } else { - graph.deny(s,pred); - } - - - } - - private void updateSelected() { + private void applySelected() { updateAllButton.setEnabled(false); updateSelectedButton.setEnabled(false); getSession().asyncRequest(new WriteRequest(){ @Override public void perform(WriteGraph graph) throws DatabaseException { - Layer0Utils.addCommentMetadata(graph, "Apply selected model updates"); - graph.markUndoPoint(); - for (Pair mod : selected) { - changes.getModifications().remove(mod); - applyLiteralChange(graph, mod); - } - selected.clear(); - - updateTree.getUpdateOps().applySelected(graph); + update.applySelected(graph); Display.getDefault().asyncExec(new Runnable() { @@ -475,113 +475,12 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { changeViewer.refresh(); updateAllButton.setEnabled(true); updateSelectedButton.setEnabled(true); - updateSelection(); + refreshChecked(); } }); } }); - } - - @Override - public void setFocus() { - composite.setFocus(); - - } - - /** - * Filters changes: - * 1. Changes that are not essential for model update (changes that can be found when the models are axcatly the same) - * 2. Runs custom filters for value changes. - * - * @param g - * @param changes - * @return - * @throws DatabaseException - */ - protected GraphChanges filterChanges(ReadGraph g, GraphChanges changes) throws DatabaseException - { - - List> modifications = new ArrayList>(); - - for (Pair mod : changes.getModifications()) { - - boolean accept = true; - for (ChangeFilter filter : filters) { - if (!filter.accept(g, mod)) { - accept = false; - break; - } - } - if (accept) - modifications.add(mod); - } - GraphChanges newChanges = new GraphChanges(changes.getResource1(),changes.getResource2(),changes.getDeletions(), changes.getAdditions(), modifications, changes.getComparable()); - return newChanges; - } - - public interface ChangeFilter { - public boolean accept(ReadGraph g, Pair change) throws DatabaseException; - } - - - - - /** - * - * Filters floating point value changes (default filter is set filter when the change is less than 1%) - * - */ - protected class FPValueFilter implements ChangeFilter { - - private double percentage = 0.01; - - public FPValueFilter() { - - } - - public FPValueFilter(double percentage) { - if (percentage < 0.0 || percentage > 1.0) - throw new IllegalArgumentException("Percentage must be between 0.0 and 1.0."); - this.percentage = percentage; - } - - @Override - public boolean accept(ReadGraph g, Pair change) throws DatabaseException { - //filter floating point values that have less than 1% difference. - if (!g.hasValue(change.first.getObject()) || !g.hasValue(change.second.getObject())) - return true; - Object v1 = g.getValue(change.first.getObject()); - Object v2 = g.getValue(change.second.getObject()); - - if (v1 instanceof Double && v2 instanceof Double) { - double d1 = (Double)v1; - double d2 = (Double)v2; - if (Math.abs(d1-d2) / Math.max(Math.abs(d1), Math.abs(d2)) < percentage) - return false; - } else if (v1 instanceof Float && v2 instanceof Float) { - float d1 = (Float)v1; - float d2 = (Float)v2; - if (Math.abs(d1-d2) / Math.max(Math.abs(d1), Math.abs(d2)) < percentage) - return false; - } - - return true; - } - } - - - private class FilterChangesRead implements Read { - private GraphChanges changes; - public FilterChangesRead(GraphChanges changes) { - this.changes = changes; - } - - @Override - public GraphChanges perform(ReadGraph graph) throws DatabaseException { - return filterChanges(graph, changes); - } - } - + } private class ModificationListContentProvider implements IStructuredContentProvider { @@ -647,9 +546,8 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { private class SelectionLabelProvider extends ColumnLabelProvider { - Collection selected; - public SelectionLabelProvider(Collection selected) { - this.selected = selected; + public SelectionLabelProvider() { + } @Override public String getText(Object element) { @@ -658,11 +556,39 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { @Override public Image getImage(Object element) { - if (selected.contains(element)) + if (update == null || !update.isInit()) + return null; + PropertyChange pc = (PropertyChange)element; + if (pc.applied()) + return null; + if (pc.selected()) return checked; else return unchecked; } + + @Override + public Color getForeground(Object element) { + PropertyChange pc = (PropertyChange)element; + if (!pc.enabled()) + return disabledColor; + return null; + } + } + + protected abstract class PropertyChangeLabelProvider extends ColumnLabelProvider { + + public PropertyChangeLabelProvider() { + + } + + @Override + public Color getForeground(Object element) { + PropertyChange pc = (PropertyChange)element; + if (!pc.enabled()) + return disabledColor; + return null; + } } private class UpdateNodeLabelProvider extends ColumnLabelProvider { @@ -670,16 +596,7 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { @Override public String getText(Object element) { final UpdateNode node = (UpdateNode)element; - try { - return getSession().syncRequest(new Read() { - @Override - public String perform(ReadGraph graph) throws DatabaseException { - return node.getLabel(graph); - } - }); - } catch (Exception e) { - return e.getMessage(); - } + return node.getLabel(); } @Override @@ -721,28 +638,30 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { @Override public Color getBackground(Object element) { final UpdateNode node = (UpdateNode)element; - Status status = node.getStatus(); - if (status == Status.CONTAINS) + UpdateStatus status = node.getStatus(); + if (status == UpdateStatus.CONTAINS) return containsColor; - if (status == Status.DELETED) + if (status == UpdateStatus.DELETED) return deletedColor; - if (status == Status.NEW) + if (status == UpdateStatus.NEW) return addedColor; return null; } + + @Override + public Color getForeground(Object element) { + final UpdateNode node = (UpdateNode)element; + if (node.getOp() != null && !node.getOp().enabled()) + return disabledColor; + return null; + } } private class SelectionEditingSupport extends EditingSupport { - @SuppressWarnings("rawtypes") - Collection selected; - - @SuppressWarnings("rawtypes") - public SelectionEditingSupport(ColumnViewer viewer, Collection selected) { + public SelectionEditingSupport(ColumnViewer viewer) { super(viewer); - this.selected = selected; - } @Override @@ -757,16 +676,21 @@ public abstract class ModelUpdateEditor extends ResourceEditorPart2 { @Override protected Object getValue(Object element) { - return selected.contains(element); + if (update == null || !update.isInit()) + return false; + PropertyChange pc = (PropertyChange)element; + return pc.selected(); } - @SuppressWarnings("unchecked") @Override protected void setValue(Object element, Object value) { + if (update == null || !update.isInit()) + return; + PropertyChange pc = (PropertyChange)element; if (Boolean.TRUE.equals(value)) - selected.add(element); + pc.select(true); else - selected.remove(element); + pc.select(false); getViewer().refresh(element); }