2222import org.eclipse.compare.CompareConfiguration;
2323import org.eclipse.compare.CompareEditorInput;
2424import org.eclipse.compare.CompareUI;
25+ import org.eclipse.compare.IEditableContent;
2526import org.eclipse.compare.IEncodedStreamContentAccessor;
2627import org.eclipse.compare.ITypedElement;
28+ import org.eclipse.compare.ResourceNode;
2729import org.eclipse.compare.structuremergeviewer.DiffNode;
2830import org.eclipse.core.resources.IFile;
31+ import org.eclipse.core.resources.IResource;
2932import org.eclipse.core.runtime.CoreException;
3033import org.eclipse.core.runtime.IProgressMonitor;
3134import org.eclipse.jface.action.IAction;
4346import org.eclipse.ui.IWorkbenchPage;
4447import org.eclipse.ui.IWorkbenchPart;
4548import org.eclipse.ui.PlatformUI;
46- import org.eclipse.ui.forms.editor.FormEditor ;
49+ import org.eclipse.ui.part.MultiPageEditorPart ;
4750import org.eclipse.ui.texteditor.ITextEditor;
4851
4952public class ClipboardCompare extends BaseCompareAction implements IObjectActionDelegate {
5053
5154 private final String clipboard = "Clipboard"; //$NON-NLS-1$
5255 private final String compareFailed = "Comparision Failed"; //$NON-NLS-1$
5356
57+ private IFile currentResouce;
58+
5459 private IWorkbenchPart activePart;
5560
61+ private int offSet;
62+ private int len;
63+
64+ private boolean partialSelection;
65+
5666 @Override
5767 protected void run(ISelection selection) {
68+ offSet = -1;
69+ len = -1;
70+ partialSelection = false;
5871 IFile[] files = Utilities.getFiles(selection);
5972 Shell parentShell = CompareUIPlugin.getShell();
6073 for (IFile file : files) {
74+ currentResouce = file;
6175 try {
62- processComparison(file, parentShell);
76+ processComparison(parentShell);
6377 } catch (Exception e) {
6478 MessageDialog.openError(parentShell, compareFailed, e.getMessage());
6579 }
@@ -74,32 +88,38 @@ protected boolean isEnabled(ISelection selection) {
7488 * Process comparison with selection or entire editor contents with contents in
7589 * clipboard
7690 *
77- * @param file Editor file
7891 * @param parentShell The shell containing this window's controls
7992 * @throws IOException, CoreException
8093 */
81- private void processComparison(IFile file, Shell parentShell) throws IOException, CoreException {
94+ private void processComparison(Shell parentShell) throws IOException, CoreException {
8295 String cb = getClipboard().toString();
83- String fileName = file .getName();
96+ String fileName = currentResouce .getName();
8497 IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
8598 IEditorPart editor = page.getActiveEditor();
8699 if (activePart instanceof IViewPart) {
87- String fileContents = new String(file .getContents().readAllBytes(), file .getCharset());
100+ String fileContents = new String(currentResouce .getContents().readAllBytes(), currentResouce .getCharset());
88101 showComparison(fileContents, fileName, cb, parentShell);
89102 return;
90103 }
91104 final String selectionContents;
92- if (editor instanceof FormEditor fromEditor) {
93- editor = fromEditor.getActiveEditor();
105+ if (editor instanceof MultiPageEditorPart mpe) {
106+ Object page2 = mpe.getSelectedPage();
107+ if (page2 instanceof IEditorPart e) {
108+ editor = e;
109+ }
94110 }
95111 if (editor instanceof ITextEditor txtEditor) {
96112 ISelection selection = txtEditor.getSelectionProvider().getSelection();
97113 if (selection instanceof ITextSelection textSelection) {
98114 selectionContents = textSelection.getText();
99115 if (selectionContents.isEmpty()) {
100- String fileContents = new String(file.getContents().readAllBytes(), file.getCharset());
116+ String fileContents = new String(currentResouce.getContents().readAllBytes(),
117+ currentResouce.getCharset());
101118 showComparison(fileContents, fileName, cb, parentShell);
102119 } else {
120+ offSet = textSelection.getOffset();
121+ len = textSelection.getLength();
122+ partialSelection = true;
103123 showComparison(selectionContents, fileName, cb, parentShell);
104124 }
105125 return;
@@ -109,7 +129,8 @@ private void processComparison(IFile file, Shell parentShell) throws IOException
109129 ISelection selection = existingCompare.getSite().getSelectionProvider().getSelection();
110130 if (selection instanceof ITextSelection textSelection) {
111131 String selectedText = textSelection.getText();
112- String fileContents = new String(file.getContents().readAllBytes(), file.getCharset());
132+ String fileContents = new String(currentResouce.getContents().readAllBytes(),
133+ currentResouce.getCharset());
113134 showComparison(fileContents, fileName, selectedText, parentShell);
114135 }
115136 }
@@ -160,6 +181,65 @@ public InputStream getContents() throws CoreException {
160181 }
161182
162183 }
184+ class EditableFileNode extends ResourceNode implements IEditableContent {
185+
186+ private final int selectionOffset;
187+ private final int selectionLength;
188+
189+ public EditableFileNode(IFile file, int selectionOffset, int selectionLength) {
190+ super(file);
191+ this.selectionOffset = selectionOffset;
192+ this.selectionLength = selectionLength;
193+ }
194+
195+ @Override
196+ public InputStream getContents() throws CoreException {
197+ IFile file = (IFile) getResource();
198+ if (!partialSelection) {
199+ return new ByteArrayInputStream(file.readAllBytes());
200+ }
201+ try {
202+ String content = new String(file.getContents().readAllBytes(), file.getCharset());
203+ int start = Math.max(0, Math.min(selectionOffset, content.length()));
204+ int end = Math.max(start, Math.min(selectionOffset + selectionLength, content.length()));
205+ String selectedPart = content.substring(start, end);
206+ return new ByteArrayInputStream(selectedPart.getBytes(file.getCharset()));
207+ } catch (IOException e) {
208+ MessageDialog.openError(CompareUIPlugin.getShell(), compareFailed, e.getMessage());
209+ }
210+ return new ByteArrayInputStream(file.readAllBytes());
211+ }
212+
213+ @Override
214+ public void setContent(byte[] newContent) {
215+ try {
216+ if (selectionLength <= 1) {
217+ ((IFile) getResource()).setContents(new ByteArrayInputStream(newContent),
218+ IResource.FORCE | IResource.KEEP_HISTORY, null);
219+ } else {
220+ IFile file = (IFile) getResource();
221+ String charset = file.getCharset();
222+ String original = new String(file.getContents().readAllBytes(), charset);
223+ String updatedSelection = new String(newContent, charset);
224+ int offset = Math.max(0, Math.min(selectionOffset, original.length()));
225+ int end = Math.max(offset, Math.min(offset + selectionLength, original.length()));
226+ String newFileContent = original.substring(0, offset) + updatedSelection
227+ + original.substring(end);
228+ ByteArrayInputStream updatedStream = new ByteArrayInputStream(newFileContent.getBytes(charset));
229+ file.setContents(updatedStream, IResource.FORCE | IResource.KEEP_HISTORY, null);
230+ }
231+
232+ } catch (Exception e) {
233+ MessageDialog.openError(CompareUIPlugin.getShell(), compareFailed, e.getMessage());
234+ }
235+ }
236+
237+ @Override
238+ public boolean isEditable() {
239+ return true;
240+ }
241+ }
242+
163243 if (source == null) {
164244 MessageDialog.openInformation(parentShell, compareFailed, "Failed to process selected file"); //$NON-NLS-1$
165245 return;
@@ -173,12 +253,20 @@ public InputStream getContents() throws CoreException {
173253 @Override
174254 protected Object prepareInput(IProgressMonitor monitor)
175255 throws InvocationTargetException, InterruptedException {
176- return new DiffNode(new ClipboardTypedElement(fileName, source),
177- new ClipboardTypedElement(clipboard, clipboardContents));
256+ ITypedElement left;
257+ if (offSet >= 0 && len >= 0) {
258+ left = new EditableFileNode(currentResouce, offSet, len);
259+ } else {
260+ left = new EditableFileNode(currentResouce, 0, Integer.MAX_VALUE);
261+ }
262+ ITypedElement right = new ClipboardTypedElement(clipboard, clipboardContents);
263+ return new DiffNode(left, right);
178264
179265 }
180266 };
267+ compareInput.setTitle(currentResouce.getName());
181268 CompareUI.openCompareEditor(compareInput);
269+
182270 }
183271
184272 /**
@@ -200,4 +288,4 @@ public void setActivePart(IAction action, IWorkbenchPart targetPart) {
200288 this.activePart = targetPart;
201289 }
202290
203- }
291+ }
0 commit comments