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

Collapse All | Expand All

(-)compare/org/eclipse/compare/internal/CompareMessages.java (-1 / +11 lines)
Lines 118-125 Link Here
118
	public static String CompareWithOther_error_not_comparable;
118
	public static String CompareWithOther_error_not_comparable;
119
	public static String CompareWithOther_error_empty;
119
	public static String CompareWithOther_error_empty;
120
	public static String CompareWithOther_clear;
120
	public static String CompareWithOther_clear;
121
	public static String CompareWithOther_warning_two_way;
122
	public static String CompareWithOther_info;
121
	public static String CompareWithOther_info;
122
	public static String CompareWithOther_externalFileButton;
123
	public static String CompareWithOther_externalFile_errorTitle;
124
	public static String CompareWithOther_externalFile_errorMessage;
125
	public static String CompareWithOther_pathLabel;
126
	public static String CompareWithOther_externalFolderBUtton;
127
	public static String CompareWithOtherResourceDialog_externalFileMainButton;
128
	public static String CompareWithOtherResourceDialog_externalFileRadioButton;
129
	public static String CompareWithOtherResourceDialog_externalFolderMainButton;
130
	public static String CompareWithOtherResourceDialog_externalFolderRadioButton;
131
	public static String CompareWithOtherResourceDialog_workspaceMainButton;
132
	public static String CompareWithOtherResourceDialog_workspaceRadioButton;
123
133
124
	static {
134
	static {
125
		NLS.initializeMessages(BUNDLE_NAME, CompareMessages.class);
135
		NLS.initializeMessages(BUNDLE_NAME, CompareMessages.class);
(-)compare/org/eclipse/compare/internal/CompareWithOtherResourceDialog.java (-114 / +456 lines)
Lines 6-21 Link Here
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *    Aleksandra Wozniak (aleksandra.k.wozniak@gmail.com) - initial API and implementation
9
 *    Aleksandra Wozniak (aleksandra.k.wozniak@gmail.com) - initial implementation
10
 *    IBM Corporation - Bug 73923 (major refactoring and adjustments) 
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.compare.internal;
12
package org.eclipse.compare.internal;
12
13
14
import java.io.FileOutputStream;
15
import java.io.IOException;
16
13
import org.eclipse.compare.CompareConfiguration;
17
import org.eclipse.compare.CompareConfiguration;
18
import org.eclipse.compare.CompareUI;
19
import org.eclipse.core.resources.IFile;
20
import org.eclipse.core.resources.IFolder;
21
import org.eclipse.core.resources.IProject;
22
import org.eclipse.core.resources.IProjectDescription;
14
import org.eclipse.core.resources.IResource;
23
import org.eclipse.core.resources.IResource;
15
import org.eclipse.core.resources.IWorkspaceRoot;
24
import org.eclipse.core.resources.IWorkspaceRoot;
16
import org.eclipse.core.resources.ResourcesPlugin;
25
import org.eclipse.core.resources.ResourcesPlugin;
26
import org.eclipse.core.runtime.CoreException;
27
import org.eclipse.core.runtime.IPath;
28
import org.eclipse.core.runtime.Path;
17
import org.eclipse.jface.dialogs.IDialogConstants;
29
import org.eclipse.jface.dialogs.IDialogConstants;
18
import org.eclipse.jface.dialogs.IMessageProvider;
30
import org.eclipse.jface.dialogs.IMessageProvider;
31
import org.eclipse.jface.dialogs.MessageDialog;
19
import org.eclipse.jface.dialogs.TitleAreaDialog;
32
import org.eclipse.jface.dialogs.TitleAreaDialog;
20
import org.eclipse.jface.viewers.ISelection;
33
import org.eclipse.jface.viewers.ISelection;
21
import org.eclipse.jface.viewers.StructuredSelection;
34
import org.eclipse.jface.viewers.StructuredSelection;
Lines 38-45 Link Here
38
import org.eclipse.swt.widgets.Button;
51
import org.eclipse.swt.widgets.Button;
39
import org.eclipse.swt.widgets.Composite;
52
import org.eclipse.swt.widgets.Composite;
40
import org.eclipse.swt.widgets.Control;
53
import org.eclipse.swt.widgets.Control;
54
import org.eclipse.swt.widgets.DirectoryDialog;
55
import org.eclipse.swt.widgets.Event;
56
import org.eclipse.swt.widgets.FileDialog;
41
import org.eclipse.swt.widgets.Group;
57
import org.eclipse.swt.widgets.Group;
42
import org.eclipse.swt.widgets.Label;
58
import org.eclipse.swt.widgets.Listener;
43
import org.eclipse.swt.widgets.Shell;
59
import org.eclipse.swt.widgets.Shell;
44
import org.eclipse.swt.widgets.Text;
60
import org.eclipse.swt.widgets.Text;
45
import org.eclipse.ui.forms.events.ExpansionAdapter;
61
import org.eclipse.ui.forms.events.ExpansionAdapter;
Lines 49-93 Link Here
49
65
50
/**
66
/**
51
 * This is a dialog that can invoke the compare editor on chosen files.
67
 * This is a dialog that can invoke the compare editor on chosen files.
52
 * 
53
 * @since 3.4
54
 */
68
 */
55
public class CompareWithOtherResourceDialog extends TitleAreaDialog {
69
public class CompareWithOtherResourceDialog extends TitleAreaDialog {
56
70
	
57
	private int CLEAR_RETURN_CODE = 150; // any number != 0
58
	private int MIN_WIDTH = 300;
71
	private int MIN_WIDTH = 300;
59
	private int MIN_HEIGHT = 175;
72
	private int MIN_HEIGHT = 175;
60
73
	
61
	private class FileTextDragListener implements DragSourceListener {
74
	private class FileTextDragListener implements DragSourceListener {
62
75
63
		private InternalSection section;
76
		private ContentTypeElement element;
64
77
65
		public FileTextDragListener(InternalSection section) {
78
		public FileTextDragListener(ContentTypeElement element) {
66
			this.section = section;
79
			this.element = element;
67
		}
80
		}
68
81
69
		public void dragFinished(DragSourceEvent event) {
82
		public void dragFinished(DragSourceEvent event) {
70
			section.fileText.setText(""); //$NON-NLS-1$
83
			element.setText(""); //$NON-NLS-1$
71
		}
84
		}
72
85
73
		public void dragSetData(DragSourceEvent event) {
86
		public void dragSetData(DragSourceEvent event) {
74
			event.data = section.fileText.getText();
87
			event.data = element.getText();
75
		}
88
		}
76
89
77
		public void dragStart(DragSourceEvent event) {
90
		public void dragStart(DragSourceEvent event) {
78
			if (section.fileText.getText() == null)
91
			if (element.getText() == null)
79
				event.doit = false;
92
				event.doit = false;
80
		}
93
		}
81
	}
94
	}
82
95
83
	private class FileTextDropListener implements DropTargetListener {
96
	private class FileTextDropListener implements DropTargetListener {
84
97
85
		private InternalSection section;
98
		private ContentTypeElement element;
86
		private ResourceTransfer resourceTransfer;
99
		private ResourceTransfer resourceTransfer;
87
		private TextTransfer textTransfer;
100
		private TextTransfer textTransfer;
88
101
89
		public FileTextDropListener(InternalSection section) {
102
		public FileTextDropListener(ContentTypeElement element) {
90
			this.section = section;
103
			this.element = element;
91
			resourceTransfer = ResourceTransfer.getInstance();
104
			resourceTransfer = ResourceTransfer.getInstance();
92
			textTransfer = TextTransfer.getInstance();
105
			textTransfer = TextTransfer.getInstance();
93
		}
106
		}
Lines 139-151 Link Here
139
				String txt = (String) event.data;
152
				String txt = (String) event.data;
140
				IResource r = ResourcesPlugin.getWorkspace().getRoot().findMember(txt);
153
				IResource r = ResourcesPlugin.getWorkspace().getRoot().findMember(txt);
141
				if (r != null)
154
				if (r != null)
142
					section.setResource(r);
155
					element.setResource(r);
143
			} else if (resourceTransfer.isSupportedType(event.currentDataType)) {
156
			} else if (resourceTransfer.isSupportedType(event.currentDataType)) {
144
				IResource[] files = (IResource[]) event.data;
157
				IResource[] files = (IResource[]) event.data;
145
				section.setResource(files[0]);
158
				if (files.length > 0)
159
					element.setResource(files[0]);
146
			}
160
			}
147
161
148
			updateErrorInfo();
149
		}
162
		}
150
163
151
		public void dropAccept(DropTargetEvent event) {
164
		public void dropAccept(DropTargetEvent event) {
Lines 153-209 Link Here
153
		}
166
		}
154
167
155
	}
168
	}
156
169
	
157
	private abstract class InternalSection {
170
	private abstract class ContentTypeElement {
158
171
		
159
		protected Group group;
172
		private Button radioButton;
160
		protected Text fileText;
173
		protected Button mainButton;
174
		protected Text text;
175
		private String type;
176
		protected InternalSection section;
161
		private IResource resource;
177
		private IResource resource;
162
178
		
163
		public InternalSection(Composite parent) {
179
		public ContentTypeElement(Composite parent, String type, InternalSection section) {
180
			this.type = type;
181
			this.section = section;
164
			createContents(parent);
182
			createContents(parent);
165
		}
183
		}
166
184
		
167
		private InternalSection() {
185
		private void createContents(Composite parent) {
168
			// not to instantiate
186
			createRadioButton(parent);
187
			createText(parent);
188
			createMainButton(parent);
189
		}
190
		
191
		private void createRadioButton(Composite parent) {
192
			radioButton = new Button(parent, SWT.RADIO);
193
			radioButton.setText(type);
194
		}
195
196
		protected void createText(Composite parent) {
197
			text = new Text(parent, SWT.BORDER);
198
			text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
199
			text.setEditable(false);
200
		}
201
		
202
		protected void createMainButton(Composite parent) {
203
			mainButton = new Button(parent, SWT.PUSH);
204
			mainButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
205
		}
206
		
207
		protected Button getRadioButton() {
208
			return radioButton;
209
		}
210
		
211
		protected String getText() {
212
			return text.getText();
213
		}
214
		
215
		protected void setText(String string) {
216
			text.setText(string);
217
		}
218
		
219
		protected InternalSection getSection() {
220
			return section;
221
		}
222
		
223
		protected void setEnabled(boolean enabled) {
224
			radioButton.setSelection(enabled);
225
			mainButton.setEnabled(enabled);
226
			text.setEnabled(enabled);
169
		}
227
		}
170
228
		
171
		public void createContents(Composite parent) {
229
		protected void setResource(IResource resource) {
172
			createGroup(parent);
230
			this.resource = resource;
173
			createFileLabel();
231
			section.setResource(resource);
174
			createFileCombo();
175
			initDrag();
176
			initDrop();
177
		}
232
		}
178
233
179
		public IResource getResource() {
234
		public IResource getResource() {
180
			return resource;
235
			return resource;
181
		}
236
		}
182
237
		
183
		public void setResource(IResource resource) {
238
		void clearResource() {
184
			this.resource = resource;
239
			resource = null;
185
			String txt = resource.getFullPath().toString();
240
			text.setText(""); //$NON-NLS-1$
186
			fileText.setText(txt);
187
		}
241
		}
242
		
243
	}
244
	
245
	private class WorkspaceContent extends ContentTypeElement {
246
		
247
		public WorkspaceContent(Composite parent, InternalSection section) {
248
			super(parent, CompareMessages.CompareWithOtherResourceDialog_workspaceRadioButton, section);
249
		}
250
		
251
		protected void createMainButton(Composite parent) {
252
			super.createMainButton(parent);
253
			mainButton.setText(CompareMessages.CompareWithOtherResourceDialog_workspaceMainButton);
254
			// temporarily hide this button. For more information about supporting for browsing workspace see bug 243744.
255
			mainButton.setVisible(false);
256
		}
257
		
258
		protected void createText(Composite parent) {
259
			
260
			super.createText(parent);
261
			text.setEditable(true);
262
			
263
			text.addModifyListener(new ModifyListener() {
264
				public void modifyText(ModifyEvent e) {
265
					section.setResource(text.getText());
266
					updateErrorInfo();
267
				}
268
			});
188
269
189
		public void setResource(String s) {
270
			text.addSelectionListener(new SelectionListener() {
190
			IResource tmp = ResourcesPlugin.getWorkspace().getRoot()
271
				public void widgetDefaultSelected(SelectionEvent e) {
191
					.findMember(s);
272
					widgetSelected(e);
192
			if (tmp instanceof IWorkspaceRoot)
273
				}
193
				resource = null;
274
				public void widgetSelected(SelectionEvent e) {
194
			else
275
					section.setResource(text.getText());
195
				resource = tmp;
276
					updateErrorInfo();
196
277
				}
278
			});
279
			
280
			initDrag();
281
			initDrop();
197
		}
282
		}
198
283
199
		protected void clearResource() {
284
		protected void setResource(IResource resource) {
200
			resource = null;
285
			super.setResource(resource);
201
			fileText.setText(""); //$NON-NLS-1$
286
			text.setText(resource.getFullPath().toOSString());
202
			updateErrorInfo();
203
		}
287
		}
204
288
205
		protected void initDrag() {
289
		protected void initDrag() {
206
			DragSource source = new DragSource(fileText, DND.DROP_MOVE
290
			DragSource source = new DragSource(text, DND.DROP_MOVE
207
					| DND.DROP_COPY | DND.DROP_DEFAULT);
291
					| DND.DROP_COPY | DND.DROP_DEFAULT);
208
			Transfer[] types = new Transfer[] { TextTransfer.getInstance(),
292
			Transfer[] types = new Transfer[] { TextTransfer.getInstance(),
209
					ResourceTransfer.getInstance() };
293
					ResourceTransfer.getInstance() };
Lines 212-260 Link Here
212
		}
296
		}
213
297
214
		protected void initDrop() {
298
		protected void initDrop() {
215
			DropTarget target = new DropTarget(fileText, DND.DROP_MOVE
299
			DropTarget target = new DropTarget(text, DND.DROP_MOVE
216
					| DND.DROP_COPY | DND.DROP_DEFAULT);
300
					| DND.DROP_COPY | DND.DROP_DEFAULT);
217
			Transfer[] types = new Transfer[] { TextTransfer.getInstance(),
301
			Transfer[] types = new Transfer[] { TextTransfer.getInstance(),
218
					ResourceTransfer.getInstance() };
302
					ResourceTransfer.getInstance() };
219
			target.setTransfer(types);
303
			target.setTransfer(types);
220
			target.addDropListener(new FileTextDropListener(this));
304
			target.addDropListener(new FileTextDropListener(this));
221
		}
305
		}
222
306
		
223
		protected void createGroup(Composite parent) {
307
	}
224
			group = new Group(parent, SWT.NONE);
308
	
225
			group.setLayout(new GridLayout(3, false));
309
	private class ExternalFileContent extends ContentTypeElement {
226
			group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
310
		
227
		}
311
		public ExternalFileContent(Composite parent, InternalSection section) {
228
312
			super(parent, CompareMessages.CompareWithOtherResourceDialog_externalFileRadioButton, section);
229
		protected void createFileCombo() {
313
		}
230
			fileText = new Text(group, SWT.BORDER);
314
		
231
			fileText
315
		protected void createMainButton(Composite parent) {
232
					.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
316
			super.createMainButton(parent);
233
317
			mainButton.setText(CompareMessages.CompareWithOtherResourceDialog_externalFileMainButton);
234
			fileText.addModifyListener(new ModifyListener() {
318
			mainButton.addSelectionListener(new SelectionListener() {
235
				public void modifyText(ModifyEvent e) {
319
				public void widgetDefaultSelected(SelectionEvent e) {
236
					setResource(fileText.getText());
320
					widgetSelected(e);
237
					updateErrorInfo();
321
				}
322
				public void widgetSelected(SelectionEvent e) {
323
					IResource r = tmpProject.getExternalFile();
324
					if (r == null) 
325
						return;
326
					setResource(r);
238
				}
327
				}
239
			});
328
			});
329
		}
240
330
241
			fileText.addSelectionListener(new SelectionListener() {
331
		protected void setResource(IResource resource) {
242
332
			super.setResource(resource);
333
			text.setText(resource.getLocation().toOSString());
334
		}
335
		
336
	}
337
	
338
	private class ExternalFolderContent extends ContentTypeElement {
339
		
340
		public ExternalFolderContent(Composite parent, InternalSection section) {
341
			super(parent, CompareMessages.CompareWithOtherResourceDialog_externalFolderRadioButton, section);
342
		}
343
		
344
		protected void createMainButton(Composite parent) {
345
			super.createMainButton(parent);
346
			mainButton.setText(CompareMessages.CompareWithOtherResourceDialog_externalFolderMainButton);
347
			mainButton.addSelectionListener(new SelectionListener() {
243
				public void widgetDefaultSelected(SelectionEvent e) {
348
				public void widgetDefaultSelected(SelectionEvent e) {
244
					widgetSelected(e);
349
					widgetSelected(e);
245
				}
350
				}
246
247
				public void widgetSelected(SelectionEvent e) {
351
				public void widgetSelected(SelectionEvent e) {
248
					setResource(fileText.getText());
352
					IResource r = tmpProject.getExternalFolder();
249
					updateErrorInfo();
353
					if (r == null)
354
						return;
355
					setResource(r);
250
				}
356
				}
251
252
			});
357
			});
253
		}
358
		}
254
359
255
		protected void createFileLabel() {
360
		protected void setResource(IResource resource) {
256
			final Label fileLabel = new Label(group, SWT.NONE);
361
			super.setResource(resource);
257
			fileLabel.setText(CompareMessages.CompareWithOther_fileLabel);
362
			text.setText(resource.getLocation().toOSString());
363
		}
364
		
365
	}
366
367
	private abstract class InternalSection {
368
		
369
		// there is no "enum" support in Java 1.4. Sigh...
370
		public static final int WORKSPACE = 0;
371
		public static final int EXTERNAL_FILE = 1;
372
		public static final int EXTERNAL_FOLDER = 2;
373
374
		protected Group group;
375
		private IResource resource;
376
		
377
		ExternalFileContent externalFileContent;
378
		ExternalFolderContent externalFolderContent;
379
		WorkspaceContent workspaceContent;
380
		
381
		public InternalSection(Composite parent) {
382
			createContents(parent);
383
		}
384
385
		private InternalSection() {
386
			// not to instantiate
387
		}
388
389
		protected void createContents(Composite parent) {
390
391
			group = new Group(parent, SWT.NONE);
392
			group.setLayout(new GridLayout(3, false));
393
			group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
394
			
395
			workspaceContent = new WorkspaceContent(group, this);
396
			externalFileContent = new ExternalFileContent(group, this);
397
			externalFolderContent = new ExternalFolderContent(group, this);
398
			
399
			addListenersToRadioButtons();
400
		}
401
		
402
		private void addListenersToRadioButtons() {
403
			final ContentTypeElement[] elements = new ContentTypeElement[] { workspaceContent, 
404
					externalFileContent, externalFolderContent };
405
			for (int i = 0; i < elements.length; i++)
406
				elements[i].getRadioButton().addListener(SWT.Selection, new Listener() {
407
					public void handleEvent(Event event) {
408
						for (int j = 0; j < elements.length; j++)
409
							if (event.widget != elements[j].getRadioButton())
410
								elements[j].setEnabled(false);
411
							else {
412
								elements[j].setEnabled(true);
413
								setResource(elements[j].getResource());
414
							}
415
					}
416
				});
417
		}
418
419
		protected IResource getResource() {
420
			return resource;
421
		}
422
423
		protected void setResource(IResource resource) {
424
			this.resource = resource;
425
			updateErrorInfo();
426
		}
427
428
		protected void setResource(String s) {
429
			IResource tmp = ResourcesPlugin.getWorkspace().getRoot()
430
					.findMember(s);
431
			if (tmp instanceof IWorkspaceRoot) 
432
				resource = null;
433
			else 
434
				resource = tmp;
435
			updateErrorInfo();
436
		}
437
438
		protected void clearResource() {
439
			resource = null;
440
			workspaceContent.clearResource();
441
			externalFileContent.clearResource();
442
			externalFolderContent.clearResource();
443
			updateErrorInfo();
444
		}
445
		
446
		protected void setContentType(int type) {
447
			switch(type) {
448
			case WORKSPACE: 
449
				workspaceContent.setEnabled(true);
450
				externalFileContent.setEnabled(false);
451
				externalFolderContent.setEnabled(false);
452
				break;
453
			case EXTERNAL_FILE:
454
				workspaceContent.setEnabled(false);
455
				externalFileContent.setEnabled(true);
456
				externalFolderContent.setEnabled(false);
457
				break;
458
			case EXTERNAL_FOLDER:
459
				workspaceContent.setEnabled(false);
460
				externalFileContent.setEnabled(false);
461
				externalFolderContent.setEnabled(true);
462
			}
258
		}
463
		}
259
	}
464
	}
260
465
Lines 282-317 Link Here
282
			createContents(parent);
487
			createContents(parent);
283
		}
488
		}
284
489
285
		public void createContents(Composite parent) {
490
		protected void createContents(Composite parent) {
286
			createGroup(parent);
287
			createFileLabel();
288
			createFileCombo();
289
			createClearButton(group);
290
			initDrag();
291
			initDrop();
292
		}
293
294
		public void createGroup(Composite parent) {
295
			final Composite p = parent;
491
			final Composite p = parent;
296
			expandable = new ExpandableComposite(parent, SWT.NONE,
492
			expandable = new ExpandableComposite(parent, SWT.NONE,
297
					ExpandableComposite.TREE_NODE | ExpandableComposite.TWISTIE);
493
					ExpandableComposite.TREE_NODE | ExpandableComposite.TWISTIE);
298
			super.createGroup(expandable);
494
			super.createContents(expandable);
495
			createClearButton(group);
299
			expandable.setClient(group);
496
			expandable.setClient(group);
300
			expandable.addExpansionListener(new ExpansionAdapter() {
497
			expandable.addExpansionListener(new ExpansionAdapter() {
301
				public void expansionStateChanged(ExpansionEvent e) {
498
				public void expansionStateChanged(ExpansionEvent e) {
302
					p.layout();
499
					p.layout();
500
					getShell().pack();
303
				}
501
				}
304
			});
502
			});
305
		}
503
		}
306
504
307
		protected void createClearButton(Composite parent) {
505
		private void createClearButton(Composite parent) {
308
			clearButton = createButton(parent, CLEAR_RETURN_CODE,
506
			clearButton = new Button(parent, SWT.PUSH);
309
					CompareMessages.CompareWithOther_clear, false);
507
			clearButton.setText(CompareMessages.CompareWithOther_clear);
310
			clearButton.addSelectionListener(new SelectionListener() {
508
			clearButton.addSelectionListener(new SelectionListener() {
311
				public void widgetDefaultSelected(SelectionEvent e) {
509
				public void widgetDefaultSelected(SelectionEvent e) {
312
					widgetSelected(e);
510
					widgetSelected(e);
313
				}
511
				}
314
315
				public void widgetSelected(SelectionEvent e) {
512
				public void widgetSelected(SelectionEvent e) {
316
					clearResource();
513
					clearResource();
317
				}
514
				}
Lines 327-337 Link Here
327
			expandable.setLayoutData(layoutData);
524
			expandable.setLayoutData(layoutData);
328
		}
525
		}
329
	}
526
	}
330
527
	
528
	private class ExternalResourcesProject {
529
		
530
		// Implementation based on org.eclipse.jdt.internal.core.ExternalFoldersManager
531
		
532
		private int counter = 0;
533
		
534
		private static final String TMP_PROJECT_NAME = ".org.eclipse.compare.tmp"; //$NON-NLS-1$
535
		
536
		private final static String TMP_PROJECT_FILE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" //$NON-NLS-1$
537
				+ "<projectDescription>\n" //$NON-NLS-1$
538
				+ "\t<name>" + TMP_PROJECT_NAME + "\t</name>\n" //$NON-NLS-1$ //$NON-NLS-2$
539
				+ "\t<comment></comment>\n" //$NON-NLS-1$
540
				+ "\t<projects>\n" //$NON-NLS-1$
541
				+ "\t</projects>\n" //$NON-NLS-1$
542
				+ "\t<buildSpec>\n" //$NON-NLS-1$
543
				+ "\t</buildSpec>\n" //$NON-NLS-1$
544
				+ "\t<natures>\n" + "\t</natures>\n" //$NON-NLS-1$//$NON-NLS-2$
545
				+ "</projectDescription>"; //$NON-NLS-1$
546
		
547
		private final static String TMP_FOLDER_NAME = "tmpFolder"; //$NON-NLS-1$
548
		
549
		private ExternalResourcesProject() {
550
			// nothing to do here
551
		}
552
		
553
		private IProject createTmpProject() throws CoreException {
554
			IProject project = getTmpProject();
555
			if (!project.isAccessible()) {
556
				try {
557
					IPath stateLocation = CompareUI.getPlugin().getStateLocation();
558
					if (!project.exists()) {
559
						IProjectDescription desc = project.getWorkspace()
560
								.newProjectDescription(project.getName());
561
						desc.setLocation(stateLocation.append(TMP_PROJECT_NAME));
562
						project.create(desc, null);
563
					}
564
					try {
565
						project.open(null);
566
					} catch (CoreException e) { // in case .project file or folder has been deleted
567
						IPath projectPath = stateLocation.append(TMP_PROJECT_NAME);
568
						projectPath.toFile().mkdirs();
569
						FileOutputStream output = new FileOutputStream(
570
								projectPath.append(".project").toOSString()); //$NON-NLS-1$
571
						try {
572
							output.write(TMP_PROJECT_FILE.getBytes());
573
						} finally {
574
							output.close();
575
						}
576
						project.open(null);
577
					}
578
					getTmpFolder(project);
579
				} catch (IOException ioe) {
580
					return project;
581
				} catch (CoreException ce) {
582
					throw new CoreException(ce.getStatus());
583
				}
584
			}
585
			project.setHidden(true);
586
			return project;
587
		}
588
		
589
		private IFolder getTmpFolder(IProject project) throws CoreException {
590
			IFolder folder = project.getFolder(TMP_FOLDER_NAME);
591
			if (!folder.exists())
592
				folder.create(IResource.NONE, true, null);
593
			return folder;
594
		}
595
		
596
		private IFile getExternalFile() {
597
			FileDialog dialog = new FileDialog(getShell());
598
			String path = dialog.open();
599
			if (path != null)
600
				return (IFile) linkResource(new Path(path));
601
			return null;
602
		}
603
604
		private IFolder getExternalFolder() {
605
			DirectoryDialog dialog = new DirectoryDialog(getShell());
606
			String path = dialog.open();
607
			if (path != null)
608
				return (IFolder) linkResource(new Path(path));
609
			return null;
610
		}
611
		
612
		private IResource linkResource(IPath path) {
613
			IResource r = null;
614
			String resourceName = path.lastSegment();
615
			try {
616
				IProject project = createTmpProject();
617
				if (!project.isOpen())
618
					project.open(null);
619
				if (path.toFile().isFile()) {
620
					r = getTmpFolder(project).getFile(resourceName);
621
					if (r.exists()) { 	// add a number to file's name when there already is a file with that name in a folder
622
						String extension = path.getFileExtension();
623
						String fileName = path.removeFileExtension().lastSegment(); 
624
						r = getTmpFolder(project).getFile(getName(fileName, extension));
625
					}
626
					((IFile)r).createLink(path, IResource.REPLACE, null);
627
				} else { // isDirectory
628
					r = getTmpFolder(project).getFolder(resourceName);
629
					if (r.exists()) {
630
						r = getTmpFolder(project).getFolder(getName(resourceName, null));
631
					}
632
					((IFolder)r).createLink(path, IResource.REPLACE, null);
633
				}
634
			} catch (CoreException e) {
635
				CompareUIPlugin.log(e);
636
				MessageDialog.openError(getShell(),
637
								CompareMessages.CompareWithOther_externalFile_errorTitle,
638
								CompareMessages.CompareWithOther_externalFile_errorMessage);
639
			}
640
			return r;
641
		}
642
		
643
		/**
644
		 * This method is used to prevent duplicating names of linked resources.
645
		 * It adds a suffix based on the <code>counter</code> value.
646
		 * 
647
		 * @param name
648
		 * @param extension optional
649
		 * @return
650
		 */
651
		private String getName(String name, String extension) {
652
			if (counter != 0) {
653
				name = name + "-" + counter; //$NON-NLS-1$
654
			}
655
			// at most 3 resources at the same time with the same name:
656
			// left, right, ancestor
657
			counter = (counter + 1) % 3;
658
			if (extension != null) {
659
				name += "." + extension; //$NON-NLS-1$
660
			}
661
			// don't change the name if counter equals 0
662
			return name;
663
		}
664
		
665
		private IProject getTmpProject() {
666
			return ResourcesPlugin.getWorkspace().getRoot().getProject(
667
					TMP_PROJECT_NAME);
668
		}
669
	}
670
	
331
	private Button okButton;
671
	private Button okButton;
332
	private InternalGroup rightPanel, leftPanel;
672
	private InternalGroup rightPanel, leftPanel;
333
	private InternalExpandable ancestorPanel;
673
	private InternalExpandable ancestorPanel;
334
	private ISelection fselection;
674
	private ISelection selection;
675
	private ExternalResourcesProject tmpProject = new ExternalResourcesProject();
335
676
336
	/**
677
	/**
337
	 * Creates the dialog.
678
	 * Creates the dialog.
Lines 346-352 Link Here
346
	protected CompareWithOtherResourceDialog(Shell shell, ISelection selection) {
687
	protected CompareWithOtherResourceDialog(Shell shell, ISelection selection) {
347
		super(shell);
688
		super(shell);
348
		setShellStyle(SWT.MODELESS | SWT.RESIZE | SWT.MAX);
689
		setShellStyle(SWT.MODELESS | SWT.RESIZE | SWT.MAX);
349
		fselection = selection;
690
		this.selection = selection;
350
	}
691
	}
351
692
352
	/*
693
	/*
Lines 376-382 Link Here
376
		rightPanel.setText(CompareMessages.CompareWithOther_rightPanel);
717
		rightPanel.setText(CompareMessages.CompareWithOther_rightPanel);
377
		rightPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
718
		rightPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
378
719
379
		setSelection(fselection);
720
		setSelection(selection);
380
		getShell().setText(CompareMessages.CompareWithOther_dialogTitle);
721
		getShell().setText(CompareMessages.CompareWithOther_dialogTitle);
381
		setTitle(CompareMessages.CompareWithOther_dialogMessage);
722
		setTitle(CompareMessages.CompareWithOther_dialogMessage);
382
		getShell().setMinimumSize(convertHorizontalDLUsToPixels(MIN_WIDTH),
723
		getShell().setMinimumSize(convertHorizontalDLUsToPixels(MIN_WIDTH),
Lines 403-432 Link Here
403
		IResource[] selectedResources = Utilities.getResources(selection);
744
		IResource[] selectedResources = Utilities.getResources(selection);
404
		switch (selectedResources.length) {
745
		switch (selectedResources.length) {
405
		case 1:
746
		case 1:
406
			leftPanel.setResource(selectedResources[0]);
747
			leftPanel.workspaceContent.setResource(selectedResources[0]);
407
			break;
748
			break;
408
		case 2:
749
		case 2:
409
			leftPanel.setResource(selectedResources[0]);
750
			leftPanel.workspaceContent.setResource(selectedResources[0]);
410
			rightPanel.setResource(selectedResources[1]);
751
			rightPanel.workspaceContent.setResource(selectedResources[1]);
411
			break;
752
			break;
412
		case 3:
753
		case 3:
413
			ancestorPanel.setResource(selectedResources[0]);
754
			ancestorPanel.workspaceContent.setResource(selectedResources[0]);
414
			ancestorPanel.expandable.setExpanded(true);
755
			ancestorPanel.expandable.setExpanded(true);
415
			leftPanel.setResource(selectedResources[1]);
756
			leftPanel.workspaceContent.setResource(selectedResources[1]);
416
			rightPanel.setResource(selectedResources[2]);
757
			rightPanel.workspaceContent.setResource(selectedResources[2]);
417
			break;
758
			break;
418
		}
759
		}
760
		setInitialContentTypes();
761
	}
762
763
	private void setInitialContentTypes() {
764
		ancestorPanel.setContentType(InternalSection.WORKSPACE);
765
		leftPanel.setContentType(InternalSection.WORKSPACE);
766
		rightPanel.setContentType(InternalSection.WORKSPACE);
419
	}
767
	}
420
768
421
	private boolean isComparePossible() {
769
	private boolean isComparePossible() {
422
		IResource[] resources;
770
		IResource[] resources;
423
		if (ancestorPanel.getResource() == null) {
771
		if (ancestorPanel.getResource() == null)
424
			resources = new IResource[] { leftPanel.getResource(),
772
			resources = new IResource[] { leftPanel.getResource(),
425
					rightPanel.getResource() };
773
					rightPanel.getResource() };
426
		} else {
774
		else
427
			resources = new IResource[] { ancestorPanel.getResource(),
775
			resources = new IResource[] { ancestorPanel.getResource(),
428
					leftPanel.getResource(), rightPanel.getResource() };
776
					leftPanel.getResource(), rightPanel.getResource() };
429
		}
430
777
431
		ResourceCompareInput r = new ResourceCompareInput(
778
		ResourceCompareInput r = new ResourceCompareInput(
432
				new CompareConfiguration());
779
				new CompareConfiguration());
Lines 440-450 Link Here
440
				setMessage(CompareMessages.CompareWithOther_error_empty,
787
				setMessage(CompareMessages.CompareWithOther_error_empty,
441
						IMessageProvider.ERROR);
788
						IMessageProvider.ERROR);
442
				okButton.setEnabled(false);
789
				okButton.setEnabled(false);
443
			} else if (ancestorPanel.getResource() == null
444
					&& ancestorPanel.fileText.getText() != "") { //$NON-NLS-1$
445
				setMessage(CompareMessages.CompareWithOther_warning_two_way,
446
						IMessageProvider.WARNING);
447
				okButton.setEnabled(true);
448
			} else if (!isComparePossible()) {
790
			} else if (!isComparePossible()) {
449
				setMessage(
791
				setMessage(
450
						CompareMessages.CompareWithOther_error_not_comparable,
792
						CompareMessages.CompareWithOther_error_not_comparable,
Lines 456-462 Link Here
456
			}
798
			}
457
		}
799
		}
458
	}
800
	}
459
801
	
460
	/**
802
	/**
461
	 * Returns table with selected resources. If any resource wasn't chosen in
803
	 * Returns table with selected resources. If any resource wasn't chosen in
462
	 * the ancestor panel, table has only two elements -- resources chosen in
804
	 * the ancestor panel, table has only two elements -- resources chosen in
(-)compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java (-6 / +9 lines)
Lines 6-21 Link Here
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *    Aleksandra Wozniak (aleksandra.k.wozniak@gmail.com) - initial API and implementation
9
 *    Aleksandra Wozniak (aleksandra.k.wozniak@gmail.com) - initial implementation
10
 *    IBM Corporation - Bug 73923 (major refactoring and adjustments)
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.compare.internal;
12
package org.eclipse.compare.internal;
12
13
13
import org.eclipse.jface.viewers.ISelection;
14
import org.eclipse.jface.viewers.ISelection;
15
import org.eclipse.jface.viewers.IStructuredSelection;
14
16
15
/**
17
/**
16
 * The "Compare with other resource" action
18
 * The "Compare with other resource" action
17
 * 
18
 * @since 3.4
19
 */
19
 */
20
public class CompareWithOtherResourceAction extends CompareAction {
20
public class CompareWithOtherResourceAction extends CompareAction {
21
21
Lines 27-35 Link Here
27
	}
27
	}
28
28
29
	protected boolean isEnabled(ISelection selection) {
29
	protected boolean isEnabled(ISelection selection) {
30
		// ignore returned value
30
		int selectionSize = 0;
31
		super.isEnabled(selection);
31
		if (selection instanceof IStructuredSelection) {
32
		return true;
32
			selectionSize = ((IStructuredSelection) selection).toArray().length;
33
		}
34
		// enable for a single selection
35
		return super.isEnabled(selection) || selectionSize == 1;
33
	}
36
	}
34
37
35
}
38
}
(-)compare/org/eclipse/compare/internal/CompareMessages.properties (-1 / +11 lines)
Lines 129-134 Link Here
129
CompareWithOther_dialogMessage=Select resources to compare
129
CompareWithOther_dialogMessage=Select resources to compare
130
CompareWithOther_error_not_comparable=Selected resources are not comparable.
130
CompareWithOther_error_not_comparable=Selected resources are not comparable.
131
CompareWithOther_error_empty=Both left and right panel must contain a valid path.
131
CompareWithOther_error_empty=Both left and right panel must contain a valid path.
132
CompareWithOther_warning_two_way=Ancestor is not a valid resource. Two-way compare will be performed.
133
CompareWithOther_clear=Clear
132
CompareWithOther_clear=Clear
134
CompareWithOther_info=Drag files from a view or between dialog's fields.
133
CompareWithOther_info=Drag files from a view or between dialog's fields.
134
CompareWithOther_externalFileButton=External file...
135
CompareWithOther_externalFolderBUtton=External folder...
136
CompareWithOther_externalFile_errorTitle=Compare With Other Resource Error
137
CompareWithOther_externalFile_errorMessage=Cannot create a link to an external resource.
138
CompareWithOther_pathLabel=Path:
139
CompareWithOtherResourceDialog_externalFileMainButton=Browse...
140
CompareWithOtherResourceDialog_externalFileRadioButton=External file
141
CompareWithOtherResourceDialog_externalFolderMainButton=Browse...
142
CompareWithOtherResourceDialog_externalFolderRadioButton=External folder
143
CompareWithOtherResourceDialog_workspaceMainButton=Browse...
144
CompareWithOtherResourceDialog_workspaceRadioButton=Workspace
(-)compare/org/eclipse/compare/internal/ResourceCompareInput.java (-14 / +38 lines)
Lines 13-38 Link Here
13
package org.eclipse.compare.internal;
13
package org.eclipse.compare.internal;
14
14
15
import java.lang.reflect.InvocationTargetException;
15
import java.lang.reflect.InvocationTargetException;
16
import com.ibm.icu.text.MessageFormat;
17
import java.util.HashSet;
16
import java.util.HashSet;
18
import java.util.Set;
17
import java.util.Set;
19
18
20
import org.eclipse.core.resources.*;
19
import org.eclipse.compare.CompareConfiguration;
21
import org.eclipse.core.runtime.*;
20
import org.eclipse.compare.CompareEditorInput;
22
21
import org.eclipse.compare.ITypedElement;
22
import org.eclipse.compare.ZipFileStructureCreator;
23
import org.eclipse.compare.structuremergeviewer.DiffNode;
24
import org.eclipse.compare.structuremergeviewer.DiffTreeViewer;
25
import org.eclipse.compare.structuremergeviewer.Differencer;
26
import org.eclipse.compare.structuremergeviewer.IDiffContainer;
27
import org.eclipse.compare.structuremergeviewer.IDiffElement;
28
import org.eclipse.compare.structuremergeviewer.IStructureComparator;
29
import org.eclipse.core.resources.IContainer;
30
import org.eclipse.core.resources.IFile;
31
import org.eclipse.core.resources.IResource;
32
import org.eclipse.core.runtime.CoreException;
33
import org.eclipse.core.runtime.IPath;
34
import org.eclipse.core.runtime.IProgressMonitor;
35
import org.eclipse.core.runtime.NullProgressMonitor;
36
import org.eclipse.jface.action.Action;
37
import org.eclipse.jface.action.IAction;
38
import org.eclipse.jface.action.IMenuManager;
39
import org.eclipse.jface.dialogs.IDialogConstants;
40
import org.eclipse.jface.dialogs.MessageDialog;
41
import org.eclipse.jface.viewers.ISelection;
42
import org.eclipse.jface.viewers.IStructuredSelection;
43
import org.eclipse.jface.viewers.Viewer;
44
import org.eclipse.jface.window.Window;
23
import org.eclipse.osgi.util.NLS;
45
import org.eclipse.osgi.util.NLS;
24
import org.eclipse.swt.SWT;
46
import org.eclipse.swt.SWT;
25
import org.eclipse.swt.events.*;
47
import org.eclipse.swt.events.SelectionAdapter;
26
import org.eclipse.swt.layout.*;
48
import org.eclipse.swt.events.SelectionEvent;
27
import org.eclipse.swt.widgets.*;
49
import org.eclipse.swt.events.SelectionListener;
28
50
import org.eclipse.swt.layout.GridLayout;
29
import org.eclipse.jface.action.*;
51
import org.eclipse.swt.widgets.Button;
30
import org.eclipse.jface.dialogs.*;
52
import org.eclipse.swt.widgets.Composite;
31
import org.eclipse.jface.viewers.*;
53
import org.eclipse.swt.widgets.Control;
32
import org.eclipse.jface.window.Window;
54
import org.eclipse.swt.widgets.Shell;
33
55
34
import org.eclipse.compare.*;
56
import com.ibm.icu.text.MessageFormat;
35
import org.eclipse.compare.structuremergeviewer.*;
36
57
37
58
38
/**
59
/**
Lines 415-420 Link Here
415
	}
436
	}
416
	
437
	
417
	private String buildLabel(IResource r) {
438
	private String buildLabel(IResource r) {
439
		// for a linked resource in a hidden project use its local file system location
440
		if (r.isLinked() && r.getProject().isHidden())
441
			return r.getLocation().toString();
418
		String n= r.getFullPath().toString();
442
		String n= r.getFullPath().toString();
419
		if (n.charAt(0) == IPath.SEPARATOR)
443
		if (n.charAt(0) == IPath.SEPARATOR)
420
			return n.substring(1);
444
			return n.substring(1);

Return to bug 73923