### Eclipse Workspace Patch 1.0 #P org.eclipse.compare 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.17.4.4 diff -u -r1.17.4.4 CompareMessages.java --- compare/org/eclipse/compare/internal/CompareMessages.java 1 Aug 2008 13:08:19 -0000 1.17.4.4 +++ compare/org/eclipse/compare/internal/CompareMessages.java 5 Aug 2008 13:32:44 -0000 @@ -120,6 +120,13 @@ public static String CompareWithOther_clear; public static String CompareWithOther_warning_two_way; public static String CompareWithOther_info; + public static String CompareWithOther_clipboardButton; + public static String CompareWithOther_clipboardSection; + public static String CompareWithOther_fileName; + public static String CompareWithOther_createTmpFile_title; + public static String CompareWithOther_createTmpFile_message; + public static String CompareWithOther_noClipboardFile; + public static String CompareWithOther_noClipboardFile_ancestor; 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/Attic/CompareWithOtherResourceDialog.java,v retrieving revision 1.1.2.4 diff -u -r1.1.2.4 CompareWithOtherResourceDialog.java --- compare/org/eclipse/compare/internal/CompareWithOtherResourceDialog.java 1 Aug 2008 13:08:19 -0000 1.1.2.4 +++ compare/org/eclipse/compare/internal/CompareWithOtherResourceDialog.java 5 Aug 2008 13:32:44 -0000 @@ -10,16 +10,33 @@ *******************************************************************************/ package org.eclipse.compare.internal; +import java.io.ByteArrayInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + 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.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; 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.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DragSource; import org.eclipse.swt.dnd.DragSourceEvent; @@ -38,6 +55,7 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; @@ -49,7 +67,7 @@ /** * This is a dialog that can invoke the compare editor on chosen files. - * + * * @since 3.4 */ public class CompareWithOtherResourceDialog extends TitleAreaDialog { @@ -57,6 +75,18 @@ private int CLEAR_RETURN_CODE = 150; // any number != 0 private int MIN_WIDTH = 300; private int MIN_HEIGHT = 175; + private int clipboardCounter = 0; + public final static 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$ private class FileTextDragListener implements DragSourceListener { @@ -156,11 +186,274 @@ } + private class ClipboardDropListener implements DropTargetListener { + + ClipboardAbstractSection clipboardSection; + + public ClipboardDropListener(ClipboardAbstractSection clipboardSection) { + this.clipboardSection = clipboardSection; + } + + public void dragEnter(DropTargetEvent event) { + if (event.detail == DND.DROP_DEFAULT) { + if ((event.operations & DND.DROP_COPY) != 0) + event.detail = DND.DROP_COPY; + else + event.detail = DND.DROP_NONE; + } + + for (int i = 0; i < event.dataTypes.length; i++) { + if (TextTransfer.getInstance().isSupportedType(event.dataTypes[i])) { + event.currentDataType = event.dataTypes[i]; + if (event.detail != DND.DROP_COPY) + event.detail = DND.DROP_NONE; + break; + } + } + } + + public void dragLeave(DropTargetEvent event) { + clipboardSection.clipboardExpandable.setExpanded(true); + getShell().pack(); + } + + public void dragOperationChanged(DropTargetEvent event) { + // intentionally empty + } + + public void dragOver(DropTargetEvent event) { + clipboardSection.clipboardExpandable.setExpanded(true); + getShell().pack(); + } + + public void drop(DropTargetEvent event) { + if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) { + String txt = (String) event.data; + clipboardSection.viewer.setDocument(new Document(txt)); + clipboardSection.getPanel().clearResource(); + clipboardSection.updateErrorInfoForClipboard(); + } + } + + public void dropAccept(DropTargetEvent event) { + // intentionally empty + } + + } + + private abstract class ClipboardAbstractSection { + + protected ExpandableComposite clipboardExpandable; + protected SourceViewer viewer; + protected Button createButton; + private InternalSection section; + + public ClipboardAbstractSection(InternalSection section) { + this.section = section; + } + + protected void createClipboardSection(Composite parent) { + final Composite p = parent; + clipboardExpandable = new ExpandableComposite(parent, SWT.NONE, + ExpandableComposite.TWISTIE); + clipboardExpandable + .setText(CompareMessages.CompareWithOther_clipboardSection); + Composite content = createContentsForClipboardSection(clipboardExpandable); + clipboardExpandable.setClient(content); + clipboardExpandable.addExpansionListener(new ExpansionAdapter() { + public void expansionStateChanged(ExpansionEvent e) { + p.layout(); + getShell().pack(); + if (e.getState()) { + section.fileText.setEnabled(false); + if (!section.resourceFromClipboard) + section.clearResourceWithoutPath(); // clearResource() causes clearing contents of fileText + } else { + section.fileText.setEnabled(true); + if (section.fileText.getText() != "") //$NON-NLS-1$ + section.setResource(section.fileText.getText()); + } + updateErrorInfoForClipboard(); + } + }); + + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.horizontalSpan = 2; + clipboardExpandable.setLayoutData(gd); + + initDropForClipboard(); + } + + private void initDropForClipboard() { + DropTarget clipboardTarget = new DropTarget(clipboardExpandable, DND.DROP_COPY | DND.DROP_DEFAULT); + Transfer[] types = new Transfer[] {TextTransfer.getInstance()}; + clipboardTarget.setTransfer(types); + clipboardTarget.addDropListener(new ClipboardDropListener(this)); + } + + private Composite createContentsForClipboardSection(Composite parent) { + + Composite contents = new Composite(parent, SWT.NONE); + contents.setLayout(new GridLayout(1, false)); + + viewer = new SourceViewer(contents, null, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + viewer.setEditable(false); + String content = (String) clipboard.getContents(TextTransfer.getInstance()); + IDocument document = new Document(content); + viewer.setDocument(document); + + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.horizontalSpan = 2; + gd.widthHint = 200; + gd.heightHint = 150; + viewer.getTextWidget().setLayoutData(gd); + + viewer.getTextWidget().addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + String txt = (String) clipboard.getContents(TextTransfer.getInstance()); + viewer.setDocument(new Document(txt)); + updateErrorInfoForClipboard(); + } + }); + + createButton = createButton(contents, CLEAR_RETURN_CODE, + CompareMessages.CompareWithOther_clipboardButton, false); + createButton.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + public void widgetSelected(SelectionEvent e) { + section.setResourceFromClipboard(createTmpFile(viewer.getDocument().get())); + updateErrorInfoForClipboard(); + } + }); + + return contents; + } + + private IFile createTmpFile(String fileContent) { + IFile file = null; + try { + IProject project = createTmpProject(); + if (!project.isOpen()) + project.open(null); + IFolder folder = project.getFolder("ClipboardFolder"); //$NON-NLS-1$ + if (!folder.exists()) + folder.create(IResource.NONE, true, null); + file = folder.getFile(CompareMessages.CompareWithOther_fileName + + clipboardCounter++); + if (!file.exists()) { + InputStream source = new ByteArrayInputStream(fileContent + .getBytes()); + file.create(source, IResource.NONE, null); + } + } catch (CoreException e) { + CompareUIPlugin.log(e); + MessageDialog.openError(getShell(), + CompareMessages.CompareWithOther_createTmpFile_title, + CompareMessages.CompareWithOther_createTmpFile_message); + return file; + } + return file; + } + + 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; + } + + private IProject getTmpProject() { + return ResourcesPlugin.getWorkspace().getRoot().getProject( + TMP_PROJECT_NAME); + } + + protected abstract void updateErrorInfoForClipboard(); + + protected boolean clipboardSectionExpanded() { + return clipboardExpandable.isExpanded(); + } + + protected boolean noResource() { + return section.getResource() == null; + } + + public InternalSection getPanel() { + return section; + } + + } + + private class ClipboardSection extends ClipboardAbstractSection { + + public ClipboardSection(InternalSection section) { + super(section); + } + + protected void updateErrorInfoForClipboard() { + if (clipboardSectionExpanded() && noResource()) { + setMessage(CompareMessages.CompareWithOther_noClipboardFile, IMessageProvider.ERROR); + createButton.setEnabled(true); + } else { + updateErrorInfo(); + createButton.setEnabled(false); + } + } + } + + + private class ClipboardAncestorSection extends ClipboardAbstractSection { + + public ClipboardAncestorSection(InternalSection section) { + super(section); + } + + protected void updateErrorInfoForClipboard() { + if (clipboardSectionExpanded() && noResource()) { + setMessage(CompareMessages.CompareWithOther_noClipboardFile_ancestor, IMessageProvider.WARNING); + createButton.setEnabled(true); + } else { + updateErrorInfo(); + createButton.setEnabled(false); + } + } + } + + private abstract class InternalSection { protected Group group; protected Text fileText; private IResource resource; + private boolean resourceFromClipboard = false; public InternalSection(Composite parent) { createContents(parent); @@ -172,8 +465,6 @@ public void createContents(Composite parent) { createGroup(parent); - createFileLabel(); - createFileCombo(); initDrag(); initDrop(); } @@ -183,19 +474,25 @@ } public void setResource(IResource resource) { + resourceFromClipboard = false; this.resource = resource; String txt = resource.getFullPath().toString(); fileText.setText(txt); } public void setResource(String s) { + resourceFromClipboard = false; IResource tmp = ResourcesPlugin.getWorkspace().getRoot() .findMember(s); if (tmp instanceof IWorkspaceRoot) resource = null; else resource = tmp; + } + public void setResourceFromClipboard(IResource resource) { + resourceFromClipboard = true; + this.resource = resource; } protected void clearResource() { @@ -204,6 +501,11 @@ updateErrorInfo(); } + protected void clearResourceWithoutPath() { + resource = null; + updateErrorInfo(); + } + protected void initDrag() { DragSource source = new DragSource(fileText, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT); @@ -224,14 +526,15 @@ protected void createGroup(Composite parent) { group = new Group(parent, SWT.NONE); - group.setLayout(new GridLayout(3, false)); + group.setLayout(new GridLayout(2, false)); group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + createFileLabel(group); + createFileCombo(group); } - protected void createFileCombo() { - fileText = new Text(group, SWT.BORDER); - fileText - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + protected void createFileCombo(Composite parent) { + fileText = new Text(parent, SWT.BORDER); + fileText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); fileText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { @@ -254,18 +557,26 @@ }); } - protected void createFileLabel() { - final Label fileLabel = new Label(group, SWT.NONE); + protected void createFileLabel(Composite parent) { + final Label fileLabel = new Label(parent, SWT.NONE); fileLabel.setText(CompareMessages.CompareWithOther_fileLabel); } } private class InternalGroup extends InternalSection { + private ClipboardSection clipboardSection; + public InternalGroup(Composite parent) { + this.clipboardSection = new ClipboardSection(this); createContents(parent); } + protected void createGroup(Composite parent) { + super.createGroup(parent); + clipboardSection.createClipboardSection(group); + } + public void setText(String text) { group.setText(text); } @@ -278,17 +589,16 @@ private class InternalExpandable extends InternalSection { private ExpandableComposite expandable; - private Button clearButton; + public Button clearButton; + private ClipboardAncestorSection clipboardAncestorSection; public InternalExpandable(Composite parent) { + this.clipboardAncestorSection = new ClipboardAncestorSection(this); createContents(parent); } public void createContents(Composite parent) { createGroup(parent); - createFileLabel(); - createFileCombo(); - createClearButton(group); initDrag(); initDrop(); } @@ -302,8 +612,10 @@ expandable.addExpansionListener(new ExpansionAdapter() { public void expansionStateChanged(ExpansionEvent e) { p.layout(); + getShell().pack(); } }); + clipboardAncestorSection.createClipboardSection(group); } protected void createClearButton(Composite parent) { @@ -334,10 +646,11 @@ private InternalGroup rightPanel, leftPanel; private InternalExpandable ancestorPanel; private ISelection fselection; + Clipboard clipboard; /** * Creates the dialog. - * + * * @param shell * a shell * @param selection @@ -349,11 +662,12 @@ super(shell); setShellStyle(SWT.MODELESS | SWT.RESIZE | SWT.MAX); fselection = selection; + clipboard = new Clipboard(Display.getDefault()); } /* * (non-Javadoc) - * + * * @see * org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets * .Composite) @@ -389,7 +703,7 @@ /* * (non-Javadoc) - * + * * @see * org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse * .swt.widgets.Composite) @@ -463,7 +777,7 @@ * the ancestor panel, table has only two elements -- resources chosen in * left and right panel. In the other case table contains all three * resources. - * + * * @return table with selected resources */ public IResource[] getResult() { Index: compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/Attic/CompareWithOtherResourceAction.java,v retrieving revision 1.1.2.3 diff -u -r1.1.2.3 CompareWithOtherResourceAction.java --- compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java 1 Aug 2008 13:08:19 -0000 1.1.2.3 +++ compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java 5 Aug 2008 13:32:44 -0000 @@ -10,11 +10,14 @@ *******************************************************************************/ 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; /** * The "Compare with other resource" action - * + * * @since 3.4 */ public class CompareWithOtherResourceAction extends CompareAction { @@ -23,6 +26,7 @@ // Show CompareWithOtherResourceDialog which return resources to compare // and ancestor if specified. Don't need to display the other dialog showSelectAncestorDialog = false; + cleanup(); super.run(selection); } @@ -32,4 +36,14 @@ 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.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareMessages.properties,v retrieving revision 1.27.4.4 diff -u -r1.27.4.4 CompareMessages.properties --- compare/org/eclipse/compare/internal/CompareMessages.properties 1 Aug 2008 13:08:19 -0000 1.27.4.4 +++ compare/org/eclipse/compare/internal/CompareMessages.properties 5 Aug 2008 13:32:44 -0000 @@ -131,4 +131,11 @@ CompareWithOther_error_empty=Both left and right panel must contain a valid path. 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_info=Drag files from Package Explorer or from another field within the dialog or expand "Clipboard" if you want to use clipboard's content instead of a resource. +CompareWithOther_clipboardButton=Create file +CompareWithOther_clipboardSection=Clipboard +CompareWithOther_fileName=Clipboard +CompareWithOther_createTmpFile_title= Unable to create file +CompareWithOther_createTmpFile_message= A file cannot be created from clipboard content. +CompareWithOther_noClipboardFile=You have to create a file from clipboard's contents if you want to compare it with something. Click "Create file" button. +CompareWithOther_noClipboardFile_ancestor=A file containing clipboard's content wasn't created. Click "Create file" button in the ancestor section if you want a three-way compare to be performed.