Added
Link Here
|
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2000, 2008 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.compare.internal; |
12 |
|
13 |
import java.io.File; |
14 |
import java.io.IOException; |
15 |
import java.net.MalformedURLException; |
16 |
import java.net.URL; |
17 |
import java.util.ArrayList; |
18 |
import java.util.Iterator; |
19 |
import java.util.List; |
20 |
|
21 |
import org.eclipse.compare.internal.merge.DocumentMerger; |
22 |
import org.eclipse.core.resources.IContainer; |
23 |
import org.eclipse.core.resources.IFile; |
24 |
import org.eclipse.core.resources.IProject; |
25 |
import org.eclipse.core.resources.IResource; |
26 |
import org.eclipse.core.resources.IWorkspace; |
27 |
import org.eclipse.core.resources.IWorkspaceRoot; |
28 |
import org.eclipse.core.resources.ResourcesPlugin; |
29 |
import org.eclipse.core.runtime.IPath; |
30 |
import org.eclipse.core.runtime.IStatus; |
31 |
import org.eclipse.core.runtime.Path; |
32 |
import org.eclipse.jface.dialogs.Dialog; |
33 |
import org.eclipse.jface.dialogs.IDialogConstants; |
34 |
import org.eclipse.jface.dialogs.IDialogSettings; |
35 |
import org.eclipse.jface.dialogs.MessageDialog; |
36 |
import org.eclipse.jface.dialogs.TitleAreaDialog; |
37 |
import org.eclipse.jface.resource.ImageDescriptor; |
38 |
import org.eclipse.jface.text.IDocument; |
39 |
import org.eclipse.jface.viewers.DoubleClickEvent; |
40 |
import org.eclipse.jface.viewers.IDoubleClickListener; |
41 |
import org.eclipse.jface.viewers.ISelection; |
42 |
import org.eclipse.jface.viewers.ISelectionChangedListener; |
43 |
import org.eclipse.jface.viewers.IStructuredSelection; |
44 |
import org.eclipse.jface.viewers.SelectionChangedEvent; |
45 |
import org.eclipse.jface.viewers.StructuredSelection; |
46 |
import org.eclipse.jface.viewers.TreeViewer; |
47 |
import org.eclipse.jface.wizard.Wizard; |
48 |
import org.eclipse.jface.wizard.WizardDialog; |
49 |
import org.eclipse.jface.wizard.WizardPage; |
50 |
import org.eclipse.swt.SWT; |
51 |
import org.eclipse.swt.events.ModifyEvent; |
52 |
import org.eclipse.swt.events.ModifyListener; |
53 |
import org.eclipse.swt.events.SelectionAdapter; |
54 |
import org.eclipse.swt.events.SelectionEvent; |
55 |
import org.eclipse.swt.graphics.Image; |
56 |
import org.eclipse.swt.graphics.Point; |
57 |
import org.eclipse.swt.layout.GridData; |
58 |
import org.eclipse.swt.layout.GridLayout; |
59 |
import org.eclipse.swt.widgets.Button; |
60 |
import org.eclipse.swt.widgets.Composite; |
61 |
import org.eclipse.swt.widgets.Control; |
62 |
import org.eclipse.swt.widgets.Event; |
63 |
import org.eclipse.swt.widgets.FileDialog; |
64 |
import org.eclipse.swt.widgets.Group; |
65 |
import org.eclipse.swt.widgets.Label; |
66 |
import org.eclipse.swt.widgets.Listener; |
67 |
import org.eclipse.swt.widgets.Shell; |
68 |
import org.eclipse.swt.widgets.Text; |
69 |
import org.eclipse.ui.model.BaseWorkbenchContentProvider; |
70 |
import org.eclipse.ui.model.WorkbenchLabelProvider; |
71 |
import org.eclipse.ui.views.navigator.ResourceComparator; |
72 |
|
73 |
/** |
74 |
* A wizard for creating a patch file by running the CVS diff command. |
75 |
*/ |
76 |
public class SaveDiffFileWizard extends Wizard { |
77 |
|
78 |
private final static int INITIAL_WIDTH = 300; |
79 |
private final static int INITIAL_HEIGHT = 350; |
80 |
|
81 |
public static void run(DocumentMerger merger, IDocument leftDoc, |
82 |
IDocument rightDoc, String leftLabel, String rightLabel, |
83 |
String leftPath, String rightPath, Shell shell, boolean rightToLeft) { |
84 |
final String title = CompareMessages.GenerateLocalDiff_title; |
85 |
final SaveDiffFileWizard wizard = new SaveDiffFileWizard(merger, |
86 |
leftDoc, rightDoc, leftLabel, rightLabel, leftPath, rightPath, |
87 |
rightToLeft); |
88 |
wizard.setWindowTitle(title); |
89 |
WizardDialog dialog = new WizardDialog(shell, wizard); |
90 |
dialog.setMinimumPageSize(INITIAL_WIDTH, INITIAL_HEIGHT); |
91 |
dialog.open(); |
92 |
} |
93 |
|
94 |
private class DirectionSelectionPage extends WizardPage { |
95 |
|
96 |
public final static int LEFT_OPTION = 1; |
97 |
public final static int RIGHT_OPTION = 2; |
98 |
|
99 |
private Button fromLeftOption; |
100 |
private Button fromRightOption; |
101 |
private RadioButtonGroup fromRadioGroup = new RadioButtonGroup(); |
102 |
|
103 |
protected DirectionSelectionPage(String pageName, String title, |
104 |
ImageDescriptor titleImage) { |
105 |
super(pageName, title, titleImage); |
106 |
} |
107 |
|
108 |
public void createControl(Composite parent) { |
109 |
Composite composite = new Composite(parent, SWT.NULL); |
110 |
GridLayout layout = new GridLayout(); |
111 |
layout.marginLeft = 5; |
112 |
layout.marginTop = 9; |
113 |
composite.setLayout(layout); |
114 |
composite.setLayoutData(new GridData()); |
115 |
setControl(composite); |
116 |
|
117 |
fromLeftOption = new Button(composite, SWT.RADIO); |
118 |
fromLeftOption.setText(leftLabel); |
119 |
|
120 |
fromRightOption = new Button(composite, SWT.RADIO); |
121 |
fromRightOption.setText(rightLabel); |
122 |
GridData data = new GridData(); |
123 |
data.verticalIndent = 6; |
124 |
fromRightOption.setLayoutData(data); |
125 |
|
126 |
fromRadioGroup.add(LEFT_OPTION, fromLeftOption); |
127 |
fromRadioGroup.add(RIGHT_OPTION, fromRightOption); |
128 |
|
129 |
Dialog.applyDialogFont(parent); |
130 |
|
131 |
// Add listeners |
132 |
fromLeftOption.addSelectionListener(new SelectionAdapter() { |
133 |
public void widgetSelected(SelectionEvent e) { |
134 |
fromRadioGroup.setSelection(LEFT_OPTION, true); |
135 |
targetFileEdited = false; |
136 |
} |
137 |
}); |
138 |
|
139 |
fromRightOption.addSelectionListener(new SelectionAdapter() { |
140 |
public void widgetSelected(SelectionEvent e) { |
141 |
fromRadioGroup.setSelection(RIGHT_OPTION, true); |
142 |
targetFileEdited = false; |
143 |
} |
144 |
}); |
145 |
|
146 |
fromRadioGroup.setSelection(rightToLeft ? RIGHT_OPTION |
147 |
: LEFT_OPTION, true); |
148 |
} |
149 |
|
150 |
public boolean isRightToLeft() { |
151 |
return fromRadioGroup.getSelected() == LEFT_OPTION; |
152 |
} |
153 |
|
154 |
} |
155 |
|
156 |
/** |
157 |
* Page to select a patch file. Overriding validatePage was necessary to |
158 |
* allow entering a file name that already exists. |
159 |
*/ |
160 |
private class LocationPage extends WizardPage { |
161 |
|
162 |
public final static int CLIPBOARD = 1; |
163 |
public final static int FILESYSTEM = 2; |
164 |
public final static int WORKSPACE = 3; |
165 |
|
166 |
private Button cpRadio; |
167 |
|
168 |
private Button fsRadio; |
169 |
protected Text fsPathText; |
170 |
private Button fsBrowseButton; |
171 |
private boolean fsBrowsed = false; |
172 |
|
173 |
private Button wsRadio; |
174 |
protected Text wsPathText; |
175 |
private Button wsBrowseButton; |
176 |
private boolean wsBrowsed = false; |
177 |
|
178 |
protected boolean pageValid; |
179 |
protected IContainer wsSelectedContainer; |
180 |
protected IPath[] foldersToCreate; |
181 |
protected int selectedLocation; |
182 |
|
183 |
/** |
184 |
* The default values store used to initialize the selections. |
185 |
*/ |
186 |
private final DefaultValuesStore store; |
187 |
|
188 |
class LocationPageContentProvider extends BaseWorkbenchContentProvider { |
189 |
boolean showClosedProjects = false; |
190 |
|
191 |
public Object[] getChildren(Object element) { |
192 |
if (element instanceof IWorkspace) { |
193 |
// Check if closed projects should be shown |
194 |
IProject[] allProjects = ((IWorkspace) element).getRoot() |
195 |
.getProjects(); |
196 |
if (showClosedProjects) |
197 |
return allProjects; |
198 |
|
199 |
ArrayList accessibleProjects = new ArrayList(); |
200 |
for (int i = 0; i < allProjects.length; i++) { |
201 |
if (allProjects[i].isOpen()) { |
202 |
accessibleProjects.add(allProjects[i]); |
203 |
} |
204 |
} |
205 |
return accessibleProjects.toArray(); |
206 |
} |
207 |
return super.getChildren(element); |
208 |
} |
209 |
} |
210 |
|
211 |
class WorkspaceDialog extends TitleAreaDialog { |
212 |
|
213 |
protected TreeViewer wsTreeViewer; |
214 |
protected Text wsFilenameText; |
215 |
protected Image dlgTitleImage; |
216 |
|
217 |
private boolean modified = false; |
218 |
|
219 |
public WorkspaceDialog(Shell shell) { |
220 |
super(shell); |
221 |
} |
222 |
|
223 |
protected Control createContents(Composite parent) { |
224 |
Control control = super.createContents(parent); |
225 |
setTitle(CompareMessages.WorkspacePatchDialogTitle); |
226 |
setMessage(CompareMessages.WorkspacePatchDialogDescription); |
227 |
dlgTitleImage = CompareUIPlugin.getImageDescriptor( |
228 |
ICompareUIConstants.IMG_WIZBAN_DIFF).createImage(); |
229 |
setTitleImage(dlgTitleImage); |
230 |
return control; |
231 |
} |
232 |
|
233 |
protected Control createDialogArea(Composite parent) { |
234 |
Composite parentComposite = (Composite) super |
235 |
.createDialogArea(parent); |
236 |
|
237 |
// Create a composite with standard margins and spacing |
238 |
Composite composite = new Composite(parentComposite, SWT.NONE); |
239 |
GridLayout layout = new GridLayout(); |
240 |
layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); |
241 |
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); |
242 |
layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); |
243 |
layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
244 |
composite.setLayout(layout); |
245 |
composite.setLayoutData(new GridData(GridData.FILL_BOTH)); |
246 |
composite.setFont(parentComposite.getFont()); |
247 |
|
248 |
getShell().setText(CompareMessages.GenerateDiffFileWizard_9); |
249 |
|
250 |
wsTreeViewer = new TreeViewer(composite, SWT.BORDER); |
251 |
final GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); |
252 |
gd.widthHint = 550; |
253 |
gd.heightHint = 250; |
254 |
wsTreeViewer.getTree().setLayoutData(gd); |
255 |
|
256 |
wsTreeViewer |
257 |
.setContentProvider(new LocationPageContentProvider()); |
258 |
wsTreeViewer.setComparator(new ResourceComparator( |
259 |
ResourceComparator.NAME)); |
260 |
wsTreeViewer.setLabelProvider(new WorkbenchLabelProvider()); |
261 |
wsTreeViewer.setInput(ResourcesPlugin.getWorkspace()); |
262 |
|
263 |
// Open to whatever is selected in the workspace field |
264 |
IPath existingWorkspacePath = new Path(wsPathText.getText()); |
265 |
if (existingWorkspacePath != null) { |
266 |
// Ensure that this workspace path is valid |
267 |
IResource selectedResource = ResourcesPlugin.getWorkspace() |
268 |
.getRoot().findMember(existingWorkspacePath); |
269 |
if (selectedResource != null) { |
270 |
wsTreeViewer.expandToLevel(selectedResource, 0); |
271 |
wsTreeViewer.setSelection(new StructuredSelection( |
272 |
selectedResource)); |
273 |
} |
274 |
} |
275 |
|
276 |
final Composite group = new Composite(composite, SWT.NONE); |
277 |
layout = new GridLayout(2, false); |
278 |
layout.marginWidth = 0; |
279 |
group.setLayout(layout); |
280 |
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, |
281 |
false)); |
282 |
|
283 |
final Label label = new Label(group, SWT.NONE); |
284 |
label.setLayoutData(new GridData()); |
285 |
label.setText(CompareMessages.Fi_le_name__9); |
286 |
|
287 |
wsFilenameText = new Text(group, SWT.BORDER); |
288 |
wsFilenameText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, |
289 |
true, false)); |
290 |
|
291 |
setupListeners(); |
292 |
|
293 |
return parent; |
294 |
} |
295 |
|
296 |
protected Button createButton(Composite parent, int id, |
297 |
String label, boolean defaultButton) { |
298 |
Button button = super.createButton(parent, id, label, |
299 |
defaultButton); |
300 |
if (id == IDialogConstants.OK_ID) { |
301 |
button.setEnabled(false); |
302 |
} |
303 |
return button; |
304 |
} |
305 |
|
306 |
private void validateDialog() { |
307 |
String fileName = wsFilenameText.getText(); |
308 |
|
309 |
if (fileName.equals("")) { //$NON-NLS-1$ |
310 |
if (modified) { |
311 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_2); |
312 |
getButton(IDialogConstants.OK_ID).setEnabled(false); |
313 |
return; |
314 |
} |
315 |
setErrorMessage(null); |
316 |
getButton(IDialogConstants.OK_ID).setEnabled(false); |
317 |
return; |
318 |
} |
319 |
|
320 |
// Make sure that the filename is valid |
321 |
if (!(ResourcesPlugin.getWorkspace().validateName(fileName, |
322 |
IResource.FILE)).isOK() |
323 |
&& modified) { |
324 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_5); |
325 |
getButton(IDialogConstants.OK_ID).setEnabled(false); |
326 |
return; |
327 |
} |
328 |
|
329 |
// Make sure that a container has been selected |
330 |
if (getSelectedContainer() == null) { |
331 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_0); |
332 |
getButton(IDialogConstants.OK_ID).setEnabled(false); |
333 |
return; |
334 |
} |
335 |
IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
336 |
IPath fullPath = wsSelectedContainer.getFullPath().append( |
337 |
fileName); |
338 |
if (workspace.getRoot().getFolder(fullPath).exists()) { |
339 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_FolderExists); |
340 |
getButton(IDialogConstants.OK_ID).setEnabled(false); |
341 |
return; |
342 |
|
343 |
} |
344 |
|
345 |
setErrorMessage(null); |
346 |
getButton(IDialogConstants.OK_ID).setEnabled(true); |
347 |
} |
348 |
|
349 |
protected void okPressed() { |
350 |
IFile file = wsSelectedContainer.getFile(new Path( |
351 |
wsFilenameText.getText())); |
352 |
if (file != null) |
353 |
wsPathText.setText(file.getFullPath().toString()); |
354 |
|
355 |
validatePage(); |
356 |
super.okPressed(); |
357 |
} |
358 |
|
359 |
private IContainer getSelectedContainer() { |
360 |
Object obj = ((IStructuredSelection) wsTreeViewer |
361 |
.getSelection()).getFirstElement(); |
362 |
if (obj instanceof IContainer) { |
363 |
wsSelectedContainer = (IContainer) obj; |
364 |
} else if (obj instanceof IFile) { |
365 |
wsSelectedContainer = ((IFile) obj).getParent(); |
366 |
} |
367 |
return wsSelectedContainer; |
368 |
} |
369 |
|
370 |
protected void cancelPressed() { |
371 |
validatePage(); |
372 |
super.cancelPressed(); |
373 |
} |
374 |
|
375 |
public boolean close() { |
376 |
if (dlgTitleImage != null) |
377 |
dlgTitleImage.dispose(); |
378 |
return super.close(); |
379 |
} |
380 |
|
381 |
void setupListeners() { |
382 |
wsTreeViewer |
383 |
.addSelectionChangedListener(new ISelectionChangedListener() { |
384 |
public void selectionChanged( |
385 |
SelectionChangedEvent event) { |
386 |
IStructuredSelection s = (IStructuredSelection) event |
387 |
.getSelection(); |
388 |
Object obj = s.getFirstElement(); |
389 |
if (obj instanceof IContainer) |
390 |
wsSelectedContainer = (IContainer) obj; |
391 |
else if (obj instanceof IFile) { |
392 |
IFile tempFile = (IFile) obj; |
393 |
wsSelectedContainer = tempFile.getParent(); |
394 |
wsFilenameText.setText(tempFile.getName()); |
395 |
} |
396 |
validateDialog(); |
397 |
} |
398 |
}); |
399 |
|
400 |
wsTreeViewer.addDoubleClickListener(new IDoubleClickListener() { |
401 |
public void doubleClick(DoubleClickEvent event) { |
402 |
ISelection s = event.getSelection(); |
403 |
if (s instanceof IStructuredSelection) { |
404 |
Object item = ((IStructuredSelection) s) |
405 |
.getFirstElement(); |
406 |
if (wsTreeViewer.getExpandedState(item)) |
407 |
wsTreeViewer.collapseToLevel(item, 1); |
408 |
else |
409 |
wsTreeViewer.expandToLevel(item, 1); |
410 |
} |
411 |
validateDialog(); |
412 |
} |
413 |
}); |
414 |
|
415 |
wsFilenameText.addModifyListener(new ModifyListener() { |
416 |
public void modifyText(ModifyEvent e) { |
417 |
modified = true; |
418 |
validateDialog(); |
419 |
} |
420 |
}); |
421 |
} |
422 |
} |
423 |
|
424 |
LocationPage(String pageName, String title, ImageDescriptor image, |
425 |
DefaultValuesStore store) { |
426 |
super(pageName, title, image); |
427 |
setPageComplete(false); |
428 |
this.store = store; |
429 |
} |
430 |
|
431 |
protected boolean validatePage() { |
432 |
switch (selectedLocation) { |
433 |
case WORKSPACE: |
434 |
pageValid = validateWorkspaceLocation(); |
435 |
break; |
436 |
case FILESYSTEM: |
437 |
pageValid = validateFilesystemLocation(); |
438 |
break; |
439 |
case CLIPBOARD: |
440 |
pageValid = true; |
441 |
break; |
442 |
} |
443 |
|
444 |
// Avoid draw flicker by clearing error message if all is valid. |
445 |
if (pageValid) { |
446 |
setMessage(null); |
447 |
setErrorMessage(null); |
448 |
} |
449 |
setPageComplete(pageValid); |
450 |
return pageValid; |
451 |
} |
452 |
|
453 |
private boolean validateFilesystemLocation() { |
454 |
// Conditions for the file system location to be valid: |
455 |
// - the path must be valid and non-empty |
456 |
// - the path must be absolute |
457 |
// - the specified file must be of type file |
458 |
// - the parent must exist (new folders can be created via browse) |
459 |
final String pathString = fsPathText.getText().trim(); |
460 |
if (pathString.length() == 0 |
461 |
|| !new Path("").isValidPath(pathString)) { //$NON-NLS-1$ |
462 |
if (fsBrowsed) |
463 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_0); |
464 |
else |
465 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_browseFilesystem); |
466 |
return false; |
467 |
} |
468 |
|
469 |
final File file = new File(pathString); |
470 |
if (!file.isAbsolute()) { |
471 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_0); |
472 |
return false; |
473 |
} |
474 |
|
475 |
if (file.isDirectory()) { |
476 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_2); |
477 |
return false; |
478 |
} |
479 |
|
480 |
if (pathString.endsWith("/") || pathString.endsWith("\\")) { //$NON-NLS-1$//$NON-NLS-2$ |
481 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_3); |
482 |
return false; |
483 |
} |
484 |
|
485 |
final File parent = file.getParentFile(); |
486 |
if (!(parent.exists() && parent.isDirectory())) { |
487 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_3); |
488 |
return false; |
489 |
} |
490 |
return true; |
491 |
} |
492 |
|
493 |
private boolean validateWorkspaceLocation() { |
494 |
// Conditions for the file system location to be valid: |
495 |
// - a parent must be selected in the workspace tree view |
496 |
// - the resource name must be valid |
497 |
if (wsPathText.getText().equals("")) { //$NON-NLS-1$ |
498 |
// Make sure that the field actually has a filename in it |
499 |
// amd make sure that the user has had a chance to browse |
500 |
if (selectedLocation == WORKSPACE && wsBrowsed) |
501 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_5); |
502 |
else |
503 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_4); |
504 |
return false; |
505 |
} |
506 |
|
507 |
// Make sure that all the segments but the last one (i.e. project + |
508 |
// all folders) exist - file doesn't have to exist. It may have |
509 |
// happened that some folder refactoring has been done since this |
510 |
// path was last saved. |
511 |
// |
512 |
// The path will always be in format project/{folders}*/file - this |
513 |
// is controlled by the workspace location dialog and by |
514 |
// validatePath method when path has been entered manually. |
515 |
IPath pathToWorkspaceFile = new Path(wsPathText.getText()); |
516 |
IStatus status = ResourcesPlugin.getWorkspace().validatePath( |
517 |
wsPathText.getText(), IResource.FILE); |
518 |
if (status.isOK()) { |
519 |
// Trim file name from path |
520 |
IPath containerPath = pathToWorkspaceFile.removeLastSegments(1); |
521 |
IResource container = ResourcesPlugin.getWorkspace().getRoot() |
522 |
.findMember(containerPath); |
523 |
if (container == null) { |
524 |
if (selectedLocation == WORKSPACE) |
525 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_4); |
526 |
return false; |
527 |
} else if (!container.isAccessible()) { |
528 |
if (selectedLocation == WORKSPACE) |
529 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_ProjectClosed); |
530 |
return false; |
531 |
} else { |
532 |
if (ResourcesPlugin.getWorkspace().getRoot().getFolder( |
533 |
pathToWorkspaceFile).exists()) { |
534 |
setErrorMessage(CompareMessages.GenerateDiffFileWizard_FolderExists); |
535 |
return false; |
536 |
} |
537 |
} |
538 |
} else { |
539 |
setErrorMessage(status.getMessage()); |
540 |
return false; |
541 |
} |
542 |
|
543 |
return true; |
544 |
} |
545 |
|
546 |
/** |
547 |
* Answers a full path to a file system file or <code>null</code> if the |
548 |
* user selected to save the patch in the clipboard. |
549 |
*/ |
550 |
public File getFile() { |
551 |
if (pageValid && selectedLocation == FILESYSTEM) { |
552 |
return new File(fsPathText.getText().trim()); |
553 |
} |
554 |
if (pageValid && selectedLocation == WORKSPACE) { |
555 |
final String filename = wsPathText.getText().trim(); |
556 |
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); |
557 |
final IFile file = root.getFile(new Path(filename)); |
558 |
return file.getLocation().toFile(); |
559 |
} |
560 |
return null; |
561 |
} |
562 |
|
563 |
/** |
564 |
* Answers the workspace string entered in the dialog or |
565 |
* <code>null</code> if the user selected to save the patch in the |
566 |
* clipboard or file system. |
567 |
* |
568 |
* @return workspace location or null |
569 |
*/ |
570 |
public String getWorkspaceLocation() { |
571 |
if (pageValid && selectedLocation == WORKSPACE) { |
572 |
final String filename = wsPathText.getText().trim(); |
573 |
return filename; |
574 |
} |
575 |
return null; |
576 |
} |
577 |
|
578 |
/** |
579 |
* Get the selected workspace resource if the patch is to be saved in |
580 |
* the workspace, or null otherwise. |
581 |
* |
582 |
* @return selected resource or null |
583 |
*/ |
584 |
public IResource getResource() { |
585 |
if (pageValid && selectedLocation == WORKSPACE) { |
586 |
IPath pathToWorkspaceFile = new Path(wsPathText.getText() |
587 |
.trim()); |
588 |
// Trim file name from path |
589 |
IPath containerPath = pathToWorkspaceFile.removeLastSegments(1); |
590 |
return ResourcesPlugin.getWorkspace().getRoot().findMember( |
591 |
containerPath); |
592 |
} |
593 |
return null; |
594 |
} |
595 |
|
596 |
public void createControl(Composite parent) { |
597 |
final Composite composite = new Composite(parent, SWT.NULL); |
598 |
composite.setLayout(new GridLayout()); |
599 |
setControl(composite); |
600 |
initializeDialogUnits(composite); |
601 |
|
602 |
setupLocationControls(composite); |
603 |
|
604 |
initializeDefaultValues(); |
605 |
|
606 |
Dialog.applyDialogFont(parent); |
607 |
|
608 |
validatePage(); |
609 |
|
610 |
updateEnablements(); |
611 |
setupListeners(); |
612 |
} |
613 |
|
614 |
private void setupLocationControls(final Composite parent) { |
615 |
final Composite composite = new Composite(parent, SWT.NULL); |
616 |
GridLayout gridLayout = new GridLayout(); |
617 |
gridLayout.numColumns = 3; |
618 |
composite.setLayout(gridLayout); |
619 |
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
620 |
|
621 |
// Clipboard |
622 |
GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); |
623 |
gd.horizontalSpan = 3; |
624 |
cpRadio = new Button(composite, SWT.RADIO); |
625 |
cpRadio.setText(CompareMessages.Save_To_Clipboard_2); |
626 |
cpRadio.setLayoutData(gd); |
627 |
|
628 |
// Filesystem |
629 |
fsRadio = new Button(composite, SWT.RADIO); |
630 |
fsRadio.setText(CompareMessages.Save_In_File_System_3); |
631 |
|
632 |
fsPathText = new Text(composite, SWT.BORDER); |
633 |
gd = new GridData(GridData.FILL_HORIZONTAL); |
634 |
fsPathText.setLayoutData(gd); |
635 |
|
636 |
fsBrowseButton = new Button(composite, SWT.PUSH); |
637 |
fsBrowseButton.setText(CompareMessages.Browse____4); |
638 |
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); |
639 |
int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); |
640 |
Point minSize = fsBrowseButton.computeSize(SWT.DEFAULT, |
641 |
SWT.DEFAULT, true); |
642 |
data.widthHint = Math.max(widthHint, minSize.x); |
643 |
fsBrowseButton.setLayoutData(data); |
644 |
|
645 |
// Workspace |
646 |
wsRadio = new Button(composite, SWT.RADIO); |
647 |
wsRadio.setText(CompareMessages.Save_In_Workspace_7); |
648 |
|
649 |
wsPathText = new Text(composite, SWT.BORDER); |
650 |
gd = new GridData(GridData.FILL_HORIZONTAL); |
651 |
wsPathText.setLayoutData(gd); |
652 |
|
653 |
wsBrowseButton = new Button(composite, SWT.PUSH); |
654 |
wsBrowseButton.setText(CompareMessages.Browse____4); |
655 |
data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); |
656 |
widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); |
657 |
minSize = fsBrowseButton |
658 |
.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); |
659 |
data.widthHint = Math.max(widthHint, minSize.x); |
660 |
wsBrowseButton.setLayoutData(data); |
661 |
|
662 |
((GridData) cpRadio.getLayoutData()).heightHint = minSize.y; |
663 |
} |
664 |
|
665 |
private void initializeDefaultValues() { |
666 |
selectedLocation = store.getLocationSelection(); |
667 |
|
668 |
updateRadioButtons(); |
669 |
|
670 |
// We need to ensure that we have a valid workspace path - user |
671 |
// could have altered workspace since last time this was saved |
672 |
wsPathText.setText(store.getWorkspacePath()); |
673 |
if (!validateWorkspaceLocation()) { |
674 |
wsPathText.setText(""); //$NON-NLS-1$ |
675 |
// Don't open wizard with an error - change to clipboard |
676 |
if (selectedLocation == WORKSPACE) { |
677 |
// Clear the error message caused by the workspace not |
678 |
// having any workspace path entered |
679 |
setErrorMessage(null); |
680 |
selectedLocation = CLIPBOARD; |
681 |
updateRadioButtons(); |
682 |
} |
683 |
} |
684 |
// Do the same thing for the filesystem field |
685 |
fsPathText.setText(store.getFilesystemPath()); |
686 |
if (!validateFilesystemLocation()) { |
687 |
fsPathText.setText(""); //$NON-NLS-1$ |
688 |
if (selectedLocation == FILESYSTEM) { |
689 |
setErrorMessage(null); |
690 |
selectedLocation = CLIPBOARD; |
691 |
updateRadioButtons(); |
692 |
} |
693 |
} |
694 |
|
695 |
} |
696 |
|
697 |
private void updateRadioButtons() { |
698 |
cpRadio.setSelection(selectedLocation == CLIPBOARD); |
699 |
fsRadio.setSelection(selectedLocation == FILESYSTEM); |
700 |
wsRadio.setSelection(selectedLocation == WORKSPACE); |
701 |
} |
702 |
|
703 |
private void setupListeners() { |
704 |
cpRadio.addListener(SWT.Selection, new Listener() { |
705 |
public void handleEvent(Event event) { |
706 |
selectedLocation = CLIPBOARD; |
707 |
validatePage(); |
708 |
updateEnablements(); |
709 |
} |
710 |
}); |
711 |
fsRadio.addListener(SWT.Selection, new Listener() { |
712 |
public void handleEvent(Event event) { |
713 |
selectedLocation = FILESYSTEM; |
714 |
validatePage(); |
715 |
updateEnablements(); |
716 |
} |
717 |
}); |
718 |
|
719 |
wsRadio.addListener(SWT.Selection, new Listener() { |
720 |
public void handleEvent(Event event) { |
721 |
selectedLocation = WORKSPACE; |
722 |
validatePage(); |
723 |
updateEnablements(); |
724 |
} |
725 |
}); |
726 |
|
727 |
ModifyListener pathTextModifyListener = new ModifyListener() { |
728 |
public void modifyText(ModifyEvent e) { |
729 |
validatePage(); |
730 |
} |
731 |
}; |
732 |
fsPathText.addModifyListener(pathTextModifyListener); |
733 |
wsPathText.addModifyListener(pathTextModifyListener); |
734 |
|
735 |
fsBrowseButton.addListener(SWT.Selection, new Listener() { |
736 |
public void handleEvent(Event event) { |
737 |
final FileDialog dialog = new FileDialog(getShell(), |
738 |
SWT.PRIMARY_MODAL | SWT.SAVE); |
739 |
if (pageValid) { |
740 |
final File file = new File(fsPathText.getText()); |
741 |
dialog.setFilterPath(file.getParent()); |
742 |
} |
743 |
dialog.setText(CompareMessages.Save_Patch_As_5); |
744 |
dialog.setFileName(CompareMessages.patch_txt_6); |
745 |
final String path = dialog.open(); |
746 |
fsBrowsed = true; |
747 |
if (path != null) { |
748 |
fsPathText.setText(new Path(path).toOSString()); |
749 |
} |
750 |
validatePage(); |
751 |
} |
752 |
}); |
753 |
|
754 |
wsBrowseButton.addListener(SWT.Selection, new Listener() { |
755 |
public void handleEvent(Event event) { |
756 |
final WorkspaceDialog dialog = new WorkspaceDialog( |
757 |
getShell()); |
758 |
wsBrowsed = true; |
759 |
dialog.open(); |
760 |
validatePage(); |
761 |
} |
762 |
}); |
763 |
|
764 |
} |
765 |
|
766 |
public void updateEnablements() { |
767 |
// Enable and disable controls based on the selected radio button. |
768 |
fsBrowseButton.setEnabled(selectedLocation == FILESYSTEM); |
769 |
fsPathText.setEnabled(selectedLocation == FILESYSTEM); |
770 |
if (selectedLocation == FILESYSTEM) |
771 |
fsBrowsed = false; |
772 |
wsPathText.setEnabled(selectedLocation == WORKSPACE); |
773 |
wsBrowseButton.setEnabled(selectedLocation == WORKSPACE); |
774 |
if (selectedLocation == WORKSPACE) |
775 |
wsBrowsed = false; |
776 |
} |
777 |
|
778 |
public int getSelectedLocation() { |
779 |
return selectedLocation; |
780 |
} |
781 |
|
782 |
} |
783 |
|
784 |
private class OptionsPage extends WizardPage { |
785 |
|
786 |
public final static int FORMAT_UNIFIED = 1; |
787 |
public final static int FORMAT_CONTEXT = 2; |
788 |
public final static int FORMAT_STANDARD = 3; |
789 |
|
790 |
public final static int ROOT_WORKSPACE = 1; |
791 |
public final static int ROOT_PROJECT = 2; |
792 |
public final static int ROOT_SELECTION = 3; |
793 |
public final static int ROOT_CUSTOM = 4; |
794 |
|
795 |
private boolean initialized = false; |
796 |
|
797 |
private Button unifiedDiffOption; |
798 |
private Button contextDiffOption; |
799 |
private Button regularDiffOption; |
800 |
|
801 |
private Button unified_workspaceRelativeOption; |
802 |
private Button unified_projectRelativeOption; |
803 |
private Button unified_selectionRelativeOption; |
804 |
private Button unified_customRelativeOption; |
805 |
private Text unified_customRelativeText; |
806 |
|
807 |
private final RadioButtonGroup diffTypeRadioGroup = new RadioButtonGroup(); |
808 |
private final RadioButtonGroup unifiedRadioGroup = new RadioButtonGroup(); |
809 |
|
810 |
private final DefaultValuesStore store; |
811 |
|
812 |
protected OptionsPage(String pageName, String title, |
813 |
ImageDescriptor titleImage, DefaultValuesStore store) { |
814 |
super(pageName, title, titleImage); |
815 |
this.store = store; |
816 |
} |
817 |
|
818 |
public void setVisible(boolean visible) { |
819 |
super.setVisible(visible); |
820 |
if (!initialized && visible) { |
821 |
File toFile = null; |
822 |
if (directionSelectionPage.isRightToLeft()) { |
823 |
toFile = new File(leftPath); |
824 |
} else { |
825 |
toFile = new File(rightPath); |
826 |
} |
827 |
String toPath = toFile.getPath(); |
828 |
unified_customRelativeText.setText(toPath); |
829 |
targetFileEdited = true; |
830 |
} |
831 |
} |
832 |
|
833 |
public void createControl(Composite parent) { |
834 |
Composite composite = new Composite(parent, SWT.NULL); |
835 |
GridLayout layout = new GridLayout(); |
836 |
composite.setLayout(layout); |
837 |
composite.setLayoutData(new GridData()); |
838 |
setControl(composite); |
839 |
|
840 |
Group diffTypeGroup = new Group(composite, SWT.NONE); |
841 |
layout = new GridLayout(); |
842 |
layout.marginHeight = 0; |
843 |
diffTypeGroup.setLayout(layout); |
844 |
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL |
845 |
| GridData.GRAB_HORIZONTAL); |
846 |
diffTypeGroup.setLayoutData(data); |
847 |
diffTypeGroup.setText(CompareMessages.Diff_output_format_12); |
848 |
|
849 |
unifiedDiffOption = new Button(diffTypeGroup, SWT.RADIO); |
850 |
unifiedDiffOption |
851 |
.setText(CompareMessages.Unified__format_required_by_Compare_With_Patch_feature__13); |
852 |
|
853 |
contextDiffOption = new Button(diffTypeGroup, SWT.RADIO); |
854 |
contextDiffOption.setText(CompareMessages.Context_14); |
855 |
regularDiffOption = new Button(diffTypeGroup, SWT.RADIO); |
856 |
regularDiffOption.setText(CompareMessages.Standard_15); |
857 |
|
858 |
diffTypeRadioGroup.add(FORMAT_UNIFIED, unifiedDiffOption); |
859 |
diffTypeRadioGroup.add(FORMAT_CONTEXT, contextDiffOption); |
860 |
diffTypeRadioGroup.add(FORMAT_STANDARD, regularDiffOption); |
861 |
|
862 |
// Unified Format Options |
863 |
Group unifiedGroup = new Group(composite, SWT.None); |
864 |
layout = new GridLayout(); |
865 |
layout.numColumns = 2; |
866 |
unifiedGroup.setLayout(layout); |
867 |
data = new GridData(GridData.HORIZONTAL_ALIGN_FILL |
868 |
| GridData.GRAB_HORIZONTAL); |
869 |
unifiedGroup.setLayoutData(data); |
870 |
unifiedGroup.setText(CompareMessages.GenerateDiffFileWizard_10); |
871 |
|
872 |
unified_workspaceRelativeOption = new Button(unifiedGroup, |
873 |
SWT.RADIO); |
874 |
unified_workspaceRelativeOption |
875 |
.setText(CompareMessages.GenerateDiffFileWizard_6); |
876 |
unified_workspaceRelativeOption.setLayoutData(new GridData( |
877 |
SWT.BEGINNING, SWT.CENTER, false, false, 2, 1)); |
878 |
|
879 |
unified_projectRelativeOption = new Button(unifiedGroup, SWT.RADIO); |
880 |
unified_projectRelativeOption |
881 |
.setText(CompareMessages.GenerateDiffFileWizard_7); |
882 |
unified_projectRelativeOption.setLayoutData(new GridData( |
883 |
SWT.BEGINNING, SWT.CENTER, false, false, 2, 1)); |
884 |
|
885 |
unified_selectionRelativeOption = new Button(unifiedGroup, |
886 |
SWT.RADIO); |
887 |
unified_selectionRelativeOption |
888 |
.setText(CompareMessages.GenerateDiffFileWizard_8); |
889 |
unified_selectionRelativeOption.setLayoutData(new GridData( |
890 |
SWT.BEGINNING, SWT.CENTER, false, false, 2, 1)); |
891 |
|
892 |
unified_customRelativeOption = new Button(unifiedGroup, SWT.RADIO); |
893 |
unified_customRelativeOption |
894 |
.setText(CompareMessages.GenerateDiffFileWizard_13); |
895 |
unified_customRelativeOption.setSelection(true); |
896 |
unified_customRelativeOption.setLayoutData(new GridData( |
897 |
SWT.BEGINNING, SWT.CENTER, false, false, 1, 1)); |
898 |
|
899 |
unified_customRelativeText = new Text(unifiedGroup, SWT.BORDER); |
900 |
unified_customRelativeText.setLayoutData(new GridData(SWT.FILL, |
901 |
SWT.CENTER, true, false, 1, 1)); |
902 |
|
903 |
unifiedRadioGroup.add(ROOT_WORKSPACE, |
904 |
unified_workspaceRelativeOption); |
905 |
unifiedRadioGroup.add(ROOT_PROJECT, unified_projectRelativeOption); |
906 |
unifiedRadioGroup.add(ROOT_SELECTION, |
907 |
unified_selectionRelativeOption); |
908 |
unifiedRadioGroup.add(ROOT_CUSTOM, unified_customRelativeOption); |
909 |
|
910 |
Dialog.applyDialogFont(parent); |
911 |
|
912 |
initializeDefaultValues(); |
913 |
|
914 |
// add listeners |
915 |
unifiedDiffOption.addSelectionListener(new SelectionAdapter() { |
916 |
public void widgetSelected(SelectionEvent e) { |
917 |
diffTypeRadioGroup.setSelection(FORMAT_UNIFIED, false); |
918 |
} |
919 |
}); |
920 |
|
921 |
contextDiffOption.addSelectionListener(new SelectionAdapter() { |
922 |
public void widgetSelected(SelectionEvent e) { |
923 |
diffTypeRadioGroup.setSelection(FORMAT_CONTEXT, false); |
924 |
} |
925 |
}); |
926 |
|
927 |
regularDiffOption.addSelectionListener(new SelectionAdapter() { |
928 |
public void widgetSelected(SelectionEvent e) { |
929 |
diffTypeRadioGroup.setSelection(FORMAT_STANDARD, false); |
930 |
} |
931 |
}); |
932 |
|
933 |
unified_workspaceRelativeOption |
934 |
.addSelectionListener(new SelectionAdapter() { |
935 |
public void widgetSelected(SelectionEvent e) { |
936 |
unifiedRadioGroup.setSelection(ROOT_WORKSPACE, |
937 |
false); |
938 |
} |
939 |
}); |
940 |
|
941 |
unified_projectRelativeOption |
942 |
.addSelectionListener(new SelectionAdapter() { |
943 |
public void widgetSelected(SelectionEvent e) { |
944 |
unifiedRadioGroup.setSelection(ROOT_PROJECT, false); |
945 |
} |
946 |
}); |
947 |
|
948 |
unified_selectionRelativeOption |
949 |
.addSelectionListener(new SelectionAdapter() { |
950 |
public void widgetSelected(SelectionEvent e) { |
951 |
unifiedRadioGroup.setSelection(ROOT_SELECTION, |
952 |
false); |
953 |
} |
954 |
}); |
955 |
|
956 |
unified_selectionRelativeOption |
957 |
.addSelectionListener(new SelectionAdapter() { |
958 |
public void widgetSelected(SelectionEvent e) { |
959 |
unifiedRadioGroup.setSelection(ROOT_CUSTOM, false); |
960 |
} |
961 |
}); |
962 |
|
963 |
// calculatePatchRoot(); |
964 |
updateEnablements(); |
965 |
|
966 |
// update selection |
967 |
diffTypeRadioGroup.selectEnabledOnly(); |
968 |
unifiedRadioGroup.selectEnabledOnly(); |
969 |
} |
970 |
|
971 |
public int getFormatSelection() { |
972 |
return diffTypeRadioGroup.getSelected(); |
973 |
} |
974 |
|
975 |
public int getRootSelection() { |
976 |
return unifiedRadioGroup.getSelected(); |
977 |
} |
978 |
|
979 |
public String getPath() { |
980 |
return unified_customRelativeText.getText(); |
981 |
} |
982 |
|
983 |
private void initializeDefaultValues() { |
984 |
// Radio buttons for format |
985 |
diffTypeRadioGroup.setSelection(store.getFormatSelection(), true); |
986 |
// Radio buttons for patch root |
987 |
unifiedRadioGroup.setSelection(store.getRootSelection(), true); |
988 |
} |
989 |
|
990 |
protected void updateEnablements() { |
991 |
diffTypeRadioGroup.setEnablement(false, new int[] { FORMAT_CONTEXT, |
992 |
FORMAT_STANDARD }, FORMAT_UNIFIED); |
993 |
unifiedRadioGroup.setEnablement(false, new int[] { ROOT_WORKSPACE, |
994 |
ROOT_PROJECT, ROOT_SELECTION }, ROOT_CUSTOM); |
995 |
} |
996 |
|
997 |
} |
998 |
|
999 |
/** |
1000 |
* Class to retrieve and store the default selected values. |
1001 |
*/ |
1002 |
private final class DefaultValuesStore { |
1003 |
|
1004 |
private static final String PREF_LAST_SELECTION = "org.eclipse.compare.internal.GenerateDiffFileWizard.PatchFileSelectionPage.lastselection"; //$NON-NLS-1$ |
1005 |
private static final String PREF_LAST_FS_PATH = "org.eclipse.compare.internal.GenerateDiffFileWizard.PatchFileSelectionPage.filesystem.path"; //$NON-NLS-1$ |
1006 |
private static final String PREF_LAST_WS_PATH = "org.eclipse.compare.internal.GenerateDiffFileWizard.PatchFileSelectionPage.workspace.path"; //$NON-NLS-1$ |
1007 |
private static final String PREF_LAST_AO_FORMAT = "org.eclipse.compare.internal.GenerateDiffFileWizard.OptionsPage.diff.format"; //$NON-NLS-1$ |
1008 |
private static final String PREF_LAST_AO_ROOT = "org.eclipse.compare.internal.GenerateDiffFileWizard.OptionsPage.patch.root"; //$NON-NLS-1$ |
1009 |
|
1010 |
private final IDialogSettings dialogSettings; |
1011 |
|
1012 |
public DefaultValuesStore() { |
1013 |
dialogSettings = CompareUIPlugin.getDefault().getDialogSettings(); |
1014 |
} |
1015 |
|
1016 |
public int getLocationSelection() { |
1017 |
int value = LocationPage.CLIPBOARD; |
1018 |
try { |
1019 |
value = dialogSettings.getInt(PREF_LAST_SELECTION); |
1020 |
} catch (NumberFormatException e) { |
1021 |
// Ignore |
1022 |
} |
1023 |
|
1024 |
switch (value) { |
1025 |
case LocationPage.FILESYSTEM: |
1026 |
case LocationPage.WORKSPACE: |
1027 |
case LocationPage.CLIPBOARD: |
1028 |
return value; |
1029 |
default: |
1030 |
return LocationPage.CLIPBOARD; |
1031 |
} |
1032 |
} |
1033 |
|
1034 |
public String getFilesystemPath() { |
1035 |
final String path = dialogSettings.get(PREF_LAST_FS_PATH); |
1036 |
return path != null ? path : ""; //$NON-NLS-1$ |
1037 |
} |
1038 |
|
1039 |
public String getWorkspacePath() { |
1040 |
final String path = dialogSettings.get(PREF_LAST_WS_PATH); |
1041 |
return path != null ? path : ""; //$NON-NLS-1$ |
1042 |
} |
1043 |
|
1044 |
public int getFormatSelection() { |
1045 |
int value = OptionsPage.FORMAT_UNIFIED; |
1046 |
try { |
1047 |
value = dialogSettings.getInt(PREF_LAST_AO_FORMAT); |
1048 |
} catch (NumberFormatException e) { |
1049 |
// Ignore |
1050 |
} |
1051 |
|
1052 |
switch (value) { |
1053 |
case OptionsPage.FORMAT_UNIFIED: |
1054 |
case OptionsPage.FORMAT_CONTEXT: |
1055 |
case OptionsPage.FORMAT_STANDARD: |
1056 |
return value; |
1057 |
default: |
1058 |
return OptionsPage.FORMAT_UNIFIED; |
1059 |
} |
1060 |
} |
1061 |
|
1062 |
public int getRootSelection() { |
1063 |
int value = OptionsPage.ROOT_WORKSPACE; |
1064 |
try { |
1065 |
value = dialogSettings.getInt(PREF_LAST_AO_ROOT); |
1066 |
} catch (NumberFormatException e) { |
1067 |
// Ignore |
1068 |
} |
1069 |
|
1070 |
switch (value) { |
1071 |
case OptionsPage.ROOT_WORKSPACE: |
1072 |
case OptionsPage.ROOT_PROJECT: |
1073 |
case OptionsPage.ROOT_SELECTION: |
1074 |
return value; |
1075 |
default: |
1076 |
return OptionsPage.ROOT_WORKSPACE; |
1077 |
} |
1078 |
} |
1079 |
|
1080 |
public void storeLocationSelection(int defaultSelection) { |
1081 |
dialogSettings.put(PREF_LAST_SELECTION, defaultSelection); |
1082 |
} |
1083 |
|
1084 |
public void storeFilesystemPath(String path) { |
1085 |
dialogSettings.put(PREF_LAST_FS_PATH, path); |
1086 |
} |
1087 |
|
1088 |
public void storeWorkspacePath(String path) { |
1089 |
dialogSettings.put(PREF_LAST_WS_PATH, path); |
1090 |
} |
1091 |
|
1092 |
public void storeOutputFormat(int selection) { |
1093 |
dialogSettings.put(PREF_LAST_AO_FORMAT, selection); |
1094 |
} |
1095 |
|
1096 |
public void storePatchRoot(int selection) { |
1097 |
dialogSettings.put(PREF_LAST_AO_ROOT, selection); |
1098 |
} |
1099 |
} |
1100 |
|
1101 |
private DirectionSelectionPage directionSelectionPage; |
1102 |
private LocationPage locationPage; |
1103 |
private OptionsPage optionsPage; |
1104 |
|
1105 |
// protected IResource[] resources; |
1106 |
private final DefaultValuesStore defaultValuesStore; |
1107 |
// private final IWorkbenchPart part; |
1108 |
|
1109 |
private DocumentMerger merger; |
1110 |
private IDocument leftDoc; |
1111 |
private IDocument rightDoc; |
1112 |
private String leftLabel; |
1113 |
private String rightLabel; |
1114 |
private String leftPath; |
1115 |
private String rightPath; |
1116 |
private boolean rightToLeft; |
1117 |
|
1118 |
private boolean targetFileEdited = false; |
1119 |
|
1120 |
public SaveDiffFileWizard(DocumentMerger merger, IDocument leftDoc, |
1121 |
IDocument rightDoc, String leftLabel, String rightLabel, |
1122 |
String leftPath, String rightPath, boolean rightToLeft) { |
1123 |
super(); |
1124 |
setWindowTitle(CompareMessages.GenerateLocalDiff_title); |
1125 |
initializeDefaultPageImageDescriptor(); |
1126 |
defaultValuesStore = new DefaultValuesStore(); |
1127 |
this.merger = merger; |
1128 |
this.leftDoc = leftDoc; |
1129 |
this.rightDoc = rightDoc; |
1130 |
this.leftLabel = leftLabel; |
1131 |
this.rightLabel = rightLabel; |
1132 |
this.leftPath = leftPath; |
1133 |
this.rightPath = rightPath; |
1134 |
this.rightToLeft = rightToLeft; |
1135 |
} |
1136 |
|
1137 |
public void addPages() { |
1138 |
String pageTitle = CompareMessages.GenerateLocalDiff_pageTitle; |
1139 |
String pageDescription = CompareMessages.GenerateLocalDiff_Specify_the_file_which_contributes_the_changes; |
1140 |
directionSelectionPage = new DirectionSelectionPage( |
1141 |
pageTitle, |
1142 |
pageTitle, |
1143 |
CompareUIPlugin |
1144 |
.getImageDescriptor(ICompareUIConstants.IMG_WIZBAN_DIFF)); |
1145 |
directionSelectionPage.setDescription(pageDescription); |
1146 |
addPage(directionSelectionPage); |
1147 |
|
1148 |
pageTitle = CompareMessages.GenerateLocalDiff_pageTitle; |
1149 |
pageDescription = CompareMessages.GenerateLocalDiff_pageDescription; |
1150 |
locationPage = new LocationPage(pageTitle, pageTitle, CompareUIPlugin |
1151 |
.getImageDescriptor(ICompareUIConstants.IMG_WIZBAN_DIFF), |
1152 |
defaultValuesStore); |
1153 |
locationPage.setDescription(pageDescription); |
1154 |
addPage(locationPage); |
1155 |
|
1156 |
pageTitle = CompareMessages.Advanced_options_19; |
1157 |
pageDescription = CompareMessages.Configure_the_options_used_for_the_CVS_diff_command_20; |
1158 |
optionsPage = new OptionsPage(pageTitle, pageTitle, CompareUIPlugin |
1159 |
.getImageDescriptor(ICompareUIConstants.IMG_WIZBAN_DIFF), |
1160 |
defaultValuesStore); |
1161 |
optionsPage.setDescription(pageDescription); |
1162 |
addPage(optionsPage); |
1163 |
} |
1164 |
|
1165 |
/** |
1166 |
* Declares the wizard banner iamge descriptor |
1167 |
*/ |
1168 |
protected void initializeDefaultPageImageDescriptor() { |
1169 |
final String iconPath = "icons/full/"; //$NON-NLS-1$ |
1170 |
try { |
1171 |
final URL installURL = CompareUIPlugin.getDefault().getBundle() |
1172 |
.getEntry("/"); //$NON-NLS-1$ |
1173 |
final URL url = new URL(installURL, iconPath |
1174 |
+ "wizards/newconnect_wiz.gif"); //$NON-NLS-1$ |
1175 |
ImageDescriptor desc = ImageDescriptor.createFromURL(url); |
1176 |
setDefaultPageImageDescriptor(desc); |
1177 |
} catch (MalformedURLException e) { |
1178 |
// Should not happen. Ignore. |
1179 |
} |
1180 |
} |
1181 |
|
1182 |
/* |
1183 |
* (Non-javadoc) Method declared on IWizard. |
1184 |
*/ |
1185 |
public boolean needsProgressMonitor() { |
1186 |
return true; |
1187 |
} |
1188 |
|
1189 |
public boolean performFinish() { |
1190 |
final int location = locationPage.getSelectedLocation(); |
1191 |
final File file = location != LocationPage.CLIPBOARD ? locationPage |
1192 |
.getFile() : null; |
1193 |
|
1194 |
if (!(file == null || validateFile(file))) { |
1195 |
return false; |
1196 |
} |
1197 |
|
1198 |
// Create the patch |
1199 |
generateDiffFile(file); |
1200 |
|
1201 |
// Refresh workspace if necessary and save default selection. |
1202 |
switch (location) { |
1203 |
case LocationPage.WORKSPACE: |
1204 |
final String workspaceResource = locationPage |
1205 |
.getWorkspaceLocation(); |
1206 |
if (workspaceResource != null) { |
1207 |
defaultValuesStore |
1208 |
.storeLocationSelection(LocationPage.WORKSPACE); |
1209 |
defaultValuesStore.storeWorkspacePath(workspaceResource); |
1210 |
} else { |
1211 |
// Problem with workspace location, choose clipboard next time |
1212 |
defaultValuesStore |
1213 |
.storeLocationSelection(LocationPage.CLIPBOARD); |
1214 |
} |
1215 |
break; |
1216 |
case LocationPage.FILESYSTEM: |
1217 |
defaultValuesStore.storeFilesystemPath(file.getPath()); |
1218 |
defaultValuesStore.storeLocationSelection(LocationPage.FILESYSTEM); |
1219 |
break; |
1220 |
case LocationPage.CLIPBOARD: |
1221 |
defaultValuesStore.storeLocationSelection(LocationPage.CLIPBOARD); |
1222 |
break; |
1223 |
default: |
1224 |
return false; |
1225 |
} |
1226 |
|
1227 |
defaultValuesStore.storeOutputFormat(optionsPage.getFormatSelection()); |
1228 |
defaultValuesStore.storePatchRoot(optionsPage.getRootSelection()); |
1229 |
|
1230 |
return true; |
1231 |
} |
1232 |
|
1233 |
private void generateDiffFile(File file) { |
1234 |
String toPath = null; |
1235 |
if (targetFileEdited) { |
1236 |
toPath = optionsPage.getPath(); |
1237 |
} else { |
1238 |
File toFile = null; |
1239 |
if (directionSelectionPage.isRightToLeft()) { |
1240 |
toFile = new File(leftPath); |
1241 |
} else { |
1242 |
toFile = new File(rightPath); |
1243 |
} |
1244 |
toPath = toFile.getPath(); |
1245 |
} |
1246 |
|
1247 |
UnifiedDiffFormatter formatter = new UnifiedDiffFormatter(merger, |
1248 |
leftDoc, rightDoc, toPath, directionSelectionPage |
1249 |
.isRightToLeft()); |
1250 |
try { |
1251 |
if (file == null) { |
1252 |
formatter.generateDiff(getShell().getDisplay()); |
1253 |
} else { |
1254 |
formatter.generateDiff(file); |
1255 |
} |
1256 |
} catch (IOException e) { |
1257 |
throw new RuntimeException(e); |
1258 |
} |
1259 |
} |
1260 |
|
1261 |
public boolean validateFile(File file) { |
1262 |
if (file == null) |
1263 |
return false; |
1264 |
|
1265 |
// Consider file valid if it doesn't exist for now. |
1266 |
if (!file.exists()) |
1267 |
return true; |
1268 |
|
1269 |
// The file exists. |
1270 |
if (!file.canWrite()) { |
1271 |
final String title = CompareMessages.GenerateLocalDiff_1; |
1272 |
final String msg = CompareMessages.GenerateLocalDiff_2; |
1273 |
final MessageDialog dialog = new MessageDialog(getShell(), title, |
1274 |
null, msg, MessageDialog.ERROR, |
1275 |
new String[] { IDialogConstants.OK_LABEL }, 0); |
1276 |
dialog.open(); |
1277 |
return false; |
1278 |
} |
1279 |
|
1280 |
final String title = CompareMessages.GenerateLocalDiff_overwriteTitle; |
1281 |
final String msg = CompareMessages.GenerateLocalDiff_overwriteMsg; |
1282 |
final MessageDialog dialog = new MessageDialog(getShell(), title, null, |
1283 |
msg, MessageDialog.QUESTION, new String[] { |
1284 |
IDialogConstants.YES_LABEL, |
1285 |
IDialogConstants.CANCEL_LABEL }, 0); |
1286 |
dialog.open(); |
1287 |
if (dialog.getReturnCode() != 0) { |
1288 |
return false; |
1289 |
} |
1290 |
return true; |
1291 |
} |
1292 |
|
1293 |
/** |
1294 |
* The class maintain proper selection of radio button within the group: |
1295 |
* <ul> |
1296 |
* <li>Only one button can be selected at the time.</li> |
1297 |
* <li>Disabled button can't be selected unless all buttons in the group are |
1298 |
* disabled.</li> |
1299 |
* </ul> |
1300 |
*/ |
1301 |
private class RadioButtonGroup { |
1302 |
|
1303 |
private List buttons = new ArrayList(3); |
1304 |
|
1305 |
private int selected = 0; |
1306 |
|
1307 |
public void add(int buttonCode, Button button) { |
1308 |
if (button != null && (button.getStyle() & SWT.RADIO) != 0) { |
1309 |
if (button.getSelection() && !buttons.isEmpty()) { |
1310 |
deselectAll(); |
1311 |
selected = buttonCode - 1; |
1312 |
} |
1313 |
buttons.add(buttonCode - 1, button); |
1314 |
} |
1315 |
} |
1316 |
|
1317 |
public int getSelected() { |
1318 |
return selected + 1; |
1319 |
} |
1320 |
|
1321 |
public int setSelection(int buttonCode, boolean selectEnabledOnly) { |
1322 |
deselectAll(); |
1323 |
|
1324 |
((Button) buttons.get(buttonCode - 1)).setSelection(true); |
1325 |
selected = buttonCode - 1; |
1326 |
if (selectEnabledOnly) |
1327 |
selected = selectEnabledOnly() - 1; |
1328 |
return getSelected(); |
1329 |
} |
1330 |
|
1331 |
public int selectEnabledOnly() { |
1332 |
deselectAll(); |
1333 |
Button selectedButton = (Button) buttons.get(selected); |
1334 |
if (!selectedButton.isEnabled()) { |
1335 |
// If the button is disabled, set selection to an enabled one |
1336 |
for (Iterator iterator = buttons.iterator(); iterator.hasNext();) { |
1337 |
Button b = (Button) iterator.next(); |
1338 |
if (b.isEnabled()) { |
1339 |
b.setSelection(true); |
1340 |
selected = buttons.indexOf(b); |
1341 |
return selected + 1; |
1342 |
} |
1343 |
} |
1344 |
// If none found, reset the initial selection |
1345 |
selectedButton.setSelection(true); |
1346 |
} else { |
1347 |
// Because selection has been cleared, set it again |
1348 |
selectedButton.setSelection(true); |
1349 |
} |
1350 |
// Return selected button's code so the value can be stored |
1351 |
return getSelected(); |
1352 |
} |
1353 |
|
1354 |
public void setEnablement(boolean enabled, int[] buttonsToChange, |
1355 |
int defaultSelection) { |
1356 |
// Enable (or disable) given buttons |
1357 |
for (int i = 0; i < buttonsToChange.length; i++) { |
1358 |
((Button) this.buttons.get(buttonsToChange[i] - 1)) |
1359 |
.setEnabled(enabled); |
1360 |
} |
1361 |
// Check whether the selected button is enabled |
1362 |
if (!((Button) this.buttons.get(selected)).isEnabled()) { |
1363 |
if (defaultSelection != -1) |
1364 |
// Set the default selection and check if it's enabled |
1365 |
setSelection(defaultSelection, true); |
1366 |
else |
1367 |
// No default selection is given, select any enabled button |
1368 |
selectEnabledOnly(); |
1369 |
} |
1370 |
} |
1371 |
|
1372 |
public void setEnablement(boolean enabled, int[] buttonsToChange) { |
1373 |
// Value -1 means that no default selection is given |
1374 |
setEnablement(enabled, buttonsToChange, -1); |
1375 |
} |
1376 |
|
1377 |
private void deselectAll() { |
1378 |
for (Iterator iterator = buttons.iterator(); iterator.hasNext();) |
1379 |
((Button) iterator.next()).setSelection(false); |
1380 |
} |
1381 |
} |
1382 |
|
1383 |
} |