KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > ui > wizards > GenerateDiffFileWizard


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Benjamin Muskalla (b.muskalla@gmx.net) - Bug 149672 [Patch] Create Patch wizard should remember previous settings
11  *******************************************************************************/

12 package org.eclipse.team.internal.ccvs.ui.wizards;
13
14
15 import java.io.File JavaDoc;
16 import java.lang.reflect.InvocationTargetException JavaDoc;
17 import java.net.MalformedURLException JavaDoc;
18 import java.net.URL JavaDoc;
19 import java.util.*;
20 import java.util.List JavaDoc;
21
22 import org.eclipse.core.resources.*;
23 import org.eclipse.core.runtime.*;
24 import org.eclipse.core.runtime.jobs.Job;
25 import org.eclipse.jface.dialogs.*;
26 import org.eclipse.jface.dialogs.Dialog;
27 import org.eclipse.jface.resource.ImageDescriptor;
28 import org.eclipse.jface.viewers.*;
29 import org.eclipse.jface.wizard.*;
30 import org.eclipse.osgi.util.NLS;
31 import org.eclipse.swt.SWT;
32 import org.eclipse.swt.events.*;
33 import org.eclipse.swt.graphics.Image;
34 import org.eclipse.swt.graphics.Point;
35 import org.eclipse.swt.layout.GridData;
36 import org.eclipse.swt.layout.GridLayout;
37 import org.eclipse.swt.widgets.*;
38 import org.eclipse.team.core.Team;
39 import org.eclipse.team.core.TeamException;
40 import org.eclipse.team.core.diff.IDiff;
41 import org.eclipse.team.core.diff.IDiffVisitor;
42 import org.eclipse.team.core.mapping.provider.ResourceDiffTree;
43 import org.eclipse.team.core.synchronize.SyncInfoSet;
44 import org.eclipse.team.internal.ccvs.core.CVSException;
45 import org.eclipse.team.internal.ccvs.core.ICVSFile;
46 import org.eclipse.team.internal.ccvs.core.client.Command;
47 import org.eclipse.team.internal.ccvs.core.client.Diff;
48 import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
49 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
50 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
51 import org.eclipse.team.internal.ccvs.ui.*;
52 import org.eclipse.team.internal.ccvs.ui.IHelpContextIds;
53 import org.eclipse.team.internal.ccvs.ui.operations.*;
54 import org.eclipse.team.internal.ccvs.ui.subscriber.CreatePatchWizardParticipant;
55 import org.eclipse.team.internal.ccvs.ui.subscriber.WorkspaceSynchronizeParticipant;
56 import org.eclipse.team.internal.core.subscribers.SubscriberSyncInfoCollector;
57 import org.eclipse.team.internal.ui.*;
58 import org.eclipse.team.ui.synchronize.*;
59 import org.eclipse.ui.IWorkbenchPart;
60 import org.eclipse.ui.PlatformUI;
61 import org.eclipse.ui.model.BaseWorkbenchContentProvider;
62 import org.eclipse.ui.model.WorkbenchLabelProvider;
63 import org.eclipse.ui.part.PageBook;
64
65 /**
66  * A wizard for creating a patch file by running the CVS diff command.
67  */

68 public class GenerateDiffFileWizard extends Wizard {
69     
70     //The initial size of this wizard.
71
private final static int INITIAL_WIDTH = 300;
72     private final static int INITIAL_HEIGHT = 350;
73    
74     public static void run(IWorkbenchPart part, final IResource[] resources, boolean unifiedSelectionEnabled) {
75         final String JavaDoc title = CVSUIMessages.GenerateCVSDiff_title;
76         final GenerateDiffFileWizard wizard = new GenerateDiffFileWizard(part,resources, unifiedSelectionEnabled);
77         wizard.setWindowTitle(title);
78         WizardDialog dialog = new WizardDialog(part.getSite().getShell(), wizard);
79         dialog.setMinimumPageSize(INITIAL_WIDTH, INITIAL_HEIGHT);
80         dialog.open();
81     }
82     
83     public static void run(IWorkbenchPart part, final IResource[] resources) {
84         GenerateDiffFileWizard.run(part,resources,true);
85     }
86     
87     /**
88      * Page to select a patch file. Overriding validatePage was necessary to allow
89      * entering a file name that already exists.
90      */

91     public class LocationPage extends WizardPage {
92         
93         /**
94          * The possible locations to save a patch.
95          */

96         public final static int CLIPBOARD = 1;
97         public final static int FILESYSTEM = 2;
98         public final static int WORKSPACE = 3;
99         
100         /**
101          * GUI controls for clipboard (cp), filesystem (fs) and workspace (ws).
102          */

103         private Button cpRadio;
104         
105         private Button fsRadio;
106         protected Text fsPathText;
107         private Button fsBrowseButton;
108         private boolean fsBrowsed = false;
109         
110         private Button wsRadio;
111         protected Text wsPathText;
112         private Button wsBrowseButton;
113         private boolean wsBrowsed = false;
114        
115         protected CreatePatchWizardParticipant fParticipant;
116         private Button chgSelectAll;
117         private Button chgDeselectAll;
118         
119         /**
120          * State information of this page, updated by the listeners.
121          */

122         protected boolean canValidate;
123         protected boolean pageValid;
124         protected IContainer wsSelectedContainer;
125         protected IPath[] foldersToCreate;
126         protected int selectedLocation;
127         
128         /**
129          * The default values store used to initialize the selections.
130          */

131         private final DefaultValuesStore store;
132     
133         
134         class LocationPageContentProvider extends BaseWorkbenchContentProvider {
135             //Never show closed projects
136
boolean showClosedProjects=false;
137             
138             public Object JavaDoc[] getChildren(Object JavaDoc element) {
139                 if (element instanceof IWorkspace) {
140                     // check if closed projects should be shown
141
IProject[] allProjects = ((IWorkspace) element).getRoot().getProjects();
142                     if (showClosedProjects)
143                         return allProjects;
144
145                     ArrayList accessibleProjects = new ArrayList();
146                     for (int i = 0; i < allProjects.length; i++) {
147                         if (allProjects[i].isOpen()) {
148                             accessibleProjects.add(allProjects[i]);
149                         }
150                     }
151                     return accessibleProjects.toArray();
152                 }
153                 
154                 return super.getChildren(element);
155             }
156         }
157         
158         class WorkspaceDialog extends TitleAreaDialog {
159
160             protected TreeViewer wsTreeViewer;
161             protected Text wsFilenameText;
162             protected Image dlgTitleImage;
163             
164             public WorkspaceDialog(Shell shell) {
165                 super(shell);
166             }
167             
168             protected Control createContents(Composite parent) {
169                 Control control = super.createContents(parent);
170                 setTitle(CVSUIMessages.Select_a_folder_then_type_in_the_file_name__8);
171                 //create title image
172
dlgTitleImage = CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_WIZBAN_DIFF).createImage();
173                 setTitleImage(dlgTitleImage);
174                 
175                 return control;
176             }
177             
178             protected Control createDialogArea(Composite parent){
179                 Composite composite = (Composite) super.createDialogArea(parent);
180                 
181                 
182                 GridLayout layout = new GridLayout();
183                 layout.numColumns = 1;
184                 layout.marginHeight= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
185                 layout.marginWidth= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
186                 composite.setLayout(layout);
187                 final GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
188                 composite.setLayoutData(data);
189                 
190                 getShell().setText(CVSUIMessages.GenerateDiffFileWizard_9);
191         
192                 wsTreeViewer = new TreeViewer(composite, SWT.BORDER);
193                 final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true);
194                 gd.widthHint= 550;
195                 gd.heightHint= 250;
196                 wsTreeViewer.getTree().setLayoutData(gd);
197                
198                 wsTreeViewer.setContentProvider(new LocationPageContentProvider());
199                 wsTreeViewer.setLabelProvider(new WorkbenchLabelProvider());
200                 wsTreeViewer.setInput(ResourcesPlugin.getWorkspace());
201                 
202                 //Open to whatever is selected in the workspace field
203
IPath existingWorkspacePath = new Path(wsPathText.getText());
204                 if (existingWorkspacePath != null){
205                     //Ensure that this workspace path is valid
206
IResource selectedResource = ResourcesPlugin.getWorkspace().getRoot().findMember(existingWorkspacePath);
207                     if (selectedResource != null) {
208                         wsTreeViewer.expandToLevel(selectedResource, 0);
209                         wsTreeViewer.setSelection(new StructuredSelection(selectedResource));
210                     }
211                 }
212                 
213                 final Composite group = new Composite(composite, SWT.NONE);
214                 layout = new GridLayout(2, false);
215                 layout.marginWidth = 0;
216                 group.setLayout(layout);
217                 group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
218                 
219                 final Label label = new Label(group, SWT.NONE);
220                 label.setLayoutData(new GridData());
221                 label.setText(CVSUIMessages.Fi_le_name__9);
222                 
223                 wsFilenameText = new Text(group,SWT.BORDER);
224                 wsFilenameText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
225                 
226                 setupListeners();
227                 
228                 return parent;
229             }
230         
231             protected void okPressed() {
232                 //make sure that a filename has been typed in
233

234                 String JavaDoc patchName = wsFilenameText.getText();
235                 
236                 if (patchName.equals("")){ //$NON-NLS-1$
237
setErrorMessage(CVSUIMessages.GenerateDiffFileWizard_2);
238                     return;
239                 }
240                 
241                 //make sure that the filename does not contain more than one segment
242
if (!(ResourcesPlugin.getWorkspace().validateName(patchName, IResource.FILE)).isOK()){
243                     wsFilenameText.setText(""); //$NON-NLS-1$
244
setErrorMessage(CVSUIMessages.GenerateDiffFileWizard_File_multisegments);
245                     return;
246                 }
247                 
248                 //Make sure that a container has been selected
249
if (wsSelectedContainer == null){
250                     getSelectedContainer();
251                 }
252                 Assert.isNotNull(wsSelectedContainer);
253                 
254                 IFile file = wsSelectedContainer.getFile(new Path(wsFilenameText.getText()));
255                 if (file != null)
256                     wsPathText.setText(file.getFullPath().toString());
257                 
258                 validatePage();
259                 super.okPressed();
260             }
261             
262             private void getSelectedContainer() {
263                 Object JavaDoc obj = ((IStructuredSelection)wsTreeViewer.getSelection()).getFirstElement();
264                 if (obj instanceof IContainer)
265                     wsSelectedContainer = (IContainer) obj;
266                 else if (obj instanceof IFile){
267                     wsSelectedContainer = ((IFile) obj).getParent();
268                 }
269             }
270
271             protected void cancelPressed() {
272               validatePage();
273               super.cancelPressed();
274             }
275          
276            public boolean close() {
277                 if (dlgTitleImage != null)
278                     dlgTitleImage.dispose();
279                 return super.close();
280             }
281               
282             void setupListeners(){
283                  wsTreeViewer.addSelectionChangedListener(
284                 new ISelectionChangedListener() {
285                     public void selectionChanged(SelectionChangedEvent event) {
286                         IStructuredSelection s = (IStructuredSelection)event.getSelection();
287                         Object JavaDoc obj=s.getFirstElement();
288                         if (obj instanceof IContainer)
289                             wsSelectedContainer = (IContainer) obj;
290                         else if (obj instanceof IFile){
291                             IFile tempFile = (IFile) obj;
292                             wsSelectedContainer = tempFile.getParent();
293                             wsFilenameText.setText(tempFile.getName());
294                         }
295                     }
296                 });
297         
298                 wsTreeViewer.addDoubleClickListener(
299                         new IDoubleClickListener() {
300                             public void doubleClick(DoubleClickEvent event) {
301                                 ISelection s= event.getSelection();
302                                 if (s instanceof IStructuredSelection) {
303                                     Object JavaDoc item = ((IStructuredSelection)s).getFirstElement();
304                                     if (wsTreeViewer.getExpandedState(item))
305                                         wsTreeViewer.collapseToLevel(item, 1);
306                                     else
307                                         wsTreeViewer.expandToLevel(item, 1);
308                                 }
309                             }
310                         });
311         
312                 wsFilenameText.addModifyListener(new ModifyListener() {
313                     public void modifyText(ModifyEvent e) {
314                       setErrorMessage(null);
315                     }
316                 });
317             }
318         }
319         
320         LocationPage(String JavaDoc pageName, String JavaDoc title, ImageDescriptor image, DefaultValuesStore store) {
321             super(pageName, title, image);
322             setPageComplete(false);
323             this.store= store;
324             this.canValidate=false;
325         }
326         
327         /**
328          * Allow the user to finish if a valid file has been entered.
329          */

330         protected boolean validatePage() {
331             
332             if (!canValidate)
333                 return false;
334             
335             switch (selectedLocation) {
336             case WORKSPACE:
337                 pageValid= validateWorkspaceLocation();
338                 break;
339             case FILESYSTEM:
340                 pageValid= validateFilesystemLocation();
341                 break;
342             case CLIPBOARD:
343                 pageValid= true;
344                 break;
345             }
346             
347             /**
348              * Avoid draw flicker by clearing error message
349              * if all is valid.
350              */

351             if (pageValid) {
352                 setMessage(null);
353                 setErrorMessage(null);
354             }
355             setPageComplete(pageValid);
356             return pageValid;
357         }
358         
359         /**
360          * The following conditions must hold for the file system location
361          * to be valid:
362          * - the path must be valid and non-empty
363          * - the path must be absolute
364          * - the specified file must be of type file
365          * - the parent must exist (new folders can be created via the browse button)
366          */

367         private boolean validateFilesystemLocation() {
368             final String JavaDoc pathString= fsPathText.getText().trim();
369             if (pathString.length() == 0 || !new Path("").isValidPath(pathString)) { //$NON-NLS-1$
370
if (fsBrowsed)
371                     setErrorMessage(CVSUIMessages.GenerateDiffFileWizard_0);
372                 return false;
373             }
374             
375             final File JavaDoc file= new File JavaDoc(pathString);
376             if (!file.isAbsolute()) {
377                 setErrorMessage(CVSUIMessages.GenerateDiffFileWizard_0);
378                 return false;
379             }
380             
381             if (file.isDirectory()) {
382                 setErrorMessage(CVSUIMessages.GenerateDiffFileWizard_2);
383                 return false;
384             }
385             
386             if (pathString.endsWith("/") || pathString.endsWith("\\")) { //$NON-NLS-1$//$NON-NLS-2$
387
setErrorMessage(CVSUIMessages.GenerateDiffFileWizard_3);
388                 return false;
389             }
390             
391             final File JavaDoc parent= file.getParentFile();
392             if (!(parent.exists() && parent.isDirectory())) {
393                 setErrorMessage(CVSUIMessages.GenerateDiffFileWizard_3);
394                 return false;
395             }
396             return true;
397         }
398         
399         /**
400          * The following conditions must hold for the file system location to be valid:
401          * - a parent must be selected in the workspace tree view
402          * - the resource name must be valid
403          */

404         private boolean validateWorkspaceLocation() {
405             //make sure that the field actually has a filename in it - making
406
//sure that the user has had a chance to browse the workspace first
407
if (wsPathText.getText().equals("")){ //$NON-NLS-1$
408
if (selectedLocation ==WORKSPACE && wsBrowsed)
409                     setErrorMessage(CVSUIMessages.GenerateDiffFileWizard_5);
410                 return false;
411             }
412             
413             //Make sure that all the segments but the last one (i.e. project + all
414
//folders) exist - file doesn't have to exist. It may have happened that
415
//some folder refactoring has been done since this path was last saved.
416
//
417
//Assume that the path will always be in format project/{folders}*/file - this
418
//is controlled by the workspace location dialog
419

420             
421             IPath pathToWorkspaceFile = new Path(wsPathText.getText());
422             //Trim file name from path
423
IPath containerPath = pathToWorkspaceFile.removeLastSegments(1);
424             
425             IResource container =ResourcesPlugin.getWorkspace().getRoot().findMember(containerPath);
426             if (container == null) {
427                 if (selectedLocation == WORKSPACE)
428                     setErrorMessage(CVSUIMessages.GenerateDiffFileWizard_4);
429                 return false;
430             }
431             
432             return true;
433         }
434         
435         /**
436          * Answers a full path to a file system file or <code>null</code> if the user
437          * selected to save the patch in the clipboard.
438          */

439         public File JavaDoc getFile() {
440             if (pageValid && selectedLocation == FILESYSTEM) {
441                 return new File JavaDoc(fsPathText.getText().trim());
442             }
443             if (pageValid && selectedLocation == WORKSPACE) {
444                 final String JavaDoc filename= wsPathText.getText().trim();
445                 IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
446                 final IFile file= root.getFile(new Path(filename));
447                 return file.getLocation().toFile();
448             }
449             return null;
450         }
451         
452         /**
453          * Answers the workspace string entered in the dialog or <code>null</code> if the user
454          * selected to save the patch in the clipboard or file system.
455          */

456         public String JavaDoc getWorkspaceLocation() {
457            
458             if (pageValid && selectedLocation == WORKSPACE) {
459                 final String JavaDoc filename= wsPathText.getText().trim();
460                 return filename;
461             }
462             return null;
463         }
464         
465         /**
466          * Get the selected workspace resource if the patch is to be saved in the
467          * workspace, or null otherwise.
468          */

469         public IResource getResource() {
470             if (pageValid && selectedLocation == WORKSPACE) {
471                 IPath pathToWorkspaceFile = new Path(wsPathText.getText().trim());
472                 //Trim file name from path
473
IPath containerPath = pathToWorkspaceFile.removeLastSegments(1);
474                 return ResourcesPlugin.getWorkspace().getRoot().findMember(containerPath);
475             }
476             return null;
477         }
478         
479         /**
480          * Allow the user to chose to save the patch to the workspace or outside
481          * of the workspace.
482          */

483         public void createControl(Composite parent) {
484             
485             final Composite composite= new Composite(parent, SWT.NULL);
486             composite.setLayout(new GridLayout());
487             setControl(composite);
488             initializeDialogUnits(composite);
489             
490             // set F1 help
491
PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IHelpContextIds.PATCH_SELECTION_PAGE);
492             
493             //Create a location group
494
Group locationGroup = new Group(composite, SWT.None);
495             GridLayout layout = new GridLayout();
496             locationGroup.setLayout(layout);
497             GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
498             locationGroup.setLayoutData(data);
499             locationGroup.setText(CVSUIMessages.GenerateDiffFileWizard_9);
500             //
501
setupClipboardControls(locationGroup);
502             setupFilesystemControls(locationGroup);
503             setupWorkspaceControls(locationGroup);
504             
505             initializeDefaultValues();
506             
507             fParticipant = new CreatePatchWizardParticipant(new ResourceScope(((GenerateDiffFileWizard)this.getWizard()).resources), (GenerateDiffFileWizard) this.getWizard());
508             try {
509                 getAllOutOfSync();
510             } catch (CVSException e) {}
511                
512             final PixelConverter converter= new PixelConverter(parent);
513             createChangesArea(composite, converter);
514
515             createSelectionButtons(composite);
516            
517             Dialog.applyDialogFont(parent);
518      
519             /**
520              * Ensure the page is in a valid state.
521              */

522             /*if (!validatePage()) {
523                 store.storeRadioSelection(CLIPBOARD);
524                 initializeDefaultValues();
525                 validatePage();
526             }
527             pageValid= true;*/

528             validatePage();
529             
530             updateEnablements();
531             setupListeners();
532         }
533         
534         
535         private void createSelectionButtons(Composite composite) {
536             final Composite buttonGroup = new Composite(composite,SWT.NONE);
537             GridLayout layout = new GridLayout();
538             layout.numColumns = 2;
539             layout.marginWidth = 0;
540             layout.marginHeight = 0;
541             layout.horizontalSpacing = 0;
542             layout.verticalSpacing = 0;
543             buttonGroup.setLayout(layout);
544             GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END
545                     | GridData.VERTICAL_ALIGN_CENTER);
546             buttonGroup.setLayoutData(data);
547             
548             chgSelectAll = createSelectionButton(CVSUIMessages.GenerateDiffFileWizard_SelectAll, buttonGroup);
549             chgDeselectAll = createSelectionButton(CVSUIMessages.GenerateDiffFileWizard_DeselectAll, buttonGroup);
550         }
551
552         private Button createSelectionButton(String JavaDoc buttonName, Composite buttonGroup) {
553             Button button = new Button(buttonGroup,SWT.PUSH);
554             button.setText(buttonName);
555             GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
556             int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
557             Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
558             data.widthHint = Math.max(widthHint, minSize.x);
559             button.setLayoutData(data);
560             return button;
561         }
562
563         /**
564          * Setup the controls for the workspace option.
565          */

566         private void setupWorkspaceControls(Composite composite) {
567             GridLayout layout;
568             
569             wsRadio= new Button(composite, SWT.RADIO);
570             wsRadio.setText(CVSUIMessages.Save_In_Workspace_7);
571             
572             final Composite nameGroup = new Composite(composite,SWT.NONE);
573             layout = new GridLayout();
574             layout.numColumns = 2;
575             layout.marginWidth = 0;
576             nameGroup.setLayout(layout);
577             final GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
578             nameGroup.setLayoutData(data);
579             
580             wsPathText= new Text(nameGroup, SWT.BORDER);
581             GridData gd= new GridData(GridData.FILL_HORIZONTAL);
582             gd.verticalAlignment = GridData.CENTER;
583             gd.grabExcessVerticalSpace = false;
584             gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
585             wsPathText.setLayoutData(gd);
586             wsPathText.setEditable(false);
587             
588             wsBrowseButton = new Button(nameGroup, SWT.NULL);
589             gd = new GridData();
590             gd.horizontalAlignment = GridData.FILL;
591             int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
592             gd.widthHint = Math.max(widthHint, wsBrowseButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
593             wsBrowseButton.setLayoutData(gd);
594             wsBrowseButton.setText(CVSUIMessages.Browse____4);
595         }
596         
597         /**
598          * Setup the controls for the file system option.
599          */

600         private void setupFilesystemControls(final Composite composite) {
601             GridLayout layout;
602             fsRadio= new Button(composite, SWT.RADIO);
603
604             fsRadio.setText(CVSUIMessages.Save_In_File_System_3);
605             
606             final Composite nameGroup = new Composite(composite,SWT.NONE);
607             layout = new GridLayout();
608             layout.numColumns = 2;
609             layout.marginWidth = 0;
610             nameGroup.setLayout(layout);
611             final GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
612             nameGroup.setLayoutData(data);
613             
614             fsPathText= new Text(nameGroup, SWT.BORDER);
615             GridData gd= new GridData(GridData.FILL_HORIZONTAL);
616             gd.verticalAlignment = GridData.CENTER;
617             gd.grabExcessVerticalSpace = false;
618             gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
619             fsPathText.setLayoutData(gd);
620             
621             fsBrowseButton = new Button(nameGroup, SWT.NULL);
622             gd = new GridData();
623             gd.horizontalAlignment = GridData.FILL;
624             int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
625             gd.widthHint = Math.max(widthHint, fsBrowseButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
626             fsBrowseButton.setLayoutData(gd);
627             fsBrowseButton.setText(CVSUIMessages.Browse____4);
628         }
629         
630         /**
631          * Setup the controls for the clipboard option.
632          */

633         private void setupClipboardControls(final Composite composite) {
634             cpRadio= new Button(composite, SWT.RADIO);
635             cpRadio.setText(CVSUIMessages.Save_To_Clipboard_2);
636         }
637         
638         private ParticipantPagePane fPagePane;
639         private PageBook bottomChild;
640         private ISynchronizePageConfiguration fConfiguration;
641         
642         private void createChangesArea(Composite parent, PixelConverter converter) {
643             
644             int size = fParticipant.getSyncInfoSet().size();
645             if (size > getFileDisplayThreshold()) {
646                 // Create a page book to allow eventual inclusion of changes
647
bottomChild = new PageBook(parent, SWT.NONE);
648                 bottomChild.setLayoutData(SWTUtils.createGridData(SWT.DEFAULT, SWT.DEFAULT, SWT.FILL, SWT.FILL, true, false));
649                 // Create composite for showing the reason for not showing the changes and a button to show them
650
Composite changeDesc = new Composite(bottomChild, SWT.NONE);
651                 changeDesc.setLayout(SWTUtils.createGridLayout(1, converter, SWTUtils.MARGINS_NONE));
652                 SWTUtils.createLabel(changeDesc, NLS.bind(CVSUIMessages.CommitWizardCommitPage_1, new String JavaDoc[] { Integer.toString(size), Integer.toString(getFileDisplayThreshold()) }));
653                 Button showChanges = new Button(changeDesc, SWT.PUSH);
654                 showChanges.setText(CVSUIMessages.CommitWizardCommitPage_5);
655                 showChanges.addSelectionListener(new SelectionAdapter() {
656                     public void widgetSelected(SelectionEvent e) {
657                         showChangesPane();
658                     }
659                 });
660                 showChanges.setLayoutData(new GridData());
661                 bottomChild.showPage(changeDesc);
662             } else {
663                 final Composite composite= new Composite(parent, SWT.NONE);
664                 composite.setLayout(SWTUtils.createGridLayout(1, converter, SWTUtils.MARGINS_NONE));
665                 composite.setLayoutData(SWTUtils.createGridData(SWT.DEFAULT, SWT.DEFAULT, SWT.FILL, SWT.FILL, true, true));
666                 
667                 createPlaceholder(composite);
668                
669                 Control c = createChangesPage(composite, fParticipant);
670                 c.setLayoutData(SWTUtils.createHVFillGridData());
671             }
672         }
673         
674         protected void showChangesPane() {
675             Control c = createChangesPage(bottomChild, fParticipant);
676             bottomChild.setLayoutData(SWTUtils.createGridData(SWT.DEFAULT, SWT.DEFAULT, SWT.FILL, SWT.FILL, true, true));
677             bottomChild.showPage(c);
678             Dialog.applyDialogFont(getControl());
679             ((Composite)getControl()).layout();
680         }
681
682         private Control createChangesPage(final Composite composite, WorkspaceSynchronizeParticipant participant) {
683             fConfiguration= participant.createPageConfiguration();
684             fPagePane= new ParticipantPagePane(getShell(), true /* modal */, fConfiguration, participant);
685             Control control = fPagePane.createPartControl(composite);
686             return control;
687         }
688         
689         public void dispose() {
690             if (fPagePane != null)
691                 fPagePane.dispose();
692             super.dispose();
693         }
694
695         private int getFileDisplayThreshold() {
696             return CVSUIPlugin.getPlugin().getPreferenceStore().getInt(ICVSUIConstants.PREF_COMMIT_FILES_DISPLAY_THRESHOLD);
697         }
698         
699          private void createPlaceholder(final Composite composite) {
700                 final Composite placeholder= new Composite(composite, SWT.NONE);
701                 placeholder.setLayoutData(new GridData(SWT.DEFAULT, convertHorizontalDLUsToPixels(IDialogConstants.VERTICAL_SPACING) /3));
702          }
703         /**
704          * Initialize the controls with the saved default values which are
705          * obtained from the DefaultValuesStore.
706          */

707         private void initializeDefaultValues() {
708
709             selectedLocation= store.getLocationSelection();
710             
711             updateRadioButtons();
712             
713             /**
714              * Text fields.
715              */

716             fsPathText.setText(store.getFilesystemPath());
717             //We need to ensure that we have a valid workspace path - user
718
//could have altered workspace since last time this was saved
719
wsPathText.setText(store.getWorkspacePath());
720             if(!validateWorkspaceLocation()) {
721                 wsPathText.setText(""); //$NON-NLS-1$
722

723                 //Don't open wizard with an error - instead change selection
724
//to clipboard
725
if (selectedLocation == WORKSPACE){
726                     //clear the error message caused by the workspace not having
727
//any workspace path entered
728
setErrorMessage(null);
729                     selectedLocation=CLIPBOARD;
730                     updateRadioButtons();
731                 }
732             }
733         }
734
735         private void updateRadioButtons() {
736             /**
737              * Radio buttons
738              */

739             cpRadio.setSelection(selectedLocation == CLIPBOARD);
740             fsRadio.setSelection(selectedLocation == FILESYSTEM);
741             wsRadio.setSelection(selectedLocation == WORKSPACE);
742         }
743         
744         /**
745          * Setup all the listeners for the controls.
746          */

747         private void setupListeners() {
748
749             cpRadio.addListener(SWT.Selection, new Listener() {
750                 public void handleEvent(Event event) {
751                     selectedLocation= CLIPBOARD;
752                     validatePage();
753                     updateEnablements();
754                 }
755             });
756             fsRadio.addListener(SWT.Selection, new Listener() {
757                 public void handleEvent(Event event) {
758                     selectedLocation= FILESYSTEM;
759                     validatePage();
760                     updateEnablements();
761                 }
762             });
763             
764             wsRadio.addListener(SWT.Selection, new Listener() {
765                 public void handleEvent(Event event) {
766                     selectedLocation= WORKSPACE;
767                     validatePage();
768                     updateEnablements();
769                 }
770             });
771             
772             fsPathText.addModifyListener(new ModifyListener() {
773                 public void modifyText(ModifyEvent e) {
774                     validatePage();
775                 }
776             });
777             
778             fsBrowseButton.addListener(SWT.Selection, new Listener() {
779                 public void handleEvent(Event event) {
780                     final FileDialog dialog = new FileDialog(getShell(), SWT.PRIMARY_MODAL | SWT.SAVE);
781                     if (pageValid) {
782                         final File JavaDoc file= new File JavaDoc(fsPathText.getText());
783                         dialog.setFilterPath(file.getParent());
784                     }
785                     dialog.setText(CVSUIMessages.Save_Patch_As_5);
786                     dialog.setFileName(CVSUIMessages.patch_txt_6);
787                     final String JavaDoc path = dialog.open();
788                     fsBrowsed = true;
789                     if (path != null) {
790                         fsPathText.setText(new Path(path).toOSString());
791                     }
792                     validatePage();
793                 }
794             });
795             
796            
797             
798             wsBrowseButton.addListener(SWT.Selection, new Listener() {
799                 public void handleEvent(Event event) {
800                     final WorkspaceDialog dialog = new WorkspaceDialog(getShell());
801                     wsBrowsed = true;
802                     dialog.open();
803                     validatePage();
804                 }
805             });
806             
807             
808             chgSelectAll.addSelectionListener(new SelectionAdapter() {
809                 public void widgetSelected(SelectionEvent e) {
810                     initCheckedItems();
811                     //Only bother changing isPageComplete state if the current state
812
//is not enabled
813
if (!isPageComplete())
814                         setPageComplete((getSelectedResources()).length > 0);
815                 }
816             });
817             
818             chgDeselectAll.addSelectionListener(new SelectionAdapter() {
819                 public void widgetSelected(SelectionEvent e) {
820                     ISynchronizePage page = fConfiguration.getPage();
821                     if (page != null){
822                         Viewer viewer = page.getViewer();
823                         if (viewer instanceof CheckboxTreeViewer) {
824                             CheckboxTreeViewer treeViewer =(CheckboxTreeViewer)viewer;
825                             treeViewer.setCheckedElements(new Object JavaDoc[0]);
826                         }
827                     }
828                     //Only bother changing isPageComplete state if the current state
829
//is enabled
830
if (isPageComplete())
831                         setPageComplete((getSelectedResources()).length > 0);
832                 }
833             });
834             
835             ISynchronizePage page = fConfiguration.getPage();
836             if (page != null) {
837                 Viewer viewer = page.getViewer();
838                 if (viewer instanceof CheckboxTreeViewer) {
839                     ((CheckboxTreeViewer)viewer).addCheckStateListener(new ICheckStateListener() {
840                         public void checkStateChanged(CheckStateChangedEvent event) {
841                             setPageComplete((resources = getSelectedResources()).length > 0);
842                         }
843                     });
844                 }
845             }
846         }
847
848         protected void initCheckedItems() {
849             ISynchronizePage page = fConfiguration.getPage();
850             if (page != null) {
851                 Viewer viewer = page.getViewer();
852                 if (viewer instanceof CheckboxTreeViewer) {
853                     TreeItem[] items=((CheckboxTreeViewer)viewer).getTree().getItems();
854                     for (int i = 0; i < items.length; i++) {
855                         ((CheckboxTreeViewer)viewer).setChecked(items[i].getData(), true);
856                     }
857                 }
858             }
859         }
860
861         protected IResource[] getSelectedResources() {
862             ISynchronizePage page = fConfiguration.getPage();
863             if (page != null) {
864                 Viewer viewer = page.getViewer();
865                 if (viewer instanceof CheckboxTreeViewer) {
866                     Object JavaDoc[] elements = ((CheckboxTreeViewer)viewer).getCheckedElements();
867                     IResource[]selectedResources = Utils.getResources(elements);
868                     ArrayList result = new ArrayList();
869                     for (int i = 0; i < selectedResources.length; i++) {
870                         IResource resource = selectedResources[i];
871                         if (fConfiguration.getSyncInfoSet().getSyncInfo(resource) != null) {
872                             result.add(resource);
873                         }
874                     }
875                     return (IResource[]) result.toArray(new IResource[result.size()]);
876                 }
877             }
878             return new IResource[0];
879         }
880         
881         /**
882          * Enable and disable controls based on the selected radio button.
883          */

884         public void updateEnablements() {
885             //clear any error message
886
setErrorMessage(null);
887             fsBrowseButton.setEnabled(selectedLocation == FILESYSTEM);
888             fsPathText.setEnabled(selectedLocation == FILESYSTEM);
889             if (selectedLocation == FILESYSTEM)
890                 fsBrowsed=false;
891             wsPathText.setEnabled(selectedLocation == WORKSPACE);
892             wsBrowseButton.setEnabled(selectedLocation == WORKSPACE);
893             if (selectedLocation == WORKSPACE)
894                 wsBrowsed=false;
895         }
896         
897         public int getSelectedLocation() {
898             return selectedLocation;
899         }
900         
901         private SyncInfoSet getAllOutOfSync() throws CVSException {
902             final SubscriberSyncInfoCollector syncInfoCollector = fParticipant.getSubscriberSyncInfoCollector();
903             //WaitForChangesJob waits for the syncInfoCollector to get all the changes
904
//before checking off the tree items and validating the page
905
class WaitForChangesJob extends Job{
906                 LocationPage fLocationPage;
907                 
908                  public WaitForChangesJob(LocationPage page) {
909                      super(""); //$NON-NLS-1$
910
fLocationPage=page;
911                   }
912                   public IStatus run(IProgressMonitor monitor) {
913                       monitor.beginTask(CVSUIMessages.CommitWizard_4, IProgressMonitor.UNKNOWN);
914                       syncInfoCollector.waitForCollector(monitor);
915                       Utils.syncExec(new Runnable JavaDoc() {
916                             public void run() {
917                                 fLocationPage.initCheckedItems();
918                                 fLocationPage.canValidate=true;
919                                 fLocationPage.validatePage();
920                             }
921                       }, getControl());
922                       monitor.done();
923                      return Status.OK_STATUS;
924                   }
925             }
926             WaitForChangesJob job =new WaitForChangesJob(this);
927             //Don't need the job in the UI, make it a system job
928
job.setSystem(true);
929             job.schedule();
930             return fParticipant.getSyncInfoSet();
931         }
932
933         public boolean hasBinaryFiles() {
934             try {
935                 final boolean[] found = new boolean[] { false };
936                 fParticipant.getSubscriber().accept(resources, IResource.DEPTH_INFINITE, new IDiffVisitor() {
937                     public boolean visit(IDiff diff) {
938                         if (isBinaryFile(diff))
939                             found[0] = true;
940                         return true;
941                     }
942                 });
943                 return found[0];
944             } catch (CoreException e) {
945                 CVSUIPlugin.log(e);
946             }
947             return false;
948         }
949
950         protected boolean isBinaryFile(IDiff diff) {
951             IFile file = getFile(diff);
952             if (file != null) {
953                 ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor(file);
954                 try {
955                     byte[] bytes = cvsFile.getSyncBytes();
956                     if (bytes != null) {
957                         return ResourceSyncInfo.getKeywordMode(bytes).toMode().equals(
958                                 Command.KSUBST_BINARY.toMode());
959                     }
960                 } catch (CVSException e) {
961                     CVSUIPlugin.log(e);
962                 }
963                 return (Team.getFileContentManager().getType(file) == Team.BINARY);
964             }
965             return false;
966         }
967         
968         protected IFile getFile(IDiff diff) {
969             IResource resource = ResourceDiffTree.getResourceFor(diff);
970             if (resource instanceof IFile) {
971                 IFile file = (IFile) resource;
972                 return file;
973             }
974             return null;
975         }
976
977         public void removeBinaryFiles() {
978             try {
979                 final List JavaDoc nonBinaryFiles = new ArrayList();
980                 fParticipant.getSubscriber().accept(resources, IResource.DEPTH_INFINITE, new IDiffVisitor() {
981                     public boolean visit(IDiff diff) {
982                         if (!isBinaryFile(diff)) {
983                             IFile file = getFile(diff);
984                             if (file != null)
985                                 nonBinaryFiles.add(file);
986                         }
987                         return true;
988                     }
989                 });
990                 resources = (IResource[]) nonBinaryFiles
991                         .toArray(new IResource[nonBinaryFiles.size()]);
992             } catch (CoreException e) {
993                 CVSUIPlugin.log(e);
994             }
995         }
996      
997     }
998         
999     /**
1000     * Page to select the options for creating the patch.
1001     *
1002     * @param pageName the name of the page
1003     * @param title the title for this wizard page,
1004     * or <code>null</code> if none
1005     * @param titleImage the image descriptor for the title of this wizard page,
1006     * or <code>null</code> if none
1007     * @param store the value store where the page stores it's data
1008     */

1009    private class OptionsPage extends WizardPage {
1010       
1011        /**
1012        * The possible file format to save a patch.
1013        */

1014        public final static int FORMAT_UNIFIED = 1;
1015        public final static int FORMAT_CONTEXT = 2;
1016        public final static int FORMAT_STANDARD = 3;
1017
1018        /**
1019        The possible root of the patch
1020        */

1021        public final static int ROOT_WORKSPACE = 1;
1022        public final static int ROOT_PROJECT = 2;
1023        public final static int ROOT_SELECTION = 3;
1024        
1025        private Button unifiedDiffOption;
1026        private Button unified_workspaceRelativeOption; //multi-patch format
1027
private Button unified_projectRelativeOption; //full project path
1028
private Button unified_selectionRelativeOption; //use path of whatever is selected
1029
private Button contextDiffOption;
1030        private Button regularDiffOption;
1031        private final RadioButtonGroup diffTypeRadioGroup = new RadioButtonGroup();
1032        private final RadioButtonGroup unifiedRadioGroup = new RadioButtonGroup();
1033
1034        private boolean patchHasCommonRoot=true;
1035        protected IPath patchRoot=ResourcesPlugin.getWorkspace().getRoot().getFullPath();
1036        
1037        private final DefaultValuesStore store;
1038        
1039        /**
1040         * Constructor for PatchFileCreationOptionsPage.
1041         */

1042        protected OptionsPage(String JavaDoc pageName, String JavaDoc title, ImageDescriptor titleImage, DefaultValuesStore store) {
1043            super(pageName, title, titleImage);
1044            this.store = store;
1045        }
1046        
1047        /*
1048         * @see IDialogPage#createControl(Composite)
1049         */

1050        public void createControl(Composite parent) {
1051            Composite composite= new Composite(parent, SWT.NULL);
1052            GridLayout layout= new GridLayout();
1053            composite.setLayout(layout);
1054            composite.setLayoutData(new GridData());
1055            setControl(composite);
1056            
1057            // set F1 help
1058
PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IHelpContextIds.PATCH_OPTIONS_PAGE);
1059                        
1060            Group diffTypeGroup = new Group(composite, SWT.NONE);
1061            layout = new GridLayout();
1062            layout.marginHeight = 0;
1063            diffTypeGroup.setLayout(layout);
1064            GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
1065            diffTypeGroup.setLayoutData(data);
1066            diffTypeGroup.setText(CVSUIMessages.Diff_output_format_12);
1067            
1068
1069            unifiedDiffOption = new Button(diffTypeGroup, SWT.RADIO);
1070            unifiedDiffOption.setText(CVSUIMessages.Unified__format_required_by_Compare_With_Patch_feature__13);
1071            
1072            contextDiffOption = new Button(diffTypeGroup, SWT.RADIO);
1073            contextDiffOption.setText(CVSUIMessages.Context_14);
1074            regularDiffOption = new Button(diffTypeGroup, SWT.RADIO);
1075            regularDiffOption.setText(CVSUIMessages.Standard_15);
1076            
1077            diffTypeRadioGroup.add(FORMAT_UNIFIED, unifiedDiffOption);
1078            diffTypeRadioGroup.add(FORMAT_CONTEXT, contextDiffOption);
1079            diffTypeRadioGroup.add(FORMAT_STANDARD, regularDiffOption);
1080            
1081            //Unified Format Options
1082
Group unifiedGroup = new Group(composite, SWT.None);
1083            layout = new GridLayout();
1084            unifiedGroup.setLayout(layout);
1085            data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
1086            unifiedGroup.setLayoutData(data);
1087            unifiedGroup.setText(CVSUIMessages.GenerateDiffFileWizard_10);
1088            
1089            unified_workspaceRelativeOption = new Button(unifiedGroup, SWT.RADIO);
1090            unified_workspaceRelativeOption.setText(CVSUIMessages.GenerateDiffFileWizard_6);
1091            unified_workspaceRelativeOption.setSelection(true);
1092            
1093            unified_projectRelativeOption = new Button(unifiedGroup, SWT.RADIO);
1094            unified_projectRelativeOption.setText(CVSUIMessages.GenerateDiffFileWizard_7);
1095            
1096            unified_selectionRelativeOption = new Button(unifiedGroup, SWT.RADIO);
1097            unified_selectionRelativeOption.setText(CVSUIMessages.GenerateDiffFileWizard_8);
1098            
1099            unifiedRadioGroup.add(ROOT_WORKSPACE, unified_workspaceRelativeOption);
1100            unifiedRadioGroup.add(ROOT_PROJECT, unified_projectRelativeOption);
1101            unifiedRadioGroup.add(ROOT_SELECTION, unified_selectionRelativeOption);
1102            
1103            Dialog.applyDialogFont(parent);
1104            
1105            initializeDefaultValues();
1106            
1107            //add listeners
1108
unifiedDiffOption.addSelectionListener(new SelectionAdapter() {
1109                public void widgetSelected(SelectionEvent e) {
1110                    setEnableUnifiedGroup(true);
1111                    updateEnablements();
1112                    diffTypeRadioGroup.setSelection(FORMAT_UNIFIED, false);
1113                }
1114            });
1115            
1116            contextDiffOption.addSelectionListener(new SelectionAdapter() {
1117                public void widgetSelected(SelectionEvent e) {
1118                    setEnableUnifiedGroup(false);
1119                    updateEnablements();
1120                    diffTypeRadioGroup.setSelection(FORMAT_CONTEXT, false);
1121                }
1122            });
1123            
1124            regularDiffOption.addSelectionListener(new SelectionAdapter() {
1125                public void widgetSelected(SelectionEvent e) {
1126                    setEnableUnifiedGroup(false);
1127                    updateEnablements();
1128                    diffTypeRadioGroup.setSelection(FORMAT_STANDARD, false);
1129                }
1130            });
1131            
1132            unified_workspaceRelativeOption
1133                    .addSelectionListener(new SelectionAdapter() {
1134                        public void widgetSelected(SelectionEvent e) {
1135                            unifiedRadioGroup.setSelection(ROOT_WORKSPACE, false);
1136                        }
1137                    });
1138
1139            unified_projectRelativeOption
1140                    .addSelectionListener(new SelectionAdapter() {
1141                        public void widgetSelected(SelectionEvent e) {
1142                            unifiedRadioGroup.setSelection(ROOT_PROJECT, false);
1143                        }
1144                    });
1145
1146            unified_selectionRelativeOption
1147                    .addSelectionListener(new SelectionAdapter() {
1148                        public void widgetSelected(SelectionEvent e) {
1149                            unifiedRadioGroup.setSelection(ROOT_SELECTION, false);
1150                        }
1151                    });
1152                
1153           calculatePatchRoot();
1154           updateEnablements();
1155            
1156            // update selection
1157
diffTypeRadioGroup.selectEnabledOnly();
1158            unifiedRadioGroup.selectEnabledOnly();
1159        }
1160        
1161        public int getFormatSelection() {
1162            return diffTypeRadioGroup.getSelected();
1163        }
1164
1165        public int getRootSelection() {
1166            return unifiedRadioGroup.getSelected();
1167        }
1168
1169        private void initializeDefaultValues() {
1170            // Radio buttons for format
1171
diffTypeRadioGroup.setSelection(store.getFormatSelection(), true);
1172            // Radio buttons for patch root
1173
unifiedRadioGroup.setSelection(store.getRootSelection(), true);
1174            
1175            if (store.getFormatSelection() != FORMAT_UNIFIED) {
1176                setEnableUnifiedGroup(false);
1177            }
1178        }
1179
1180        
1181        protected void updateEnablements() {
1182            if (!patchHasCommonRoot){
1183                diffTypeRadioGroup.setEnablement(false, new int[] {
1184                        FORMAT_CONTEXT, FORMAT_STANDARD }, FORMAT_UNIFIED);
1185                unifiedRadioGroup.setEnablement(false, new int[] {
1186                        ROOT_PROJECT, ROOT_SELECTION }, ROOT_WORKSPACE);
1187            }
1188            
1189            // temporary until we figure out best way to fix synchronize view
1190
// selection
1191
if (!unifiedSelectionEnabled)
1192                unifiedRadioGroup.setEnablement(false, new int[] {ROOT_SELECTION});
1193        }
1194
1195        private void calculatePatchRoot(){
1196            //check to see if this is a multi select patch, if so disable
1197
IResource[] tempResources = ((GenerateDiffFileWizard)this.getWizard()).resources;
1198            
1199            //Guard for quick cancellation to avoid ArrayOutOfBounds (see Bug# 117234)
1200
if (tempResources == null)
1201                return;
1202            
1203            if (tempResources.length > 1){
1204                //Check to see is the selected resources are contained by the same parent (climbing
1205
//parent by parent to the project root)
1206
//If so, then allow selection relative patches -> set the relative path to the common
1207
//parent [also allow project relative patches]
1208
//If parents are different projects, allow only multiproject selection
1209

1210                patchHasCommonRoot=true;
1211                int segmentMatch=-1;
1212                IPath path = tempResources[0].getFullPath().removeLastSegments(1);
1213                for (int i = 1; i < tempResources.length; i++) {
1214                    int segments=path.matchingFirstSegments(tempResources[i].getFullPath());
1215                    //Keep track of the lowest number of matches that were found - the common
1216
//path will be this number
1217
if (segmentMatch == -1 ||
1218                        segmentMatch>segments){
1219                        segmentMatch=segments;
1220                    }
1221                    //However, if no segments for any one resource - break out of the loop
1222
if (segments == 0){
1223                        patchHasCommonRoot=false;
1224                        break;
1225                    }
1226                }
1227                if (patchHasCommonRoot){
1228                    IPath tempPath = path.uptoSegment(segmentMatch);
1229                    /*IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
1230                    while (!root.exists(tempPath) &&
1231                            !tempPath.isRoot()){
1232                        tempPath = tempPath.removeLastSegments(1);
1233                    }*/

1234                    patchRoot=tempPath;
1235                }
1236            } else {
1237                IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
1238            
1239                //take the file name off the path and use that as the patch root
1240
//patchRoot = tempResources[0].getFullPath().removeLastSegments(1);
1241
IPath fullPath = tempResources[0].getFullPath();
1242                IResource resource = root.findMember(fullPath);
1243                
1244                //keep trimming the path until we find something that can be used as the
1245
//patch root
1246
while (resource == null &&
1247                       !(resource instanceof IWorkspaceRoot)){
1248                    fullPath=fullPath.removeLastSegments(1);
1249                    resource=root.findMember(fullPath);
1250                }
1251                patchRoot = resource.getFullPath();
1252                if (resource.getType() == IResource.FILE)
1253                    patchRoot =resource.getFullPath().removeLastSegments(1);
1254            }
1255        }
1256        /**
1257         * Return the list of Diff command options configured on this page.
1258         */

1259        public LocalOption[] getOptions() {
1260            List JavaDoc options = new ArrayList(5);
1261          /* if(includeNewFilesOptions.getSelection()) {
1262                options.add(Diff.INCLUDE_NEWFILES);
1263            }
1264            if(!recurseOption.getSelection()) {
1265                options.add(Command.DO_NOT_RECURSE);
1266            }*/

1267            
1268            //Add new files for now
1269
options.add(Diff.INCLUDE_NEWFILES);
1270            
1271            if(unifiedDiffOption.getSelection()) {
1272                options.add(Diff.UNIFIED_FORMAT);
1273            } else if(contextDiffOption.getSelection()) {
1274                options.add(Diff.CONTEXT_FORMAT);
1275            }
1276            
1277            return (LocalOption[]) options.toArray(new LocalOption[options.size()]);
1278        }
1279        protected void setEnableUnifiedGroup(boolean enabled){
1280            unifiedRadioGroup.setEnablement(enabled, new int[] {
1281                    ROOT_WORKSPACE, ROOT_PROJECT, ROOT_SELECTION });
1282            
1283            //temporary until we figure out best way to fix synchronize view selection
1284
if (!unifiedSelectionEnabled)
1285                unifiedRadioGroup.setEnablement(false, new int[] {ROOT_SELECTION});
1286        }
1287    }
1288 
1289    /**
1290     * Class to retrieve and store the default selected values.
1291     */

1292    private final class DefaultValuesStore {
1293        
1294        private static final String JavaDoc PREF_LAST_SELECTION= "org.eclipse.team.internal.ccvs.ui.wizards.GenerateDiffFileWizard.PatchFileSelectionPage.lastselection"; //$NON-NLS-1$
1295
private static final String JavaDoc PREF_LAST_FS_PATH= "org.eclipse.team.internal.ccvs.ui.wizards.GenerateDiffFileWizard.PatchFileSelectionPage.filesystem.path"; //$NON-NLS-1$
1296
private static final String JavaDoc PREF_LAST_WS_PATH= "org.eclipse.team.internal.ccvs.ui.wizards.GenerateDiffFileWizard.PatchFileSelectionPage.workspace.path"; //$NON-NLS-1$
1297
private static final String JavaDoc PREF_LAST_AO_FORMAT = "org.eclipse.team.internal.ccvs.ui.wizards.GenerateDiffFileWizard.OptionsPage.diff.format"; //$NON-NLS-1$
1298
private static final String JavaDoc PREF_LAST_AO_ROOT = "org.eclipse.team.internal.ccvs.ui.wizards.GenerateDiffFileWizard.OptionsPage.patch.root"; //$NON-NLS-1$
1299

1300        
1301        private final IDialogSettings dialogSettings;
1302        
1303        public DefaultValuesStore() {
1304            dialogSettings= CVSUIPlugin.getPlugin().getDialogSettings();
1305        }
1306        
1307        public int getLocationSelection() {
1308            int value= LocationPage.CLIPBOARD;
1309            try {
1310                value= dialogSettings.getInt(PREF_LAST_SELECTION);
1311            } catch (NumberFormatException JavaDoc e) {
1312            }
1313            
1314            switch (value) {
1315            case LocationPage.FILESYSTEM:
1316            case LocationPage.WORKSPACE:
1317            case LocationPage.CLIPBOARD:
1318                return value;
1319            default:
1320                return LocationPage.CLIPBOARD;
1321            }
1322        }
1323        
1324        public String JavaDoc getFilesystemPath() {
1325            final String JavaDoc path= dialogSettings.get(PREF_LAST_FS_PATH);
1326            return path != null ? path : ""; //$NON-NLS-1$
1327
}
1328        
1329        public String JavaDoc getWorkspacePath() {
1330            final String JavaDoc path= dialogSettings.get(PREF_LAST_WS_PATH);
1331            return path != null ? path : ""; //$NON-NLS-1$
1332
}
1333        
1334
1335        public int getFormatSelection() {
1336            int value = OptionsPage.FORMAT_UNIFIED;
1337            try {
1338                value = dialogSettings.getInt(PREF_LAST_AO_FORMAT);
1339            } catch (NumberFormatException JavaDoc e) {
1340            }
1341
1342            switch (value) {
1343            case OptionsPage.FORMAT_UNIFIED:
1344            case OptionsPage.FORMAT_CONTEXT:
1345            case OptionsPage.FORMAT_STANDARD:
1346                return value;
1347            default:
1348                return OptionsPage.FORMAT_UNIFIED;
1349            }
1350        }
1351
1352        public int getRootSelection() {
1353            int value = OptionsPage.ROOT_WORKSPACE;
1354            try {
1355                value = dialogSettings.getInt(PREF_LAST_AO_ROOT);
1356            } catch (NumberFormatException JavaDoc e) {
1357            }
1358
1359            switch (value) {
1360            case OptionsPage.ROOT_WORKSPACE:
1361            case OptionsPage.ROOT_PROJECT:
1362            case OptionsPage.ROOT_SELECTION:
1363                return value;
1364            default:
1365                return OptionsPage.ROOT_WORKSPACE;
1366            }
1367        }
1368            
1369        public void storeLocationSelection(int defaultSelection) {
1370            dialogSettings.put(PREF_LAST_SELECTION, defaultSelection);
1371        }
1372        
1373        public void storeFilesystemPath(String JavaDoc path) {
1374            dialogSettings.put(PREF_LAST_FS_PATH, path);
1375        }
1376        
1377        public void storeWorkspacePath(String JavaDoc path) {
1378            dialogSettings.put(PREF_LAST_WS_PATH, path);
1379        }
1380        
1381        public void storeOutputFormat(int selection) {
1382            dialogSettings.put(PREF_LAST_AO_FORMAT, selection);
1383        }
1384
1385        public void storePatchRoot(int selection) {
1386            dialogSettings.put(PREF_LAST_AO_ROOT, selection);
1387        }
1388    }
1389    
1390    private LocationPage locationPage;
1391    private OptionsPage optionsPage;
1392    
1393    protected IResource[] resources;
1394    private final DefaultValuesStore defaultValuesStore;
1395    private final IWorkbenchPart part;
1396  
1397    //temporary until we figure out best way to fix synchronize view selection
1398
protected boolean unifiedSelectionEnabled;
1399    
1400    public GenerateDiffFileWizard(IWorkbenchPart part, IResource[] resources, boolean unifiedSelectionEnabled) {
1401        super();
1402        this.part = part;
1403        this.resources = resources;
1404        setWindowTitle(CVSUIMessages.GenerateCVSDiff_title);
1405        initializeDefaultPageImageDescriptor();
1406        defaultValuesStore= new DefaultValuesStore();
1407        this.unifiedSelectionEnabled=unifiedSelectionEnabled;
1408    }
1409    
1410    public void addPages() {
1411        String JavaDoc pageTitle = CVSUIMessages.GenerateCVSDiff_pageTitle;
1412        String JavaDoc pageDescription = CVSUIMessages.GenerateCVSDiff_pageDescription;
1413        locationPage = new LocationPage(pageTitle, pageTitle, CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_WIZBAN_DIFF), defaultValuesStore);
1414        locationPage.setDescription(pageDescription);
1415        addPage(locationPage);
1416        
1417        pageTitle = CVSUIMessages.Advanced_options_19;
1418        pageDescription = CVSUIMessages.Configure_the_options_used_for_the_CVS_diff_command_20;
1419        optionsPage = new OptionsPage(pageTitle, pageTitle, CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_WIZBAN_DIFF), defaultValuesStore);
1420        optionsPage.setDescription(pageDescription);
1421        addPage(optionsPage);
1422    }
1423    
1424    /**
1425     * Declares the wizard banner iamge descriptor
1426     */

1427    protected void initializeDefaultPageImageDescriptor() {
1428        final String JavaDoc iconPath= "icons/full/"; //$NON-NLS-1$
1429
try {
1430            final URL JavaDoc installURL = CVSUIPlugin.getPlugin().getBundle().getEntry("/"); //$NON-NLS-1$
1431
final URL JavaDoc url = new URL JavaDoc(installURL, iconPath + "wizards/newconnect_wiz.gif"); //$NON-NLS-1$
1432
ImageDescriptor desc = ImageDescriptor.createFromURL(url);
1433            setDefaultPageImageDescriptor(desc);
1434        } catch (MalformedURLException JavaDoc e) {
1435            // Should not happen. Ignore.
1436
}
1437    }
1438    
1439    /* (Non-javadoc)
1440     * Method declared on IWizard.
1441     */

1442    public boolean needsProgressMonitor() {
1443        return true;
1444    }
1445    
1446    /**
1447     * Completes processing of the wizard. If this method returns <code>
1448     * true</code>, the wizard will close; otherwise, it will stay active.
1449     */

1450    public boolean performFinish() {
1451        
1452        final int location= locationPage.getSelectedLocation();
1453
1454        final File JavaDoc file= location != LocationPage.CLIPBOARD? locationPage.getFile() : null;
1455        
1456        if (!(file == null || validateFile(file))) {
1457            return false;
1458        }
1459    
1460        //Is this a multi-patch?
1461
boolean multiPatch=false;
1462        if (optionsPage.unifiedDiffOption.getSelection() && optionsPage.unified_workspaceRelativeOption.getSelection())
1463            multiPatch=true;
1464        
1465       
1466        //If not a multipatch, patch should use project relative or selection relative paths[default]?
1467
boolean useProjectRelativePaths=false;
1468        if (optionsPage.unifiedDiffOption.getSelection() &&
1469            optionsPage.unified_projectRelativeOption.getSelection())
1470            useProjectRelativePaths=true;
1471        
1472        // TODO: Check for binary files
1473
if (locationPage.hasBinaryFiles()) {
1474            int result = promptToIncludeBinary();
1475            if (result == 2)
1476                return false;
1477            if (result == 1)
1478                locationPage.removeBinaryFiles();
1479        }
1480        
1481        /**
1482         * Perform diff operation.
1483         */

1484        try {
1485         if (file != null) {
1486            generateDiffToFile(file,multiPatch,useProjectRelativePaths);
1487         } else {
1488            generateDiffToClipboard(multiPatch,useProjectRelativePaths);
1489         }
1490        } catch (TeamException e) {}
1491        
1492        /**
1493         * Refresh workspace if necessary and save default selection.
1494         */

1495        switch (location) {
1496        
1497        case LocationPage.WORKSPACE:
1498            final String JavaDoc workspaceResource= locationPage.getWorkspaceLocation();
1499            if (workspaceResource != null){
1500                defaultValuesStore.storeLocationSelection(LocationPage.WORKSPACE);
1501                defaultValuesStore.storeWorkspacePath(workspaceResource);
1502               /* try {
1503                    workspaceResource.getParent().refreshLocal(IResource.DEPTH_ONE, null);
1504                } catch(CoreException e) {
1505                    CVSUIPlugin.openError(getShell(), CVSUIMessages.GenerateCVSDiff_error, null, e);
1506                    return false;
1507                } */

1508            } else {
1509                //Problem with workspace location, open with clipboard next time
1510
defaultValuesStore.storeLocationSelection(LocationPage.CLIPBOARD);
1511            }
1512            break;
1513            
1514        case LocationPage.FILESYSTEM:
1515            defaultValuesStore.storeFilesystemPath(file.getPath());
1516            defaultValuesStore.storeLocationSelection(LocationPage.FILESYSTEM);
1517            break;
1518            
1519        case LocationPage.CLIPBOARD:
1520            defaultValuesStore.storeLocationSelection(LocationPage.CLIPBOARD);
1521            break;
1522            
1523        default:
1524            return false;
1525        }
1526        
1527
1528        /**
1529         * Save default selections of Options Page
1530         */

1531
1532        defaultValuesStore.storeOutputFormat(optionsPage.getFormatSelection());
1533        defaultValuesStore.storePatchRoot(optionsPage.getRootSelection());
1534
1535        return true;
1536    }
1537    
1538    private int promptToIncludeBinary() {
1539        MessageDialog dialog = new MessageDialog(getShell(), CVSUIMessages.GenerateDiffFileWizard_11, null, // accept
1540
// the
1541
// default
1542
// window
1543
// icon
1544
CVSUIMessages.GenerateDiffFileWizard_12, MessageDialog.QUESTION, new String JavaDoc[] { IDialogConstants.YES_LABEL,
1545                        IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL }, 1); // no is the default
1546
return dialog.open();
1547    }
1548    
1549    private void generateDiffToClipboard(boolean multiPatch, boolean useProjectRelativePaths) throws TeamException {
1550        DiffOperation diffop = new ClipboardDiffOperation(part,RepositoryProviderOperation.asResourceMappers(resources),optionsPage.getOptions(),multiPatch, useProjectRelativePaths, optionsPage.patchRoot);
1551        try {
1552            diffop.run();
1553        } catch (InvocationTargetException JavaDoc e) {}
1554          catch (InterruptedException JavaDoc e) {}
1555    }
1556
1557    private void generateDiffToFile(File JavaDoc file, boolean multiPatch, boolean useProjectRelativePaths) throws TeamException {
1558        DiffOperation diffop = null;
1559        if (locationPage.selectedLocation == LocationPage.WORKSPACE){
1560            diffop = new WorkspaceFileDiffOperation(part,RepositoryProviderOperation.asResourceMappers(resources),optionsPage.getOptions(),file, multiPatch, useProjectRelativePaths, optionsPage.patchRoot);
1561        }
1562        else {
1563            diffop = new FileDiffOperation(part,RepositoryProviderOperation.asResourceMappers(resources),optionsPage.getOptions(),file, multiPatch, useProjectRelativePaths, optionsPage.patchRoot);
1564        }
1565        
1566        try {
1567            diffop.run();
1568        } catch (InvocationTargetException JavaDoc e) {}
1569          catch (InterruptedException JavaDoc e) {}
1570    }
1571
1572    public boolean validateFile(File JavaDoc file) {
1573        
1574        if (file == null)
1575            return false;
1576        
1577        /**
1578         * Consider file valid if it doesn't exist for now.
1579         */

1580        if (!file.exists())
1581            return true;
1582        
1583        /**
1584         * The file exists.
1585         */

1586        if (!file.canWrite()) {
1587            final String JavaDoc title= CVSUIMessages.GenerateCVSDiff_1;
1588            final String JavaDoc msg= CVSUIMessages.GenerateCVSDiff_2;
1589            final MessageDialog dialog= new MessageDialog(getShell(), title, null, msg, MessageDialog.ERROR, new String JavaDoc[] { IDialogConstants.OK_LABEL }, 0);
1590            dialog.open();
1591            return false;
1592        }
1593        
1594        final String JavaDoc title = CVSUIMessages.GenerateCVSDiff_overwriteTitle;
1595        final String JavaDoc msg = CVSUIMessages.GenerateCVSDiff_overwriteMsg;
1596        final MessageDialog dialog = new MessageDialog(getShell(), title, null, msg, MessageDialog.QUESTION, new String JavaDoc[] { IDialogConstants.YES_LABEL, IDialogConstants.CANCEL_LABEL }, 0);
1597        dialog.open();
1598        if (dialog.getReturnCode() != 0)
1599            return false;
1600        
1601        return true;
1602    }
1603
1604    public LocationPage getLocationPage() {
1605        return locationPage;
1606    }
1607    
1608    /**
1609     * The class maintain proper selection of radio button within the group:
1610     * <ul>
1611     * <li>Only one button can be selected at the time.</li>
1612     * <li>Disabled button can't be selected unless all buttons in the group
1613     * are disabled.</li>
1614     * </ul>
1615     */

1616    /*private*/ class RadioButtonGroup {
1617
1618        /**
1619         * List of buttons in the group. Both radio groups contain 3 elements.
1620         */

1621        private List JavaDoc buttons = new ArrayList(3);
1622
1623        /**
1624         * Index of the selected button.
1625         */

1626        private int selected = 0;
1627
1628        /**
1629         * Add a button to the group. While adding a new button the method
1630         * checks if there is only one button selected in the group.
1631         *
1632         * @param buttonCode
1633         * A button's code (eg. <code>ROOT_WORKSPACE</code>). To get
1634         * an index we need to subtract 1 from it.
1635         * @param button
1636         * A button to add.
1637         */

1638        public void add(int buttonCode, Button button) {
1639            if (button != null && (button.getStyle() & SWT.RADIO) != 0) {
1640                if (button.getSelection() && !buttons.isEmpty()) {
1641                    deselectAll();
1642                    selected = buttonCode - 1;
1643                }
1644                buttons.add(buttonCode - 1, button);
1645            }
1646        }
1647
1648        /**
1649         * Returns selected button's code.
1650         *
1651         * @return Selected button's code.
1652         */

1653        public int getSelected() {
1654            return selected + 1;
1655        }
1656
1657        /**
1658         * Set selection to the given button. When
1659         * <code>selectEnabledOnly</code> flag is true the returned value can
1660         * differ from the parameter when a button we want to set selection to
1661         * is disabled and there are other buttons which are enabled.
1662         *
1663         * @param buttonCode
1664         * A button's code (eg. <code>ROOT_WORKSPACE</code>). To get
1665         * an index we need to subtract 1 from it.
1666         * @return Code of the button to which selection was finally set.
1667         */

1668        public int setSelection(int buttonCode, boolean selectEnabledOnly) {
1669            deselectAll();
1670
1671            ((Button) buttons.get(buttonCode - 1)).setSelection(true);
1672            selected = buttonCode - 1;
1673            if (selectEnabledOnly)
1674                selected = selectEnabledOnly() - 1;
1675            return getSelected();
1676        }
1677
1678        /**
1679         * Make sure that only an enabled radio button is selected.
1680         *
1681         * @return A code of the selected button.
1682         */

1683        public int selectEnabledOnly() {
1684            deselectAll();
1685
1686            Button selectedButton = (Button) buttons.get(selected);
1687            if (!selectedButton.isEnabled()) {
1688                // if the button is disabled, set selection to an enabled one
1689
for (Iterator iterator = buttons.iterator(); iterator.hasNext();) {
1690                    Button b = (Button) iterator.next();
1691                    if (b.isEnabled()) {
1692                        b.setSelection(true);
1693                        selected = buttons.indexOf(b);
1694                        return selected + 1;
1695                    }
1696                }
1697                // if none found, reset the initial selection
1698
selectedButton.setSelection(true);
1699            } else {
1700                // because selection has been cleared, set it again
1701
selectedButton.setSelection(true);
1702            }
1703            // return selected button's code so the value can be stored
1704
return getSelected();
1705        }
1706
1707        /**
1708         * Enable or disable given buttons.
1709         *
1710         * @param enabled
1711         * Indicates whether to enable or disable the buttons.
1712         * @param buttonsToChange
1713         * Buttons to enable/disable.
1714         * @param defaultSelection
1715         * The button to select if the currently selected button
1716         * becomes disabled.
1717         */

1718        public void setEnablement(boolean enabled, int[] buttonsToChange,
1719                int defaultSelection) {
1720
1721            // enable (or disable) given buttons
1722
for (int i = 0; i < buttonsToChange.length; i++) {
1723                ((Button) this.buttons.get(buttonsToChange[i] - 1))
1724                        .setEnabled(enabled);
1725            }
1726            // check whether the selected button is enabled
1727
if (!((Button) this.buttons.get(selected)).isEnabled()) {
1728                if (defaultSelection != -1)
1729                    // set the default selection and check if it's enabled
1730
setSelection(defaultSelection, true);
1731                else
1732                    // no default selection is given, select any enabled button
1733
selectEnabledOnly();
1734            }
1735        }
1736
1737        /**
1738         * Enable or disable given buttons with no default selection. The selection
1739         * will be set to an enabled button using the <code>selectEnabledOnly</code> method.
1740         *
1741         * @param enabled Indicates whether to enable or disable the buttons.
1742         * @param buttonsToChange Buttons to enable/disable.
1743         */

1744        public void setEnablement(boolean enabled, int[] buttonsToChange) {
1745            // -1 means that no default selection is given
1746
setEnablement(enabled, buttonsToChange, -1);
1747        }
1748
1749        /**
1750         * Deselect all buttons in the group.
1751         */

1752        private void deselectAll() {
1753            // clear all selections
1754
for (Iterator iterator = buttons.iterator(); iterator.hasNext();)
1755                ((Button) iterator.next()).setSelection(false);
1756        }
1757    }
1758        
1759}
1760
Popular Tags