1 11 package org.eclipse.jface.internal.databinding.internal; 12 13 import org.eclipse.jface.internal.databinding.provisional.BindSpec; 14 import org.eclipse.jface.internal.databinding.provisional.Binding; 15 import org.eclipse.jface.internal.databinding.provisional.BindingEvent; 16 import org.eclipse.jface.internal.databinding.provisional.DataBindingContext; 17 import org.eclipse.jface.internal.databinding.provisional.observable.list.IListChangeListener; 18 import org.eclipse.jface.internal.databinding.provisional.observable.list.IObservableList; 19 import org.eclipse.jface.internal.databinding.provisional.observable.list.ListDiff; 20 import org.eclipse.jface.internal.databinding.provisional.observable.list.ListDiffEntry; 21 import org.eclipse.jface.internal.databinding.provisional.observable.value.IObservableValue; 22 import org.eclipse.jface.internal.databinding.provisional.observable.value.WritableValue; 23 import org.eclipse.jface.internal.databinding.provisional.validation.ValidationError; 24 25 29 public class ListBinding extends Binding { 30 31 private boolean updating = false; 32 33 private IObservableList modelList; 34 35 private final IObservableList targetList; 36 37 45 public ListBinding(DataBindingContext context, IObservableList targetList, 46 IObservableList modelList, BindSpec bindSpec) { 47 super(context); 48 this.targetList = targetList; 49 this.modelList = modelList; 50 targetList.addListChangeListener(targetChangeListener); 52 modelList.addListChangeListener(modelChangeListener); 53 updateTargetFromModel(); 54 } 55 56 private final IListChangeListener targetChangeListener = new IListChangeListener() { 57 public void handleListChange(IObservableList source, ListDiff diff) { 58 if (updating) { 59 return; 60 } 61 BindingEvent e = new BindingEvent(modelList, targetList, diff, 63 BindingEvent.EVENT_COPY_TO_MODEL, 64 BindingEvent.PIPELINE_AFTER_GET); 65 if (failure(errMsg(fireBindingEvent(e)))) { 66 return; 67 } 68 updating = true; 69 try { 70 ListDiff setDiff = (ListDiff) e.diff; 73 ListDiffEntry[] differences = setDiff.getDifferences(); 74 for (int i = 0; i < differences.length; i++) { 75 ListDiffEntry entry = differences[i]; 76 if (entry.isAddition()) { 77 modelList.add(entry.getPosition(), entry.getElement()); 78 } else { 79 modelList.remove(entry.getPosition()); 80 } 81 } 82 e.pipelinePosition = BindingEvent.PIPELINE_AFTER_CHANGE; 83 if (failure(errMsg(fireBindingEvent(e)))) { 84 return; 85 } 86 } finally { 87 updating = false; 88 } 89 } 90 }; 91 92 private IListChangeListener modelChangeListener = new IListChangeListener() { 93 public void handleListChange(IObservableList source, ListDiff diff) { 94 if (updating) { 95 return; 96 } 97 BindingEvent e = new BindingEvent(modelList, targetList, diff, 99 BindingEvent.EVENT_COPY_TO_TARGET, 100 BindingEvent.PIPELINE_AFTER_GET); 101 if (failure(errMsg(fireBindingEvent(e)))) { 102 return; 103 } 104 updating = true; 105 try { 106 ListDiff setDiff = (ListDiff) e.diff; 109 ListDiffEntry[] differences = setDiff.getDifferences(); 110 for (int i = 0; i < differences.length; i++) { 111 ListDiffEntry entry = differences[i]; 112 if (entry.isAddition()) { 113 targetList.add(entry.getPosition(), entry.getElement()); 114 } else { 115 targetList.remove(entry.getPosition()); 116 } 117 } 118 e.pipelinePosition = BindingEvent.PIPELINE_AFTER_CHANGE; 119 if (failure(errMsg(fireBindingEvent(e)))) { 120 return; 121 } 122 } finally { 123 updating = false; 124 } 125 } 126 }; 127 128 private WritableValue partialValidationErrorObservable = new WritableValue( 129 null); 130 131 private WritableValue validationErrorObservable = new WritableValue(null); 132 133 private ValidationError errMsg(ValidationError validationError) { 134 partialValidationErrorObservable.setValue(null); 135 validationErrorObservable.setValue(validationError); 136 return validationError; 137 } 138 139 private boolean failure(ValidationError errorMessage) { 140 if (errorMessage != null 142 && errorMessage.status == ValidationError.ERROR) { 143 return true; 144 } 145 return false; 146 } 147 148 public void updateTargetFromModel() { 149 updating = true; 150 try { 151 targetList.clear(); 152 targetList.addAll(modelList); 153 } finally { 154 updating = false; 155 } 156 } 157 158 public IObservableValue getValidationError() { 159 return validationErrorObservable; 160 } 161 162 public IObservableValue getPartialValidationError() { 163 return partialValidationErrorObservable; 164 } 165 166 public void updateModelFromTarget() { 167 updating = true; 168 try { 169 modelList.clear(); 170 modelList.addAll(targetList); 171 } finally { 172 updating = false; 173 } 174 } 175 } 176 | Popular Tags |