1 11 package org.eclipse.debug.internal.ui.views; 12 13 import java.util.ArrayList ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 17 import org.eclipse.core.runtime.IAdaptable; 18 import org.eclipse.core.runtime.IProgressMonitor; 19 import org.eclipse.core.runtime.IStatus; 20 import org.eclipse.core.runtime.Status; 21 import org.eclipse.core.runtime.jobs.Job; 22 import org.eclipse.debug.core.ILaunch; 23 import org.eclipse.jface.util.Assert; 24 import org.eclipse.jface.viewers.IStructuredSelection; 25 import org.eclipse.jface.viewers.TreeViewer; 26 import org.eclipse.jface.viewers.ViewerSorter; 27 import org.eclipse.swt.SWT; 28 import org.eclipse.swt.events.DisposeEvent; 29 import org.eclipse.swt.events.DisposeListener; 30 import org.eclipse.swt.widgets.Composite; 31 import org.eclipse.swt.widgets.Item; 32 import org.eclipse.swt.widgets.Tree; 33 import org.eclipse.swt.widgets.TreeItem; 34 import org.eclipse.swt.widgets.Widget; 35 import org.eclipse.ui.model.IWorkbenchAdapter; 36 import org.eclipse.ui.progress.UIJob; 37 38 44 public class RemoteTreeViewer extends TreeViewer { 45 46 private ExpansionJob fExpansionJob = null; 47 private SelectionJob fSelectionJob = null; 48 49 50 class ExpansionJob extends UIJob { 51 52 private Object element; 53 private List parents = new ArrayList (); 55 60 public ExpansionJob() { 61 super(DebugUIViewsMessages.LaunchViewer_1); setPriority(Job.INTERACTIVE); 63 setSystem(true); 64 } 65 66 69 public IStatus runInUIThread(IProgressMonitor monitor) { 70 if (getControl().isDisposed() || element == null) { 71 return Status.OK_STATUS; 72 } 73 synchronized (RemoteTreeViewer.this) { 74 boolean allParentsExpanded = true; 75 Iterator iterator = parents.iterator(); 76 while (iterator.hasNext() && !monitor.isCanceled()) { 77 Object parent = iterator.next(); 78 Widget item = findItem(parent); 79 if (item != null) { 80 expandToLevel(parent, 1); 81 } else { 82 allParentsExpanded = false; 83 break; 84 } 85 } 86 if (allParentsExpanded) { 87 Widget item = findItem(element); 88 if (item != null) { 89 if (isExpandable(element)) { 90 expandToLevel(element, 1); 91 } 92 element = null; 93 parents.clear(); 94 return Status.OK_STATUS; 95 } 96 } 97 return Status.OK_STATUS; 98 } 99 } 100 101 public void validate(Object object) { 102 if (element != null) { 103 if (element.equals(object) || parents.contains(object)) { 104 cancel(); 105 element = null; 106 } 107 } 108 } 109 110 public void setDeferredExpansion(Object toExpand) { 111 element = toExpand; 112 parents.clear(); 113 addAllParents(parents, element); 114 } 115 116 } 117 118 class SelectionJob extends UIJob { 119 120 private IStructuredSelection selection; 121 private Object first; 122 private List parents = new ArrayList (); 124 129 public SelectionJob() { 130 super(DebugUIViewsMessages.LaunchViewer_0); setPriority(Job.INTERACTIVE); 132 setSystem(true); 133 } 134 135 138 public IStatus runInUIThread(IProgressMonitor monitor) { 139 if (getControl().isDisposed() || selection == null) { 140 return Status.OK_STATUS; 141 } 142 synchronized (RemoteTreeViewer.this) { 143 boolean allParentsExpanded = true; 144 Iterator iterator = parents.iterator(); 145 while (iterator.hasNext() && !monitor.isCanceled()) { 146 Object parent = iterator.next(); 147 Widget item = findItem(parent); 148 if (item != null) { 149 expandToLevel(parent, 1); 150 } else { 151 allParentsExpanded = false; 152 break; 153 } 154 } 155 if (allParentsExpanded) { 156 if (findItem(first) != null) { 157 setSelection(selection, true); 158 selection = null; 159 first = null; 160 parents.clear(); 161 return Status.OK_STATUS; 162 } 163 } 164 165 return Status.OK_STATUS; 166 } 167 } 168 169 public void setDeferredSelection(IStructuredSelection sel) { 170 selection = sel; 171 first = selection.getFirstElement(); 172 parents.clear(); 173 addAllParents(parents, first); 174 } 175 176 public void validate(Object object) { 177 if (first != null) { 178 if (first.equals(object) || parents.contains(object)) { 179 cancel(); 180 selection = null; 181 } 182 } 183 } 184 } 185 186 187 192 public RemoteTreeViewer(Composite parent) { 193 super(parent); 194 addDisposeListener(); 195 fExpansionJob = new ExpansionJob(); 196 fSelectionJob = new SelectionJob(); 197 } 198 199 206 public RemoteTreeViewer(Composite parent, int style) { 207 super(parent, style); 208 addDisposeListener(); 209 fExpansionJob = new ExpansionJob(); 210 fSelectionJob = new SelectionJob(); 211 } 212 213 218 public RemoteTreeViewer(Tree tree) { 219 super(tree); 220 addDisposeListener(); 221 fExpansionJob = new ExpansionJob(); 222 fSelectionJob = new SelectionJob(); 223 } 224 225 private void addDisposeListener() { 226 getControl().addDisposeListener(new DisposeListener() { 227 public void widgetDisposed(DisposeEvent e) { 228 cancelJobs(); 229 } 230 }); 231 } 232 233 protected void runDeferredUpdates() { 234 if (fExpansionJob != null) { 235 fExpansionJob.schedule(); 236 } 237 if (fSelectionJob != null) { 238 fSelectionJob.schedule(); 239 } 240 } 241 242 248 protected void validateDeferredUpdates(Object element) { 249 if (element != null) { 250 if (fExpansionJob != null) { 251 fExpansionJob.validate(element); 252 } 253 if (fSelectionJob != null) { 254 fSelectionJob.validate(element); 255 } 256 } 257 } 258 259 262 public synchronized void add(Object parentElement, Object childElement) { 263 super.add(parentElement, childElement); 264 runDeferredUpdates(); 265 } 266 267 270 public synchronized void add(Object parentElement, Object [] childElements) { 271 super.add(parentElement, childElements); 272 runDeferredUpdates(); 273 } 274 275 278 public synchronized void remove(Object element) { 279 validateDeferredUpdates(element); 280 super.remove(element); 281 } 282 283 286 public synchronized void remove(Object [] elements) { 287 for (int i = 0; i < elements.length; i++) { 288 validateDeferredUpdates(elements[i]); 289 } 290 super.remove(elements); 291 } 292 293 296 public void cancelJobs() { 297 cancel(fSelectionJob); 298 cancel(fExpansionJob); 299 } 300 301 public synchronized void deferExpansion(Object element) { 302 TreeItem treeItem = (TreeItem) findItem(element); 303 if (treeItem == null) { 304 fExpansionJob.setDeferredExpansion(element); 305 fExpansionJob.schedule(); 306 } else { 307 if (!getExpanded(treeItem)) { 308 fExpansionJob.setDeferredExpansion(element); 309 fExpansionJob.schedule(); 310 } 311 } 312 } 313 314 public synchronized void deferSelection(IStructuredSelection selection) { 315 if (fSelectionJob == null) { 316 fSelectionJob = new SelectionJob(); 317 } 318 319 fSelectionJob.setDeferredSelection(selection); 320 fSelectionJob.schedule(); 321 } 322 323 public IStructuredSelection getDeferredSelection() { 324 if (fSelectionJob != null) { 325 return fSelectionJob.selection; 326 } 327 return null; 328 } 329 330 private void cancel(Job job) { 331 if (job != null) { 332 job.cancel(); 333 } 334 } 335 336 private void addAllParents(List list, Object element) { 337 if (element instanceof IAdaptable) { 338 IAdaptable adaptable = (IAdaptable) element; 339 IWorkbenchAdapter adapter = (IWorkbenchAdapter) adaptable.getAdapter(IWorkbenchAdapter.class); 340 if (adapter != null) { 341 Object parent = adapter.getParent(element); 342 if (parent != null) { 343 list.add(0, parent); 344 if (!(parent instanceof ILaunch)) 345 addAllParents(list, parent); 346 } 347 } 348 } 349 } 350 351 public Object [] filter(Object [] elements) { 352 return super.filter(elements); 353 } 354 355 public Object [] getCurrentChildren(Object parent) { 356 Widget widget = findItem(parent); 357 if (widget != null) { 358 Item[] items = getChildren(widget); 359 Object [] children = new Object [items.length]; 360 for (int i = 0; i < children.length; i++) { 361 Object data = items[i].getData(); 362 if (data == null) { 363 return null; 364 } 365 children[i] = data; 366 } 367 return children; 368 } 369 return null; 370 } 371 372 public synchronized void prune(final Object parent, final int offset) { 373 Widget widget = findItem(parent); 374 if (widget != null) { 375 final Item[] currentChildren = getChildren(widget); 376 if (offset < currentChildren.length) { 377 preservingSelection(new Runnable () { 378 public void run() { 379 for (int i = offset; i < currentChildren.length; i++) { 380 if (currentChildren[i].getData() != null) { 381 disassociate(currentChildren[i]); 382 } 383 currentChildren[i].dispose(); 384 } 385 } 386 }); 387 } 388 } 389 } 390 391 public synchronized void replace(final Object parent, final Object [] children, final int offset) { 392 preservingSelection(new Runnable () { 393 public void run() { 394 Widget[] widgets = findItems(parent); 395 for (int n = 0; n < widgets.length; n++) { 396 Widget widget = widgets[n]; 397 if (widget == null) { 398 add(parent, children); 399 } else { 400 Item[] currentChildren = getChildren(widget); 401 int pos = offset; 402 if (pos >= currentChildren.length) { 403 add(parent, children); 405 } else { 406 for (int i = 0; i < children.length; i++) { 408 Object child = children[i]; 409 if (pos < currentChildren.length) { 410 Item item = currentChildren[pos]; 412 Object data = item.getData(); 413 if (!child.equals(data)) { 414 internalRefresh(item, child, true, true); 416 } else { 417 doUpdateItem(item, child); 419 updatePlus(item, child); 420 } 421 } else { 422 int numLeft = children.length - i; 424 if (numLeft > 1) { 425 Object [] others = new Object [numLeft]; 426 System.arraycopy(children, i, others, 0, numLeft); 427 add(parent, others); 428 } else { 429 add(parent, child); 430 } 431 break; 432 } 433 pos++; 434 } 435 } 436 } 437 } 438 439 runDeferredUpdates(); 440 } 441 }); 442 } 443 444 protected void internalAdd(Widget widget, Object parentElement, Object [] childElements) { 445 446 if (widget instanceof Item) { 449 Item ti = (Item) widget; 450 if (!getExpanded(ti)) { 451 boolean needDummy = isExpandable(parentElement); 452 boolean haveDummy = false; 453 Item[] items = getItems(ti); 455 for (int i = 0; i < items.length; i++) { 456 if (items[i].getData() != null) { 457 disassociate(items[i]); 458 items[i].dispose(); 459 } else { 460 if (needDummy && !haveDummy) { 461 haveDummy = true; 462 } else { 463 items[i].dispose(); 464 } 465 } 466 } 467 if (needDummy && !haveDummy) 469 newItem(ti, SWT.NULL, -1); 470 return; 471 } 472 } 473 474 if (childElements.length > 0) { 475 Object [] filtered = filter(childElements); 476 if(getSorter() != null) 477 getSorter().sort(this,filtered); 478 createAddedElements(widget, filtered); 479 } 480 } 481 482 483 486 private void createAddedElements(Widget widget, Object [] elements) { 487 488 if(elements.length == 1){ 489 if (equals(elements[0], widget.getData())) 490 return; 491 } 492 493 ViewerSorter sorter = getSorter (); 494 Item[] items = getChildren(widget); 495 496 int lastInsertion = 0; 499 500 if(items.length == 0){ 502 for (int i = 0; i < elements.length; i++) { 503 createTreeItem(widget, elements[i], -1); 504 } 505 return; 506 } 507 508 for (int i = 0; i < elements.length; i++) { 509 boolean newItem = true; 510 Object element = elements[i]; 511 int index; 512 if(sorter == null){ 513 index = -1; 514 } 515 else{ 516 lastInsertion = insertionPosition(items,sorter,lastInsertion, element); 517 if(lastInsertion == items.length) 519 index = -1; 520 else{ while(lastInsertion < items.length && sorter.compare(this,element,items[lastInsertion].getData()) == 0){ 522 if (items[lastInsertion].getData().equals(element)) { 525 refresh(element); 527 newItem = false; 528 } 529 lastInsertion ++; } 531 if(lastInsertion == items.length) 533 index = -1; 534 else 535 index = lastInsertion + i; } 537 } 538 if(newItem) 539 createTreeItem(widget, element, index); 540 } 541 } 542 543 private int insertionPosition(Item[] items, ViewerSorter sorter, int lastInsertion, Object element) { 544 int size = items.length; 545 if (sorter == null) 546 return size; 547 int min = lastInsertion, max = size - 1; 548 549 while (min <= max) { 550 int mid = (min + max) / 2; 551 Object data = items[mid].getData(); 552 int compare = sorter.compare(this, data, element); 553 if (compare == 0) { 554 return mid; } 556 if (compare < 0) 557 min = mid + 1; 558 else 559 max = mid - 1; 560 } 561 return min; 562 } 563 564 public void update(Object element, String [] properties) { 565 Assert.isNotNull(element); 566 Widget[] widgets = findItems(element); 567 for (int i = 0; i < widgets.length; i++) { 568 Widget widget = widgets[i]; 569 if (widget != null) { 570 internalUpdate(widget, element, properties); 571 } 572 } 573 } 574 575 protected Widget[] findItems(Object target) { 576 List widgets = new ArrayList (); 577 Object root = getRoot(); 578 if (root != null) { 579 if (equals(root, target)) { 580 Widget widget = findItem(root); 581 widgets.add(widget); 582 } 583 } 584 Item[] children = getChildren(getControl()); 585 586 if (children != null) { 587 for (int i = 0; i < children.length; i++) { 588 Item child = children[i]; 589 internalFindItems(target, child, widgets); 590 } 591 } 592 return (Widget[]) widgets.toArray(new Widget[widgets.size()]); 593 } 594 595 private void internalFindItems(Object target, Item item, List widgets) { 596 if (equals(target, item.getData())) { 597 widgets.add(item); 598 } 599 600 Item[] children = getChildren(item); 601 for (int i = 0; i < children.length; i++) { 602 Item child = children[i]; 603 internalFindItems(target, child, widgets); 604 } 605 } 606 } 607 608 609 | Popular Tags |