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 .IStreamContentAccessor ;
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 ;
@@ -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