### Eclipse Workspace Patch 1.0 #P org.eclipse.compare Index: compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java,v retrieving revision 1.2 diff -u -r1.2 CompareWithOtherResourceAction.java --- compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java 19 Aug 2008 07:58:04 -0000 1.2 +++ compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java 25 Aug 2008 09:10:22 -0000 @@ -10,6 +10,9 @@ *******************************************************************************/ package org.eclipse.compare.internal; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.viewers.ISelection; /** @@ -23,6 +26,8 @@ // Show CompareWithOtherResourceDialog which return resources to compare // and ancestor if specified. Don't need to display the other dialog showSelectAncestorDialog = false; + // prevent reusing old temporary files + cleanup(); super.run(selection); } @@ -32,4 +37,15 @@ return true; } + private void cleanup() { + try { + String projectName = CompareWithOtherResourceDialog.TMP_PROJECT_NAME; + IProject project = ResourcesPlugin.getWorkspace().getRoot() + .getProject(projectName); + project.delete(true, true, null); + } catch (CoreException e) { + CompareUIPlugin.log(e); + } + } + } Index: compare/org/eclipse/compare/internal/CompareMessages.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareMessages.java,v retrieving revision 1.18 diff -u -r1.18 CompareMessages.java --- compare/org/eclipse/compare/internal/CompareMessages.java 19 Aug 2008 07:58:04 -0000 1.18 +++ compare/org/eclipse/compare/internal/CompareMessages.java 25 Aug 2008 09:10:22 -0000 @@ -120,6 +120,11 @@ public static String CompareWithOther_clear; public static String CompareWithOther_warning_two_way; public static String CompareWithOther_info; + public static String CompareWithOther_externalFileButton; + public static String CompareWithOther_externalFile_errorTitle; + public static String CompareWithOther_externalFile_errorMessage; + public static String CompareWithOther_pathLabel; + public static String CompareWithOther_externalFolderBUtton; static { NLS.initializeMessages(BUNDLE_NAME, CompareMessages.class); Index: compare/org/eclipse/compare/internal/CompareWithOtherResourceDialog.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareWithOtherResourceDialog.java,v retrieving revision 1.4 diff -u -r1.4 CompareWithOtherResourceDialog.java --- compare/org/eclipse/compare/internal/CompareWithOtherResourceDialog.java 20 Aug 2008 08:47:36 -0000 1.4 +++ compare/org/eclipse/compare/internal/CompareWithOtherResourceDialog.java 25 Aug 2008 09:10:23 -0000 @@ -10,12 +10,25 @@ *******************************************************************************/ package org.eclipse.compare.internal; +import java.io.FileOutputStream; +import java.io.IOException; + import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.CompareUI; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; 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.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; @@ -36,12 +49,16 @@ import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; import org.eclipse.ui.forms.events.ExpansionAdapter; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.widgets.ExpandableComposite; @@ -55,9 +72,23 @@ public class CompareWithOtherResourceDialog extends TitleAreaDialog { private int CLEAR_RETURN_CODE = 150; // any number != 0 + private int OPEN_EXTERNAL_RETURN_CODE = 153; private int MIN_WIDTH = 300; private int MIN_HEIGHT = 175; + public static final String TMP_PROJECT_NAME = ".org.eclipse.compare.tmp"; //$NON-NLS-1$ + private final static String TMP_PROJECT_FILE = "\n" //$NON-NLS-1$ + + "\n" //$NON-NLS-1$ + + "\t" + TMP_PROJECT_NAME + "\t\n" //$NON-NLS-1$ //$NON-NLS-2$ + + "\t\n" //$NON-NLS-1$ + + "\t\n" //$NON-NLS-1$ + + "\t\n" //$NON-NLS-1$ + + "\t\n" //$NON-NLS-1$ + + "\t\n" //$NON-NLS-1$ + + "\t\n" + "\t\n" //$NON-NLS-1$//$NON-NLS-2$ + + ""; //$NON-NLS-1$ + public final static String EXTERNAL_FILES_FOLDER_NAME = "ExternalFilesFolder"; //$NON-NLS-1$ + private class FileTextDragListener implements DragSourceListener { private InternalSection section; @@ -67,15 +98,18 @@ } public void dragFinished(DragSourceEvent event) { - section.fileText.setText(""); //$NON-NLS-1$ + section.fileCombo.setText(""); //$NON-NLS-1$ } public void dragSetData(DragSourceEvent event) { - event.data = section.fileText.getText(); + if (TextTransfer.getInstance().isSupportedType(event.dataType)) { + event.data = section.fileCombo.getText(); + } else + event.data = section.fileCombo.getText(); } public void dragStart(DragSourceEvent event) { - if (section.fileText.getText() == null) + if (section.fileCombo.getText() == null) event.doit = false; } } @@ -137,12 +171,13 @@ if (textTransfer.isSupportedType(event.currentDataType)) { String txt = (String) event.data; - IResource r = ResourcesPlugin.getWorkspace().getRoot().findMember(txt); - if (r != null) - section.setResource(r); + section.setResource(ResourcesPlugin.getWorkspace().getRoot() + .findMember(txt)); + section.updateAllSectionInfo(); } else if (resourceTransfer.isSupportedType(event.currentDataType)) { IResource[] files = (IResource[]) event.data; section.setResource(files[0]); + section.updateAllSectionInfo(); } updateErrorInfo(); @@ -157,8 +192,12 @@ private abstract class InternalSection { protected Group group; - protected Text fileText; + protected Combo fileCombo; private IResource resource; + private Button openExternalFileButton, openExternalFolderButton; + private String path = ""; //$NON-NLS-1$ + private Text pathLabel; + protected Label pLabel; public InternalSection(Composite parent) { createContents(parent); @@ -169,9 +208,21 @@ } public void createContents(Composite parent) { - createGroup(parent); - createFileLabel(); - createFileCombo(); + + group = new Group(parent, SWT.NONE); + group.setLayout(new GridLayout(2, false)); + group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + Composite infoComposite = new Composite(group, SWT.NONE); + infoComposite.setLayout(new GridLayout(2, false)); + infoComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + createInfo(infoComposite); + + Composite buttonsComposite = new Composite(group, SWT.NONE); + buttonsComposite.setLayout(new GridLayout(-1, true)); + buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); + createButtons(buttonsComposite); + initDrag(); initDrop(); } @@ -182,28 +233,32 @@ public void setResource(IResource resource) { this.resource = resource; - String txt = resource.getFullPath().toString(); - fileText.setText(txt); + path = resource.getLocation().toOSString(); + pathLabel.setText(dividePath(path)); } public void setResource(String s) { IResource tmp = ResourcesPlugin.getWorkspace().getRoot() .findMember(s); - if (tmp instanceof IWorkspaceRoot) + if (tmp instanceof IWorkspaceRoot) { resource = null; - else + pathLabel.setText(""); //$NON-NLS-1$ + } + else { resource = tmp; - + path = resource.getLocation().toOSString(); + pathLabel.setText(dividePath(path)); + } } protected void clearResource() { resource = null; - fileText.setText(""); //$NON-NLS-1$ + fileCombo.setText(""); //$NON-NLS-1$ updateErrorInfo(); } protected void initDrag() { - DragSource source = new DragSource(fileText, DND.DROP_MOVE + DragSource source = new DragSource(fileCombo, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT); Transfer[] types = new Transfer[] { TextTransfer.getInstance(), ResourceTransfer.getInstance() }; @@ -212,7 +267,7 @@ } protected void initDrop() { - DropTarget target = new DropTarget(fileText, DND.DROP_MOVE + DropTarget target = new DropTarget(fileCombo, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT); Transfer[] types = new Transfer[] { TextTransfer.getInstance(), ResourceTransfer.getInstance() }; @@ -220,42 +275,224 @@ target.addDropListener(new FileTextDropListener(this)); } - protected void createGroup(Composite parent) { - group = new Group(parent, SWT.NONE); - group.setLayout(new GridLayout(3, false)); - group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + protected void createButtons(Composite parent) { + createOpenExternalFileButton(parent); + createOpenExternalFolderButton(parent); + } + + protected void createInfo(Composite parent) { + createFileLabel(parent); + createFileCombo(parent); + createPathLabel(parent); } - protected void createFileCombo() { - fileText = new Text(group, SWT.BORDER); - fileText - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + protected void createFileCombo(Composite parent) { + fileCombo = new Combo(parent, SWT.NONE); + fileCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + fileCombo.setItems(new String[] {""}); //$NON-NLS-1$ + fileCombo.setText(fileCombo.getItem(0)); - fileText.addModifyListener(new ModifyListener() { + fileCombo.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { - setResource(fileText.getText()); + setResource(fileCombo.getText()); + if (getResource() != null) { + path = resource.getLocation().toOSString(); + pathLabel.setText(dividePath(path)); + } else { + pathLabel.setText(""); //$NON-NLS-1$ + } updateErrorInfo(); } }); - fileText.addSelectionListener(new SelectionListener() { - + fileCombo.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } - public void widgetSelected(SelectionEvent e) { - setResource(fileText.getText()); + setResource(fileCombo.getText()); updateErrorInfo(); } + }); + } + protected void createOpenExternalFileButton(Composite parent) { + openExternalFileButton = createButton(parent, + OPEN_EXTERNAL_RETURN_CODE, + CompareMessages.CompareWithOther_externalFileButton, false); + openExternalFileButton.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + public void widgetSelected(SelectionEvent e) { + resource = getExtenalFile(); + updateAllSectionInfo(); + } }); } - protected void createFileLabel() { - final Label fileLabel = new Label(group, SWT.NONE); + protected void createOpenExternalFolderButton(Composite parent) { + openExternalFolderButton = createButton(parent, + OPEN_EXTERNAL_RETURN_CODE, + CompareMessages.CompareWithOther_externalFolderBUtton, false); + openExternalFolderButton.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + public void widgetSelected(SelectionEvent e) { + resource = getExternalDirectory(); + updateAllSectionInfo(); + } + }); + } + + private void updateAllSectionInfo() { + addToHistory(resource); + pathLabel.setText(dividePath(path)); + getShell().pack(); + pathLabel.getParent().layout(); + updateErrorInfo(); + } + + private void addToHistory(IResource r) { + String txt = r.getFullPath().toString(); + fileCombo.add(txt); + fileCombo.setText(txt); + } + + private IFile getExtenalFile() { + FileDialog dialog = new FileDialog(getShell()); + path = dialog.open(); + IFile f = (IFile) getIResource(new Path(path), IResource.FILE); + return f; + } + + private IFolder getExternalDirectory() { + DirectoryDialog dialog = new DirectoryDialog(getShell()); + path = dialog.open(); + IFolder f = (IFolder) getIResource(new Path(path), IResource.FOLDER); + return f; + } + + private IResource getIResource(IPath iPath, int type) { + IResource r = null; + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IWorkspaceRoot root = workspace.getRoot(); + IProject project = root.getProject(TMP_PROJECT_NAME); + String resourceName = iPath.lastSegment(); + try { + project = createTmpProject(); + if (!project.isOpen()) + project.open(null); + IFolder folderForExternal = project.getFolder(EXTERNAL_FILES_FOLDER_NAME); + if (!folderForExternal.exists()) + folderForExternal.create(IResource.NONE, true, null); + if (type == IResource.FILE) { + r = folderForExternal.getFile(resourceName); + if (!r.exists()) + ((IFile)r).createLink(iPath, IResource.REPLACE, null); + } + else { + r = folderForExternal.getFolder(resourceName); + if (!r.exists()) + ((IFolder)r).createLink(iPath, IResource.REPLACE, null); + } + } catch (CoreException e) { + CompareUIPlugin.log(e); + MessageDialog.openError(getShell(), + CompareMessages.CompareWithOther_externalFile_errorTitle, + CompareMessages.CompareWithOther_externalFile_errorMessage); + } + return r; + } + + /* + * (non-javadoc) + * + * Implementation based on org.eclipse.jdt.internakl.core.ExternalFoldersManager#createExternalFoldersProject + */ + private IProject createTmpProject() throws CoreException { + IProject tmpProject = getTmpProject(); + if (!tmpProject.isAccessible()) { + try { + if (!tmpProject.exists()) { + IProjectDescription desc = tmpProject.getWorkspace() + .newProjectDescription(tmpProject.getName()); + IPath location = CompareUI.getPlugin() + .getStateLocation(); + desc.setLocation(location.append(TMP_PROJECT_NAME)); + tmpProject.create(desc, null); + } + try { + tmpProject.open(null); + } catch (CoreException e1) { // in case .project file or folder has been deleted + IPath location1 = CompareUI.getPlugin() + .getStateLocation(); + IPath projectPath1 = location1.append(TMP_PROJECT_NAME); + projectPath1.toFile().mkdirs(); + FileOutputStream output = new FileOutputStream( + projectPath1.append(".project").toOSString()); //$NON-NLS-1$ + try { + output.write(TMP_PROJECT_FILE.getBytes()); + } finally { + output.close(); + } + tmpProject.open(null); + } + } catch (IOException ioe) { + return tmpProject; + } catch (CoreException ce) { + throw new CoreException(ce.getStatus()); + } + } + return tmpProject; + } + + /* + * (non-javadoc) + * + * Following method is analogical to org.eclipse.jdt.internal + */ + private IProject getTmpProject() { + return ResourcesPlugin.getWorkspace().getRoot().getProject( + TMP_PROJECT_NAME); + } + + protected void createFileLabel(Composite parent) { + final Label fileLabel = new Label(parent, SWT.NONE); fileLabel.setText(CompareMessages.CompareWithOther_fileLabel); } + + protected void createPathLabel(Composite parent) { + pLabel = new Label(parent, SWT.NONE); + pLabel.setText(CompareMessages.CompareWithOther_pathLabel); + pLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, true)); + pathLabel = new Text(parent, SWT.MULTI); + pathLabel.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + pathLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + } + + private String dividePath(String text) { + String[] parts; + int lineLengthLimit = computeLineLengthLimit(this); + int lineLength = 0; + String s = new String(); + String separator = new String(System.getProperty("file.separator")); //$NON-NLS-1$ + if (separator.equals("\\")) //$NON-NLS-1$ + parts = text.split("\\" + separator); //$NON-NLS-1$ + else + parts = text.split(separator); + for (int i = 0; i < parts.length; i++) { + lineLength += parts[i].length(); + if (lineLength >= lineLengthLimit) { + s += "\n"; //$NON-NLS-1$ + lineLength = 0; + } + s += parts[i]; + s += separator; + } + return s; + } } private class InternalGroup extends InternalSection { @@ -283,35 +520,33 @@ } public void createContents(Composite parent) { - createGroup(parent); - createFileLabel(); - createFileCombo(); - createClearButton(group); - initDrag(); - initDrop(); - } - - public void createGroup(Composite parent) { final Composite p = parent; expandable = new ExpandableComposite(parent, SWT.NONE, ExpandableComposite.TREE_NODE | ExpandableComposite.TWISTIE); - super.createGroup(expandable); + super.createContents(expandable); expandable.setClient(group); expandable.addExpansionListener(new ExpansionAdapter() { public void expansionStateChanged(ExpansionEvent e) { p.layout(); + getShell().pack(); } }); } - protected void createClearButton(Composite parent) { + protected void createInfo(Composite parent) { + createFileLabel(parent); + createFileCombo(parent); + createClearButton(parent); + createPathLabel(parent); + } + + private void createClearButton(Composite parent) { clearButton = createButton(parent, CLEAR_RETURN_CODE, CompareMessages.CompareWithOther_clear, false); clearButton.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } - public void widgetSelected(SelectionEvent e) { clearResource(); } @@ -332,6 +567,7 @@ private InternalGroup rightPanel, leftPanel; private InternalExpandable ancestorPanel; private ISelection fselection; + private int lineLimit = 0; /** * Creates the dialog. @@ -441,7 +677,7 @@ IMessageProvider.ERROR); okButton.setEnabled(false); } else if (ancestorPanel.getResource() == null - && ancestorPanel.fileText.getText() != "") { //$NON-NLS-1$ + && ancestorPanel.fileCombo.getText() != "") { //$NON-NLS-1$ setMessage(CompareMessages.CompareWithOther_warning_two_way, IMessageProvider.WARNING); okButton.setEnabled(true); @@ -457,6 +693,17 @@ } } + public int computeLineLengthLimit(InternalSection section) { + int leftLenght = leftPanel.fileCombo.getText().length(); + int rightLength = rightPanel.fileCombo.getText().length(); + int maxLenght = (leftLenght > rightLength ? leftLenght : rightLength); + if (maxLenght > lineLimit) + lineLimit = maxLenght; + if (section instanceof InternalExpandable) + return Math.max(lineLimit * 2 + 20, 90); + return maxLenght; + } + /** * Returns table with selected resources. If any resource wasn't chosen in * the ancestor panel, table has only two elements -- resources chosen in Index: compare/org/eclipse/compare/internal/CompareMessages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareMessages.properties,v retrieving revision 1.29 diff -u -r1.29 CompareMessages.properties --- compare/org/eclipse/compare/internal/CompareMessages.properties 19 Aug 2008 07:58:04 -0000 1.29 +++ compare/org/eclipse/compare/internal/CompareMessages.properties 25 Aug 2008 09:10:22 -0000 @@ -132,3 +132,8 @@ CompareWithOther_warning_two_way=Ancestor is not a valid resource. Two-way compare will be performed. CompareWithOther_clear=Clear CompareWithOther_info=Drag files from a view or between dialog's fields. +CompareWithOther_externalFileButton=External file... +CompareWithOther_externalFolderBUtton=External folder... +CompareWithOther_externalFile_errorTitle=Compare With Other Resource Error +CompareWithOther_externalFile_errorMessage=I cannot create a link to external file. +CompareWithOther_pathLabel=Path: