Skip to content

Commit e365828

Browse files
committed
Support for modifying source in compare clipboard editor
1 parent 401d483 commit e365828

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;
@@ -51,15 +54,26 @@ public class ClipboardCompare extends BaseCompareAction implements IObjectAction
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,17 +88,16 @@ 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
}
@@ -97,9 +110,13 @@ private void processComparison(IFile file, Shell parentShell) throws IOException
97110
if (selection instanceof ITextSelection textSelection) {
98111
selectionContents = textSelection.getText();
99112
if (selectionContents.isEmpty()) {
100-
String fileContents = new String(file.getContents().readAllBytes(), file.getCharset());
113+
String fileContents = new String(currentResouce.getContents().readAllBytes(),
114+
currentResouce.getCharset());
101115
showComparison(fileContents, fileName, cb, parentShell);
102116
} else {
117+
offSet = textSelection.getOffset();
118+
len = textSelection.getLength();
119+
partialSelection = true;
103120
showComparison(selectionContents, fileName, cb, parentShell);
104121
}
105122
return;
@@ -109,7 +126,8 @@ private void processComparison(IFile file, Shell parentShell) throws IOException
109126
ISelection selection = existingCompare.getSite().getSelectionProvider().getSelection();
110127
if (selection instanceof ITextSelection textSelection) {
111128
String selectedText = textSelection.getText();
112-
String fileContents = new String(file.getContents().readAllBytes(), file.getCharset());
129+
String fileContents = new String(currentResouce.getContents().readAllBytes(),
130+
currentResouce.getCharset());
113131
showComparison(fileContents, fileName, selectedText, parentShell);
114132
}
115133
}
@@ -155,6 +173,65 @@ public InputStream getContents() throws CoreException {
155173
}
156174

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

174257
}
175258
};
259+
compareInput.setTitle(currentResouce.getName());
176260
CompareUI.openCompareEditor(compareInput);
177261
}
178262

@@ -191,4 +275,4 @@ public void setActivePart(IAction action, IWorkbenchPart targetPart) {
191275
this.activePart = targetPart;
192276
}
193277

194-
}
278+
}

0 commit comments

Comments
 (0)