1 11 package org.eclipse.compare.internal.patch; 12 13 import java.lang.reflect.InvocationTargetException ; 14 15 import org.eclipse.compare.*; 16 import org.eclipse.compare.internal.*; 17 import org.eclipse.compare.patch.PatchConfiguration; 18 import org.eclipse.compare.structuremergeviewer.*; 19 import org.eclipse.core.runtime.Assert; 20 import org.eclipse.core.runtime.IProgressMonitor; 21 import org.eclipse.jface.action.*; 22 import org.eclipse.jface.dialogs.MessageDialog; 23 import org.eclipse.jface.resource.*; 24 import org.eclipse.jface.viewers.*; 25 import org.eclipse.osgi.util.NLS; 26 import org.eclipse.swt.graphics.Image; 27 import org.eclipse.swt.graphics.Point; 28 import org.eclipse.swt.widgets.Composite; 29 30 public abstract class PatchCompareEditorInput extends CompareEditorInput { 31 32 private static final String IMAGE_CACHE_KEY = "IMAGE_CACHE"; 34 public static ImageDescriptor createOverlay(Image baseImage, ImageDescriptor overlayImage, int quadrant) { 35 return new DecoratorOverlayIcon(baseImage, createArrayFrom(overlayImage, quadrant), new Point(Math.max(baseImage.getBounds().width, 16), Math.max(baseImage.getBounds().height, 16))); 36 } 37 38 private static ImageDescriptor[] createArrayFrom( 39 ImageDescriptor overlayImage, int quadrant) { 40 ImageDescriptor[] descs = new ImageDescriptor[] { null, null, null, null, null }; 41 descs[quadrant] = overlayImage; 42 return descs; 43 } 44 45 class PatcherCompareEditorLabelProvider extends LabelProvider { 46 private ILabelProvider wrappedProvider; 47 48 public PatcherCompareEditorLabelProvider(ILabelProvider labelProvider) { 49 wrappedProvider = labelProvider; 50 } 51 52 public String getText(Object element) { 53 String text = wrappedProvider.getText(element); 54 if (element instanceof PatchDiffNode){ 55 PatchDiffNode node = (PatchDiffNode) element; 56 if (!node.isEnabled()) { 57 if (node instanceof PatchProjectDiffNode) { 58 return NLS.bind(PatchMessages.Diff_2Args, new String []{text, PatchMessages.PreviewPatchLabelDecorator_ProjectDoesNotExist}); 59 } 60 return NLS.bind(PatchMessages.Diff_2Args, 61 new String []{text, PatchMessages.PatcherCompareEditorInput_NotIncluded}); 62 } 63 if (node instanceof PatchFileDiffNode) { 64 PatchFileDiffNode fileNode = (PatchFileDiffNode) node; 65 if (getPatcher().hasCachedContents(fileNode.getDiffResult().getDiff())) { 66 text = NLS.bind(PatchMessages.Diff_2Args, new String [] {text, PatchMessages.HunkMergePage_Merged}); 67 } 68 if (!fileNode.fileExists()) { 69 text = NLS.bind(PatchMessages.Diff_2Args, new String [] {text, PatchMessages.PatchCompareEditorInput_0}); 70 } 71 } 72 if (node instanceof HunkDiffNode) { 73 HunkDiffNode hunkNode = (HunkDiffNode) node; 74 if (hunkNode.isManuallyMerged()) { 75 text = NLS.bind(PatchMessages.Diff_2Args, new String [] {text, PatchMessages.HunkMergePage_Merged}); 76 } 77 } 78 if (getPatcher().isRetargeted(node.getPatchElement())) 79 return NLS.bind(PatchMessages.Diff_2Args, 80 new String []{getPatcher().getOriginalPath(node.getPatchElement()).toString(), 81 NLS.bind(PatchMessages.PreviewPatchPage_Target, new String []{node.getName()})}); 82 } 83 return text; 84 } 85 86 public Image getImage(Object element) { 87 Image image = wrappedProvider.getImage(element); 88 if (element instanceof PatchDiffNode){ 89 PatchDiffNode node = (PatchDiffNode) element; 90 if (!node.isEnabled() && image != null) { 91 LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getPatcher().getConfiguration()); 92 return imageCache.createImage(createOverlay(image, CompareUIPlugin.getImageDescriptor(ICompareUIConstants.REMOVED_OVERLAY), IDecoration.TOP_LEFT)); 93 } 94 } 95 if (element instanceof HunkDiffNode) { 96 HunkDiffNode node = (HunkDiffNode) element; 97 if (node.isManuallyMerged()) { 98 LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getPatcher().getConfiguration()); 99 return imageCache.createImage(PatchCompareEditorInput.createOverlay(image, CompareUIPlugin.getImageDescriptor(ICompareUIConstants.IS_MERGED_OVERLAY), IDecoration.TOP_LEFT)); 100 } 101 } 102 return image; 103 } 104 } 105 106 private final DiffNode root; 107 private final WorkspacePatcher patcher; 108 private TreeViewer viewer; 109 private boolean fShowAll; 110 111 117 public PatchCompareEditorInput(WorkspacePatcher patcher, CompareConfiguration configuration) { 118 super(configuration); 119 Assert.isNotNull(patcher); 120 this.patcher = patcher; 121 root = new DiffNode(Differencer.NO_CHANGE) { 122 public boolean hasChildren() { 123 return true; 124 } 125 }; 126 initializeImageCache(); 127 } 128 129 130 private void initializeImageCache() { 131 LocalResourceManager imageCache = new LocalResourceManager(JFaceResources.getResources()); 132 patcher.setProperty(IMAGE_CACHE_KEY, imageCache); 133 } 134 135 protected void handleDispose() { 136 super.handleDispose(); 137 getImageCache(getPatcher().getConfiguration()).dispose(); 138 } 139 140 public static LocalResourceManager getImageCache(PatchConfiguration patchConfiguration) { 141 return (LocalResourceManager)patchConfiguration.getProperty(IMAGE_CACHE_KEY); 142 } 143 144 protected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException , InterruptedException { 145 initLabels(); 146 return root; 147 } 148 149 private void initLabels() { 150 CompareConfiguration cc = getCompareConfiguration(); 151 cc.setLeftEditable(true); 153 cc.setRightEditable(false); 154 cc.setLeftLabel(getCompareConfiguration().getLeftLabel(root)); 156 cc.setLeftImage(getCompareConfiguration().getLeftImage(root)); 157 cc.setRightLabel(getCompareConfiguration().getRightLabel(root)); 158 cc.setRightImage(getCompareConfiguration().getRightImage(root)); 159 } 160 161 164 protected void updateTree() { 165 if (getViewer() != null && !getViewer().getControl().isDisposed()) 166 getViewer().refresh(true); 167 } 168 169 172 protected void buildTree(){ 173 174 if (getRoot().hasChildren()) { 176 resetRoot(); 177 } 178 getViewer().setInput(getRoot()); 180 181 getPatcher().refresh(); 183 184 if (getPatcher().isWorkspacePatch()){ 186 processProjects(getPatcher().getDiffProjects()); 187 } else { 188 processDiffs(getPatcher().getDiffs()); 189 } 190 191 getViewer().refresh(); 193 } 194 195 private void processDiffs(FileDiff[] diffs) { 196 for (int i = 0; i < diffs.length; i++) { 197 processDiff(diffs[i], getRoot()); 198 } 199 } 200 201 private void processProjects(DiffProject[] diffProjects) { 202 for (int i = 0; i < diffProjects.length; i++) { 204 PatchProjectDiffNode projectNode = new PatchProjectDiffNode(getRoot(), diffProjects[i], getPatcher().getConfiguration()); 205 FileDiff[] diffs = diffProjects[i].getFileDiffs(); 206 for (int j = 0; j < diffs.length; j++) { 207 FileDiff fileDiff = diffs[j]; 208 processDiff(fileDiff, projectNode); 209 } 210 } 211 } 212 213 private void processDiff(FileDiff diff, DiffNode parent) { 214 FileDiffResult diffResult = getPatcher().getDiffResult(diff); 215 PatchFileDiffNode node = PatchFileDiffNode.createDiffNode(parent, diffResult); 216 HunkResult[] hunkResults = diffResult.getHunkResults(); 217 for (int i = 0; i < hunkResults.length; i++) { 218 HunkResult hunkResult = hunkResults[i]; 219 if (!hunkResult.isOK()) { 220 HunkDiffNode hunkNode = HunkDiffNode.createDiffNode(node, hunkResult, true); 221 Object left = hunkNode.getLeft(); 222 if (left instanceof UnmatchedHunkTypedElement) { 223 UnmatchedHunkTypedElement element = (UnmatchedHunkTypedElement) left; 224 element.addContentChangeListener(new IContentChangeListener() { 225 public void contentChanged(IContentChangeNotifier source) { 226 if (getViewer() == null || getViewer().getControl().isDisposed()) 227 return; 228 getViewer().refresh(true); 229 } 230 }); 231 } 232 } 233 } 234 } 235 236 239 public Viewer createDiffViewer(Composite parent) { 240 viewer = new DiffTreeViewer(parent, getCompareConfiguration()){ 241 protected void fillContextMenu(IMenuManager manager) { 242 PatchCompareEditorInput.this.fillContextMenu(manager); 243 } 244 }; 245 246 viewer.setLabelProvider(new PatcherCompareEditorLabelProvider((ILabelProvider)viewer.getLabelProvider())); 247 viewer.getTree().setData(CompareUI.COMPARE_VIEWER_TITLE, PatchMessages.PatcherCompareEditorInput_PatchContents); 248 viewer.addOpenListener(new IOpenListener() { 249 public void open(OpenEvent event) { 250 IStructuredSelection sel= (IStructuredSelection) event.getSelection(); 251 Object obj= sel.getFirstElement(); 252 if (obj instanceof HunkDiffNode) { 253 getCompareConfiguration().setLeftLabel(PatchMessages.PreviewPatchPage2_PatchedLocalFile); 254 getCompareConfiguration().setRightLabel(PatchMessages.PreviewPatchPage2_OrphanedHunk); 255 } else { 256 getCompareConfiguration().setLeftLabel(PatchMessages.PatcherCompareEditorInput_LocalCopy); 257 getCompareConfiguration().setRightLabel(PatchMessages.PatcherCompareEditorInput_AfterPatch); 258 } 259 } 260 261 }); 262 viewer.setFilters(getFilters()); 263 viewer.setInput(root); 264 return viewer; 265 } 266 267 private ViewerFilter[] getFilters() { 268 return new ViewerFilter[] { new ViewerFilter() { 269 public boolean select(Viewer v, Object parentElement, Object element) { 270 if (element instanceof PatchDiffNode) { 271 PatchDiffNode node = (PatchDiffNode) element; 272 return node.isEnabled() || isShowAll(); 273 } 274 return false; 275 } 276 } }; 277 } 278 279 protected boolean isShowAll() { 280 return fShowAll; 281 } 282 283 protected void setShowAll(boolean show) { 284 fShowAll = show; 285 } 286 287 public void contributeDiffViewerToolbarItems(Action[] actions, boolean workspacePatch){ 288 ToolBarManager tbm= CompareViewerPane.getToolBarManager(viewer.getControl().getParent()); 289 if (tbm != null) { 290 tbm.removeAll(); 291 292 tbm.add(new Separator("contributed")); 294 for (int i = 0; i < actions.length; i++) { 295 tbm.appendToGroup("contributed", actions[i]); } 297 298 tbm.update(true); 299 } 300 } 301 302 public TreeViewer getViewer() { 303 return viewer; 304 } 305 306 public DiffNode getRoot() { 307 return root; 308 } 309 310 public void resetRoot() { 311 IDiffElement[] children = root.getChildren(); 312 for (int i = 0; i < children.length; i++) { 313 IDiffElement child = children[i]; 314 root.remove(child); 315 } 316 } 317 318 public WorkspacePatcher getPatcher() { 319 return patcher; 320 } 321 322 public boolean confirmRebuild(String message) { 323 if (getPatcher().hasCachedContents()) { 324 if (promptToDiscardCachedChanges(message)) { 325 getPatcher().clearCachedContents(); 326 return true; 327 } 328 return false; 329 } 330 return true; 331 } 332 333 private boolean promptToDiscardCachedChanges(String message) { 334 return MessageDialog.openConfirm(viewer.getControl().getShell(), PatchMessages.PatcherCompareEditorInput_0, message); 335 } 336 337 342 public boolean hasResultToApply() { 343 boolean atLeastOneIsEnabled = false; 344 if (getViewer() != null) { 345 IDiffElement[] elements = getRoot().getChildren(); 346 for (int i = 0; i < elements.length; i++) { 347 IDiffElement element = elements[i]; 348 if (isEnabled(element)) { 349 atLeastOneIsEnabled = true; 350 break; 351 } 352 } 353 } 354 return atLeastOneIsEnabled; 355 } 356 357 private boolean isEnabled(IDiffElement element) { 358 if (element instanceof PatchDiffNode) { 359 PatchDiffNode node = (PatchDiffNode) element; 360 return node.isEnabled(); 361 } 362 return false; 363 } 364 365 protected abstract void fillContextMenu(IMenuManager manager); 366 367 public Viewer findStructureViewer(Viewer oldViewer, ICompareInput input, 368 Composite parent) { 369 if (Utilities.isHunk(input)) 370 return null; 371 return super.findStructureViewer(oldViewer, input, parent); 372 } 373 } 374 | Popular Tags |