summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorTomasz Zarna2012-02-17 10:06:57 (EST)
committer Matthias Sohn2012-02-17 10:06:57 (EST)
commit7205115b9a2280ab366c75a03d0348245a4243a7 (patch)
treedecdf4943c03ae34bfda9d8cfa70446224e11780
parentc5cd6e4b637cf9b904458177db2a08e0ddbe66ce (diff)
downloadegit-7205115b9a2280ab366c75a03d0348245a4243a7.zip
egit-7205115b9a2280ab366c75a03d0348245a4243a7.tar.gz
egit-7205115b9a2280ab366c75a03d0348245a4243a7.tar.bz2
Allow to save patches in the workspacerefs/changes/71/4971/8
CQ: 6030 Bug: 368774 Change-Id: Ib3f78eceaea6f9ca3f916622d836b1d39613fd08 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Chris Aniszczyk <zx@twitter.com>
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java45
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java249
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/LocationPage.java632
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties15
4 files changed, 733 insertions, 208 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
index 140c7fc..f76248f 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
@@ -3037,6 +3037,51 @@ public class UIText extends NLS {
public static String GitCreatePatchWizard_LinesOfContext;
/** */
+ public static String GitCreatePatchWizard_ReadOnlyTitle;
+
+ /** */
+ public static String GitCreatePatchWizard_ReadOnlyMsg;
+
+ /** */
+ public static String GitCreatePatchWizard_OverwriteTitle;
+
+ /** */
+ public static String GitCreatePatchWizard_OverwriteMsg;
+
+ /** */
+ public static String GitCreatePatchWizard_Workspace;
+
+ /** */
+ public static String GitCreatePatchWizard_WorkspacePatchDialogTitle;
+
+ /** */
+ public static String GitCreatePatchWizard_WorkspacePatchDialogDescription;
+
+ /** */
+ public static String GitCreatePatchWizard_WorkspacePatchDialogEnterFileName;
+
+ /** */
+ public static String GitCreatePatchWizard_WorkspacePatchDialogEnterValidLocation;
+
+ /** */
+ public static String GitCreatePatchWizard_WorkspacePatchDialogFileName;
+
+ /** */
+ public static String GitCreatePatchWizard_WorkspacePatchDialogSavePatch;
+
+ /** */
+ public static String GitCreatePatchWizard_WorkspacePatchEnterValidFileName;
+
+ /** */
+ public static String GitCreatePatchWizard_WorkspacePatchFolderExists;
+
+ /** */
+ public static String GitCreatePatchWizard_WorkspacePatchProjectClosed;
+
+ /** */
+ public static String GitCreatePatchWizard_WorkspacePatchSelectByBrowsing;
+
+ /** */
public static String GitCreateProjectViaWizardWizard_AbortedMessage;
/** */
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java
index bbf7f48..10edd0b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java
@@ -9,6 +9,7 @@
* Contributors:
* Stefan Lay (SAP AG) - initial implementation
* Daniel Megert <daniel_megert@ch.ibm.com> - Create Patch... dialog should not set file location - http://bugs.eclipse.org/361405
+ * Tomasz Zarna <Tomasz.Zarna@pl.ibm.com> - Allow to save patches in Workspace
*******************************************************************************/
package org.eclipse.egit.ui.internal.history;
@@ -20,9 +21,7 @@ import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.Path;
import org.eclipse.egit.core.op.CreatePatchOperation;
import org.eclipse.egit.core.op.CreatePatchOperation.DiffHeaderFormat;
import org.eclipse.egit.ui.Activator;
@@ -31,6 +30,7 @@ import org.eclipse.egit.ui.UIText;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
@@ -52,15 +52,10 @@ import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.graphics.Point;
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.Label;
-import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
@@ -148,8 +143,11 @@ public class GitCreatePatchWizard extends Wizard {
operation.setHeaderFormat(optionsPage.getSelectedHeaderFormat());
operation.setContextLines(Integer.parseInt(optionsPage.contextLines.getText()));
- final boolean isFile = locationPage.fsRadio.getSelection();
- final String fileName = locationPage.fsPathText.getText();
+ final File file = !locationPage.fsRadio.getSelection() ? locationPage
+ .getFile() : null;
+
+ if (!(file == null || validateFile(file)))
+ return false;
try {
getContainer().run(true, true, new IRunnableWithProgress() {
@@ -159,11 +157,10 @@ public class GitCreatePatchWizard extends Wizard {
operation.execute(monitor);
String content = operation.getPatchContent();
- if (isFile) {
- writeToFile(fileName, content);
- } else {
+ if (file != null)
+ writeToFile(file, content);
+ else
copyToClipboard(content);
- }
} catch (IOException e) {
throw new InvocationTargetException(e);
} catch (CoreException e) {
@@ -196,9 +193,9 @@ public class GitCreatePatchWizard extends Wizard {
});
}
- private void writeToFile(final String fileName, String content)
+ private void writeToFile(final File file, String content)
throws IOException {
- Writer output = new BufferedWriter(new FileWriter(fileName));
+ Writer output = new BufferedWriter(new FileWriter(file));
try {
// FileWriter always assumes default encoding is
// OK!
@@ -208,202 +205,31 @@ public class GitCreatePatchWizard extends Wizard {
}
}
- /**
- * A wizard page to choose the target location
- */
- public class LocationPage extends WizardPage {
-
- private static final String PATH_KEY = "GitCreatePatchWizard.LocationPage.path"; //$NON-NLS-1$
-
- private Button cpRadio;
-
- private Button fsRadio;
-
- private Text fsPathText;
-
- private Button fsBrowseButton;
-
- private boolean pageValid;
-
- /**
- * @param pageName
- * @param title
- * @param titleImage
- */
- protected LocationPage(String pageName, String title,
- ImageDescriptor titleImage) {
- super(pageName, title, titleImage);
- }
-
- public void createControl(Composite parent) {
- final Composite composite = new Composite(parent, SWT.NULL);
- GridLayout gridLayout = new GridLayout();
- gridLayout.numColumns = 3;
- composite.setLayout(gridLayout);
- composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- initializeDialogUnits(composite);
-
- // clipboard
- GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
- gd.horizontalSpan = 3;
- cpRadio = new Button(composite, SWT.RADIO);
- cpRadio.setText(UIText.GitCreatePatchWizard_Clipboard);
- cpRadio.setLayoutData(gd);
- cpRadio.setSelection(true);
-
- // filesystem
- fsRadio = new Button(composite, SWT.RADIO);
- fsRadio.setText(UIText.GitCreatePatchWizard_File);
- fsRadio.setSelection(false);
-
- fsPathText = new Text(composite, SWT.BORDER);
- gd = new GridData(GridData.FILL_HORIZONTAL);
- fsPathText.setLayoutData(gd);
- fsPathText.setText(createFileName());
- fsPathText.setEnabled(false);
-
- fsBrowseButton = new Button(composite, SWT.PUSH);
- fsBrowseButton.setText(UIText.GitCreatePatchWizard_Browse);
- GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
- int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
- Point minSize = fsBrowseButton.computeSize(SWT.DEFAULT,
- SWT.DEFAULT, true);
- data.widthHint = Math.max(widthHint, minSize.x);
- fsBrowseButton.setLayoutData(data);
- fsBrowseButton.setEnabled(false);
-
- cpRadio.addListener(SWT.Selection, new Listener() {
- public void handleEvent(Event event) {
- // disable other input controls
- if (((Button) event.widget).getSelection()) {
- fsPathText.setEnabled(false);
- fsBrowseButton.setEnabled(false);
- validatePage();
- }
- }
- });
-
- fsRadio.addListener(SWT.Selection, new Listener() {
-
- public void handleEvent(Event event) {
- if (((Button) event.widget).getSelection()) {
- // enable filesystem input controls
- fsPathText.setEnabled(true);
- fsBrowseButton.setEnabled(true);
- // set focus to filesystem input text control
- fsPathText.setFocus();
- validatePage();
- }
- }
- });
-
- fsPathText.addModifyListener(new ModifyListener() {
-
- public void modifyText(ModifyEvent e) {
- if (validatePage()) {
- IPath filePath= Path.fromOSString(fsPathText.getText()).removeLastSegments(1);
- getDialogSettings().put(PATH_KEY, filePath.toPortableString());
- }
- }
- });
-
- fsBrowseButton.addListener(SWT.Selection, new Listener() {
- public void handleEvent(Event event) {
- final FileDialog dialog = new FileDialog(getShell(),
- SWT.PRIMARY_MODAL | SWT.SAVE);
- if (pageValid) {
- final File file = new File(fsPathText.getText());
- dialog.setFilterPath(file.getParent());
- dialog.setFileName(file.getName());
- } else {
- dialog.setFileName(""); //$NON-NLS-1$
- }
- dialog.setText(""); //$NON-NLS-1$
- final String path = dialog.open();
- if (path != null)
- fsPathText.setText(new Path(path).toOSString());
- validatePage();
- }
- });
-
- Dialog.applyDialogFont(composite);
- setControl(composite);
-
- }
-
- private String createFileName() {
- String suggestedFileName = commit != null ? CreatePatchOperation
- .suggestFileName(commit) : db.getWorkTree().getName()
- .concat(".patch"); //$NON-NLS-1$
- String path = getDialogSettings().get(PATH_KEY);
- if (path != null)
- return Path.fromPortableString(path).append(suggestedFileName).toOSString();
-
- return (new File(System.getProperty("user.dir", ""), suggestedFileName)).getPath(); //$NON-NLS-1$ //$NON-NLS-2$
- }
+ private boolean validateFile(File file) {
+ if (file == null)
+ return false;
- /**
- * Allow the user to finish if a valid file has been entered.
- *
- * @return page is valid
- */
- protected boolean validatePage() {
- if (fsRadio.getSelection()) {
- pageValid = validateFilesystemLocation();
- } else if (cpRadio.getSelection()) {
- pageValid = true;
- }
+ // Consider file valid if it doesn't exist for now.
+ if (!file.exists())
+ return true;
- /**
- * Avoid draw flicker by clearing error message if all is valid.
- */
- if (pageValid) {
- setMessage(null);
- setErrorMessage(null);
- }
- setPageComplete(pageValid);
- return pageValid;
+ // The file exists.
+ if (!file.canWrite()) {
+ final String title= UIText.GitCreatePatchWizard_ReadOnlyTitle;
+ final String msg= UIText.GitCreatePatchWizard_ReadOnlyMsg;
+ final MessageDialog dialog= new MessageDialog(getShell(), title, null, msg, MessageDialog.ERROR, new String[] { IDialogConstants.OK_LABEL }, 0);
+ dialog.open();
+ return false;
}
- /**
- * The following conditions must hold for the file system location to be
- * valid: - the path must be valid and non-empty - the path must be
- * absolute - the specified file must be of type file - the parent must
- * exist (new folders can be created via the browse button)
- *
- * @return if the location is valid
- */
- private boolean validateFilesystemLocation() {
- final String pathString = fsPathText.getText().trim();
- if (pathString.length() == 0
- || !new Path("").isValidPath(pathString)) { //$NON-NLS-1$
- setErrorMessage(UIText.GitCreatePatchWizard_FilesystemError);
- return false;
- }
-
- final File file = new File(pathString);
- if (!file.isAbsolute()) {
- setErrorMessage(UIText.GitCreatePatchWizard_FilesystemInvalidError);
- return false;
- }
-
- if (file.isDirectory()) {
- setErrorMessage(UIText.GitCreatePatchWizard_FilesystemDirectoryError);
- return false;
- }
-
- if (pathString.endsWith("/") || pathString.endsWith("\\")) { //$NON-NLS-1$//$NON-NLS-2$
- setErrorMessage(UIText.GitCreatePatchWizard_FilesystemDirectoryNotExistsError);
- return false;
- }
+ final String title = UIText.GitCreatePatchWizard_OverwriteTitle;
+ final String msg = UIText.GitCreatePatchWizard_OverwriteMsg;
+ final MessageDialog dialog = new MessageDialog(getShell(), title, null, msg, MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.CANCEL_LABEL }, 0);
+ dialog.open();
+ if (dialog.getReturnCode() != 0)
+ return false;
- final File parent = file.getParentFile();
- if (!(parent.exists() && parent.isDirectory())) {
- setErrorMessage(UIText.GitCreatePatchWizard_FilesystemDirectoryNotExistsError);
- return false;
- }
- return true;
- }
+ return true;
}
/**
@@ -496,12 +322,11 @@ public class GitCreatePatchWizard extends Wizard {
text = text.trim();
char[] charArray = text.toCharArray();
- for (char c : charArray) {
+ for (char c : charArray)
if(!Character.isDigit(c)) {
setErrorMessage(UIText.GitCreatePatchWizard_ContextMustBePositiveInt);
return false;
}
- }
return true;
}
@@ -511,4 +336,12 @@ public class GitCreatePatchWizard extends Wizard {
return (DiffHeaderFormat) selection.getFirstElement();
}
}
+
+ Repository getRepository() {
+ return db;
+ }
+
+ RevCommit getCommit() {
+ return commit;
+ }
} \ No newline at end of file
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/LocationPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/LocationPage.java
new file mode 100644
index 0000000..e8966cf
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/LocationPage.java
@@ -0,0 +1,632 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2012 SAP AG 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:
+ * Tomasz Zarna <Tomasz.Zarna@pl.ibm.com> - Allow to save patches in Workspace
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.history;
+
+import java.io.File;
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.op.CreatePatchOperation;
+import org.eclipse.egit.ui.UIIcons;
+import org.eclipse.egit.ui.UIText;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+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.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.model.BaseWorkbenchContentProvider;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.ui.views.navigator.ResourceComparator;
+
+/**
+ * A wizard page to choose the target location.
+ * <p>
+ * Extracted from {@link GitCreatePatchWizard}
+ */
+public class LocationPage extends WizardPage {
+
+ private static final String PATH_KEY = "GitCreatePatchWizard.LocationPage.path"; //$NON-NLS-1$
+
+ private Button cpRadio;
+
+ Button fsRadio;
+
+ private Text fsPathText;
+
+ private Button fsBrowseButton;
+
+ private Button wsRadio;
+
+ private Text wsPathText;
+
+ private Button wsBrowseButton;
+
+ private boolean wsBrowsed = false;
+
+ private boolean pageValid;
+
+ private IContainer wsSelectedContainer;
+
+ private class LocationPageContentProvider extends BaseWorkbenchContentProvider {
+ //Never show closed projects
+ boolean showClosedProjects = false;
+
+ public Object[] getChildren(Object element) {
+ if (element instanceof IWorkspace) {
+ // check if closed projects should be shown
+ IProject[] allProjects = ((IWorkspace) element).getRoot().getProjects();
+ if (showClosedProjects)
+ return allProjects;
+
+ ArrayList<IProject> accessibleProjects = new ArrayList<IProject>();
+ for (IProject project : allProjects) {
+ if (project.isOpen())
+ accessibleProjects.add(project);
+ }
+ return accessibleProjects.toArray();
+ }
+ return super.getChildren(element);
+ }
+ }
+
+ private class WorkspaceDialog extends TitleAreaDialog {
+
+ protected TreeViewer wsTreeViewer;
+ protected Text wsFilenameText;
+ protected Image dlgTitleImage;
+
+ private boolean modified = false;
+
+ public WorkspaceDialog(Shell shell) {
+ super(shell);
+ }
+
+ protected Control createContents(Composite parent) {
+ Control control = super.createContents(parent);
+ setTitle(UIText.GitCreatePatchWizard_WorkspacePatchDialogTitle);
+ setMessage(UIText.GitCreatePatchWizard_WorkspacePatchDialogDescription);
+ //create title image
+ dlgTitleImage = UIIcons.WIZBAN_CREATE_PATCH.createImage();
+ setTitleImage(dlgTitleImage);
+
+ return control;
+ }
+
+ protected Control createDialogArea(Composite parent){
+ Composite parentComposite = (Composite) super.createDialogArea(parent);
+
+ // create a composite with standard margins and spacing
+ Composite composite = new Composite(parentComposite, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
+ layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+ layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+ layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+ composite.setFont(parentComposite.getFont());
+
+ getShell().setText(UIText.GitCreatePatchWizard_WorkspacePatchDialogSavePatch);
+
+ wsTreeViewer = new TreeViewer(composite, SWT.BORDER);
+ final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true);
+ gd.widthHint= 550;
+ gd.heightHint= 250;
+ wsTreeViewer.getTree().setLayoutData(gd);
+
+ wsTreeViewer.setContentProvider(new LocationPageContentProvider());
+ wsTreeViewer.setComparator(new ResourceComparator(ResourceComparator.NAME));
+ wsTreeViewer.setLabelProvider(new WorkbenchLabelProvider());
+ wsTreeViewer.setInput(ResourcesPlugin.getWorkspace());
+
+ //Open to whatever is selected in the workspace field
+ IPath existingWorkspacePath = new Path(wsPathText.getText());
+ //Ensure that this workspace path is valid
+ IResource selectedResource = ResourcesPlugin.getWorkspace().getRoot().findMember(existingWorkspacePath);
+ if (selectedResource != null) {
+ wsTreeViewer.expandToLevel(selectedResource, 0);
+ wsTreeViewer.setSelection(new StructuredSelection(selectedResource));
+ }
+
+ final Composite group = new Composite(composite, SWT.NONE);
+ layout = new GridLayout(2, false);
+ layout.marginWidth = 0;
+ group.setLayout(layout);
+ group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ final Label label = new Label(group, SWT.NONE);
+ label.setLayoutData(new GridData());
+ label.setText(UIText.GitCreatePatchWizard_WorkspacePatchDialogFileName);
+
+ wsFilenameText = new Text(group,SWT.BORDER);
+ wsFilenameText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ setupListeners();
+
+ return parent;
+ }
+
+ protected Button createButton(Composite parent, int id,
+ String label, boolean defaultButton) {
+ Button button = super.createButton(parent, id, label,
+ defaultButton);
+ if (id == IDialogConstants.OK_ID) {
+ button.setEnabled(false);
+ }
+ return button;
+ }
+
+ private void validateDialog() {
+ String fileName = wsFilenameText.getText();
+
+ if (fileName.equals("")) { //$NON-NLS-1$
+ if (modified) {
+ setErrorMessage(UIText.GitCreatePatchWizard_WorkspacePatchDialogEnterFileName);
+ getButton(IDialogConstants.OK_ID).setEnabled(false);
+ return;
+ } else {
+ setErrorMessage(null);
+ getButton(IDialogConstants.OK_ID).setEnabled(false);
+ return;
+ }
+ }
+
+ // make sure that the filename is valid
+ if (!(ResourcesPlugin.getWorkspace().validateName(fileName,
+ IResource.FILE)).isOK() && modified) {
+ setErrorMessage(UIText.GitCreatePatchWizard_WorkspacePatchEnterValidFileName);
+ getButton(IDialogConstants.OK_ID).setEnabled(false);
+ return;
+ }
+
+ // Make sure that a container has been selected
+ if (getSelectedContainer() == null) {
+ setErrorMessage(UIText.GitCreatePatchWizard_WorkspacePatchDialogEnterValidLocation);
+ getButton(IDialogConstants.OK_ID).setEnabled(false);
+ return;
+ } else {
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IPath fullPath = wsSelectedContainer.getFullPath().append(
+ fileName);
+ if (workspace.getRoot().getFolder(fullPath).exists()) {
+ setErrorMessage(UIText.GitCreatePatchWizard_WorkspacePatchFolderExists);
+ getButton(IDialogConstants.OK_ID).setEnabled(false);
+ return;
+ }
+ }
+
+ setErrorMessage(null);
+ getButton(IDialogConstants.OK_ID).setEnabled(true);
+ }
+
+ protected void okPressed() {
+ IFile file = wsSelectedContainer.getFile(new Path(
+ wsFilenameText.getText()));
+ if (file != null)
+ wsPathText.setText(file.getFullPath().toString());
+
+ validatePage();
+ super.okPressed();
+ }
+
+ private IContainer getSelectedContainer() {
+ Object obj = ((IStructuredSelection)wsTreeViewer.getSelection()).getFirstElement();
+ if (obj instanceof IContainer)
+ wsSelectedContainer = (IContainer) obj;
+ else if (obj instanceof IFile)
+ wsSelectedContainer = ((IFile) obj).getParent();
+ return wsSelectedContainer;
+ }
+
+ protected void cancelPressed() {
+ validatePage();
+ super.cancelPressed();
+ }
+
+ public boolean close() {
+ if (dlgTitleImage != null)
+ dlgTitleImage.dispose();
+ return super.close();
+ }
+
+ void setupListeners(){
+ wsTreeViewer.addSelectionChangedListener(
+ new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection s = (IStructuredSelection)event.getSelection();
+ Object obj=s.getFirstElement();
+ if (obj instanceof IContainer)
+ wsSelectedContainer = (IContainer) obj;
+ else if (obj instanceof IFile){
+ IFile tempFile = (IFile) obj;
+ wsSelectedContainer = tempFile.getParent();
+ wsFilenameText.setText(tempFile.getName());
+ }
+ validateDialog();
+ }
+ });
+
+ wsTreeViewer.addDoubleClickListener(
+ new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ ISelection s= event.getSelection();
+ if (s instanceof IStructuredSelection) {
+ Object item = ((IStructuredSelection)s).getFirstElement();
+ if (wsTreeViewer.getExpandedState(item))
+ wsTreeViewer.collapseToLevel(item, 1);
+ else
+ wsTreeViewer.expandToLevel(item, 1);
+ }
+ validateDialog();
+ }
+ });
+
+ wsFilenameText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ modified = true;
+ validateDialog();
+ }
+ });
+ }
+ }
+
+ /**
+ * @param pageName
+ * @param title
+ * @param titleImage
+ */
+ protected LocationPage(String pageName, String title,
+ ImageDescriptor titleImage) {
+ super(pageName, title, titleImage);
+ }
+
+ public void createControl(Composite parent) {
+ final Composite composite = new Composite(parent, SWT.NULL);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 3;
+ composite.setLayout(gridLayout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ initializeDialogUnits(composite);
+
+ // clipboard
+ GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ gd.horizontalSpan = 3;
+ cpRadio = new Button(composite, SWT.RADIO);
+ cpRadio.setText(UIText.GitCreatePatchWizard_Clipboard);
+ cpRadio.setLayoutData(gd);
+ cpRadio.setSelection(true);
+
+ // filesystem
+ fsRadio = new Button(composite, SWT.RADIO);
+ fsRadio.setText(UIText.GitCreatePatchWizard_File);
+ fsRadio.setSelection(false);
+
+ fsPathText = new Text(composite, SWT.BORDER);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ fsPathText.setLayoutData(gd);
+ fsPathText.setText(createFileName());
+ fsPathText.setEnabled(false);
+
+ fsBrowseButton = new Button(composite, SWT.PUSH);
+ fsBrowseButton.setText(UIText.GitCreatePatchWizard_Browse);
+ GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+ int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+ Point minSize = fsBrowseButton.computeSize(SWT.DEFAULT,
+ SWT.DEFAULT, true);
+ data.widthHint = Math.max(widthHint, minSize.x);
+ fsBrowseButton.setLayoutData(data);
+ fsBrowseButton.setEnabled(false);
+
+ // workspace
+ wsRadio = new Button(composite, SWT.RADIO);
+ wsRadio.setText(UIText.GitCreatePatchWizard_Workspace);
+ wsRadio.setSelection(false);
+
+ wsPathText = new Text(composite, SWT.BORDER);
+ wsPathText.setLayoutData(gd);
+ wsPathText.setEnabled(false);
+
+ wsBrowseButton = new Button(composite, SWT.PUSH);
+ wsBrowseButton.setText(UIText.GitCreatePatchWizard_Browse);
+ wsBrowseButton.setLayoutData(data);
+ wsBrowseButton.setEnabled(false);
+
+ cpRadio.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+ // disable other input controls
+ if (((Button) event.widget).getSelection()) {
+ fsPathText.setEnabled(false);
+ fsBrowseButton.setEnabled(false);
+ wsPathText.setEnabled(false);
+ wsBrowseButton.setEnabled(false);
+ validatePage();
+ }
+ }
+ });
+
+ fsRadio.addListener(SWT.Selection, new Listener() {
+
+ public void handleEvent(Event event) {
+ if (((Button) event.widget).getSelection()) {
+ // enable filesystem input controls
+ fsPathText.setEnabled(true);
+ fsBrowseButton.setEnabled(true);
+ wsPathText.setEnabled(false);
+ wsBrowseButton.setEnabled(false);
+ // set focus to filesystem input text control
+ fsPathText.setFocus();
+ validatePage();
+ }
+ }
+ });
+
+ fsPathText.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent e) {
+ if (validatePage()) {
+ IPath filePath= Path.fromOSString(fsPathText.getText()).removeLastSegments(1);
+ getDialogSettings().put(PATH_KEY, filePath.toPortableString());
+ }
+ }
+ });
+
+ fsBrowseButton.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+ final FileDialog dialog = new FileDialog(getShell(),
+ SWT.PRIMARY_MODAL | SWT.SAVE);
+ if (pageValid) {
+ final File file = new File(fsPathText.getText());
+ dialog.setFilterPath(file.getParent());
+ dialog.setFileName(file.getName());
+ } else {
+ dialog.setFileName(""); //$NON-NLS-1$
+ }
+ dialog.setText(""); //$NON-NLS-1$
+ final String path = dialog.open();
+ if (path != null)
+ fsPathText.setText(new Path(path).toOSString());
+ validatePage();
+ }
+ });
+
+ wsRadio.addListener(SWT.Selection, new Listener() {
+
+ public void handleEvent(Event event) {
+ if (((Button) event.widget).getSelection()) {
+ fsPathText.setEnabled(false);
+ fsBrowseButton.setEnabled(false);
+ // enable workspace input controls
+ wsPathText.setEnabled(true);
+ wsBrowseButton.setEnabled(true);
+ // set focus to workspace input text control
+ wsPathText.setFocus();
+ validatePage();
+ }
+ }
+ });
+
+ wsPathText.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent e) {
+ if (validatePage()) {
+ IPath filePath= Path.fromOSString(wsPathText.getText()).removeLastSegments(1);
+ getDialogSettings().put(PATH_KEY, filePath.toPortableString());
+ }
+ }
+ });
+
+ wsBrowseButton.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+ final WorkspaceDialog dialog = new WorkspaceDialog(getShell());
+ wsBrowsed = true;
+ dialog.open();
+ validatePage();
+ }
+ });
+
+ Dialog.applyDialogFont(composite);
+ setControl(composite);
+
+ }
+
+ private String createFileName() {
+ String suggestedFileName = getCommit() != null ? CreatePatchOperation
+ .suggestFileName(getCommit()) : getRepository().getWorkTree()
+ .getName().concat(".patch"); //$NON-NLS-1$
+ String path = getDialogSettings().get(PATH_KEY);
+ if (path != null)
+ return Path.fromPortableString(path).append(suggestedFileName).toOSString();
+
+ return (new File(System.getProperty("user.dir", ""), suggestedFileName)).getPath(); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private RevCommit getCommit() {
+ return ((GitCreatePatchWizard)getWizard()).getCommit();
+ }
+
+ private Repository getRepository() {
+ return ((GitCreatePatchWizard)getWizard()).getRepository();
+ }
+
+ /**
+ * Allow the user to finish if a valid file has been entered.
+ *
+ * @return page is valid
+ */
+ protected boolean validatePage() {
+ if (wsRadio.getSelection()) {
+ pageValid = validateWorkspaceLocation();
+ }else if (fsRadio.getSelection()) {
+ pageValid = validateFilesystemLocation();
+ } else if (cpRadio.getSelection()) {
+ pageValid = true;
+ }
+
+ /**
+ * Avoid draw flicker by clearing error message if all is valid.
+ */
+ if (pageValid) {
+ setMessage(null);
+ setErrorMessage(null);
+ }
+ setPageComplete(pageValid);
+ return pageValid;
+ }
+
+ /**
+ * The following conditions must hold for the file system location to be
+ * valid:
+ * - the path must be valid and non-empty
+ * - the path must be absolute
+ * - the specified file must be of type file
+ * - the parent must exist (new folders can be created via the browse button)
+ *
+ * @return if the location is valid
+ */
+ private boolean validateFilesystemLocation() {
+ final String pathString = fsPathText.getText().trim();
+ if (pathString.length() == 0
+ || !new Path("").isValidPath(pathString)) { //$NON-NLS-1$
+ setErrorMessage(UIText.GitCreatePatchWizard_FilesystemError);
+ return false;
+ }
+
+ final File file = new File(pathString);
+ if (!file.isAbsolute()) {
+ setErrorMessage(UIText.GitCreatePatchWizard_FilesystemInvalidError);
+ return false;
+ }
+
+ if (file.isDirectory()) {
+ setErrorMessage(UIText.GitCreatePatchWizard_FilesystemDirectoryError);
+ return false;
+ }
+
+ if (pathString.endsWith("/") || pathString.endsWith("\\")) { //$NON-NLS-1$//$NON-NLS-2$
+ setErrorMessage(UIText.GitCreatePatchWizard_FilesystemDirectoryNotExistsError);
+ return false;
+ }
+
+ final File parent = file.getParentFile();
+ if (!(parent.exists() && parent.isDirectory())) {
+ setErrorMessage(UIText.GitCreatePatchWizard_FilesystemDirectoryNotExistsError);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * The following conditions must hold for the workspace location to be valid:
+ * - a parent must be selected in the workspace tree view
+ * - the resource name must be valid
+ *
+ * @return if the location is valid
+ */
+ private boolean validateWorkspaceLocation() {
+ //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 (wsRadio.getSelection() && wsBrowsed)
+ setErrorMessage(UIText.GitCreatePatchWizard_WorkspacePatchEnterValidFileName);
+ else
+ setErrorMessage(UIText.GitCreatePatchWizard_WorkspacePatchSelectByBrowsing);
+ 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.
+ //
+ // The path will always be in format project/{folders}*/file - this
+ // is controlled by the workspace location dialog and by
+ // validatePath method when path has been entered manually.
+
+ IPath pathToWorkspaceFile = new Path(wsPathText.getText());
+ IStatus status = ResourcesPlugin.getWorkspace().validatePath(wsPathText.getText(), IResource.FILE);
+ if (status.isOK()) {
+ //Trim file name from path
+ IPath containerPath = pathToWorkspaceFile.removeLastSegments(1);
+ IResource container = ResourcesPlugin.getWorkspace().getRoot().findMember(containerPath);
+ if (container == null) {
+ if (wsRadio.getSelection())
+ setErrorMessage(UIText.GitCreatePatchWizard_WorkspacePatchSelectByBrowsing);
+ return false;
+ } else if (!container.isAccessible()) {
+ if (wsRadio.getSelection())
+ setErrorMessage(UIText.GitCreatePatchWizard_WorkspacePatchProjectClosed);
+ return false;
+ } else {
+ if (ResourcesPlugin.getWorkspace().getRoot().getFolder(
+ pathToWorkspaceFile).exists()) {
+ setErrorMessage(UIText.GitCreatePatchWizard_WorkspacePatchFolderExists);
+ return false;
+ }
+ }
+ } else {
+ setErrorMessage(status.getMessage());
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @return answers a full path to a file system file or
+ * <code>null</code> if the user selected to save the patch in
+ * the clipboard.
+ */
+ public File getFile() {
+ if (pageValid && fsRadio.getSelection())
+ return new File(fsPathText.getText().trim());
+ if (pageValid && wsRadio.getSelection()) {
+ final String filename= wsPathText.getText().trim();
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ final IFile file = root.getFile(new Path(filename));
+ return file.getLocation().toFile();
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
index 4dd9fae..b789dac 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
@@ -1045,6 +1045,21 @@ GitCreatePatchWizard_FilesystemInvalidError=Please enter a valid location.
GitCreatePatchWizard_FilesystemDirectoryError=Please enter a file name.
GitCreatePatchWizard_FilesystemDirectoryNotExistsError=The specified directory does not exist.
GitCreatePatchWizard_LinesOfContext=Lines of &context:
+GitCreatePatchWizard_ReadOnlyTitle=Read-only file
+GitCreatePatchWizard_ReadOnlyMsg=The specified file is read-only and cannot be overwritten.
+GitCreatePatchWizard_OverwriteTitle=Confirm Overwrite
+GitCreatePatchWizard_OverwriteMsg=A file with that name already exists. Overwrite?
+GitCreatePatchWizard_Workspace=&Workspace
+GitCreatePatchWizard_WorkspacePatchDialogTitle=Set a Patch Location
+GitCreatePatchWizard_WorkspacePatchDialogDescription=Select a folder in the workspace and enter a name for the patch.
+GitCreatePatchWizard_WorkspacePatchDialogEnterFileName=Please enter a file name.
+GitCreatePatchWizard_WorkspacePatchDialogEnterValidLocation=Please enter a valid location.
+GitCreatePatchWizard_WorkspacePatchDialogFileName=Fi&le name:
+GitCreatePatchWizard_WorkspacePatchDialogSavePatch=Save Patch
+GitCreatePatchWizard_WorkspacePatchEnterValidFileName=Please enter a valid filename.
+GitCreatePatchWizard_WorkspacePatchFolderExists=The specified path points to an existing folder.
+GitCreatePatchWizard_WorkspacePatchProjectClosed=The specified path points to a closed project.
+GitCreatePatchWizard_WorkspacePatchSelectByBrowsing=Please select a location in the workspace by browsing.
GitCreateProjectViaWizardWizard_AbortedMessage=Action was aborted
GitCreateProjectViaWizardWizard_WizardTitle=Import Projects from Git Repository {0}
GitImportWithDirectoriesPage_PageMessage=Depending on the wizard, you may select a directory to determine the wizard's scope