View | Details | Raw Unified | Return to bug 193324 | Differences between
and this patch

Collapse All | Expand All

(-)plugin.properties (+2 lines)
Lines 79-81 Link Here
79
CompareLocalHistory.tooltip= Compare the Selected Resource with Local History
79
CompareLocalHistory.tooltip= Compare the Selected Resource with Local History
80
ReplaceLocalHistory.label= &Local History...
80
ReplaceLocalHistory.label= &Local History...
81
ReplaceLocalHistory.tooltip= Replace the Selected Resource with Local History
81
ReplaceLocalHistory.tooltip= Replace the Selected Resource with Local History
82
CompareWithEachOtherAction.label= &Each Other
83
CompareWithEachOtherAction.tooltip= Compare the Selected Resources
(-)plugin.xml (+9 lines)
Lines 154-159 Link Here
154
               enablesFor="1"
154
               enablesFor="1"
155
               overrideActionId="replaceFromHistory"
155
               overrideActionId="replaceFromHistory"
156
               tooltip="%ReplaceLocalHistory.tooltip"/>
156
               tooltip="%ReplaceLocalHistory.tooltip"/>
157
         <action
158
               class="org.eclipse.team.internal.ui.actions.CompareAction"
159
               enablesFor="2+"
160
               id="org.eclipse.team.ui.compareWithEachOther"
161
               label="%CompareWithEachOtherAction.label"
162
               menubarPath="compareWithMenu/compareWithGroup"
163
               overrideActionId="compareWithEachOther"
164
               tooltip="CompareWithEachOtherAction.tooltip">
165
         </action>
157
      </objectContribution>
166
      </objectContribution>
158
   </extension>
167
   </extension>
159
<!-- ************** Views ********************** -->
168
<!-- ************** Views ********************** -->
(-)src/org/eclipse/team/ui/synchronize/SaveableCompareEditorInput.java (-2 / +2 lines)
Lines 195-201 Link Here
195
		setDirty(saveable.isDirty());
195
		setDirty(saveable.isDirty());
196
	}
196
	}
197
197
198
	private ISaveablesLifecycleListener getSaveablesLifecycleListener(
198
	protected ISaveablesLifecycleListener getSaveablesLifecycleListener(
199
			IWorkbenchPart part) {
199
			IWorkbenchPart part) {
200
		ISaveablesLifecycleListener listener = (ISaveablesLifecycleListener)Utils.getAdapter(part, ISaveablesLifecycleListener.class);
200
		ISaveablesLifecycleListener listener = (ISaveablesLifecycleListener)Utils.getAdapter(part, ISaveablesLifecycleListener.class);
201
		if (listener == null)
201
		if (listener == null)
Lines 300-306 Link Here
300
		return page;
300
		return page;
301
	}
301
	}
302
	
302
	
303
	/* package */ void propogateInputChange() {
303
	protected void propogateInputChange() {
304
		if (!inputChangeListeners.isEmpty()) {
304
		if (!inputChangeListeners.isEmpty()) {
305
			Object[] allListeners = inputChangeListeners.getListeners();
305
			Object[] allListeners = inputChangeListeners.getListeners();
306
			for (int i = 0; i < allListeners.length; i++) {
306
			for (int i = 0; i < allListeners.length; i++) {
(-)src/org/eclipse/team/internal/ui/synchronize/TwoSidesSaveableCompareEditorInput.java (+414 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 * IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.team.internal.ui.synchronize;
12
13
import java.lang.reflect.InvocationTargetException;
14
15
import org.eclipse.compare.*;
16
import org.eclipse.compare.structuremergeviewer.*;
17
import org.eclipse.core.resources.IResource;
18
import org.eclipse.core.runtime.Assert;
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.jface.util.IPropertyChangeListener;
21
import org.eclipse.jface.viewers.Viewer;
22
import org.eclipse.osgi.util.NLS;
23
import org.eclipse.swt.events.DisposeEvent;
24
import org.eclipse.swt.events.DisposeListener;
25
import org.eclipse.swt.widgets.Composite;
26
import org.eclipse.swt.widgets.Control;
27
import org.eclipse.team.internal.ui.mapping.AbstractCompareInput;
28
import org.eclipse.team.internal.ui.mapping.CompareInputChangeNotifier;
29
import org.eclipse.team.internal.ui.synchronize.EditableSharedDocumentAdapter.ISharedDocumentAdapterListener;
30
import org.eclipse.team.ui.mapping.SaveableComparison;
31
import org.eclipse.team.ui.synchronize.SaveableCompareEditorInput;
32
import org.eclipse.ui.*;
33
import org.eclipse.ui.services.IDisposable;
34
35
public class TwoSidesSaveableCompareEditorInput extends
36
		SaveableCompareEditorInput {
37
	
38
	private ICompareInputChangeListener compareInputChangeListener;
39
	private IPropertyListener propertyListener;
40
	
41
	private Saveable leftSaveable;
42
	private Saveable rightSaveable;
43
	
44
	private ITypedElement left;
45
	private ITypedElement right;
46
	
47
	private static ITypedElement getLeftFileElement(ICompareInput input,
48
			CompareEditorInput editorInput) {
49
		if (input.getLeft() instanceof LocalResourceTypedElement) {
50
			return (LocalResourceTypedElement) input.getLeft();
51
		}
52
//		if (editorInput instanceof CompareFileRevisionEditorInput) {
53
//			return ((CompareFileRevisionEditorInput) editorInput).getLocalElement();
54
//		}
55
		return null;
56
	}
57
	
58
	private static ITypedElement getRightFileElement(ICompareInput input,
59
			CompareEditorInput editorInput) {
60
		if (input.getRight() instanceof LocalResourceTypedElement) {
61
			return (LocalResourceTypedElement) input.getRight();
62
		}
63
//		if (editorInput instanceof CompareFileRevisionEditorInput) {
64
//			return ((CompareFileRevisionEditorInput) editorInput).getLocalElement();
65
//		}
66
		return null;
67
	}
68
	
69
	private class InternalResourceSaveableComparison extends LocalResourceSaveableComparison implements ISharedDocumentAdapterListener {
70
		private LocalResourceTypedElement lrte;
71
		private boolean connected = false;
72
		public InternalResourceSaveableComparison(
73
				ICompareInput input, CompareEditorInput editorInput, ITypedElement typedElement) {
74
			super(input, editorInput, typedElement);
75
			ITypedElement element = typedElement;
76
			if (element instanceof LocalResourceTypedElement) {
77
				lrte = (LocalResourceTypedElement) element;
78
				if (lrte.isConnected()) {
79
					registerSaveable(true);
80
				} else {
81
					lrte.setSharedDocumentListener(this);
82
				}
83
			}
84
		}
85
		protected void fireInputChange() {
86
			TwoSidesSaveableCompareEditorInput.this.fireInputChange();
87
		}
88
		public void dispose() {
89
			super.dispose();
90
			if (lrte != null)
91
				lrte.setSharedDocumentListener(null);
92
		}
93
		public void handleDocumentConnected() {
94
			if (connected)
95
				return;
96
			connected = true;
97
			registerSaveable(false);
98
			if (lrte != null)
99
				lrte.setSharedDocumentListener(null);
100
		}
101
		
102
		private void registerSaveable(boolean init) {
103
			ICompareContainer container = getContainer();
104
			IWorkbenchPart part = container.getWorkbenchPart();
105
			if (part != null) {
106
				ISaveablesLifecycleListener lifecycleListener= getSaveablesLifecycleListener(part);
107
				// Remove this saveable from the lifecycle listener
108
				if (!init)
109
					lifecycleListener.handleLifecycleEvent(
110
							new SaveablesLifecycleEvent(part, SaveablesLifecycleEvent.POST_CLOSE, new Saveable[] { this }, false));
111
				// Now fix the hashing so it uses the connected document
112
				initializeHashing();
113
				// Finally, add this saveable back to the listener
114
				lifecycleListener.handleLifecycleEvent(
115
						new SaveablesLifecycleEvent(part, SaveablesLifecycleEvent.POST_OPEN, new Saveable[] { this }, false));
116
			}
117
		}
118
		public void handleDocumentDeleted() {
119
			// Ignore
120
		}
121
		public void handleDocumentDisconnected() {
122
			// Ignore
123
		}
124
		public void handleDocumentFlushed() {
125
			// Ignore
126
		}
127
		public void handleDocumentSaved() {
128
			// Ignore
129
		}
130
	}
131
	
132
	public TwoSidesSaveableCompareEditorInput(ITypedElement left,
133
			ITypedElement right, IWorkbenchPage page) {
134
		super(new CompareConfiguration(), page);
135
		this.left = left;
136
		this.right = right;
137
	}
138
	
139
	/* (non-Javadoc)
140
	 * @see org.eclipse.compare.CompareEditorInput#contentsCreated()
141
	 */
142
	protected void contentsCreated() {
143
		super.contentsCreated();
144
		compareInputChangeListener = new ICompareInputChangeListener() {
145
			public void compareInputChanged(ICompareInput source) {
146
				if (source == getCompareResult()) {
147
					boolean closed = false;
148
					if (source.getKind() == Differencer.NO_CHANGE) {
149
						closed = closeEditor(true);
150
					}
151
					if (!closed) {
152
						// The editor was closed either because the compare input still has changes
153
						// or because the editor input is dirty. In either case, fire the changes
154
						// to the registered listeners
155
						propogateInputChange();
156
					}
157
				}
158
			}
159
		};
160
		getCompareInput().addCompareInputChangeListener(compareInputChangeListener);
161
		
162
		if (getLeftSaveable() instanceof SaveableComparison) {
163
			SaveableComparison lscm = (SaveableComparison) leftSaveable;
164
			propertyListener = new IPropertyListener() {
165
				public void propertyChanged(Object source, int propId) {
166
					if (propId == SaveableComparison.PROP_DIRTY) {
167
						setDirty(leftSaveable.isDirty());
168
					}
169
				}
170
			};
171
			lscm.addPropertyListener(propertyListener);
172
		}
173
		
174
		if (getRightSaveable() instanceof SaveableComparison) {
175
			SaveableComparison rscm = (SaveableComparison) rightSaveable;
176
			propertyListener = new IPropertyListener() {
177
				public void propertyChanged(Object source, int propId) {
178
					if (propId == SaveableComparison.PROP_DIRTY) {
179
						setDirty(rightSaveable.isDirty());
180
					}
181
				}
182
			};
183
			rscm.addPropertyListener(propertyListener);
184
		}
185
		
186
		setDirty(leftSaveable.isDirty() || rightSaveable.isDirty());
187
	}
188
	
189
	/* (non-Javadoc)
190
	 * @see org.eclipse.compare.CompareEditorInput#handleDispose()
191
	 */
192
	protected void handleDispose() {
193
		super.handleDispose();
194
		ICompareInput compareInput = getCompareInput();
195
		if (compareInput != null)
196
			compareInput.removeCompareInputChangeListener(compareInputChangeListener);
197
		if (leftSaveable instanceof SaveableComparison) {
198
			SaveableComparison scm = (SaveableComparison) leftSaveable;
199
			scm.removePropertyListener(propertyListener);
200
		}
201
		if (leftSaveable instanceof LocalResourceSaveableComparison) {
202
			LocalResourceSaveableComparison rsc = (LocalResourceSaveableComparison) leftSaveable;
203
			rsc.dispose();
204
		}
205
		if (rightSaveable instanceof SaveableComparison) {
206
			SaveableComparison scm = (SaveableComparison) rightSaveable;
207
			scm.removePropertyListener(propertyListener);
208
		}
209
		if (rightSaveable instanceof LocalResourceSaveableComparison) {
210
			LocalResourceSaveableComparison rsc = (LocalResourceSaveableComparison) rightSaveable;
211
			rsc.dispose();
212
		}
213
214
		if (getCompareResult() instanceof IDisposable) {
215
			((IDisposable) getCompareResult()).dispose();
216
		}
217
	}
218
	
219
	public String getToolTipText() {
220
221
		IResource leftResource = getLeftResource();
222
		IResource rightResource = getRightResource();
223
224
		if (leftResource != null && rightResource != null) {
225
			String leftLabel = leftResource.getFullPath().makeRelative()
226
					.toString();
227
			String rightLabel = rightResource.getFullPath().makeRelative()
228
					.toString();
229
			return NLS
230
					.bind(
231
							"Two-way compare of {0} with {1}", new String[] { leftLabel, rightLabel }); //$NON-NLS-1$
232
		}
233
234
		return NLS
235
				.bind(
236
						"Two-way compare of {0} with {1}", new String[] { left.getName(), right.getName() }); //$NON-NLS-1$
237
	}
238
	
239
	protected void fireInputChange() {
240
			((MyDiffNode)getCompareResult()).fireChange();
241
	}
242
	
243
	protected Saveable getLeftSaveable() {
244
		if (leftSaveable == null) {
245
			leftSaveable = createLeftSaveable();
246
		}
247
		return leftSaveable;
248
	}
249
	
250
	protected Saveable getRightSaveable() {
251
		if (rightSaveable == null) {
252
			rightSaveable = createRightSaveable();
253
		}
254
		return rightSaveable;
255
	}
256
	
257
	protected Saveable createLeftSaveable() {
258
		Object compareResult = getCompareResult();
259
		Assert.isNotNull(compareResult, "This method cannot be called until after prepareInput is called"); //$NON-NLS-1$
260
		ITypedElement leftFileElement = getLeftFileElement((ICompareInput)compareResult, this);
261
		return new InternalResourceSaveableComparison((ICompareInput)compareResult, this, leftFileElement);
262
	}
263
	
264
	protected Saveable createRightSaveable() {
265
		Object compareResult = getCompareResult();
266
		Assert.isNotNull(compareResult, "This method cannot be called until after prepareInput is called"); //$NON-NLS-1$
267
		ITypedElement rightFileElement = getRightFileElement((ICompareInput)compareResult, this);
268
		return new InternalResourceSaveableComparison((ICompareInput)compareResult, this, rightFileElement);
269
	}
270
271
	/* (non-Javadoc)
272
	 * @see org.eclipse.ui.ISaveablesSource#getActiveSaveables()
273
	 */
274
	public Saveable[] getActiveSaveables() {
275
		if (getCompareResult() == null)
276
			return new Saveable[0];
277
		return new Saveable[] { getLeftSaveable(), getRightSaveable() };
278
	}
279
	
280
	/* (non-Javadoc)
281
	 * @see org.eclipse.compare.CompareEditorInput#findContentViewer(org.eclipse.jface.viewers.Viewer, org.eclipse.compare.structuremergeviewer.ICompareInput, org.eclipse.swt.widgets.Composite)
282
	 */
283
	public Viewer findContentViewer(Viewer oldViewer, ICompareInput input, Composite parent) {
284
		Viewer newViewer = super.findContentViewer(oldViewer, input, parent);
285
		boolean isNewViewer= newViewer != oldViewer;
286
		if (isNewViewer && newViewer instanceof IPropertyChangeNotifier
287
				&& leftSaveable instanceof IPropertyChangeListener
288
				&& rightSaveable instanceof IPropertyChangeListener) {
289
			// Register the model for change events if appropriate
290
			final IPropertyChangeNotifier dsp= (IPropertyChangeNotifier) newViewer;
291
			final IPropertyChangeListener lpcl = (IPropertyChangeListener) leftSaveable;
292
			final IPropertyChangeListener rpcl = (IPropertyChangeListener) rightSaveable;
293
			dsp.addPropertyChangeListener(lpcl);
294
			dsp.addPropertyChangeListener(rpcl);
295
			Control c= newViewer.getControl();
296
			c.addDisposeListener(
297
				new DisposeListener() {
298
					public void widgetDisposed(DisposeEvent e) {
299
						dsp.removePropertyChangeListener(lpcl);
300
						dsp.removePropertyChangeListener(rpcl);
301
					}
302
				}
303
			);
304
		}
305
		return newViewer;
306
	}
307
	
308
	
309
	public boolean isDirty() {
310
		if (leftSaveable != null && leftSaveable.isDirty())
311
			return true;
312
		if (rightSaveable != null && rightSaveable.isDirty())
313
			return true;
314
		return super.isDirty();
315
	}
316
	
317
	protected ICompareInput prepareCompareInput(IProgressMonitor monitor)
318
			throws InvocationTargetException, InterruptedException {
319
		ICompareInput input = createCompareInput();
320
		getCompareConfiguration().setLeftEditable(isLeftEditable(input)); 
321
		getCompareConfiguration().setRightEditable(isRightEditable(input));
322
		// both are local
323
//		ensureContentsCached(getLeftRevision(), getRightRevision(), monitor);
324
		initLabels(input);
325
		return input;
326
	}
327
	
328
	private boolean isLeftEditable(ICompareInput input) {
329
		Object left = input.getLeft();
330
		if (left instanceof IEditableContent) {
331
			return ((IEditableContent) left).isEditable();
332
		}
333
		return false;
334
	}
335
	
336
	private boolean isRightEditable(ICompareInput input) {
337
		Object right = input.getRight();
338
		if (right instanceof IEditableContent) {
339
			return ((IEditableContent) right).isEditable();
340
		}
341
		return false;
342
	}
343
	
344
	private void initLabels(ICompareInput input) {
345
		CompareConfiguration cc = getCompareConfiguration();
346
		
347
		IResource leftResource = getLeftResource();
348
		IResource rightResource = getRightResource();
349
		
350
		if (leftResource != null && rightResource != null) {
351
			String leftLabel = leftResource.getFullPath().makeRelative()
352
					.toString();
353
			String rightLabel = rightResource.getFullPath().makeRelative()
354
					.toString();
355
			
356
			cc.setLeftLabel(leftLabel);
357
			cc.setRightLabel(rightLabel);
358
		}
359
		
360
	}
361
	
362
	private ICompareInput createCompareInput() {
363
		return new MyDiffNode(left, right);
364
	}
365
	
366
	CompareInputChangeNotifier notifier = new CompareInputChangeNotifier() {
367
		protected IResource[] getResources(ICompareInput input) {
368
			IResource leftResource = getLeftResource();
369
			IResource rightResource = getRightResource();
370
			if (leftResource == null && rightResource == null)
371
				return new IResource[0];
372
			if (leftResource == null && rightResource != null)
373
				return new IResource[] { rightResource };
374
			if (leftResource != null && rightResource == null)
375
				return new IResource[] { leftResource };
376
			return new IResource[] { leftResource, rightResource };
377
		}
378
	};
379
	
380
	public class MyDiffNode extends AbstractCompareInput {
381
		public MyDiffNode(ITypedElement left, ITypedElement right) {
382
			super(Differencer.CHANGE, null, left, right);
383
		}
384
		public void fireChange() {
385
			super.fireChange();
386
		}
387
		protected CompareInputChangeNotifier getChangeNotifier() {
388
			return notifier;
389
		}
390
		public boolean needsUpdate() {
391
			return true;
392
		}
393
		public void update() {
394
			fireChange();
395
		}
396
	}
397
	
398
	private IResource getLeftResource() {
399
		if (left instanceof LocalResourceTypedElement
400
				&& left instanceof IResourceProvider) {
401
			return ((IResourceProvider) left).getResource();
402
		}
403
		return null;
404
	}
405
406
	private IResource getRightResource() {
407
		if (right instanceof LocalResourceTypedElement
408
				&& right instanceof IResourceProvider) {
409
			return ((IResourceProvider) right).getResource();
410
		}
411
		return null;
412
	}
413
	
414
}
(-)src/org/eclipse/team/internal/ui/actions/CompareAction.java (+84 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 * IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.team.internal.ui.actions;
12
13
import java.lang.reflect.InvocationTargetException;
14
15
import org.eclipse.compare.*;
16
import org.eclipse.core.resources.IFile;
17
import org.eclipse.core.resources.IResource;
18
import org.eclipse.jface.action.IAction;
19
import org.eclipse.jface.viewers.ISelection;
20
import org.eclipse.team.internal.ui.synchronize.TwoSidesSaveableCompareEditorInput;
21
import org.eclipse.team.ui.synchronize.SaveableCompareEditorInput;
22
import org.eclipse.ui.*;
23
24
public class CompareAction extends TeamAction {
25
26
	
27
	protected void execute(IAction action) throws InvocationTargetException,
28
			InterruptedException {
29
		
30
		IResource[] selectedResources = getSelectedResources();
31
		
32
		if (selectedResources.length == 2) {
33
34
			ITypedElement left = null;
35
			if (selectedResources[0] != null) {
36
				left = getElementFor(selectedResources[0]);
37
			}
38
39
			ITypedElement right = null;
40
			if (selectedResources[1] != null) {
41
				right = getElementFor(selectedResources[1]);
42
			}
43
44
			openInCompare(left, right);
45
		}
46
	}
47
	
48
	//XXX: from CompareRevisionAction*
49
	private void openInCompare(ITypedElement left, ITypedElement right) {
50
		IWorkbenchPage workBenchPage = getTargetPage();
51
		CompareEditorInput input = createCompareEditorInput(left, right, workBenchPage);
52
		IEditorPart editor = CompareRevisionAction.findReusableCompareEditor(workBenchPage);
53
		if (editor != null) {
54
			IEditorInput otherInput = editor.getEditorInput();
55
			if (otherInput.equals(input)) {
56
				// simply provide focus to editor
57
				workBenchPage.activate(editor);
58
			} else {
59
				// if editor is currently not open on that input either re-use
60
				// existing
61
				CompareUI.reuseCompareEditor(input, (IReusableEditor) editor);
62
				workBenchPage.activate(editor);
63
			}
64
		} else {
65
			CompareUI.openCompareEditor(input);
66
		}
67
	}
68
	
69
	protected TwoSidesSaveableCompareEditorInput createCompareEditorInput(
70
			ITypedElement left, ITypedElement right, IWorkbenchPage page) {
71
		return new TwoSidesSaveableCompareEditorInput(left,
72
				right, page);
73
	}
74
	
75
	public void selectionChanged(IAction action, ISelection selection) {
76
		super.selectionChanged(action, selection);
77
	}
78
	
79
	//XXX: from CompareRevisionAction
80
	private ITypedElement getElementFor(IResource resource) {
81
		return SaveableCompareEditorInput.createFileElement((IFile)resource);
82
	}
83
84
}

Return to bug 193324