Java tutorial
/******************************************************************************* * Copyright (c) 2003, 2006 Subclipse project and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Subclipse project committers - initial API and implementation ******************************************************************************/ package org.tigris.subversion.subclipse.ui.wizards.generatediff; import java.io.File; import java.io.IOException; import java.util.HashMap; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import org.tigris.subversion.subclipse.ui.IHelpContextIds; import org.tigris.subversion.subclipse.ui.ISVNUIConstants; import org.tigris.subversion.subclipse.ui.Policy; import org.tigris.subversion.subclipse.ui.SVNUIPlugin; import org.tigris.subversion.subclipse.ui.util.ResourceSelectionTree; import org.tigris.subversion.subclipse.ui.util.WorkspaceDialog; /** * Page to select a patch file. Overriding validatePage was necessary to allow * entering a file name that already exists. */ class PatchFileSelectionPage extends WizardPage { private Text filenameCombo; private Button browseButton; private Button saveInFilesystem; private Button saveInWorkspace; private Button saveToClipboard; private ResourceSelectionTree resourceSelectionTree; private IResource[] resources; protected Text wsPathText; private Button wsBrowseButton; private boolean wsBrowsed = false; private HashMap statusMap; public final int CLIPBOARD = 1; public final int FILESYSTEM = 2; public final int WORKSPACE = 3; public PatchFileSelectionPage(String pageName, String title, ImageDescriptor image, IStructuredSelection selection, HashMap statusMap) { super(pageName, title, image); this.statusMap = statusMap; Object[] selectedResources = selection.toArray(); resources = new IResource[selectedResources.length]; for (int i = 0; i < selectedResources.length; i++) resources[i] = (IResource) selectedResources[i]; setPageComplete(false); } /** * Allow the user to finish if a valid file has been entered. */ protected boolean validatePage() { boolean valid = false; switch (getSaveType()) { case WORKSPACE: valid = validateWorkspaceLocation(); break; case FILESYSTEM: File file = new File(getFilesystemFile()); valid = isValidFile(file); break; case CLIPBOARD: valid = true; break; } // Avoid draw flicker by clearing error message // if all is valid. if (valid) { setMessage(null); setErrorMessage(null); } else { setErrorMessage(Policy.bind("GenerateSVNDiff.EnterFilename")); //$NON-NLS-1$ } setPageComplete(valid && getSelectedResources().length > 0); return valid; } private boolean isValidFile(File file) { if (!file.isAbsolute()) return false; if (file.isDirectory()) return false; File parent = file.getParentFile(); if (parent == null) return false; if (!parent.exists()) return false; if (!parent.isDirectory()) return false; if (!file.exists()) { try { if (!file.createNewFile()) { return false; } file.delete(); } catch (IOException e) { return false; } } return true; } /** * Answers a full path to a file system file or <code>null</code> if the user * selected to save the patch in the workspace. */ public String getFilesystemFile() { if (saveInFilesystem.getSelection()) { return filenameCombo.getText(); } return null; } /** * Answers a workspace file or <code>null</code> if the user selected to save * the patch outside of the workspace. */ public IFile getWorkspaceFile() { if (saveInWorkspace.getSelection() && wsPathText.getText().length() > 0) { return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(wsPathText.getText())); } return null; } /** * Allow the user to chose to save the patch to the workspace or outside * of the workspace. */ public void createControl(Composite parent) { Composite composite = new Composite(parent, SWT.NULL); GridLayout layout = new GridLayout(); composite.setLayout(layout); composite.setLayoutData(new GridData()); setControl(composite); initializeDialogUnits(composite); // set F1 help PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IHelpContextIds.PATCH_SELECTION_PAGE); // Clipboard saveToClipboard = new Button(composite, SWT.RADIO); saveToClipboard.setText(Policy.bind("GenerateSVNDiff.SaveToClipboard")); //$NON-NLS-1$ saveToClipboard.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { validatePage(); updateEnablements(); } }); // File System saveInFilesystem = new Button(composite, SWT.RADIO); saveInFilesystem.setText(Policy.bind("GenerateSVNDiff.SaveInFileSystem")); //$NON-NLS-1$ saveInFilesystem.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { validatePage(); updateEnablements(); } }); Composite nameGroup = new Composite(composite, SWT.NONE); layout = new GridLayout(); layout.numColumns = 2; layout.marginWidth = 0; nameGroup.setLayout(layout); GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); nameGroup.setLayoutData(data); filenameCombo = new Text(nameGroup, SWT.BORDER); GridData gd = new GridData(GridData.FILL_HORIZONTAL); filenameCombo.setLayoutData(gd); filenameCombo.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { setPageComplete(validatePage()); } }); FocusListener focusListener = new FocusAdapter() { public void focusGained(FocusEvent e) { ((Text) e.getSource()).selectAll(); } public void focusLost(FocusEvent e) { ((Text) e.getSource()).setText(((Text) e.getSource()).getText()); } }; filenameCombo.addFocusListener(focusListener); browseButton = new Button(nameGroup, SWT.NULL); browseButton.setText(Policy.bind("GenerateSVNDiff.Browse")); //$NON-NLS-1$ data = new GridData(GridData.HORIZONTAL_ALIGN_END); data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); browseButton.setLayoutData(data); browseButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { FileDialog d = new FileDialog(getShell(), SWT.PRIMARY_MODAL | SWT.SAVE); d.setText(Policy.bind("GenerateSVNDiff.SavePatchAs")); //$NON-NLS-1$ d.setFileName(Policy.bind("GenerateSVNDiff.patchTxt")); //$NON-NLS-1$ String file = d.open(); if (file != null) { IPath path = new Path(file); setFilesystemFilename(path.toOSString()); } } }); // Workspace saveInWorkspace = new Button(composite, SWT.RADIO); saveInWorkspace.setText(Policy.bind("GenerateSVNDiff.SaveInWorkspace")); //$NON-NLS-1$ saveInWorkspace.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { validatePage(); updateEnablements(); } }); final Composite pathGroup = new Composite(composite, SWT.NONE); layout = new GridLayout(); layout.numColumns = 2; layout.marginWidth = 0; pathGroup.setLayout(layout); data = new GridData(SWT.FILL, SWT.FILL, true, false); pathGroup.setLayoutData(data); wsPathText = new Text(pathGroup, SWT.BORDER); gd = new GridData(GridData.FILL_HORIZONTAL); gd.verticalAlignment = GridData.CENTER; gd.grabExcessVerticalSpace = false; gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; wsPathText.setLayoutData(gd); wsPathText.setEditable(false); wsBrowseButton = new Button(pathGroup, SWT.NULL); gd = new GridData(); gd.horizontalAlignment = GridData.FILL; int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); gd.widthHint = Math.max(widthHint, wsBrowseButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x); wsBrowseButton.setLayoutData(gd); wsBrowseButton.setText(Policy.bind("GenerateSVNDiff.Browse")); //$NON-NLS-1$ wsBrowseButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { final WorkspaceDialog dialog = new WorkspaceDialog(getShell(), Policy.bind("GenerateSVNDiff.workspaceDialogTitle"), //$NON-NLS-1$ Policy.bind("GenerateSVNDiff.workspaceDialogMessage"), SVNUIPlugin.getPlugin().getImageDescriptor(ISVNUIConstants.IMG_WIZBAN_DIFF), wsPathText); wsBrowsed = true; dialog.open(); validatePage(); } }); resourceSelectionTree = new ResourceSelectionTree(composite, SWT.NONE, Policy.bind("GenerateSVNDiff.Changes"), ResourceSelectionTree.dedupeResources(resources), statusMap, //$NON-NLS-1$ null, true, null, null); ((CheckboxTreeViewer) resourceSelectionTree.getTreeViewer()).setAllChecked(true); resourceSelectionTree.getTreeViewer().addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { validatePage(); } }); saveToClipboard.setSelection(true); validatePage(); updateEnablements(); } /** * Sets the file name in the file system text. */ protected void setFilesystemFilename(String filename) { filenameCombo.setText(filename); } public IResource[] getSelectedResources() { return resourceSelectionTree.getSelectedResources(); } /** * Enable and disable controls based on the selected radio button. */ protected void updateEnablements() { int type = getSaveType(); browseButton.setEnabled(type == FILESYSTEM); filenameCombo.setEnabled(type == FILESYSTEM); wsPathText.setEnabled(type == WORKSPACE); wsBrowseButton.setEnabled(type == WORKSPACE); if (type == WORKSPACE) wsBrowsed = false; } /** * Answers the type of the patch file destination. */ public int getSaveType() { if (saveInFilesystem.getSelection()) { return FILESYSTEM; } else if (saveToClipboard.getSelection()) { return CLIPBOARD; } else { return WORKSPACE; } } /** * The following conditions must hold for the file system location to be valid: * - a parent must be selected in the workspace tree view * - the resource name must be valid */ private boolean validateWorkspaceLocation() { int type = getSaveType(); //make sure that the field actually has a filename in it - making //sure that the user has had a chance to browse the workspace first if (wsPathText.getText().equals("")) { //$NON-NLS-1$ if (type == WORKSPACE && wsBrowsed) setErrorMessage(Policy.bind("GenerateSVNDiff.validFileName")); //$NON-NLS-1$ return false; } //Make sure that all the segments but the last one (i.e. project + all //folders) exist - file doesn't have to exist. It may have happened that //some folder refactoring has been done since this path was last saved. // //Assume that the path will always be in format project/{folders}*/file - this //is controlled by the workspace location dialog IPath pathToWorkspaceFile = new Path(wsPathText.getText()); //Trim file name from path IPath containerPath = pathToWorkspaceFile.removeLastSegments(1); IResource container = ResourcesPlugin.getWorkspace().getRoot().findMember(containerPath); if (container == null) { if (type == WORKSPACE) setErrorMessage(Policy.bind("GenerateSVNDiff.validFileName")); //$NON-NLS-1$ return false; } return true; } }