1 12 package org.eclipse.jface.internal.databinding.provisional.viewers; 13 14 import java.util.Collections ; 15 import java.util.HashSet ; 16 import java.util.Set ; 17 18 import org.eclipse.core.databinding.observable.IStaleListener; 19 import org.eclipse.core.databinding.observable.Observables; 20 import org.eclipse.core.databinding.observable.StaleEvent; 21 import org.eclipse.core.databinding.observable.set.IObservableSet; 22 import org.eclipse.core.databinding.observable.set.ISetChangeListener; 23 import org.eclipse.core.databinding.observable.set.SetChangeEvent; 24 import org.eclipse.core.databinding.observable.set.SetDiff; 25 import org.eclipse.jface.viewers.TreeViewer; 26 import org.eclipse.swt.widgets.Control; 27 28 class TreeNode implements ISetChangeListener, IStaleListener { 29 private UnorderedTreeContentProvider contentProvider; 30 private Object element; 31 32 private HashSet parents = null; 34 35 Object parent; 38 39 42 private IObservableSet children; 43 44 private boolean hasPendingNode = false; 45 private boolean isStale; 46 private boolean listeningToChildren = false; 47 private boolean prefetchEnqueued = false; 48 49 53 public TreeNode(Object element, UnorderedTreeContentProvider cp) { 54 this.element = element; 55 this.contentProvider = cp; 56 children = contentProvider.createChildSet(element); 57 if (children == null) { 58 children = Observables.emptyObservableSet(); 59 listeningToChildren = true; 60 } 61 hasPendingNode = children.isStale(); 62 } 63 64 67 public void addParent(Object parent) { 68 if (this.parent == null) { 69 this.parent = parent; 70 } else { 71 if (parent.equals(this.parent)) { 72 return; 73 } 74 if (parents == null) { 75 parents = new HashSet (); 76 parents.add(this.parent); 77 } 78 parents.add(parent); 79 } 80 } 81 82 85 public void removeParent(Object parent) { 86 if (this.parents != null) { 87 parents.remove(parent); 88 } 89 90 if (parent == this.parent) { 91 if (parents == null || parents.isEmpty()) { 92 this.parent = null; 93 } else { 94 this.parent = parents.iterator().next(); 95 } 96 } 97 98 if (this.parents != null && this.parents.size() <= 1) { 99 this.parents = null; 100 } 101 } 102 103 109 public Set getChildren() { 110 if (!listeningToChildren) { 111 listeningToChildren = true; 112 children.addSetChangeListener(this); 113 hasPendingNode = children.isEmpty() && children.isStale(); 114 children.addStaleListener(this); 115 updateStale(); 116 } 117 118 if (hasPendingNode) { 120 Object pendingNode = contentProvider.getPendingNode(); 121 return Collections.singleton(pendingNode); 122 } 123 return children; 124 } 125 126 129 public IObservableSet getChildrenSet() { 130 return children; 131 } 132 133 private void updateStale() { 134 boolean willBeStale = children.isStale(); 135 if (willBeStale != isStale) { 136 isStale = willBeStale; 137 138 contentProvider.changeStale(isStale? 1 : -1); 139 } 140 } 141 142 145 public boolean isStale() { 146 return isStale; 147 } 148 149 155 public boolean shouldShowPlus() { 156 if (children == null) { 157 return true; 162 } 163 if (!listeningToChildren && !prefetchEnqueued) { 164 prefetchEnqueued = true; 165 contentProvider.enqueuePrefetch(this); 166 } 167 return !listeningToChildren || hasPendingNode || !children.isEmpty(); 168 } 169 170 173 public void dispose() { 174 if (children != null) { 175 if (listeningToChildren) { 176 contentProvider.remove(element, children, true); 177 children.removeSetChangeListener(this); 178 children.removeStaleListener(this); 179 } 180 children.dispose(); 181 children = null; 182 183 if (listeningToChildren && isStale) { 184 contentProvider.changeStale(-1); 185 } 186 } 187 } 188 189 192 public boolean isDisposed() { 193 return children == null; 194 } 195 196 202 public Object getParent() { 203 return parent; 204 } 205 206 210 public Set getParents() { 211 if (parents == null) { 212 if (parent == null) { 213 return Collections.EMPTY_SET; 214 } else { 215 return Collections.singleton(parent); 216 } 217 } else { 218 return parents; 219 } 220 } 221 222 225 public void handleSetChange(SetChangeEvent event) { 226 SetDiff diff = event.diff; 227 TreeViewer viewer = this.contentProvider.getViewer(); 228 if (viewer != null) { 229 Control control = viewer.getControl(); 230 if (control != null) { 231 if (control.isDisposed()) { 232 contentProvider.dispose(); 235 return; 236 } 237 } 238 } 239 240 boolean shouldHavePendingNode = children.isEmpty() && children.isStale(); 241 242 Set additions = diff.getAdditions(); 243 if (shouldHavePendingNode && !hasPendingNode) { 245 HashSet newAdditions = new HashSet (); 246 newAdditions.addAll(additions); 247 newAdditions.add(contentProvider.getPendingNode()); 248 additions = newAdditions; 249 hasPendingNode = true; 250 } 251 252 Set removals = diff.getRemovals(); 253 if (!shouldHavePendingNode && hasPendingNode) { 255 HashSet newRemovals = new HashSet (); 256 newRemovals.addAll(removals); 257 newRemovals.add(contentProvider.getPendingNode()); 258 removals = newRemovals; 259 hasPendingNode = false; 260 } 261 if (!additions.isEmpty()) { 262 contentProvider.add(element, additions); 263 } 264 if (!removals.isEmpty()) { 265 contentProvider.remove(element, removals, children.isEmpty() && !hasPendingNode); 266 } 267 268 updateStale(); 269 } 270 271 public void handleStale(StaleEvent staleEvent) { 272 TreeViewer viewer = this.contentProvider.getViewer(); 273 if (viewer != null) { 274 Control control = viewer.getControl(); 275 if (control != null) { 276 if (control.isDisposed()) { 277 contentProvider.dispose(); 280 return; 281 } 282 } 283 } 284 285 boolean shouldHavePendingNode = children.isEmpty() && children.isStale(); 286 287 if (shouldHavePendingNode && !hasPendingNode) { 289 hasPendingNode = shouldHavePendingNode; 290 contentProvider.add(element, Collections.singleton(contentProvider.getPendingNode())); 291 } 292 293 if (!shouldHavePendingNode && hasPendingNode) { 295 hasPendingNode = shouldHavePendingNode; 296 contentProvider.remove(element, Collections.singleton(contentProvider.getPendingNode()), true); 297 } 298 299 updateStale(); 300 } 301 302 305 public Object getElement() { 306 return element; 307 } 308 309 312 public void prefetch() { 313 TreeViewer viewer = this.contentProvider.getViewer(); 314 if (viewer != null) { 315 Control control = viewer.getControl(); 316 if (control != null) { 317 if (control.isDisposed()) { 318 return; 321 } 322 } 323 } 324 325 Set children = getChildren(); 326 if (!children.isEmpty()) { 327 contentProvider.add(element, children); 328 } else { 329 contentProvider.getViewer().refresh(element); 331 } 332 } 333 } 334 | Popular Tags |