### 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.20 diff -u -r1.20 CompareMessages.java --- compare/org/eclipse/compare/internal/CompareMessages.java 10 Oct 2008 14:55:31 -0000 1.20 +++ compare/org/eclipse/compare/internal/CompareMessages.java 15 Nov 2008 21:45:19 -0000 @@ -117,6 +117,7 @@ public static String CompareWithOther_error_not_comparable; public static String CompareWithOther_error_empty; public static String CompareWithOther_clear; + public static String CompareWithOther_clipboardRadioButton; public static String CompareWithOther_info; public static String CompareWithOther_externalFileButton; public static String CompareWithOther_externalFile_errorTitle; @@ -129,6 +130,13 @@ public static String CompareWithOtherResourceDialog_externalFolderRadioButton; public static String CompareWithOtherResourceDialog_workspaceMainButton; public static String CompareWithOtherResourceDialog_workspaceRadioButton; + public static String CompareWithOther_showInEditorButton; + public static String CompareWithOther_refreshButton; + public static String CompareWithOther_createTmpFile_title; + public static String CompareWithOther_createTmpFile_message; + public static String CompareWithOther_fileName_0; + public static String CompareWithOther_fileName_1; + public static String CompareWithOther_fileName_2; static { NLS.initializeMessages(BUNDLE_NAME, CompareMessages.class); 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.3 diff -u -r1.3 CompareWithOtherResourceAction.java --- compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java 16 Sep 2008 14:03:31 -0000 1.3 +++ compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java 15 Nov 2008 21:45:20 -0000 @@ -23,6 +23,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 + CompareWithOtherResourceDialog.cleanup(); super.run(selection); } 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.5 diff -u -r1.5 CompareWithOtherResourceDialog.java --- compare/org/eclipse/compare/internal/CompareWithOtherResourceDialog.java 16 Sep 2008 14:03:31 -0000 1.5 +++ compare/org/eclipse/compare/internal/CompareWithOtherResourceDialog.java 15 Nov 2008 21:45:23 -0000 @@ -11,8 +11,12 @@ *******************************************************************************/ package org.eclipse.compare.internal; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import org.eclipse.compare.CompareConfiguration; import org.eclipse.compare.CompareUI; @@ -33,6 +37,7 @@ 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; @@ -52,15 +57,21 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IEditorDescriptor; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; import org.eclipse.ui.forms.events.ExpansionAdapter; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.widgets.ExpandableComposite; +import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.part.ResourceTransfer; /** @@ -363,6 +374,146 @@ } } + + private class ClipboardContent extends ContentTypeElement { + + protected Button showInEditorButton; + private Clipboard clipboard; + + public ClipboardContent(Composite parent, InternalSection section) { + super(parent, CompareMessages.CompareWithOther_clipboardRadioButton, section); + clipboard = new Clipboard(Display.getDefault()); + } + + protected void createText(Composite parent) { + text = new Text(parent, SWT.BORDER | SWT.MULTI); + text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + text.setEditable(false); + } + + protected void createMainButton(Composite parent) { + + Composite buttonComposite = new Composite(parent, SWT.NONE); + buttonComposite.setLayout(new GridLayout(1, false)); + + createRefreshButton(buttonComposite); + createShowInEditorButton(buttonComposite); + } + + protected void setEnabled(boolean enabled) { + super.setEnabled(enabled); + showInEditorButton.setEnabled(enabled); + if (enabled) { + String fileContent = clipboard.getContents(TextTransfer.getInstance()).toString(); + text.setText(fileContent); + setResource(createClipboardFile(fileContent, section.clipboardFileName)); + } + } + + private void createShowInEditorButton(Composite parent) { + showInEditorButton = new Button(parent, SWT.PUSH); + showInEditorButton.setText(CompareMessages.CompareWithOther_showInEditorButton); + showInEditorButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + showInEditorButton.setEnabled(false); + showInEditorButton.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + public void widgetSelected(SelectionEvent e) { + IWorkbenchPage page = getWorkbenchPage(); + String id = getEditorId(page); + try { + FileEditorInput input = new FileEditorInput((IFile)getResource()); + page.openEditor(input, id); + } catch (PartInitException e1) { + CompareUIPlugin.log(e1); + } + } + }); + } + + private String getEditorId(IWorkbenchPage page) { + IFile file = createClipboardFile("test content", "testFile"); //$NON-NLS-1$ //$NON-NLS-2$ // create empty clipboard file to get it's default editor + IEditorDescriptor descriptor = CompareUI.getPlugin().getWorkbench().getEditorRegistry().getDefaultEditor(file.getName()); + if (descriptor != null) + return descriptor.getId(); + return null; + } + + private void createRefreshButton(Composite parent) { + mainButton = new Button(parent, SWT.PUSH); + mainButton.setText(CompareMessages.CompareWithOther_refreshButton); + mainButton.setEnabled(false); + mainButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + mainButton.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + public void widgetSelected(SelectionEvent e) { + String newFileContent = clipboard.getContents(TextTransfer.getInstance()).toString(); + IFile currentClipboardFile = section.getMyClipboardFile(); + String contents = getFilesContent(currentClipboardFile); + if (contents == null || !contents.equals(newFileContent)) { + text.setText(newFileContent); + setResource(createClipboardFile(newFileContent, section.clipboardFileName)); + } + } + }); + } + + private IFile createClipboardFile(String fileContent, String fileName) { + IFile file = null; + try { + file = tmpProject.getClipboardFileHandler(fileName); + if (file.exists()) + file.delete(true, null); + 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 String getFilesContent(IFile file) { + + if (!file.exists()) + return null; + + InputStream stream = null; + + try { + stream = file.getContents(); + } catch (CoreException e1) { + CompareUIPlugin.log(e1); + return null; + } + + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + StringBuffer buffer = new StringBuffer(); + int c; + + try { + while ((c = reader.read()) != -1) + buffer.append((char)c); + } catch (IOException e) { + CompareUIPlugin.log(e); + return null; // we don't need only a part of a content + } finally { + try { + stream.close(); + } catch (IOException e) { + CompareUIPlugin.log(e); + return null; + } + } + return buffer.toString(); + } + } private abstract class InternalSection { @@ -373,10 +524,12 @@ protected Group group; private IResource resource; + private String clipboardFileName; ExternalFileContent externalFileContent; ExternalFolderContent externalFolderContent; WorkspaceContent workspaceContent; + ClipboardContent clipboardContent; public InternalSection(Composite parent) { createContents(parent); @@ -385,6 +538,15 @@ private InternalSection() { // not to instantiate } + + public IFile getMyClipboardFile() { + try { + IFile file = tmpProject.getClipboardFileHandler(clipboardFileName); + return file; + } catch (CoreException e) { + return null; + } + } protected void createContents(Composite parent) { @@ -395,13 +557,14 @@ workspaceContent = new WorkspaceContent(group, this); externalFileContent = new ExternalFileContent(group, this); externalFolderContent = new ExternalFolderContent(group, this); + clipboardContent = new ClipboardContent(group, this); addListenersToRadioButtons(); } private void addListenersToRadioButtons() { final ContentTypeElement[] elements = new ContentTypeElement[] { workspaceContent, - externalFileContent, externalFolderContent }; + externalFileContent, externalFolderContent, clipboardContent }; for (int i = 0; i < elements.length; i++) elements[i].getRadioButton().addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { @@ -461,6 +624,10 @@ externalFolderContent.setEnabled(true); } } + + protected void setClipboardFileName(String name) { + this.clipboardFileName = name; + } } private class InternalGroup extends InternalSection { @@ -525,7 +692,7 @@ } } - private class ExternalResourcesProject { + private class ExternalResourcesAndClipboardProject { // Implementation based on org.eclipse.jdt.internal.core.ExternalFoldersManager @@ -544,9 +711,10 @@ + "\t\n" + "\t\n" //$NON-NLS-1$//$NON-NLS-2$ + ""; //$NON-NLS-1$ - private final static String TMP_FOLDER_NAME = "tmpFolder"; //$NON-NLS-1$ + private final static String EXTERNAL_FILES_FOLDER_NAME = "externalsFolder"; //$NON-NLS-1$ + private final static String CLIPBOARD_FILES_FOLDER_NAME = "ClipboardFolder"; //$NON-NLS-1$ - private ExternalResourcesProject() { + private ExternalResourcesAndClipboardProject() { // nothing to do here } @@ -587,7 +755,7 @@ } private IFolder getTmpFolder(IProject project) throws CoreException { - IFolder folder = project.getFolder(TMP_FOLDER_NAME); + IFolder folder = project.getFolder(EXTERNAL_FILES_FOLDER_NAME); if (!folder.exists()) folder.create(IResource.NONE, true, null); return folder; @@ -666,13 +834,25 @@ return ResourcesPlugin.getWorkspace().getRoot().getProject( TMP_PROJECT_NAME); } + + private IFile getClipboardFileHandler(String fileName) throws CoreException { + IFile file = null; + IProject project = createTmpProject(); + if (!project.isOpen()) + project.open(null); + IFolder folder = project.getFolder(CLIPBOARD_FILES_FOLDER_NAME); + if (!folder.exists()) + folder.create(IResource.NONE, true, null); + file = folder.getFile(fileName + ".txt"); //$NON-NLS-1$ + return file; + } } private Button okButton; private InternalGroup rightPanel, leftPanel; private InternalExpandable ancestorPanel; private ISelection selection; - private ExternalResourcesProject tmpProject = new ExternalResourcesProject(); + private ExternalResourcesAndClipboardProject tmpProject = new ExternalResourcesAndClipboardProject(); /** * Creates the dialog. @@ -705,16 +885,19 @@ ancestorPanel = new InternalExpandable(mainPanel); ancestorPanel.setText(CompareMessages.CompareWithOther_ancestor); + ancestorPanel.setClipboardFileName(CompareMessages.CompareWithOther_fileName_0); GridData ancestorGD = new GridData(SWT.FILL, SWT.FILL, true, false); ancestorGD.horizontalSpan = 2; ancestorPanel.setLayoutData(ancestorGD); leftPanel = new InternalGroup(mainPanel); leftPanel.setText(CompareMessages.CompareWithOther_leftPanel); + leftPanel.setClipboardFileName(CompareMessages.CompareWithOther_fileName_1); leftPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); rightPanel = new InternalGroup(mainPanel); rightPanel.setText(CompareMessages.CompareWithOther_rightPanel); + rightPanel.setClipboardFileName(CompareMessages.CompareWithOther_fileName_2); rightPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); setSelection(selection); @@ -819,4 +1002,58 @@ rightResource }; return resources; } + + /** + * Removes temporary files created from clipboard's content or imported to + * workspace only for comparing. + */ + public static void cleanup() { + try { + IProject project = ResourcesPlugin.getWorkspace().getRoot() + .getProject(ExternalResourcesAndClipboardProject.TMP_PROJECT_NAME); + project.delete(true, true, null); + } catch (CoreException e) { + CompareUIPlugin.log(e); + } + } + + private IWorkbenchPage getWorkbenchPage() { + return CompareUI.getPlugin().getWorkbench().getActiveWorkbenchWindow().getActivePage(); + } + + private void closeEditorWithClipboard(IWorkbenchPage page) { + IEditorReference[] editors = page.getEditorReferences(); + String[] names = new String[] { CompareMessages.CompareWithOther_fileName_0, + CompareMessages.CompareWithOther_fileName_1, + CompareMessages.CompareWithOther_fileName_2 }; + for (int i = 0; i < editors.length; i++) + for (int j = 0; j < 3; j++) + try { + if (editors[i].getEditorInput().getName().equals(names[j] + ".txt")) //$NON-NLS-1$ + page.closeEditor(editors[i].getEditor(false), false); + } catch (PartInitException e) { + CompareUIPlugin.log(e); + } + } + + /** + * Closes all editor pages containing clipboard files before closing the dialog + * and setting its return code to OK. + */ + public void okPressed() { + IWorkbenchPage page = getWorkbenchPage(); + closeEditorWithClipboard(page); + super.okPressed(); + } + + /** + * Closes all editor pages containing clipboard files before closing the dialog + * and setting its return code to CANCEL. + */ + public void cancelPressed() { + IWorkbenchPage page = getWorkbenchPage(); + closeEditorWithClipboard(page); + super.cancelPressed(); + } + } Index: compare/org/eclipse/compare/internal/ResourceCompareInput.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/ResourceCompareInput.java,v retrieving revision 1.40 diff -u -r1.40 ResourceCompareInput.java --- compare/org/eclipse/compare/internal/ResourceCompareInput.java 16 Sep 2008 14:03:31 -0000 1.40 +++ compare/org/eclipse/compare/internal/ResourceCompareInput.java 15 Nov 2008 21:45:24 -0000 @@ -436,7 +436,15 @@ } private String buildLabel(IResource r) { - // for a linked resource in a hidden project use its local file system location + // for a clipboard file return its name. As a clipboard file -- such as external files and folders -- + // is linked and hidden, the only way to distinguish it is checking its name. + String[] names = new String[] { CompareMessages.CompareWithOther_fileName_0 + ".txt", //$NON-NLS-1$ + CompareMessages.CompareWithOther_fileName_1 + ".txt", //$NON-NLS-1$ + CompareMessages.CompareWithOther_fileName_2 + ".txt" }; //$NON-NLS-1$ + for (int i = 0; i < 3; i++) + if (r.getName().equals(names[i])) + return r.getName(); + // for other linked resource in a hidden project use its local file system location if (r.isLinked() && r.getProject().isHidden()) return r.getLocation().toString(); String n= r.getFullPath().toString(); 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.31 diff -u -r1.31 CompareMessages.properties --- compare/org/eclipse/compare/internal/CompareMessages.properties 10 Oct 2008 14:55:31 -0000 1.31 +++ compare/org/eclipse/compare/internal/CompareMessages.properties 15 Nov 2008 21:45:19 -0000 @@ -129,6 +129,7 @@ CompareWithOther_error_not_comparable=Selected resources are not comparable. CompareWithOther_error_empty=Both left and right panel must contain a valid path. CompareWithOther_clear=Clear +CompareWithOther_clipboardRadioButton=Clipboard CompareWithOther_info=Drag files from a view or between dialog's fields. CompareWithOther_externalFileButton=External file... CompareWithOther_externalFolderBUtton=External folder... @@ -141,3 +142,10 @@ CompareWithOtherResourceDialog_externalFolderRadioButton=External folder CompareWithOtherResourceDialog_workspaceMainButton=Browse... CompareWithOtherResourceDialog_workspaceRadioButton=Workspace +CompareWithOther_showInEditorButton=Show in editor +CompareWithOther_refreshButton=Refresh +CompareWithOther_createTmpFile_title=Unable to create a file +CompareWithOther_createTmpFile_message=A file cannot be created from clipbard's content. +CompareWithOther_fileName_0=clipboard-0 +CompareWithOther_fileName_1=clipboard-1 +CompareWithOther_fileName_2=clipboard-2