Skip to content

Commit a089065

Browse files
committed
Support for modifying source in compare clipboard editor
1 parent 3f12c83 commit a089065

File tree

1 file changed

+94
-10
lines changed

1 file changed

+94
-10
lines changed

team/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ClipboardCompare.java

Lines changed: 94 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@
2222
import org.eclipse.compare.CompareConfiguration;
2323
import org.eclipse.compare.CompareEditorInput;
2424
import org.eclipse.compare.CompareUI;
25+
import org.eclipse.compare.IEditableContent;
2526
import org.eclipse.compare.IStreamContentAccessor;
2627
import org.eclipse.compare.ITypedElement;
28+
import org.eclipse.compare.ResourceNode;
2729
import org.eclipse.compare.structuremergeviewer.DiffNode;
2830
import org.eclipse.core.resources.IFile;
31+
import org.eclipse.core.resources.IResource;
2932
import org.eclipse.core.runtime.CoreException;
3033
import org.eclipse.core.runtime.IProgressMonitor;
3134
import org.eclipse.jface.action.IAction;
@@ -50,15 +53,26 @@ public class ClipboardCompare extends BaseCompareAction implements IObjectAction
5053
private final String clipboard = "Clipboard"; //$NON-NLS-1$
5154
private final String compareFailed = "Comparision Failed"; //$NON-NLS-1$
5255

56+
private IFile currentResouce;
57+
5358
private IWorkbenchPart activePart;
5459

60+
private int offSet;
61+
private int len;
62+
63+
private boolean partialSelection;
64+
5565
@Override
5666
protected void run(ISelection selection) {
67+
offSet = -1;
68+
len = -1;
69+
partialSelection = false;
5770
IFile[] files = Utilities.getFiles(selection);
5871
Shell parentShell = CompareUIPlugin.getShell();
5972
for (IFile file : files) {
73+
currentResouce = file;
6074
try {
61-
processComparison(file, parentShell);
75+
processComparison(parentShell);
6276
} catch (Exception e) {
6377
MessageDialog.openError(parentShell, compareFailed, e.getMessage());
6478
}
@@ -73,17 +87,16 @@ protected boolean isEnabled(ISelection selection) {
7387
* Process comparison with selection or entire editor contents with contents in
7488
* clipboard
7589
*
76-
* @param file Editor file
7790
* @param parentShell The shell containing this window's controls
7891
* @throws IOException, CoreException
7992
*/
80-
private void processComparison(IFile file, Shell parentShell) throws IOException, CoreException {
93+
private void processComparison(Shell parentShell) throws IOException, CoreException {
8194
String cb = getClipboard().toString();
82-
String fileName = file.getName();
95+
String fileName = currentResouce.getName();
8396
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
8497
IEditorPart editor = page.getActiveEditor();
8598
if (activePart instanceof IViewPart) {
86-
String fileContents = new String(file.getContents().readAllBytes(), file.getCharset());
99+
String fileContents = new String(currentResouce.getContents().readAllBytes(), currentResouce.getCharset());
87100
showComparison(fileContents, fileName, cb, parentShell);
88101
return;
89102
}
@@ -93,9 +106,13 @@ private void processComparison(IFile file, Shell parentShell) throws IOException
93106
if (selection instanceof ITextSelection textSelection) {
94107
selectionContents = textSelection.getText();
95108
if (selectionContents.isEmpty()) {
96-
String fileContents = new String(file.getContents().readAllBytes(), file.getCharset());
109+
String fileContents = new String(currentResouce.getContents().readAllBytes(),
110+
currentResouce.getCharset());
97111
showComparison(fileContents, fileName, cb, parentShell);
98112
} else {
113+
offSet = textSelection.getOffset();
114+
len = textSelection.getLength();
115+
partialSelection = true;
99116
showComparison(selectionContents, fileName, cb, parentShell);
100117
}
101118
return;
@@ -105,7 +122,8 @@ private void processComparison(IFile file, Shell parentShell) throws IOException
105122
ISelection selection = existingCompare.getSite().getSelectionProvider().getSelection();
106123
if (selection instanceof ITextSelection textSelection) {
107124
String selectedText = textSelection.getText();
108-
String fileContents = new String(file.getContents().readAllBytes(), file.getCharset());
125+
String fileContents = new String(currentResouce.getContents().readAllBytes(),
126+
currentResouce.getCharset());
109127
showComparison(fileContents, fileName, selectedText, parentShell);
110128
}
111129
}
@@ -151,6 +169,65 @@ public InputStream getContents() throws CoreException {
151169
}
152170

153171
}
172+
class EditableFileNode extends ResourceNode implements IEditableContent {
173+
174+
private final int selectionOffset;
175+
private final int selectionLength;
176+
177+
public EditableFileNode(IFile file, int selectionOffset, int selectionLength) {
178+
super(file);
179+
this.selectionOffset = selectionOffset;
180+
this.selectionLength = selectionLength;
181+
}
182+
183+
@Override
184+
public InputStream getContents() throws CoreException {
185+
IFile file = (IFile) getResource();
186+
if (!partialSelection) {
187+
return new ByteArrayInputStream(file.readAllBytes());
188+
}
189+
try {
190+
String content = new String(file.getContents().readAllBytes(), file.getCharset());
191+
int start = Math.max(0, Math.min(selectionOffset, content.length()));
192+
int end = Math.max(start, Math.min(selectionOffset + selectionLength, content.length()));
193+
String selectedPart = content.substring(start, end);
194+
return new ByteArrayInputStream(selectedPart.getBytes(file.getCharset()));
195+
} catch (IOException e) {
196+
MessageDialog.openError(CompareUIPlugin.getShell(), compareFailed, e.getMessage());
197+
}
198+
return new ByteArrayInputStream(file.readAllBytes());
199+
}
200+
201+
@Override
202+
public void setContent(byte[] newContent) {
203+
try {
204+
if (selectionLength <= 1) {
205+
((IFile) getResource()).setContents(new ByteArrayInputStream(newContent),
206+
IResource.FORCE | IResource.KEEP_HISTORY, null);
207+
} else {
208+
IFile file = (IFile) getResource();
209+
String charset = file.getCharset();
210+
String original = new String(file.getContents().readAllBytes(), charset);
211+
String updatedSelection = new String(newContent, charset);
212+
int offset = Math.max(0, Math.min(selectionOffset, original.length()));
213+
int end = Math.max(offset, Math.min(offset + selectionLength, original.length()));
214+
String newFileContent = original.substring(0, offset) + updatedSelection
215+
+ original.substring(end);
216+
ByteArrayInputStream updatedStream = new ByteArrayInputStream(newFileContent.getBytes(charset));
217+
file.setContents(updatedStream, IResource.FORCE | IResource.KEEP_HISTORY, null);
218+
}
219+
220+
} catch (Exception e) {
221+
MessageDialog.openError(CompareUIPlugin.getShell(), compareFailed, e.getMessage());
222+
}
223+
}
224+
225+
@Override
226+
public boolean isEditable() {
227+
return true;
228+
}
229+
}
230+
154231
if (source == null) {
155232
MessageDialog.openInformation(parentShell, compareFailed, "Failed to process selected file"); //$NON-NLS-1$
156233
return;
@@ -164,11 +241,18 @@ public InputStream getContents() throws CoreException {
164241
@Override
165242
protected Object prepareInput(IProgressMonitor monitor)
166243
throws InvocationTargetException, InterruptedException {
167-
return new DiffNode(new ClipboardTypedElement(fileName, source),
168-
new ClipboardTypedElement(clipboard, clipboardContents));
244+
ITypedElement left;
245+
if (offSet >= 0 && len >= 0) {
246+
left = new EditableFileNode(currentResouce, offSet, len);
247+
} else {
248+
left = new EditableFileNode(currentResouce, 0, Integer.MAX_VALUE);
249+
}
250+
ITypedElement right = new ClipboardTypedElement(clipboard, clipboardContents);
251+
return new DiffNode(left, right);
169252

170253
}
171254
};
255+
compareInput.setTitle(currentResouce.getName());
172256
CompareUI.openCompareEditor(compareInput);
173257
}
174258

@@ -187,4 +271,4 @@ public void setActivePart(IAction action, IWorkbenchPart targetPart) {
187271
this.activePart = targetPart;
188272
}
189273

190-
}
274+
}

0 commit comments

Comments
 (0)