1 11 package org.eclipse.compare.structuremergeviewer; 12 13 import java.util.Iterator ; 14 import java.util.ResourceBundle ; 15 16 import org.eclipse.compare.*; 17 import org.eclipse.compare.internal.Utilities; 18 import org.eclipse.jface.action.*; 19 import org.eclipse.jface.util.IPropertyChangeListener; 20 import org.eclipse.jface.util.PropertyChangeEvent; 21 import org.eclipse.jface.viewers.*; 22 import org.eclipse.swt.SWT; 23 import org.eclipse.swt.events.DisposeEvent; 24 import org.eclipse.swt.graphics.Image; 25 import org.eclipse.swt.widgets.*; 26 27 38 public class DiffTreeViewer extends TreeViewer { 39 40 static class DiffViewerComparator extends ViewerComparator { 41 42 public boolean isSorterProperty(Object element, Object property) { 43 return false; 44 } 45 46 public int category(Object node) { 47 if (node instanceof DiffNode) { 48 Object o= ((DiffNode) node).getId(); 49 if (o instanceof DocumentRangeNode) 50 return ((DocumentRangeNode) o).getTypeCode(); 51 } 52 return 0; 53 } 54 } 55 56 class DiffViewerContentProvider implements ITreeContentProvider { 57 58 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 59 } 61 62 public boolean isDeleted(Object element) { 63 return false; 64 } 65 66 public void dispose() { 67 inputChanged(DiffTreeViewer.this, getInput(), null); 68 } 69 70 public Object getParent(Object element) { 71 if (element instanceof IDiffElement) 72 return ((IDiffElement)element).getParent(); 73 return null; 74 } 75 76 public final boolean hasChildren(Object element) { 77 if (element instanceof IDiffContainer) 78 return ((IDiffContainer)element).hasChildren(); 79 return false; 80 } 81 82 public final Object [] getChildren(Object element) { 83 if (element instanceof IDiffContainer) 84 return ((IDiffContainer)element).getChildren(); 85 return new Object [0]; 86 } 87 88 public Object [] getElements(Object element) { 89 return getChildren(element); 90 } 91 } 92 93 97 class DiffViewerLabelProvider extends LabelProvider { 98 99 public String getText(Object element) { 100 101 if (element instanceof IDiffElement) 102 return ((IDiffElement)element).getName(); 103 104 return Utilities.getString(fBundle, "defaultLabel"); } 106 107 public Image getImage(Object element) { 108 if (element instanceof IDiffElement) { 109 IDiffElement input= (IDiffElement) element; 110 111 int kind= input.getKind(); 112 if (fLeftIsLocal) { 113 switch (kind & Differencer.DIRECTION_MASK) { 114 case Differencer.LEFT: 115 kind= (kind &~ Differencer.LEFT) | Differencer.RIGHT; 116 break; 117 case Differencer.RIGHT: 118 kind= (kind &~ Differencer.RIGHT) | Differencer.LEFT; 119 break; 120 } 121 } 122 123 return fCompareConfiguration.getImage(input.getImage(), kind); 124 } 125 return null; 126 } 127 } 128 129 static class FilterSame extends ViewerFilter { 130 public boolean select(Viewer viewer, Object parentElement, Object element) { 131 if (element instanceof IDiffElement) 132 return (((IDiffElement)element).getKind() & Differencer.PSEUDO_CONFLICT) == 0; 133 return true; 134 } 135 public boolean isFilterProperty(Object element, Object property) { 136 return false; 137 } 138 } 139 140 private ResourceBundle fBundle; 141 private CompareConfiguration fCompareConfiguration; 142 boolean fLeftIsLocal; 143 private IPropertyChangeListener fPropertyChangeListener; 144 145 private Action fCopyLeftToRightAction; 146 private Action fCopyRightToLeftAction; 147 private Action fEmptyMenuAction; 148 private Action fExpandAllAction; 149 150 156 public DiffTreeViewer(Tree tree, CompareConfiguration configuration) { 157 super(tree); 158 initialize(configuration == null ? new CompareConfiguration() : configuration); 159 } 160 161 167 public DiffTreeViewer(Composite parent, CompareConfiguration configuration) { 168 super(new Tree(parent, SWT.MULTI)); 169 initialize(configuration == null ? new CompareConfiguration() : configuration); 170 } 171 172 private void initialize(CompareConfiguration configuration) { 173 174 Control tree= getControl(); 175 176 INavigatable nav= new INavigatable() { 177 public boolean selectChange(int flag) { 178 if (flag == INavigatable.FIRST_CHANGE) { 179 setSelection(StructuredSelection.EMPTY); 180 flag = INavigatable.NEXT_CHANGE; 181 } else if (flag == INavigatable.LAST_CHANGE) { 182 setSelection(StructuredSelection.EMPTY); 183 flag = INavigatable.PREVIOUS_CHANGE; 184 } 185 return internalNavigate(flag == INavigatable.NEXT_CHANGE, true); 187 } 188 public Object getInput() { 189 return DiffTreeViewer.this.getInput(); 190 } 191 public boolean openSelectedChange() { 192 internalOpen(); 193 return true; 194 } 195 public boolean hasChange(int changeFlag) { 196 return getNextItem(changeFlag == INavigatable.NEXT_CHANGE) != null; 197 } 198 }; 199 tree.setData(INavigatable.NAVIGATOR_PROPERTY, nav); 200 201 fLeftIsLocal= Utilities.getBoolean(configuration, "LEFT_IS_LOCAL", false); 203 tree.setData(CompareUI.COMPARE_VIEWER_TITLE, getTitle()); 204 205 Composite parent= tree.getParent(); 206 207 fBundle= ResourceBundle.getBundle("org.eclipse.compare.structuremergeviewer.DiffTreeViewerResources"); 209 fCompareConfiguration= configuration; 211 if (fCompareConfiguration != null) { 212 fPropertyChangeListener= new IPropertyChangeListener() { 213 public void propertyChange(PropertyChangeEvent event) { 214 DiffTreeViewer.this.propertyChange(event); 215 } 216 }; 217 fCompareConfiguration.addPropertyChangeListener(fPropertyChangeListener); 218 } 219 220 setContentProvider(new DiffViewerContentProvider()); 221 setLabelProvider(new DiffViewerLabelProvider()); 222 223 addSelectionChangedListener( 224 new ISelectionChangedListener() { 225 public void selectionChanged(SelectionChangedEvent se) { 226 updateActions(); 227 } 228 } 229 ); 230 231 setComparator(new DiffViewerComparator()); 232 233 ToolBarManager tbm= CompareViewerPane.getToolBarManager(parent); 234 if (tbm != null) { 235 tbm.removeAll(); 236 237 tbm.add(new Separator("merge")); tbm.add(new Separator("modes")); tbm.add(new Separator("navigation")); 241 createToolItems(tbm); 242 updateActions(); 243 244 tbm.update(true); 245 } 246 247 MenuManager mm= new MenuManager(); 248 mm.setRemoveAllWhenShown(true); 249 mm.addMenuListener( 250 new IMenuListener() { 251 public void menuAboutToShow(IMenuManager mm2) { 252 fillContextMenu(mm2); 253 if (mm2.isEmpty()) { 254 if (fEmptyMenuAction == null) { 255 fEmptyMenuAction= new Action(Utilities.getString(fBundle, "emptyMenuItem")) { }; 258 fEmptyMenuAction.setEnabled(false); 259 } 260 mm2.add(fEmptyMenuAction); 261 } 262 } 263 } 264 ); 265 tree.setMenu(mm.createContextMenu(tree)); 266 } 267 268 273 public String getTitle() { 274 String title= Utilities.getString(fBundle, "title", null); if (title == null) 276 title= Utilities.getString("DiffTreeViewer.title"); return title; 278 } 279 280 285 protected ResourceBundle getBundle() { 286 return fBundle; 287 } 288 289 294 public CompareConfiguration getCompareConfiguration() { 295 return fCompareConfiguration; 296 } 297 298 304 protected void handleDispose(DisposeEvent event) { 305 306 if (fCompareConfiguration != null) { 307 if (fPropertyChangeListener != null) 308 fCompareConfiguration.removePropertyChangeListener(fPropertyChangeListener); 309 fCompareConfiguration= null; 310 } 311 fPropertyChangeListener= null; 312 313 super.handleDispose(event); 314 } 315 316 321 protected void propertyChange(PropertyChangeEvent event) { 322 } 324 325 protected void inputChanged(Object in, Object oldInput) { 326 super.inputChanged(in, oldInput); 327 328 if (in != oldInput) { 329 initialSelection(); 330 updateActions(); 331 } 332 } 333 334 344 protected void initialSelection() { 345 navigate(true); 346 } 347 348 353 protected void internalExpandToLevel(Widget node, int level) { 354 355 Object data= node.getData(); 356 357 if (dontExpand(data)) 358 return; 359 360 super.internalExpandToLevel(node, level); 361 } 362 363 375 protected boolean dontExpand(Object o) { 376 return o instanceof DiffNode && ((DiffNode)o).dontExpand(); 377 } 378 379 381 392 protected void createToolItems(ToolBarManager toolbarManager) { 393 394 402 410 418 } 426 427 435 protected void fillContextMenu(IMenuManager manager) { 436 if (fExpandAllAction == null) { 437 fExpandAllAction= new Action() { 438 public void run() { 439 expandSelection(); 440 } 441 }; 442 Utilities.initAction(fExpandAllAction, fBundle, "action.ExpandAll."); } 444 445 boolean enable= false; 446 ISelection selection= getSelection(); 447 if (selection instanceof IStructuredSelection) { 448 Iterator elements= ((IStructuredSelection)selection).iterator(); 449 while (elements.hasNext()) { 450 Object element= elements.next(); 451 if (element instanceof IDiffContainer) { 452 if (((IDiffContainer)element).hasChildren()) { 453 enable= true; 454 break; 455 } 456 } 457 } 458 } 459 fExpandAllAction.setEnabled(enable); 460 461 manager.add(fExpandAllAction); 462 463 if (fCopyLeftToRightAction != null) 464 manager.add(fCopyLeftToRightAction); 465 if (fCopyRightToLeftAction != null) 466 manager.add(fCopyRightToLeftAction); 467 } 468 469 474 protected void expandSelection() { 475 ISelection selection= getSelection(); 476 if (selection instanceof IStructuredSelection) { 477 Iterator elements= ((IStructuredSelection)selection).iterator(); 478 while (elements.hasNext()) { 479 Object next= elements.next(); 480 expandToLevel(next, ALL_LEVELS); 481 } 482 } 483 } 484 485 493 protected void copySelected(boolean leftToRight) { 494 ISelection selection= getSelection(); 495 if (selection instanceof IStructuredSelection) { 496 Iterator e= ((IStructuredSelection) selection).iterator(); 497 while (e.hasNext()) { 498 Object element= e.next(); 499 if (element instanceof ICompareInput) 500 copyOne((ICompareInput) element, leftToRight); 501 } 502 } 503 } 504 505 513 protected void copyOne(ICompareInput node, boolean leftToRight) { 514 515 node.copy(leftToRight); 516 517 update(new Object [] { node }, null); 519 } 520 521 529 protected void navigate(boolean next) { 530 internalNavigate(next, false); 532 } 533 534 536 546 private boolean internalNavigate(boolean next, boolean fireOpen) { 547 Control c= getControl(); 548 if (!(c instanceof Tree) || c.isDisposed()) 549 return false; 550 TreeItem item = getNextItem(next); 551 if (item != null) { 552 internalSetSelection(item, fireOpen); 553 } 554 return item == null; 555 } 556 557 private TreeItem getNextItem(boolean next) { 558 Control c= getControl(); 559 if (!(c instanceof Tree) || c.isDisposed()) 560 return null; 561 562 Tree tree= (Tree) c; 563 TreeItem item= null; 564 TreeItem children[]= tree.getSelection(); 565 if (children != null && children.length > 0) 566 item= children[0]; 567 if (item == null) { 568 children= tree.getItems(); 569 if (children != null && children.length > 0) { 570 item= children[0]; 571 if (item != null && item.getItemCount() <= 0) { 572 return item; 573 } 574 } 575 } 576 577 while (true) { 578 item= findNextPrev(item, next); 579 if (item == null) 580 break; 581 if (item.getItemCount() <= 0) 582 break; 583 } 584 return item; 585 } 586 587 private TreeItem findNextPrev(TreeItem item, boolean next) { 588 589 if (item == null) 590 return null; 591 592 TreeItem children[]= null; 593 594 if (!next) { 595 596 TreeItem parent= item.getParentItem(); 597 if (parent != null) 598 children= parent.getItems(); 599 else 600 children= item.getParent().getItems(); 601 602 if (children != null && children.length > 0) { 603 int index= 0; 605 for (; index < children.length; index++) 606 if (children[index] == item) 607 break; 608 609 if (index > 0) { 610 611 item= children[index-1]; 612 613 while (true) { 614 createChildren(item); 615 int n= item.getItemCount(); 616 if (n <= 0) 617 break; 618 619 item.setExpanded(true); 620 item= item.getItems()[n-1]; 621 } 622 623 return item; 625 } 626 } 627 628 item= parent; 630 631 } else { 632 item.setExpanded(true); 633 createChildren(item); 634 635 if (item.getItemCount() > 0) { 636 children= item.getItems(); 638 return children[0]; 639 } 640 641 while (item != null) { 642 children= null; 643 TreeItem parent= item.getParentItem(); 644 if (parent != null) 645 children= parent.getItems(); 646 else 647 children= item.getParent().getItems(); 648 649 if (children != null && children.length > 0) { 650 int index= 0; 652 for (; index < children.length; index++) 653 if (children[index] == item) 654 break; 655 656 if (index < children.length-1) { 657 return children[index+1]; 659 } 660 } 661 662 item= parent; 664 } 665 } 666 667 return item; 668 } 669 670 private void internalSetSelection(TreeItem ti, boolean fireOpen) { 671 if (ti != null) { 672 Object data= ti.getData(); 673 if (data != null) { 674 ISelection selection= new StructuredSelection(data); 676 setSelection(selection, true); 677 ISelection currentSelection= getSelection(); 678 if (fireOpen && currentSelection != null && selection.equals(currentSelection)) { 679 fireOpen(new OpenEvent(this, selection)); 680 } 681 } 682 } 683 } 684 685 private final boolean isEditable(Object element, boolean left) { 686 if (element instanceof ICompareInput) { 687 ICompareInput diff= (ICompareInput) element; 688 Object side= left ? diff.getLeft() : diff.getRight(); 689 if (side == null && diff instanceof IDiffElement) { 690 IDiffContainer container= ((IDiffElement)diff).getParent(); 691 if (container instanceof ICompareInput) { 692 ICompareInput parent= (ICompareInput) container; 693 side= left ? parent.getLeft() : parent.getRight(); 694 } 695 } 696 if (side instanceof IEditableContent) 697 return ((IEditableContent) side).isEditable(); 698 } 699 return false; 700 } 701 702 private void updateActions() { 703 int leftToRight= 0; 704 int rightToLeft= 0; 705 ISelection selection= getSelection(); 706 if (selection instanceof IStructuredSelection) { 707 IStructuredSelection ss= (IStructuredSelection) selection; 708 Iterator e= ss.iterator(); 709 while (e.hasNext()) { 710 Object element= e.next(); 711 if (element instanceof ICompareInput) { 712 if (isEditable(element, false)) 713 leftToRight++; 714 if (isEditable(element, true)) 715 rightToLeft++; 716 if (leftToRight > 0 && rightToLeft > 0) 717 break; 718 } 719 } 720 if (fExpandAllAction != null) 721 fExpandAllAction.setEnabled(selection.isEmpty()); 722 } 723 if (fCopyLeftToRightAction != null) 724 fCopyLeftToRightAction.setEnabled(leftToRight > 0); 725 if (fCopyRightToLeftAction != null) 726 fCopyRightToLeftAction.setEnabled(rightToLeft > 0); 727 } 728 729 732 private void internalOpen() { 733 ISelection selection= getSelection(); 734 if (selection != null && !selection.isEmpty()) { 735 fireOpen(new OpenEvent(this, selection)); 736 } 737 } 738 } 739 740 | Popular Tags |