1 11 12 package org.eclipse.ui.texteditor; 13 14 import org.eclipse.core.runtime.Assert; 15 import org.eclipse.core.runtime.IStatus; 16 import org.eclipse.core.runtime.Status; 17 18 import org.eclipse.swt.SWTError; 19 import org.eclipse.swt.custom.StyledText; 20 import org.eclipse.swt.dnd.Clipboard; 21 import org.eclipse.swt.dnd.DND; 22 import org.eclipse.swt.dnd.TextTransfer; 23 import org.eclipse.swt.dnd.Transfer; 24 import org.eclipse.swt.events.FocusEvent; 25 import org.eclipse.swt.events.FocusListener; 26 import org.eclipse.swt.events.ModifyEvent; 27 import org.eclipse.swt.events.ModifyListener; 28 import org.eclipse.swt.events.MouseEvent; 29 import org.eclipse.swt.events.MouseListener; 30 31 import org.eclipse.jface.text.BadLocationException; 32 import org.eclipse.jface.text.IDocument; 33 import org.eclipse.jface.text.IRegion; 34 import org.eclipse.jface.text.ITextListener; 35 import org.eclipse.jface.text.ITextViewer; 36 import org.eclipse.jface.text.Region; 37 import org.eclipse.jface.text.TextEvent; 38 39 import org.eclipse.ui.internal.texteditor.TextEditorPlugin; 40 41 import org.eclipse.jface.viewers.ISelectionChangedListener; 42 import org.eclipse.jface.viewers.SelectionChangedEvent; 43 44 45 49 class DeleteLineTarget { 50 51 54 private static class DeleteLineClipboard implements MouseListener, ModifyListener, ISelectionChangedListener, ITextListener, FocusListener { 55 56 57 private final ITextViewer fViewer; 58 72 73 private int fIndex= -1; 74 75 private Clipboard fClipboard; 76 77 private final StringBuffer fBuffer= new StringBuffer (); 78 79 private boolean fDeleting; 80 81 86 public DeleteLineClipboard(ITextViewer viewer) { 87 Assert.isNotNull(viewer); 88 fViewer= viewer; 89 } 90 91 96 public ITextViewer getViewer() { 97 return fViewer; 98 } 99 100 104 private void saveState() { 105 fIndex= fViewer.getTextWidget().getCaretOffset(); 106 } 107 108 114 private boolean hasSameState() { 115 return fIndex == fViewer.getTextWidget().getCaretOffset(); 116 } 117 118 121 public void checkState() { 122 123 if (fClipboard == null) { 124 StyledText text= fViewer.getTextWidget(); 125 if (text == null) 126 return; 127 128 fViewer.getSelectionProvider().addSelectionChangedListener(this); 129 text.addFocusListener(this); 130 text.addMouseListener(this); 131 text.addModifyListener(this); 132 133 fClipboard= new Clipboard(text.getDisplay()); 134 fBuffer.setLength(0); 135 136 } else if (!hasSameState()) { 137 fBuffer.setLength(0); 138 } 139 } 140 141 146 public void append(String deltaString) { 147 fBuffer.append(deltaString); 148 String string= fBuffer.toString(); 149 Transfer[] dataTypes= new Transfer[] { TextTransfer.getInstance() }; 150 Object [] data= new Object [] { string }; 151 fClipboard.setContents(data, dataTypes); 152 } 153 154 157 private void uninstall() { 158 159 if (fClipboard == null) 160 return; 161 162 StyledText text= fViewer.getTextWidget(); 163 if (text == null) 164 return; 165 166 fViewer.getSelectionProvider().removeSelectionChangedListener(this); 167 text.removeFocusListener(this); 168 text.removeMouseListener(this); 169 text.removeModifyListener(this); 170 171 fClipboard.dispose(); 172 fClipboard= null; 173 } 174 175 180 public void setDeleting(boolean deleting) { 181 fDeleting= deleting; 182 } 183 184 187 public void mouseDoubleClick(MouseEvent e) { 188 uninstall(); 189 } 190 191 194 public void mouseDown(MouseEvent e) { 195 uninstall(); 196 } 197 198 201 public void mouseUp(MouseEvent e) { 202 uninstall(); 203 } 204 205 208 public void selectionChanged(SelectionChangedEvent event) { 209 uninstall(); 210 } 211 212 215 public void focusGained(FocusEvent e) { 216 uninstall(); 217 } 218 219 222 public void focusLost(FocusEvent e) { 223 uninstall(); 224 } 225 226 229 public void textChanged(TextEvent event) { 230 uninstall(); 231 } 232 233 236 public void modifyText(ModifyEvent e) { 237 if (!fDeleting) 238 uninstall(); 239 } 240 } 241 242 245 private final DeleteLineClipboard fClipboard; 246 247 252 public DeleteLineTarget(ITextViewer viewer) { 253 fClipboard= new DeleteLineClipboard(viewer); 254 } 255 256 267 private static IRegion getDeleteRegion(IDocument document, int offset, int length, int type) throws BadLocationException { 268 269 int line= document.getLineOfOffset(offset); 270 int resultOffset= 0; 271 int resultLength= 0; 272 273 switch (type) { 274 case DeleteLineAction.WHOLE: 275 resultOffset= document.getLineOffset(line); 276 int endOffset= offset + length; 277 IRegion endLineInfo= document.getLineInformationOfOffset(endOffset); 278 int endLine= document.getLineOfOffset(endLineInfo.getOffset()); 279 if (endLineInfo.getOffset() == endOffset && endLine > 0 && length > 0) 280 endLine= endLine - 1; 281 resultLength= document.getLineOffset(endLine) + document.getLineLength(endLine) - resultOffset; 282 break; 283 284 case DeleteLineAction.TO_BEGINNING: 285 resultOffset= document.getLineOffset(line); 286 resultLength= offset - resultOffset; 287 break; 288 289 case DeleteLineAction.TO_END: 290 resultOffset= offset; 291 292 IRegion lineRegion= document.getLineInformation(line); 293 int end= lineRegion.getOffset() + lineRegion.getLength(); 294 295 if (offset == end) { 296 String lineDelimiter= document.getLineDelimiter(line); 297 resultLength= lineDelimiter == null ? 0 : lineDelimiter.length(); 298 299 } else { 300 resultLength= end - resultOffset; 301 } 302 break; 303 304 default: 305 throw new IllegalArgumentException (); 306 } 307 308 return new Region(resultOffset, resultLength); 309 } 310 311 322 public void deleteLine(IDocument document, int offset, int length, int type, boolean copyToClipboard) throws BadLocationException { 323 324 IRegion deleteRegion= getDeleteRegion(document, offset, length, type); 325 int deleteOffset= deleteRegion.getOffset(); 326 int deleteLength= deleteRegion.getLength(); 327 328 if (deleteLength == 0) 329 return; 330 331 if (copyToClipboard) { 332 333 fClipboard.checkState(); 334 try { 335 fClipboard.append(document.get(deleteOffset, deleteLength)); 336 } catch (SWTError e) { 337 if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD) 338 throw e; 339 342 Status status= new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, e.code, EditorMessages.Editor_error_clipboard_copy_failed_message, e); 344 TextEditorPlugin.getDefault().getLog().log(status); 345 346 fClipboard.uninstall(); 347 return; } 349 350 fClipboard.setDeleting(true); 351 document.replace(deleteOffset, deleteLength, null); 352 fClipboard.setDeleting(false); 353 354 fClipboard.saveState(); 355 356 } else { 357 document.replace(deleteOffset, deleteLength, ""); } 359 } 360 } 361 | Popular Tags |