### Eclipse Workspace Patch 1.0 #P org.eclipse.compare Index: compare/org/eclipse/compare/internal/GenerateDiffFileWizard.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/Attic/GenerateDiffFileWizard.java,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 GenerateDiffFileWizard.java --- compare/org/eclipse/compare/internal/GenerateDiffFileWizard.java 4 Feb 2009 09:54:51 -0000 1.1.2.2 +++ compare/org/eclipse/compare/internal/GenerateDiffFileWizard.java 26 Feb 2009 00:21:38 -0000 @@ -15,13 +15,27 @@ import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Set; +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.CompareEditorInput; +import org.eclipse.compare.ResourceNode; +import org.eclipse.compare.contentmergeviewer.ITokenComparator; +import org.eclipse.compare.contentmergeviewer.TokenComparator; +import org.eclipse.compare.internal.ResourceCompareInput.FilteredBufferedResourceNode; import org.eclipse.compare.internal.merge.DocumentMerger; +import org.eclipse.compare.internal.merge.DocumentMerger.IDocumentMergerInput; +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.compare.structuremergeviewer.Differencer; +import org.eclipse.compare.structuremergeviewer.ICompareInput; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -35,11 +49,18 @@ import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.IPageChangingListener; import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.PageChangingEvent; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -69,6 +90,9 @@ import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer; import org.eclipse.ui.model.BaseWorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; import org.eclipse.ui.views.navigator.ResourceComparator; @@ -88,8 +112,42 @@ final GenerateDiffFileWizard wizard = new GenerateDiffFileWizard(merger, rightToLeft); wizard.setWindowTitle(title); WizardDialog dialog = new WizardDialog(shell, wizard); + + dialog.addPageChangingListener(new IPageChangingListener() { + + public void handlePageChanging(PageChangingEvent event) { + if(event.getTargetPage() instanceof LocationPage) { + LocationPage page = (LocationPage) event.getTargetPage(); + page.updateChangesControl(); + } + } + + }); + + dialog.setMinimumPageSize(INITIAL_WIDTH, INITIAL_HEIGHT); + dialog.open(); + } + public static void run(IResource[] input, Shell shell) { + final String title = CompareMessages.GenerateLocalDiff_title; + final GenerateDiffFileWizard wizard = new GenerateDiffFileWizard(input); + wizard.setWindowTitle(title); + WizardDialog dialog = new WizardDialog(shell, wizard); + + dialog.addPageChangingListener(new IPageChangingListener() { + + public void handlePageChanging(PageChangingEvent event) { + if(event.getTargetPage() instanceof LocationPage) { + LocationPage page = (LocationPage) event.getTargetPage(); + page.updateChangesControl(); + } + } + + }); + dialog.setMinimumPageSize(INITIAL_WIDTH, INITIAL_HEIGHT); + dialog.setBlockOnOpen(false); dialog.open(); + } protected class DirectionSelectionPage extends WizardPage { @@ -209,11 +267,14 @@ protected IPath[] foldersToCreate; protected int selectedLocation; + private ContainerCheckedTreeViewer viewer; + private LocalChangesContentProvider provider; /** * The default values store used to initialize the selections. */ private final DefaultValuesStore store; - + private Button chgSelectAll; + private Button chgDeselectAll; class LocationPageContentProvider extends BaseWorkbenchContentProvider { //Never show closed projects @@ -448,6 +509,22 @@ this.store= store; } + public void updateChangesControl() { + Differencer dif = new Differencer(); + if(directionSelectionPage.isRightToLeft()) + startNode = (DiffNode) dif.findDifferences(false, null, null, null, + new FilteredBufferedResourceNode(rightResource), + new FilteredBufferedResourceNode(leftResource)); + else if(!directionSelectionPage.isRightToLeft()) + startNode = (DiffNode) dif.findDifferences(false, null, null, null, + new FilteredBufferedResourceNode(leftResource), + new FilteredBufferedResourceNode(rightResource)); + provider.setNode(startNode); + viewer.refresh(); + initCheckedItems(); + associatedResources = getSelectedAssociatedFiles(); + } + /** * Allow the user to finish if a valid file has been entered. */ @@ -464,6 +541,11 @@ break; } + if ((associatedResources = getSelectedAssociatedFiles()).size() == 0) { + pageValid = false; + setErrorMessage(CompareMessages.GenerateDiffFileWizard_noChangesSelected); + } + /** * Avoid draw flicker by clearing error message * if all is valid. @@ -623,7 +705,9 @@ public void createControl(Composite parent) { final Composite composite= new Composite(parent, SWT.NULL); - composite.setLayout(new GridLayout()); + GridLayout lay = new GridLayout(); + lay.verticalSpacing = 15; + composite.setLayout(lay); setControl(composite); initializeDialogUnits(composite); @@ -632,9 +716,24 @@ //Create a location group setupLocationControls(composite); - + initializeDefaultValues(); - + + Label changesLabel = new Label(composite, SWT.HORIZONTAL); + changesLabel.setText("Changes"); + + viewer = new ContainerCheckedTreeViewer(composite, SWT.CHECK | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.BORDER | SWT.HORIZONTAL); + + viewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH)); + provider = new LocalChangesContentProvider(startNode); + viewer.setContentProvider(provider); + viewer.setLabelProvider(new LocalChangesLabelProvider()); + viewer.setInput(leftResource.getWorkspace().getRoot()); + initCheckedItems(); + + createSelectionButtons(composite); + Dialog.applyDialogFont(parent); validatePage(); @@ -642,7 +741,35 @@ updateEnablements(); setupListeners(); } - + + private void createSelectionButtons(Composite composite) { + final Composite buttonGroup = new Composite(composite,SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + buttonGroup.setLayout(layout); + GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END + | GridData.VERTICAL_ALIGN_CENTER); + buttonGroup.setLayoutData(data); + + chgSelectAll = createSelectionButton(CompareMessages.GenerateDiffFileWizard_SelectAll, buttonGroup); + chgDeselectAll = createSelectionButton(CompareMessages.GenerateDiffFileWizard_DeselectAll, buttonGroup); + } + + private Button createSelectionButton(String buttonName, Composite buttonGroup) { + Button button = new Button(buttonGroup,SWT.PUSH); + button.setText(buttonName); + GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); + int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); + Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + data.widthHint = Math.max(widthHint, minSize.x); + button.setLayoutData(data); + return button; + } + /** * Setup the controls for the location. */ @@ -813,9 +940,57 @@ validatePage(); } }); + + chgSelectAll.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + initCheckedItems(); + //Only bother changing isPageComplete state if the current state + //is not enabled + if (!isPageComplete()) + setPageComplete(validatePage()); + } + }); + + chgDeselectAll.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + viewer.setCheckedElements(new Object[0]); + //Only bother changing isPageComplete state if the current state + //is enabled + if (isPageComplete()) + setPageComplete(validatePage()); + } + }); + + viewer.addCheckStateListener(new ICheckStateListener() { + public void checkStateChanged(CheckStateChangedEvent event) { + setPageComplete(validatePage()); + } + }); } + + protected void initCheckedItems() { + TreeItem[] items=((CheckboxTreeViewer)viewer).getTree().getItems(); + for (int i = 0; i < items.length; i++) { + ((CheckboxTreeViewer)viewer).setChecked(items[i].getData(), true); + } + } + protected Map getSelectedAssociatedFiles() { + Object[] elements = viewer.getCheckedElements(); + Map result = new HashMap(); + for (int i = 0; i < elements.length; i++) { + if(!(elements[i] instanceof IProject)) { + DiffNode node = (DiffNode) elements[i]; + IResource lr = Utilities.getResource(node.getLeft()); + IResource rr = Utilities.getResource(node.getRight()); + if(lr instanceof IFile || rr instanceof IFile) + result.put(lr, rr); + } + } + return result; + } + /** * Enable and disable controls based on the selected radio button. */ @@ -1197,7 +1372,6 @@ private final DefaultValuesStore defaultValuesStore; - private DocumentMerger merger; private IDocument leftDoc; private IDocument rightDoc; private String leftPath; @@ -1209,21 +1383,67 @@ private Text unified_customRelativeText; private Button unified_customRelativeOption; + private IResource rightResource; + private IResource leftResource; + + private Map associatedResources; + public GenerateDiffFileWizard() { super(); setWindowTitle(CompareMessages.GenerateLocalDiff_title); initializeDefaultPageImageDescriptor(); defaultValuesStore = new DefaultValuesStore(); + associatedResources = new HashMap(); } + private DiffNode startNode; + + public GenerateDiffFileWizard(IResource[] input) { + this(); + + this.leftDoc = new Document(); + this.rightDoc = new Document(); + + leftResource = input[0]; + rightResource = input[1]; + + leftPath = leftResource.getFullPath().toString(); + rightPath = rightResource.getFullPath().toString(); + + Differencer dif = new Differencer(); + startNode = (DiffNode) dif.findDifferences(false, null, null, null, + new FilteredBufferedResourceNode(leftResource), + new FilteredBufferedResourceNode(rightResource)); + + } + public GenerateDiffFileWizard(DocumentMerger merger, boolean rightToLeft) { this(); - this.merger = merger; this.leftDoc = merger.getDocument(MergeViewerContentProvider.LEFT_CONTRIBUTOR); this.rightDoc = merger.getDocument(MergeViewerContentProvider.RIGHT_CONTRIBUTOR); this.leftPath = merger.getCompareConfiguration().getLeftLabel(leftDoc); this.rightPath = merger.getCompareConfiguration().getRightLabel(rightDoc); this.rightToLeft = rightToLeft; + IWorkbenchPart workbenchPart = merger.getCompareConfiguration().getContainer().getWorkbenchPart(); + + if(workbenchPart instanceof CompareEditor) { + + CompareEditor editor = (CompareEditor)workbenchPart; + + CompareEditorInput input = (CompareEditorInput)editor.getEditorInput(); + input.getCompareResult(); + if(input.getCompareResult() instanceof ICompareInput) { + ICompareInput node = (ICompareInput)input.getCompareResult(); + + leftResource = ((ResourceNode)node.getLeft()).getResource(); + rightResource = ((ResourceNode)node.getRight()).getResource(); + Differencer dif = new Differencer(); + startNode = (DiffNode) dif.findDifferences(false, null, null, null, + new FilteredBufferedResourceNode(leftResource), + new FilteredBufferedResourceNode(rightResource)); + } + + } } public void addPages() { @@ -1325,7 +1545,7 @@ public boolean needsProgressMonitor() { return true; } - + /** * Completes processing of the wizard. If this method returns * true, the wizard will close; otherwise, it will stay active. @@ -1340,24 +1560,24 @@ } //Validation of patch root - if(optionsPage.getRootSelection() == OptionsPage.ROOT_CUSTOM) { - String path = optionsPage.getPath(); - IFile file2; - try { - file2 = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(path)); - } catch(IllegalArgumentException e) { - final String title = CompareMessages.GenerateLocalDiff_3; - final String msg = CompareMessages.GenerateLocalDiff_4; - final MessageDialog dialog = new MessageDialog(getShell(), title, - null, msg, MessageDialog.ERROR, - new String[] { IDialogConstants.OK_LABEL }, 0); - dialog.open(); - return false; - } - if(!validateFile2(file2)) { - return false; - } - } +// if(optionsPage.getRootSelection() == OptionsPage.ROOT_CUSTOM) { +// String path = optionsPage.getPath(); +// IFile file2; +// try { +// file2 = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(path)); +// } catch(IllegalArgumentException e) { +// final String title = CompareMessages.GenerateLocalDiff_3; +// final String msg = CompareMessages.GenerateLocalDiff_4; +// final MessageDialog dialog = new MessageDialog(getShell(), title, +// null, msg, MessageDialog.ERROR, +// new String[] { IDialogConstants.OK_LABEL }, 0); +// dialog.open(); +// return false; +// } +// if(!validateFile2(file2)) { +// return false; +// } +// } // Create the patch generateDiffFile(file); @@ -1424,10 +1644,9 @@ } else { oldPath = this.rightPath; } - - UnifiedDiffFormatter formatter = new UnifiedDiffFormatter(merger, - leftDoc, rightDoc, oldPath, toPath, directionSelectionPage - .isRightToLeft()); + + //TODO extend formatter to use list of mergers. + UnifiedDiffFormatter formatter = new UnifiedDiffFormatter(createFormatterInput()); try { if (file == null) { formatter.generateDiff(); @@ -1438,6 +1657,124 @@ throw new RuntimeException(e); } } + + private Object[][] createFormatterInput() { + Set keys = associatedResources.keySet(); + Object[][] result = new Object[keys.size()][3]; + DocumentMerger merg = null; + int i = 0; + for (Iterator iterator = keys.iterator(); iterator.hasNext();) { + IFile sourceRes = (IFile) iterator.next(); + IFile targetRes = (IFile) associatedResources.get(sourceRes); + merg = createDocumentMerger(sourceRes, targetRes); + result[i][0] = merg; + result[i][1] = sourceRes; + result[i][2] = targetRes; + i++; + } + return result; + } + + private DocumentMerger createDocumentMerger(IFile leftFile, IFile rightFile){ + IDocument leftDoc = convertFileToDocument(leftFile); + IDocument rightDoc = convertFileToDocument(rightFile); + if (leftDoc == null) { + leftDoc = new Document(); + } + if (rightDoc == null) { + rightDoc = new Document(); + } + DocumentMerger docMerger; + docMerger = new DocumentMerger(new LocalDiffMergerInput(leftDoc, rightDoc)); + try { + docMerger.doDiff(); + } catch (Exception e) { + throw new RuntimeException(e); + } + return docMerger; + } + + private IDocument convertFileToDocument(IFile file) { + if(file == null) + return null; + StringBuffer str = new StringBuffer(); + int c; + try{ + InputStream inputStream = file.getContents(); + while ((c = inputStream.read())!=-1){ + str.append((char)c); + } + inputStream.close(); + return new Document(str.toString()); + }catch(Exception ex){ + CompareUIPlugin.log(ex); + } + + return null; + } + + class LocalDiffMergerInput implements IDocumentMergerInput { + + private IDocument leftDoc; + private IDocument rightDoc; + + public LocalDiffMergerInput(IDocument leftDoc, IDocument rightDoc) { + this.leftDoc = leftDoc ; + this.rightDoc= rightDoc; + } + + public ITokenComparator createTokenComparator(String line) { + return new TokenComparator(line); + } + public CompareConfiguration getCompareConfiguration() { + return new CompareConfiguration(); + } + public IDocument getDocument(char contributor) { + switch (contributor) { + case MergeViewerContentProvider.LEFT_CONTRIBUTOR: + return leftDoc; + case MergeViewerContentProvider.RIGHT_CONTRIBUTOR: + return rightDoc; + case MergeViewerContentProvider.ANCESTOR_CONTRIBUTOR: + return null; + } + return null; + } + public int getHunkStart() { + return 0; + } + public Position getRegion(char contributor) { + switch (contributor) { + case MergeViewerContentProvider.LEFT_CONTRIBUTOR: + return new Position(0, leftDoc.getLength()); + case MergeViewerContentProvider.RIGHT_CONTRIBUTOR: + return new Position(0, rightDoc.getLength()); + case MergeViewerContentProvider.ANCESTOR_CONTRIBUTOR: + return new Position(0, 0); + } + return null; + } + public boolean isHunkOnLeft() { + return false; + } + public boolean isIgnoreAncestor() { + return true; + } + public boolean isPatchHunk() { + return false; + } + + public boolean isShowPseudoConflicts() { + return false; + } + public boolean isThreeWay() { + return false; + } + public boolean isPatchHunkOk() { + return false; + } + + } public boolean validateFile(File file) { @@ -1644,4 +1981,6 @@ } } + + } 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.2.2 diff -u -r1.20.2.2 CompareMessages.java --- compare/org/eclipse/compare/internal/CompareMessages.java 26 Jan 2009 14:13:04 -0000 1.20.2.2 +++ compare/org/eclipse/compare/internal/CompareMessages.java 26 Feb 2009 00:21:36 -0000 @@ -177,6 +177,9 @@ public static String GenerateLocalDiff_4; public static String GenerateLocalDiff_5; public static String GenerateLocalDiff_6; + public static String GenerateDiffFileWizard_SelectAll; + public static String GenerateDiffFileWizard_DeselectAll; + public static String GenerateDiffFileWizard_noChangesSelected; static { NLS.initializeMessages(BUNDLE_NAME, CompareMessages.class); Index: compare/org/eclipse/compare/internal/Utilities.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java,v retrieving revision 1.69 diff -u -r1.69 Utilities.java --- compare/org/eclipse/compare/internal/Utilities.java 15 Jul 2008 14:45:29 -0000 1.69 +++ compare/org/eclipse/compare/internal/Utilities.java 26 Feb 2009 00:21:40 -0000 @@ -781,4 +781,13 @@ }); } } + + public static IResource getResource(ITypedElement element) { + if (element instanceof BufferedResourceNode) { + BufferedResourceNode bn= (BufferedResourceNode) element; + return bn.getResource(); + } + return null; + + } } 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.2.3 diff -u -r1.31.2.3 CompareMessages.properties --- compare/org/eclipse/compare/internal/CompareMessages.properties 4 Feb 2009 09:54:51 -0000 1.31.2.3 +++ compare/org/eclipse/compare/internal/CompareMessages.properties 26 Feb 2009 00:21:36 -0000 @@ -145,6 +145,7 @@ CompareWithOtherResourceDialog_workspaceMainButton=Browse... CompareWithOtherResourceDialog_workspaceRadioButton=Workspace +CreatePatchActionTitle=Create Patch... WorkspacePatchDialogTitle=Set a Patch Location WorkspacePatchDialogDescription=Select a folder in the workspace and enter a name for the patch. Save_To_Clipboard_2=&Clipboard @@ -188,7 +189,7 @@ GenerateDiffFileWizard_13=Use only &file path: GenerateDiffFileWizard_Left=&Left: GenerateDiffFileWizard_Right=&Right: -CreatePatchActionTitle=Create Patch... +CreatePatchActionTitle=Create Patch WorkspacePatchDialogTitle=Set a Patch Location WorkspacePatchDialogDescription=Select a folder in the workspace and enter a name for the patch. Save_To_Clipboard_2=&Clipboard @@ -231,4 +232,7 @@ GenerateDiffFileWizard_ProjectClosed=The specified path points to a closed project. GenerateDiffFileWizard_13=Use only &file path: GenerateDiffFileWizard_Left=&Left: -GenerateDiffFileWizard_Right=&Right: \ No newline at end of file +GenerateDiffFileWizard_Right=&Right: +GenerateDiffFileWizard_SelectAll=Select &All +GenerateDiffFileWizard_DeselectAll=&Deselect All +GenerateDiffFileWizard_noChangesSelected=No changes selected. \ No newline at end of file Index: compare/org/eclipse/compare/internal/ICompareUIConstants.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/ICompareUIConstants.java,v retrieving revision 1.13.6.1 diff -u -r1.13.6.1 ICompareUIConstants.java --- compare/org/eclipse/compare/internal/ICompareUIConstants.java 26 Jan 2009 10:55:49 -0000 1.13.6.1 +++ compare/org/eclipse/compare/internal/ICompareUIConstants.java 26 Feb 2009 00:21:38 -0000 @@ -40,7 +40,7 @@ public static final String PROP_TITLE_IMAGE = PREFIX + "TitleImage"; //$NON-NLS-1$ public static final String PROP_SELECTED_EDITION = PREFIX + "SelectedEdition"; //$NON-NLS-1$ - public static final int COMPARE_IMAGE_WIDTH= 22; + public static final int COMPARE_IMAGE_WIDTH= 17; public static final String PREF_NAVIGATION_END_ACTION= PREFIX + "NavigationEndAction"; //$NON-NLS-1$ public static final String PREF_NAVIGATION_END_ACTION_LOCAL= PREFIX + "NavigationEndActionLocal"; //$NON-NLS-1$ Index: compare/org/eclipse/compare/internal/UnifiedDiffFormatter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/Attic/UnifiedDiffFormatter.java,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 UnifiedDiffFormatter.java --- compare/org/eclipse/compare/internal/UnifiedDiffFormatter.java 26 Jan 2009 14:13:04 -0000 1.1.2.2 +++ compare/org/eclipse/compare/internal/UnifiedDiffFormatter.java 26 Feb 2009 00:21:39 -0000 @@ -17,6 +17,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; @@ -26,7 +27,9 @@ import org.eclipse.compare.internal.merge.DocumentMerger; import org.eclipse.compare.internal.merge.DocumentMerger.Diff; import org.eclipse.compare.rangedifferencer.RangeDifference; +import org.eclipse.core.resources.IFile; import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.TextTransfer; @@ -52,22 +55,10 @@ public static final String RANGE_INFORMATION_PREFIX = "@@ -"; //$NON-NLS-1$ public static final String RANGE_INFORMATION_AFFIX = " @@"; //$NON-NLS-1$ - private DocumentMerger merger; - private IDocument leftDoc; - private IDocument rightDoc; - private String oldPath; - private String newPath; - private boolean rightToLeft; - - public UnifiedDiffFormatter(DocumentMerger merger, IDocument leftDoc, - IDocument rightDoc, String oldPath, String newPath, - boolean rightToLeft) { - this.merger = merger; - this.leftDoc = leftDoc; - this.rightDoc = rightDoc; - this.oldPath = oldPath; - this.newPath = newPath; - this.rightToLeft = rightToLeft; + private Object[][] input; + + public UnifiedDiffFormatter(Object[][] input) { + this.input = input; } /** @@ -148,95 +139,135 @@ * @param strictUnixFormat determinates if the format should be fully compatible with the Unix one. */ private void generateDiff(PrintStream output, boolean strictUnixFormat) { - ArrayList allDiffs = merger.getAllDiffs(); - // If the first block isn't the only one, or first block is different - if (allDiffs.size() > 1 || isPartDifferent(allDiffs, 0)) { - output.println(INDEX_MARKER + oldPath); - output.println(DELIMITER); - Date oldDate = Calendar.getInstance().getTime(); - Date newDate = Calendar.getInstance().getTime(); - String oldDateFormat = DateFormat.getDateTimeInstance().format(oldDate); - String newDateFormat = DateFormat.getDateTimeInstance().format(newDate); - output.println(OLD_FILE_PREFIX + oldPath + '\t' - + oldDateFormat + " -0000"); //$NON-NLS-1$ - output.println(NEW_FILE_PREFIX + newPath + '\t' - + newDateFormat + " -0000"); //$NON-NLS-1$ - - boolean firstHunk = true; - Hunk currentHunk = null; - - int currentLineNumberOld = 0; - int currentLineNumberNew = 0; - - for (int partNumber = 0; partNumber < allDiffs.size(); partNumber++) { - - ArrayList oldPart = getPart(partNumber, LEFT_CONTRIBUTOR); - ArrayList newPart = getPart(partNumber, RIGHT_CONTRIBUTOR); - - if (isPartDifferent(allDiffs, partNumber)) { - // This part has some changes - if (firstHunk) { - // Hunk will start with changed block - currentHunk = new Hunk(0, 0, strictUnixFormat); - firstHunk = false; - } - if (partNumber == (allDiffs.size() - 1)) { - // If it is the last part - currentHunk.addPartRangeToOld(oldPart, 0, oldPart - .size(), true); - currentHunk.addPartRangeToNew(newPart, 0, newPart - .size(), true); - } else { - currentHunk.addPartRangeToOld(oldPart, 0, oldPart - .size(), false); - currentHunk.addPartRangeToNew(newPart, 0, newPart - .size(), false); - } - } else { - if (firstHunk) { - // Hunk will start with context - currentHunk = new Hunk((oldPart.size() - 1) - NUMBER_OF_CONTEXT_LINES, - (oldPart.size() - 1) - NUMBER_OF_CONTEXT_LINES, strictUnixFormat); - firstHunk = false; - currentHunk.addPartRangeToBoth(oldPart, - (oldPart.size() - 1) - NUMBER_OF_CONTEXT_LINES, oldPart.size(), false); - } else { + for (int fileNr = 0; fileNr < input.length; fileNr++) { + DocumentMerger merger = (DocumentMerger) input[fileNr][0]; + IDocument leftDoc = convertFileToDocument((IFile)input[fileNr][1]); + IDocument rightDoc = convertFileToDocument((IFile)input[fileNr][2]); + String oldPath; + String newPath; + if (leftDoc == null) { + leftDoc = new Document(); + newPath = ((IFile)input[fileNr][2]).getFullPath().toString(); + oldPath = ((IFile)input[fileNr][2]).getFullPath().toString(); + } + else if (rightDoc == null) { + rightDoc = new Document(); + newPath = ((IFile)input[fileNr][1]).getFullPath().toString(); + oldPath = ((IFile)input[fileNr][1]).getFullPath().toString(); + } + else { + oldPath = ((IFile)input[fileNr][1]).getFullPath().toString(); + newPath = ((IFile)input[fileNr][2]).getFullPath().toString(); + } + + ArrayList allDiffs = merger.getAllDiffs(); + // If the first block isn't the only one, or first block is different + if (allDiffs.size() > 1 || isPartDifferent(allDiffs, 0)) { + output.println(INDEX_MARKER + oldPath); + output.println(DELIMITER); + Date oldDate = Calendar.getInstance().getTime(); + Date newDate = Calendar.getInstance().getTime(); + String oldDateFormat = DateFormat.getDateTimeInstance().format(oldDate); + String newDateFormat = DateFormat.getDateTimeInstance().format(newDate); + output.println(OLD_FILE_PREFIX + oldPath + '\t' + + oldDateFormat + " -0000"); //$NON-NLS-1$ + output.println(NEW_FILE_PREFIX + newPath + '\t' + + newDateFormat + " -0000"); //$NON-NLS-1$ + + boolean firstHunk = true; + Hunk currentHunk = null; + + int currentLineNumberOld = 0; + int currentLineNumberNew = 0; + + for (int partNumber = 0; partNumber < allDiffs.size(); partNumber++) { + + ArrayList oldPart = getPart(partNumber, LEFT_CONTRIBUTOR, merger, leftDoc, rightDoc); + ArrayList newPart = getPart(partNumber, RIGHT_CONTRIBUTOR, merger, leftDoc, rightDoc); + + if (isPartDifferent(allDiffs, partNumber)) { + // This part has some changes + if (firstHunk) { + // Hunk will start with changed block + currentHunk = new Hunk(0, 0, strictUnixFormat); + firstHunk = false; + } if (partNumber == (allDiffs.size() - 1)) { // If it is the last part - currentHunk.addPartRangeToBoth(oldPart, 0, NUMBER_OF_CONTEXT_LINES, true); + currentHunk.addPartRangeToOld(oldPart, 0, oldPart + .size(), true); + currentHunk.addPartRangeToNew(newPart, 0, newPart + .size(), true); + } else { + currentHunk.addPartRangeToOld(oldPart, 0, oldPart + .size(), false); + currentHunk.addPartRangeToNew(newPart, 0, newPart + .size(), false); + } + } else { + if (firstHunk) { + // Hunk will start with context + currentHunk = new Hunk((oldPart.size() - 1) - NUMBER_OF_CONTEXT_LINES, + (oldPart.size() - 1) - NUMBER_OF_CONTEXT_LINES, strictUnixFormat); + firstHunk = false; + currentHunk.addPartRangeToBoth(oldPart, + (oldPart.size() - 1) - NUMBER_OF_CONTEXT_LINES, oldPart.size(), false); } else { - if (oldPart.size() - 1 < 2*NUMBER_OF_CONTEXT_LINES) { - // Context too short to start new hunk - currentHunk.addPartRangeToBoth(oldPart, 0, - oldPart.size(), false); + if (partNumber == (allDiffs.size() - 1)) { + // If it is the last part + currentHunk.addPartRangeToBoth(oldPart, 0, NUMBER_OF_CONTEXT_LINES, true); } else { - // Context long enough to start new hunk - currentHunk.addPartRangeToBoth(oldPart, 0, NUMBER_OF_CONTEXT_LINES, - false); - currentHunk.printTo(output); - currentHunk = new Hunk(currentLineNumberOld - + (oldPart.size() - 1) - NUMBER_OF_CONTEXT_LINES, - currentLineNumberNew + (oldPart.size() - 1) - - NUMBER_OF_CONTEXT_LINES, strictUnixFormat); - currentHunk.addPartRangeToBoth(oldPart, - (oldPart.size() - 1) - NUMBER_OF_CONTEXT_LINES, - oldPart.size(), false); + if (oldPart.size() - 1 < 2*NUMBER_OF_CONTEXT_LINES) { + // Context too short to start new hunk + currentHunk.addPartRangeToBoth(oldPart, 0, + oldPart.size(), false); + } else { + // Context long enough to start new hunk + currentHunk.addPartRangeToBoth(oldPart, 0, NUMBER_OF_CONTEXT_LINES, + false); + currentHunk.printTo(output); + currentHunk = new Hunk(currentLineNumberOld + + (oldPart.size() - 1) - NUMBER_OF_CONTEXT_LINES, + currentLineNumberNew + (oldPart.size() - 1) + - NUMBER_OF_CONTEXT_LINES, strictUnixFormat); + currentHunk.addPartRangeToBoth(oldPart, + (oldPart.size() - 1) - NUMBER_OF_CONTEXT_LINES, + oldPart.size(), false); + } } } } + currentLineNumberOld += oldPart.size(); + currentLineNumberNew += newPart.size(); } - currentLineNumberOld += oldPart.size(); - currentLineNumberNew += newPart.size(); - } - // Print the last hunk - currentHunk.printTo(output); + // Print the last hunk + currentHunk.printTo(output); + } } } - private ArrayList getPart(int nr, char side) { + private IDocument convertFileToDocument(IFile file) { + if(file == null) + return null; + StringBuffer str = new StringBuffer(); + int c; + try{ + InputStream inputStream = file.getContents(); + while ((c = inputStream.read())!=-1){ + str.append((char)c); + } + inputStream.close(); + return new Document(str.toString()); + }catch(Exception ex){ + CompareUIPlugin.log(ex); + } + + return null; + } + + private ArrayList getPart(int nr, char side, DocumentMerger merger, IDocument leftDoc, IDocument rightDoc) { try { - String s = extract(nr, side).replaceAll("\r\n", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ - s.replaceAll("\r", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + String s = extract(nr, side, merger, leftDoc, rightDoc).replaceAll("\r", ""); //$NON-NLS-1$ //$NON-NLS-2$ ArrayList diffLines = new ArrayList(Arrays .asList(s.split("\n", -1))); //$NON-NLS-1$ return diffLines; @@ -246,10 +277,9 @@ return null; } - private String extract(int nr, char side) throws BadLocationException { + private String extract(int nr, char side, DocumentMerger merger, IDocument leftDoc, IDocument rightDoc) throws BadLocationException { Diff diff = ((Diff) merger.getAllDiffs().get(nr)); - if (side == LEFT_CONTRIBUTOR && !rightToLeft - || side == RIGHT_CONTRIBUTOR && rightToLeft) { + if (side == LEFT_CONTRIBUTOR) { return leftDoc.get(diff.getPosition(LEFT_CONTRIBUTOR).offset, diff .getPosition(LEFT_CONTRIBUTOR).length); } 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 26 Feb 2009 00:21:39 -0000 @@ -129,6 +129,11 @@ ResourceCompareInput(CompareConfiguration config) { super(config); } + + public Object createDiff(){ + Differencer dif = new Differencer(); + return dif.findDifferences(false, null, null, null, fLeft, fRight); + } public Viewer createDiffViewer(Composite parent) { fDiffViewer= new DiffTreeViewer(parent, getCompareConfiguration()) { Index: plugin.xml =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/plugins/org.eclipse.compare/plugin.xml,v retrieving revision 1.68 diff -u -r1.68 plugin.xml --- plugin.xml 25 Aug 2008 12:35:11 -0000 1.68 +++ plugin.xml 26 Feb 2009 00:21:35 -0000 @@ -192,6 +192,9 @@ id="compareWithMenu"> + + @@ -280,6 +283,26 @@ id="addFromHistoryAction"> + + + + + + + +