### 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 11 Aug 2008 10:02:35 -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_clipboardSection; + public static String CompareWithOther_fileName; + public static String CompareWithOther_createTmpFile_title; + public static String CompareWithOther_createTmpFile_message; + public static String CompareWithOther_refreshButton; + public static String CompareWithOther_clipboardInfo_1; + public static String CompareWithOther_clipboardInfo_2; 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 11 Aug 2008 10:02:36 -0000 @@ -10,16 +10,32 @@ *******************************************************************************/ 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.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 +54,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,14 +66,27 @@ /** * This is a dialog that can invoke the compare editor on chosen files. - * + * * @since 3.4 */ public class CompareWithOtherResourceDialog extends TitleAreaDialog { private int CLEAR_RETURN_CODE = 150; // any number != 0 + private int REFRESH_RETURN_CODE = 154; 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 { @@ -71,10 +101,7 @@ } public void dragSetData(DragSourceEvent event) { - if (TextTransfer.getInstance().isSupportedType(event.dataType)) { - event.data = section.fileText.getText(); - } else - event.data = section.fileText.getText(); + event.data = section.fileText.getText(); } public void dragStart(DragSourceEvent event) { @@ -156,6 +183,278 @@ } + 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 fileContent = (String) event.data; + clipboardSection.setViewerContent(fileContent); + IFile file = clipboardSection.createTmpFile(fileContent); + // don't update a fileText's content + clipboardSection.getPanel().setResourceFromClipboard(file); + updateErrorInfo(); + } + } + + public void dropAccept(DropTargetEvent event) { + // intentionally empty + } + + } + + private abstract class ClipboardAbstractSection { + + protected ExpandableComposite clipboardExpandable; + protected SourceViewer viewer; + protected Button refreshButton; + 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); + // do not clear contents of the fileText + section.clearResourceWithoutPath(); + setViewerAndCreateFile(); + } else { + section.fileText.setEnabled(true); + section.clearResourceWithoutPath(); + if (section.fileText.getText() != "") //$NON-NLS-1$ + section.setResource(section.fileText.getText()); + } + updateErrorInfo(); + } + }); + + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.horizontalSpan = 2; + clipboardExpandable.setLayoutData(gd); + + initDropForClipboard(); + } + + private void setViewerAndCreateFile() { + String newContent = (String) clipboard.getContents(TextTransfer.getInstance()); + setViewerContent(newContent); + } + + public void setViewerContent(String newContent) { + viewer.setDocument(new Document(newContent)); + // don't update a fileText's content + section.setResourceFromClipboard(createTmpFile(newContent)); + } + + 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)); + + Label infoLabel = new Label(contents, SWT.NONE); + infoLabel.setText(clipboardInfo()); + GridData labelGd = new GridData(SWT.FILL, SWT.FILL, true, true); + labelGd.horizontalSpan = 3; + infoLabel.setLayoutData(labelGd); + + viewer = new SourceViewer(contents, null, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + viewer.setEditable(false); + + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.horizontalSpan = 3; + gd.widthHint = 200; + gd.heightHint = 150; + viewer.getTextWidget().setLayoutData(gd); + // although viewer is not editable, we need ModifyListener to + // set viewer's content and error message after dropping a portion of text + viewer.getTextWidget().addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + setViewerAndCreateFile(); + updateErrorInfo(); + } + }); + + createRefreshButton(contents); + parent.layout(); + + return contents; + } + + abstract protected String clipboardInfo(); + + private void createRefreshButton(Composite parent) { + refreshButton = createButton(parent, REFRESH_RETURN_CODE, CompareMessages.CompareWithOther_refreshButton, false); + refreshButton.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + public void widgetSelected(SelectionEvent e) { + setViewerAndCreateFile(); + updateErrorInfo(); + } + }); + } + + 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 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 String clipboardInfo() { + return CompareMessages.CompareWithOther_clipboardInfo_1 + "\n" + //$NON-NLS-1$ + CompareMessages.CompareWithOther_clipboardInfo_2; + } + } + + private class ClipboardAncestorSection extends ClipboardAbstractSection { + + public ClipboardAncestorSection(InternalSection section) { + super(section); + } + + protected String clipboardInfo() { + return CompareMessages.CompareWithOther_clipboardInfo_1 + + CompareMessages.CompareWithOther_clipboardInfo_2; + } + } + private abstract class InternalSection { protected Group group; @@ -172,8 +471,6 @@ public void createContents(Composite parent) { createGroup(parent); - createFileLabel(); - createFileCombo(); initDrag(); initDrop(); } @@ -195,7 +492,10 @@ resource = null; else resource = tmp; + } + public void setResourceFromClipboard(IResource resource) { + this.resource = resource; } protected void clearResource() { @@ -204,6 +504,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 +529,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) { @@ -241,31 +547,36 @@ }); fileText.addSelectionListener(new SelectionListener() { - public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } - public void widgetSelected(SelectionEvent e) { setResource(fileText.getText()); updateErrorInfo(); } - }); } - 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(); } @@ -298,12 +608,15 @@ expandable = new ExpandableComposite(parent, SWT.NONE, ExpandableComposite.TREE_NODE | ExpandableComposite.TWISTIE); super.createGroup(expandable); + createClearButton(group); expandable.setClient(group); expandable.addExpansionListener(new ExpansionAdapter() { public void expansionStateChanged(ExpansionEvent e) { p.layout(); + getShell().pack(); } }); + clipboardAncestorSection.createClipboardSection(group); } protected void createClearButton(Composite parent) { @@ -334,10 +647,11 @@ private InternalGroup rightPanel, leftPanel; private InternalExpandable ancestorPanel; private ISelection fselection; + Clipboard clipboard; /** * Creates the dialog. - * + * * @param shell * a shell * @param selection @@ -349,11 +663,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 +704,7 @@ /* * (non-Javadoc) - * + * * @see * org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse * .swt.widgets.Composite) @@ -463,7 +778,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 11 Aug 2008 10:02:35 -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 11 Aug 2008 10:02:35 -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_clipboardSection=Clipboard +CompareWithOther_fileName=Clipboard +CompareWithOther_createTmpFile_title= Unable to create file +CompareWithOther_createTmpFile_message= A file cannot be created from clipboard content. +CompareWithOther_refreshButton=Refresh +CompareWithOther_clipboardInfo_1=Add content to the viewer below by dropping a portion of text into it or use Refresh +CompareWithOther_clipboardInfo_2=button if you want fill the viewer with current clipboard's content.