1 package org.simantics.interop.update.editor;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashSet;
7 import java.util.Map.Entry;
8 import java.util.Stack;
10 import org.eclipse.jface.resource.ImageDescriptor;
11 import org.eclipse.jface.resource.JFaceResources;
12 import org.eclipse.jface.resource.LocalResourceManager;
13 import org.eclipse.jface.viewers.CellEditor;
14 import org.eclipse.jface.viewers.CheckStateChangedEvent;
15 import org.eclipse.jface.viewers.CheckboxCellEditor;
16 import org.eclipse.jface.viewers.CheckboxTreeViewer;
17 import org.eclipse.jface.viewers.ColumnLabelProvider;
18 import org.eclipse.jface.viewers.ColumnViewer;
19 import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
20 import org.eclipse.jface.viewers.EditingSupport;
21 import org.eclipse.jface.viewers.ICheckStateListener;
22 import org.eclipse.jface.viewers.IStructuredContentProvider;
23 import org.eclipse.jface.viewers.ITreeContentProvider;
24 import org.eclipse.jface.viewers.ITreeViewerListener;
25 import org.eclipse.jface.viewers.TableViewer;
26 import org.eclipse.jface.viewers.TableViewerColumn;
27 import org.eclipse.jface.viewers.TreeExpansionEvent;
28 import org.eclipse.jface.viewers.TreeViewerColumn;
29 import org.eclipse.jface.viewers.Viewer;
30 import org.eclipse.swt.SWT;
31 import org.eclipse.swt.events.SelectionAdapter;
32 import org.eclipse.swt.events.SelectionEvent;
33 import org.eclipse.swt.graphics.Color;
34 import org.eclipse.swt.graphics.Image;
35 import org.eclipse.swt.graphics.RGB;
36 import org.eclipse.swt.layout.FillLayout;
37 import org.eclipse.swt.layout.GridData;
38 import org.eclipse.swt.layout.GridLayout;
39 import org.eclipse.swt.widgets.Button;
40 import org.eclipse.swt.widgets.Composite;
41 import org.eclipse.swt.widgets.Display;
42 import org.eclipse.swt.widgets.Label;
43 import org.eclipse.swt.widgets.Text;
44 import org.simantics.db.ReadGraph;
45 import org.simantics.db.Resource;
46 import org.simantics.db.Session;
47 import org.simantics.db.Statement;
48 import org.simantics.db.WriteGraph;
49 import org.simantics.db.common.request.WriteRequest;
50 import org.simantics.db.exception.DatabaseException;
51 import org.simantics.db.layer0.util.Layer0Utils;
52 import org.simantics.db.request.Read;
53 import org.simantics.interop.test.GraphChanges;
54 import org.simantics.interop.test.GraphComparator;
55 import org.simantics.interop.update.Activator;
56 import org.simantics.interop.update.model.UpdateList;
57 import org.simantics.interop.update.model.UpdateNode;
58 import org.simantics.interop.update.model.UpdateNode.Status;
59 import org.simantics.interop.update.model.UpdateOp;
60 import org.simantics.interop.update.model.UpdateTree;
61 import org.simantics.interop.utils.TableUtils;
62 import org.simantics.ui.SimanticsUI;
63 import org.simantics.utils.datastructures.Callback;
64 import org.simantics.utils.datastructures.Pair;
65 import org.simantics.utils.ui.ExceptionUtils;
69 * Editor for updating models.
71 * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
74 public abstract class ModelUpdateEditor extends Composite{
76 private Composite errorComposite;
78 private CheckboxTreeViewer changeBrowser;
79 private TableViewer changeViewer;
81 private GraphChanges changes;
82 private UpdateTree updateTree;
83 private UpdateList updateList;
85 private GraphChanges changes2;
86 private GraphChanges changes3;
87 private UpdateTree updateTree2;
88 private UpdateList updateList2;
90 private Button updateAllButton;
91 private Button updateSelectedButton;
93 private LocalResourceManager manager = new LocalResourceManager(JFaceResources.getResources());
95 private Image checked;
96 private Image unchecked;
97 private Image warning;
99 private Color containsColor;
100 private Color deletedColor;
101 private Color addedColor;
104 private HashSet<UpdateNode> selectedStructure = new HashSet<UpdateNode>();
106 private List<ChangeFilter> filters = new ArrayList<ChangeFilter>();
108 public ModelUpdateEditor(Composite parent) {
109 super(parent,SWT.NONE);
110 checked = manager.createImage(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/tick.png"));
111 unchecked = manager.createImage(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/cross.png"));
112 warning = manager.createImage(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/error.png"));
115 containsColor = new Color(parent.getDisplay(), new RGB(255,255,220));
116 deletedColor = new Color(parent.getDisplay(), new RGB(255,220,220));
117 addedColor = new Color(parent.getDisplay(), new RGB(220,255,220));
119 this.setLayout(new GridLayout(1,false));
121 errorComposite = new Composite(this, SWT.BORDER);
122 GridData data = new GridData();
123 data.grabExcessHorizontalSpace = true;
124 data.grabExcessVerticalSpace = false;
125 data.horizontalAlignment = SWT.FILL;
126 data.verticalAlignment = SWT.TOP;
127 errorComposite.setLayoutData(data);
128 errorComposite.setLayout(new GridLayout(2, false));
130 errorComposite.setVisible(false);
132 // IEditorInput input = getEditorInput();
133 // if (!(input instanceof UpdateEditorInput)) {
134 // Label label = new Label(composite, SWT.NONE);
135 // label.setText("Unknown input.");
139 Composite fillComposite = new Composite(this, SWT.NONE);
140 data = new GridData();
141 data.grabExcessHorizontalSpace = true;
142 data.grabExcessVerticalSpace = true;
143 data.horizontalAlignment = SWT.FILL;
144 data.verticalAlignment = SWT.FILL;
145 fillComposite.setLayoutData(data);
146 fillComposite.setLayout(new FillLayout(SWT.VERTICAL));
149 changeBrowser = new CheckboxTreeViewer(fillComposite,SWT.MULTI|SWT.V_SCROLL|SWT.BORDER|SWT.FULL_SELECTION );
151 changeBrowser.setContentProvider(new UpdateTreeContentProvider());
153 changeBrowser.getTree().setHeaderVisible(true);
155 ColumnViewerToolTipSupport.enableFor(changeBrowser);
158 TreeViewerColumn dataColumn = TableUtils.addColumn(changeBrowser, "Data", true, 600);
160 dataColumn.setLabelProvider(new UpdateNodeLabelProvider());
162 changeBrowser.addCheckStateListener(new ICheckStateListener() {
165 public void checkStateChanged(CheckStateChangedEvent event) {
166 UpdateNode node = (UpdateNode) event.getElement();
167 if (node.getOp() != null) {
168 node.getOp().select(Boolean.TRUE.equals(event.getChecked()));
175 changeBrowser.addTreeListener(new ITreeViewerListener() {
178 public void treeExpanded(TreeExpansionEvent event) {
179 event.getTreeViewer().getControl().getDisplay().asyncExec(new Runnable() {
183 // TreeViewer uses lazy load, checked states must be updated when the tree is expanded.
191 public void treeCollapsed(TreeExpansionEvent event) {
195 changeBrowser.setUseHashlookup(true);
199 changeViewer = new TableViewer(fillComposite,SWT.MULTI|SWT.V_SCROLL|SWT.BORDER|SWT.FULL_SELECTION);
201 changeViewer.getTable().setHeaderVisible(true);
202 changeViewer.getTable().setLinesVisible(true);
204 changeViewer.setContentProvider(new ModificationListContentProvider());
206 changeViewer.setUseHashlookup(true);
208 TableViewerColumn selection = TableUtils.addColumn(changeViewer, getColumntTitle(0), false, false, 20);
209 TableViewerColumn diagram = TableUtils.addColumn(changeViewer, getColumntTitle(1), true, true, 100);
210 TableViewerColumn symbol = TableUtils.addColumn(changeViewer, getColumntTitle(2), true, true, 100);
211 TableViewerColumn property = TableUtils.addColumn(changeViewer, getColumntTitle(3), true, true, 100);
212 TableViewerColumn oldValue = TableUtils.addColumn(changeViewer, getColumntTitle(4), true, true, 100);
213 TableViewerColumn newValue = TableUtils.addColumn(changeViewer, getColumntTitle(5), true, true, 100);
215 diagram.setLabelProvider(getLabelProvider(1));
216 symbol.setLabelProvider(getLabelProvider(2));
217 property.setLabelProvider(getLabelProvider(3));
218 oldValue.setLabelProvider(getLabelProvider(4));
219 newValue.setLabelProvider(getLabelProvider(5));
221 selection.setLabelProvider(new SelectionLabelProvider());
222 selection.getColumn().addSelectionListener(new SelectionAdapter() {
224 public void widgetSelected(SelectionEvent e) {
225 if (updateList.getChanges().size() > 0) {
226 if (updateList.getSelected().size() > 0) {
227 updateList.clearSelected();
229 for (Pair<Statement, Statement> nr : updateList.getChanges())
230 updateList.addSelected(nr);
232 changeViewer.refresh();
236 selection.setEditingSupport(new SelectionEditingSupport(changeViewer));
239 Composite buttonComposite = new Composite(this, SWT.NONE);
241 data = new GridData();
242 data.grabExcessHorizontalSpace = true;
243 data.grabExcessVerticalSpace = false;
244 data.horizontalAlignment = SWT.FILL;
245 data.verticalAlignment = SWT.BOTTOM;
247 buttonComposite.setLayoutData(data);
249 buttonComposite.setLayout(new GridLayout(3, false));
251 Label label = new Label(buttonComposite, SWT.NONE);
252 data = new GridData();
253 data.grabExcessHorizontalSpace = true;
254 data.grabExcessVerticalSpace = false;
255 data.horizontalAlignment = SWT.FILL;
256 data.verticalAlignment = SWT.CENTER;
257 label.setLayoutData(data);
259 updateAllButton = new Button(buttonComposite, SWT.PUSH);
260 updateAllButton.setText("Update All");
261 updateAllButton.addSelectionListener(new SelectionAdapter() {
263 public void widgetSelected(SelectionEvent e) {
267 updateSelectedButton = new Button(buttonComposite, SWT.PUSH);
268 updateSelectedButton.setText("Update Selected");
269 updateSelectedButton.addSelectionListener(new SelectionAdapter() {
271 public void widgetSelected(SelectionEvent e) {
277 protected Session getSession() {
278 return SimanticsUI.getSession();
281 protected String getColumntTitle(int i) {
296 throw new RuntimeException("Unknown column index" + i);
301 protected abstract ColumnLabelProvider getLabelProvider(int i);
302 protected abstract Pair<GraphComparator,String> getChanges(Resource r1, Resource r2) throws DatabaseException;
303 protected abstract UpdateTree getUpdateTree(GraphChanges changes) throws DatabaseException;
304 protected UpdateList getUpdateList(GraphChanges changes) throws DatabaseException {
305 return new UpdateList(changes.getModifications());
308 protected void addFilters(List<ChangeFilter> filters) {
312 public GraphChanges getChanges() {
316 public UpdateTree getUpdateTree() {
320 public UpdateList getUpdateList() {
324 public CheckboxTreeViewer getChangeBrowser() {
325 return changeBrowser;
328 public TableViewer getChangeViewer() {
332 private void showWarning(String text) {
333 errorComposite.setVisible(true);
335 Label label = new Label(errorComposite, SWT.NONE);
336 label.setImage(warning);
337 label = new Label(errorComposite, SWT.NONE);
339 //this.setStatusMessage("Update contains structural changes (new or deleted symbols), please create a new model.");
344 private List<ICheckStateListener> checkStateListeners = new ArrayList<>();
347 public void addCheckStateListener(ICheckStateListener listener) {
348 checkStateListeners.add(listener);
351 public void removeCheckStateListener(ICheckStateListener listener) {
352 checkStateListeners.remove(listener);
355 public void refreshChecked() {
356 Stack<UpdateNode> nodeStack = new Stack<UpdateNode>();
357 nodeStack.push((UpdateNode)updateTree.getRootNode());
358 while (!nodeStack.isEmpty()) {
359 UpdateNode n = nodeStack.pop();
360 if (n.getOp() != null) {
361 UpdateOp op = n.getOp();
362 if (!op.isAdd() && !op.isDelete()) {
363 changeBrowser.setGrayed(n, true);
364 changeBrowser.setChecked(n, true);
366 boolean applied = op.applied();
368 changeBrowser.setChecked(n, true);
369 changeBrowser.setGrayed(n, true);
370 selectedStructure.remove(n);
372 boolean sel = op.selected();
374 selectedStructure.add(n);
377 selectedStructure.remove(n);
379 changeBrowser.setChecked(n, sel);
380 changeBrowser.setGrayed(n, false);
384 changeBrowser.setGrayed(n, true);
385 changeBrowser.setChecked(n, true);
387 for (UpdateNode c : n.getChildren()) {
388 nodeStack.add((UpdateNode)c);
392 changeBrowser.refresh();
393 for (ICheckStateListener l : checkStateListeners) {
394 l.checkStateChanged(new CheckStateChangedEvent(changeBrowser, null, false));
396 changeViewer.refresh();
401 public void load(UpdateEditorInput uei) {
405 Resource oldModel = uei.getR1(); // old model that is being updated, contains user made changes
406 Resource newModel = uei.getR2(); // new model,
407 Resource originalModel = uei.getR3(); // original old model without user made changes
411 if (originalModel != null) {
412 // tree way comparison
413 // compare the original and the old model
414 Pair<GraphComparator,String> result2 = getChanges(originalModel, oldModel);
415 GraphComparator comparator2 = result2.first;
416 if (result2.second != null)
417 showWarning(result2.second);
418 comparator2.test(getSession());
419 changes2 = comparator2.getChanges();
420 changes2 = getSession().syncRequest(new FilterChangesRead(changes2));
421 updateTree2 = getUpdateTree(changes2);
422 updateList2 = getUpdateList(changes2);
424 // compare the original and the new model
425 Pair<GraphComparator,String> result3 = getChanges(originalModel,newModel);
426 GraphComparator comparator3 = result3.first;
427 if (result3.second != null)
428 showWarning(result3.second);
429 comparator3.test(getSession());
430 changes3 = comparator3.getChanges();
431 changes3 = getSession().syncRequest(new FilterChangesRead(changes3));
434 Pair<GraphComparator,String> result = getChanges(oldModel,newModel);
435 GraphComparator comparator = result.first;
436 if (result.second != null)
437 showWarning(result.second);
438 if (originalModel != null) {
439 // three-way comparison: use change information to configure
440 // the comparison between the old and the new model.
442 // 1. map comparable resources
443 for (Entry<Resource, Resource> origToOld : changes2.getComparable().getEntries()) {
444 Resource oldR = origToOld.getValue();
445 Resource newR = changes3.getComparable().getRight(origToOld.getKey());
447 comparator.addComparableResources(oldR, newR);
450 // 2. mark removed resources as distinct, so that comparison does not pair them
451 for (Statement s : changes2.getDeletions()) {
452 if (changes3.getComparable().containsLeft(s.getObject()))
453 comparator.addNonMatchedRight(changes3.getComparable().getRight(s.getObject()));
456 for (Statement s : changes3.getDeletions()) {
457 if (changes2.getComparable().containsLeft(s.getObject()))
458 comparator.addNonMatchedLeft(changes2.getComparable().getRight(s.getObject()));
460 if (uei.isNewDistinct()) {
461 // 3. mark added resources as distinct, so that comparison does not pair them
462 for (Statement s : changes2.getAdditions()) {
463 comparator.addNonMatchedLeft(s.getObject());
466 for (Statement s : changes3.getAdditions()) {
467 comparator.addNonMatchedRight(s.getObject());
471 comparator.test(getSession());
472 changes = comparator.getChanges();
473 changes = getSession().syncRequest(new FilterChangesRead(changes));
474 updateTree = getUpdateTree(changes);
475 updateList = getUpdateList(changes);
477 if (originalModel != null) {
478 createDefaultSelections();
481 } catch (DatabaseException e) {
482 Text text = new Text(this, SWT.MULTI);
483 text.setText(e.getMessage());
493 protected void setInputs() {
494 changeViewer.setInput(updateList.getChanges());
495 changeBrowser.setInput(updateTree);
498 private void applyAll() {
499 updateAllButton.setEnabled(false);
500 updateSelectedButton.setEnabled(false);
501 getSession().asyncRequest(new WriteRequest(){
503 public void perform(WriteGraph graph) throws DatabaseException {
504 Layer0Utils.addCommentMetadata(graph, "Apply all model updates");
505 graph.markUndoPoint();
506 for (Pair<Statement, Statement> mod : updateList.getChanges()) {
507 applyLiteralChange(graph, mod);
511 updateTree.getUpdateOps().applyAll(graph);
513 Display.getDefault().asyncExec(new Runnable() {
518 updateAllButton.setEnabled(true);
519 updateSelectedButton.setEnabled(true);
521 changeViewer.refresh();
527 }, new Callback<DatabaseException>() {
529 public void run(DatabaseException parameter) {
530 if (parameter != null)
531 ExceptionUtils.logAndShowError("Cannot update model", parameter);
536 protected void applyLiteralChange(WriteGraph graph, Pair<Statement, Statement> mod) throws DatabaseException {
537 if (mod.second == null) {
538 graph.deny(mod.first);
541 Resource s = changes.getComparable().getLeft(mod.second.getSubject());
542 Resource pred = mod.second.getPredicate();
543 if (graph.hasValue(mod.second.getObject())) {
544 Object value = graph.getValue(mod.second.getObject());
545 graph.claimLiteral(s, pred, value);
553 private void applySelected() {
554 updateAllButton.setEnabled(false);
555 updateSelectedButton.setEnabled(false);
556 getSession().asyncRequest(new WriteRequest(){
558 public void perform(WriteGraph graph) throws DatabaseException {
559 Layer0Utils.addCommentMetadata(graph, "Apply selected model updates");
560 graph.markUndoPoint();
561 for (Pair<Statement, Statement> mod : updateList.getSelected()) {
562 updateList.removeChange(mod);
563 applyLiteralChange(graph, mod);
566 updateTree.getUpdateOps().applySelected(graph);
568 Display.getDefault().asyncExec(new Runnable() {
572 changeViewer.refresh();
573 updateAllButton.setEnabled(true);
574 updateSelectedButton.setEnabled(true);
582 protected void createDefaultSelections() {
583 // select all changes
584 for (Entry<Resource, UpdateOp> op : updateTree.getUpdateOps().getResourceMap().entrySet()) {
585 op.getValue().select(true);
589 for (Pair<Statement, Statement> pair : updateList.getChanges()) {
590 updateList.addSelected(pair);
593 // preserve user-made changes (by removing selections)
594 for (Entry<Resource, UpdateOp> op : updateTree.getUpdateOps().getResourceMap().entrySet()) {
595 UpdateOp op2 = updateTree2.getUpdateOps().getUpdateOp(op.getKey());
597 if (changes3.getComparable().containsRight(op.getKey())){
598 op2 = updateTree2.getUpdateOps().getUpdateOp(changes3.getComparable().getLeft(op.getKey()));
601 if (op2 != null && op.getValue().getClass() == op2.getClass()) {
602 op.getValue().select(false);
606 for (Pair<Statement, Statement> pair : updateList.getChanges()) {
607 if (pair.first != null) {
608 boolean found = false;
609 for (Pair<Statement, Statement> pair2 : updateList2.getChanges()) {
610 if (pair.first.equals(pair2.first)) {
616 updateList.removeSelected(pair);
626 * 1. Changes that are not essential for model update (changes that can be found when the models are axcatly the same)
627 * 2. Runs custom filters for value changes.
632 * @throws DatabaseException
634 protected GraphChanges filterChanges(ReadGraph g, GraphChanges changes) throws DatabaseException
637 List<Pair<Statement,Statement>> modifications = new ArrayList<Pair<Statement,Statement>>();
639 for (Pair<Statement, Statement> mod : changes.getModifications()) {
641 boolean accept = true;
642 for (ChangeFilter filter : filters) {
643 if (!filter.accept(g, mod)) {
649 modifications.add(mod);
651 GraphChanges newChanges = new GraphChanges(changes.getResource1(),changes.getResource2(),changes.getDeletions(), changes.getAdditions(), modifications, changes.getComparable());
655 public interface ChangeFilter {
656 public boolean accept(ReadGraph g, Pair<Statement, Statement> change) throws DatabaseException;
662 * Filters floating point value changes (default filter is set filter when the change is less than 1%)
665 protected class FPValueFilter implements ChangeFilter {
667 private double percentage = 0.01;
669 public FPValueFilter() {
673 public FPValueFilter(double percentage) {
674 if (percentage < 0.0 || percentage > 1.0)
675 throw new IllegalArgumentException("Percentage must be between 0.0 and 1.0.");
676 this.percentage = percentage;
680 public boolean accept(ReadGraph g, Pair<Statement, Statement> change) throws DatabaseException {
681 //filter floating point values that have less than 1% difference.
682 if (!g.hasValue(change.first.getObject()) || !g.hasValue(change.second.getObject()))
684 Object v1 = g.getValue(change.first.getObject());
685 Object v2 = g.getValue(change.second.getObject());
687 if (v1 instanceof Double && v2 instanceof Double) {
688 double d1 = (Double)v1;
689 double d2 = (Double)v2;
690 if (Math.abs(d1-d2) / Math.max(Math.abs(d1), Math.abs(d2)) < percentage)
692 } else if (v1 instanceof Float && v2 instanceof Float) {
693 float d1 = (Float)v1;
694 float d2 = (Float)v2;
695 if (Math.abs(d1-d2) / Math.max(Math.abs(d1), Math.abs(d2)) < percentage)
704 private class FilterChangesRead implements Read<GraphChanges> {
705 private GraphChanges changes;
706 public FilterChangesRead(GraphChanges changes) {
707 this.changes = changes;
711 public GraphChanges perform(ReadGraph graph) throws DatabaseException {
712 return filterChanges(graph, changes);
717 private class ModificationListContentProvider implements IStructuredContentProvider {
719 @SuppressWarnings("unchecked")
721 public Object[] getElements(Object inputElement) {
722 if (inputElement == null)
724 Collection<Pair<Statement, Statement>> coll = (Collection<Pair<Statement, Statement>>)inputElement;
725 return coll.toArray();
729 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
734 public void dispose() {
739 private class UpdateTreeContentProvider implements ITreeContentProvider {
741 public Object[] getElements(Object inputElement) {
742 if (inputElement instanceof UpdateTree)
743 return new Object[]{((UpdateTree)inputElement).getRootNode()};
744 if (inputElement instanceof UpdateNode) {
745 UpdateNode node = (UpdateNode)inputElement;
746 return node.getChildren().toArray();
748 return new Object[0];
752 public Object getParent(Object element) {
757 public Object[] getChildren(Object parentElement) {
758 UpdateNode node = (UpdateNode)parentElement;
759 return node.getChildren().toArray();
763 public boolean hasChildren(Object element) {
764 UpdateNode node = (UpdateNode)element;
765 return node.getChildren().size() > 0;
769 public void dispose() {
774 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
779 private class SelectionLabelProvider extends ColumnLabelProvider {
781 public SelectionLabelProvider() {
785 public String getText(Object element) {
790 public Image getImage(Object element) {
791 if (updateList == null)
793 if (updateList.isSelected((Pair<Statement, Statement>) element))
800 private class UpdateNodeLabelProvider extends ColumnLabelProvider {
803 public String getText(Object element) {
804 final UpdateNode node = (UpdateNode)element;
805 return node.getLabel();
809 public Image getImage(Object element) {
810 final UpdateNode node = (UpdateNode)element;
812 ImageDescriptor id = getSession().syncRequest(new Read<ImageDescriptor>() {
814 public ImageDescriptor perform(ReadGraph graph) throws DatabaseException {
815 return node.getImage(graph);
818 return manager.createImage(id);
819 } catch (Exception e) {
825 public String getToolTipText(Object element) {
826 final UpdateNode node = (UpdateNode)element;
827 if (node.getOp() != null) {
828 return node.getOp().toString();
835 public int getToolTipDisplayDelayTime(Object object) {
840 public int getToolTipTimeDisplayed(Object object) {
845 public Color getBackground(Object element) {
846 final UpdateNode node = (UpdateNode)element;
847 Status status = node.getStatus();
848 if (status == Status.CONTAINS)
849 return containsColor;
850 if (status == Status.DELETED)
852 if (status == Status.NEW)
858 private class SelectionEditingSupport extends EditingSupport {
861 @SuppressWarnings("rawtypes")
862 public SelectionEditingSupport(ColumnViewer viewer) {
868 protected boolean canEdit(Object element) {
873 protected CellEditor getCellEditor(Object element) {
874 return new CheckboxCellEditor(null, SWT.CHECK);
878 protected Object getValue(Object element) {
879 if (updateList == null)
881 return updateList.isSelected((Pair<Statement, Statement>) element);
884 @SuppressWarnings("unchecked")
886 protected void setValue(Object element, Object value) {
887 if (updateList == null)
889 if (Boolean.TRUE.equals(value))
890 updateList.addSelected((Pair<Statement, Statement>) element);
892 updateList.removeSelected((Pair<Statement, Statement>) element);
894 getViewer().refresh(element);