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