1 13 package org.eclipse.compare.internal; 14 15 import java.util.*; 16 import java.util.List ; 17 18 import org.eclipse.compare.ICompareContainer; 19 import org.eclipse.core.commands.operations.*; 20 import org.eclipse.jface.action.*; 21 import org.eclipse.jface.preference.IPreferenceStore; 22 import org.eclipse.jface.preference.PreferenceConverter; 23 import org.eclipse.jface.text.*; 24 import org.eclipse.jface.text.source.*; 25 import org.eclipse.jface.util.IPropertyChangeListener; 26 import org.eclipse.jface.util.PropertyChangeEvent; 27 import org.eclipse.jface.viewers.ISelectionChangedListener; 28 import org.eclipse.jface.viewers.SelectionChangedEvent; 29 import org.eclipse.swt.SWT; 30 import org.eclipse.swt.custom.StyledText; 31 import org.eclipse.swt.graphics.*; 32 import org.eclipse.swt.widgets.*; 33 import org.eclipse.ui.IWorkbenchActionConstants; 34 import org.eclipse.ui.PlatformUI; 35 import org.eclipse.ui.editors.text.EditorsUI; 36 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; 37 import org.eclipse.ui.texteditor.FindReplaceAction; 38 41 public class MergeSourceViewer extends SourceViewer 42 implements ISelectionChangedListener, ITextListener, IMenuListener, IOperationHistoryListener { 43 44 public static final String UNDO_ID= "undo"; public static final String REDO_ID= "redo"; public static final String CUT_ID= "cut"; public static final String COPY_ID= "copy"; public static final String PASTE_ID= "paste"; public static final String DELETE_ID= "delete"; public static final String SELECT_ALL_ID= "selectAll"; public static final String SAVE_ID= "save"; public static final String FIND_ID= "find"; 54 class TextOperationAction extends MergeViewerAction { 55 56 private int fOperationCode; 57 58 TextOperationAction(int operationCode, boolean mutable, boolean selection, boolean content) { 59 this(operationCode, null, mutable, selection, content); 60 61 } 62 63 public TextOperationAction(int operationCode, String actionDefinitionId, boolean mutable, boolean selection, boolean content) { 64 super(mutable, selection, content); 65 if (actionDefinitionId != null) 66 setActionDefinitionId(actionDefinitionId); 67 fOperationCode= operationCode; 68 update(); 69 } 70 71 public void run() { 72 if (isEnabled()) 73 doOperation(fOperationCode); 74 } 75 76 public boolean isEnabled() { 77 return fOperationCode != -1 && canDoOperation(fOperationCode); 78 } 79 80 public void update() { 81 this.setEnabled(isEnabled()); 82 } 83 } 84 85 private ResourceBundle fResourceBundle; 86 private Position fRegion; 87 private boolean fEnabled= true; 88 private HashMap fActions= new HashMap(); 89 private IDocument fRememberedDocument; 90 91 private boolean fAddSaveAction= true; 92 private boolean isConfigured = false; 93 94 private IPropertyChangeListener fPreferenceChangeListener; 96 private boolean fShowLineNumber=false; 97 private LineNumberRulerColumn fLineNumberColumn; 98 private List textActions = new ArrayList(); 99 100 public MergeSourceViewer(Composite parent, int style, ResourceBundle bundle, ICompareContainer container) { 101 super(parent, new CompositeRuler(), style | SWT.H_SCROLL | SWT.V_SCROLL); 102 103 fResourceBundle= bundle; 104 105 MenuManager menu= new MenuManager(); 106 menu.setRemoveAllWhenShown(true); 107 menu.addMenuListener(this); 108 StyledText te= getTextWidget(); 109 te.setMenu(menu.createContextMenu(te)); 110 container.registerContextMenu(menu, this); 111 112 fPreferenceChangeListener= new IPropertyChangeListener() { 114 public void propertyChange(PropertyChangeEvent event) { 115 MergeSourceViewer.this.handlePropertyChangeEvent(event); 116 } 117 }; 118 EditorsUI.getPreferenceStore().addPropertyChangeListener(fPreferenceChangeListener); 119 fShowLineNumber= EditorsUI.getPreferenceStore().getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER); 120 if(fShowLineNumber){ 121 updateLineNumberRuler(); 122 } 123 124 IOperationHistory history = getHistory(); 125 if (history != null) 126 history.addOperationHistoryListener(this); 127 } 128 129 public void rememberDocument(IDocument doc) { 130 fRememberedDocument= doc; 134 } 135 136 public IDocument getRememberedDocument() { 137 return fRememberedDocument; 138 } 139 140 public void hideSaveAction() { 141 fAddSaveAction= false; 142 } 143 144 public void setFont(Font font) { 145 StyledText te= getTextWidget(); 146 if (te != null) 147 te.setFont(font); 148 if (fLineNumberColumn != null) { 149 fLineNumberColumn.setFont(font); 150 layoutViewer(); 151 } 152 } 153 154 public void setBackgroundColor(Color color) { 155 StyledText te= getTextWidget(); 156 if (te != null) 157 te.setBackground(color); 158 if (fLineNumberColumn != null) 159 fLineNumberColumn.setBackground(color); 160 } 161 162 public void setEnabled(boolean enabled) { 163 if (enabled != fEnabled) { 164 fEnabled= enabled; 165 StyledText c= getTextWidget(); 166 if (c != null) { 167 c.setEnabled(enabled); 168 Display d= c.getDisplay(); 169 c.setBackground(enabled ? d.getSystemColor(SWT.COLOR_LIST_BACKGROUND) : null); 170 } 171 } 172 } 173 174 public boolean getEnabled() { 175 return fEnabled; 176 } 177 178 public void setRegion(Position region) { 179 fRegion= region; 180 } 181 182 public Position getRegion() { 183 return fRegion; 184 } 185 186 public boolean isControlOkToUse() { 187 StyledText t= getTextWidget(); 188 return t != null && !t.isDisposed(); 189 } 190 191 public void setSelection(Position position) { 192 if (position != null) 193 setSelectedRange(position.getOffset(), position.getLength()); 194 } 195 196 public void setLineBackground(Position position, Color c) { 197 StyledText t= getTextWidget(); 198 if (t != null && !t.isDisposed()) { 199 Point region= new Point(0, 0); 200 getLineRange(position, region); 201 202 region.x-= getDocumentRegionOffset(); 203 204 try { 205 t.setLineBackground(region.x, region.y, c); 206 } catch (IllegalArgumentException ex) { 207 } 209 } 210 } 211 212 public void resetLineBackground() { 213 StyledText t= getTextWidget(); 214 if (t != null && !t.isDisposed()) { 215 int lines= getLineCount(); 216 t.setLineBackground(0, lines, null); 217 } 218 } 219 220 223 public int getLineCount() { 224 IRegion region= getVisibleRegion(); 225 226 int length= region.getLength(); 227 if (length == 0) 228 return 0; 229 230 IDocument doc= getDocument(); 231 int startLine= 0; 232 int endLine= 0; 233 234 int start= region.getOffset(); 235 try { 236 startLine= doc.getLineOfOffset(start); 237 } catch(BadLocationException ex) { 238 } 240 try { 241 endLine= doc.getLineOfOffset(start+length); 242 } catch(BadLocationException ex) { 243 } 245 246 return endLine-startLine+1; 247 } 248 249 public int getViewportLines() { 250 StyledText te= getTextWidget(); 251 Rectangle clArea= te.getClientArea(); 252 if (!clArea.isEmpty()) 253 return clArea.height / te.getLineHeight(); 254 return 0; 255 } 256 257 public int getViewportHeight() { 258 StyledText te= getTextWidget(); 259 Rectangle clArea= te.getClientArea(); 260 if (!clArea.isEmpty()) 261 return clArea.height; 262 return 0; 263 } 264 265 268 public int getDocumentRegionOffset() { 269 int start= getVisibleRegion().getOffset(); 270 IDocument doc= getDocument(); 271 if (doc != null) { 272 try { 273 return doc.getLineOfOffset(start); 274 } catch(BadLocationException ex) { 275 } 277 } 278 return 0; 279 } 280 281 public int getVerticalScrollOffset() { 282 StyledText st= getTextWidget(); 283 int lineHeight= st.getLineHeight(); 284 return getTopInset() - ((getDocumentRegionOffset()*lineHeight) + st.getTopPixel()); 285 } 286 287 291 public Point getLineRange(Position p, Point region) { 292 293 IDocument doc= getDocument(); 294 295 if (p == null || doc == null) { 296 region.x= 0; 297 region.y= 0; 298 return region; 299 } 300 301 int start= p.getOffset(); 302 int length= p.getLength(); 303 304 int startLine= 0; 305 try { 306 startLine= doc.getLineOfOffset(start); 307 } catch (BadLocationException e) { 308 } 310 311 int lineCount= 0; 312 313 if (length == 0) { 314 323 } else { 324 int endLine= 0; 325 try { 326 endLine= doc.getLineOfOffset(start + length - 1); } catch (BadLocationException e) { 328 } 330 lineCount= endLine-startLine+1; 331 } 332 333 region.x= startLine; 334 region.y= lineCount; 335 return region; 336 } 337 338 341 public void vscroll(int line) { 342 343 int srcViewSize= getLineCount(); 344 int srcExtentSize= getViewportLines(); 345 346 if (srcViewSize > srcExtentSize) { 347 348 if (line < 0) 349 line= 0; 350 351 int cp= getTopIndex(); 352 if (cp != line) 353 setTopIndex(line + getDocumentRegionOffset()); 354 } 355 } 356 357 public void addAction(String actionId, MergeViewerAction action) { 358 fActions.put(actionId, action); 359 } 360 361 public IAction getAction(String actionId) { 362 IAction action= (IAction) fActions.get(actionId); 363 if (action == null) { 364 action= createAction(actionId); 365 if (action == null) 366 return null; 367 if (action instanceof MergeViewerAction) { 368 MergeViewerAction mva = (MergeViewerAction) action; 369 if (mva.isContentDependent()) 370 addTextListener(this); 371 if (mva.isSelectionDependent()) 372 addSelectionChangedListener(this); 373 374 Utilities.initAction(action, fResourceBundle, "action." + actionId + "."); } 376 addAction(actionId, action); 377 378 } 379 if (action instanceof MergeViewerAction) { 380 MergeViewerAction mva = (MergeViewerAction) action; 381 if (mva.isEditableDependent() && !isEditable()) 382 return null; 383 } 384 return action; 385 } 386 387 protected IAction createAction(String actionId) { 388 if (UNDO_ID.equals(actionId)) 389 return new TextOperationAction(UNDO, "org.eclipse.ui.edit.undo", true, false, true); if (REDO_ID.equals(actionId)) 391 return new TextOperationAction(REDO, "org.eclipse.ui.edit.redo", true, false, true); if (CUT_ID.equals(actionId)) 393 return new TextOperationAction(CUT, "org.eclipse.ui.edit.cut", true, true, false); if (COPY_ID.equals(actionId)) 395 return new TextOperationAction(COPY, "org.eclipse.ui.edit.copy", false, true, false); if (PASTE_ID.equals(actionId)) 397 return new TextOperationAction(PASTE, "org.eclipse.ui.edit.paste", true, false, false); if (DELETE_ID.equals(actionId)) 399 return new TextOperationAction(DELETE, "org.eclipse.ui.edit.delete", true, false, false); if (SELECT_ALL_ID.equals(actionId)) 401 return new TextOperationAction(SELECT_ALL, "org.eclipse.ui.edit.selectAll", false, false, false); return null; 403 } 404 405 public void selectionChanged(SelectionChangedEvent event) { 406 Iterator e= fActions.values().iterator(); 407 while (e.hasNext()) { 408 Object next = e.next(); 409 if (next instanceof MergeViewerAction) { 410 MergeViewerAction action = (MergeViewerAction) next; 411 if (action.isSelectionDependent()) 412 action.update(); 413 } 414 } 415 } 416 417 public void textChanged(TextEvent event) { 418 updateContentDependantActions(); 419 } 420 421 void updateContentDependantActions() { 422 Iterator e= fActions.values().iterator(); 423 while (e.hasNext()) { 424 Object next = e.next(); 425 if (next instanceof MergeViewerAction) { 426 MergeViewerAction action = (MergeViewerAction) next; 427 if (action.isContentDependent()) 428 action.update(); 429 } 430 } 431 } 432 433 436 public void menuAboutToShow(IMenuManager menu) { 437 438 menu.add(new Separator("undo")); addMenu(menu, UNDO_ID); 440 addMenu(menu, REDO_ID); 441 menu.add(new GroupMarker("save")); if (fAddSaveAction) 443 addMenu(menu, SAVE_ID); 444 menu.add(new Separator("file")); 446 menu.add(new Separator("ccp")); addMenu(menu, CUT_ID); 448 addMenu(menu, COPY_ID); 449 addMenu(menu, PASTE_ID); 450 addMenu(menu, DELETE_ID); 451 addMenu(menu, SELECT_ALL_ID); 452 453 menu.add(new Separator("edit")); menu.add(new Separator("find")); addMenu(menu, FIND_ID); 456 457 menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); 458 459 menu.add(new Separator("text")); for (Iterator iterator = textActions.iterator(); iterator.hasNext();) { 461 IAction action = (IAction) iterator.next(); 462 menu.add(action); 463 } 464 465 menu.add(new Separator("rest")); 467 updateActions(); 470 } 471 472 private void addMenu(IMenuManager menu, String actionId) { 473 IAction action= getAction(actionId); 474 if (action != null) 475 menu.add(action); 476 } 477 478 protected void handleDispose() { 479 480 removeTextListener(this); 481 removeSelectionChangedListener(this); 482 EditorsUI.getPreferenceStore().removePropertyChangeListener(fPreferenceChangeListener); 483 484 IOperationHistory history = getHistory(); 485 if (history != null) 486 history.removeOperationHistoryListener(this); 487 488 super.handleDispose(); 489 } 490 491 495 public void updateActions() { 496 Iterator e= fActions.values().iterator(); 497 while (e.hasNext()) { 498 Object next = e.next(); 499 if (next instanceof MergeViewerAction) { 500 MergeViewerAction action = (MergeViewerAction) next; 501 action.update(); 502 } if (next instanceof FindReplaceAction) { 503 FindReplaceAction action = (FindReplaceAction) next; 504 action.update(); 505 } 506 } 507 } 508 509 public void configure(SourceViewerConfiguration configuration) { 510 if (isConfigured ) 511 unconfigure(); 512 isConfigured = true; 513 super.configure(configuration); 514 } 515 516 523 public void setBounds (int x, int y, int width, int height) { 524 if(getControl() instanceof Composite){ 525 ((Composite)getControl()).setBounds(x, y, width, height); 526 } else { 527 getTextWidget().setBounds(x, y, width, height); 528 } 529 } 530 531 535 protected void handlePropertyChangeEvent(PropertyChangeEvent event) { 536 537 String key= event.getProperty(); 538 539 if(key.equals(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER)){ 540 boolean b= EditorsUI.getPreferenceStore().getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER); 541 if (b != fShowLineNumber){ 542 toggleLineNumberRuler(); 543 } 544 } else if (key.equals(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR)) { 545 updateLineNumberColumnPresentation(true); 546 } 547 } 548 549 552 private void updateLineNumberRuler() 553 { 554 IVerticalRuler v= getVerticalRuler(); 555 if (v!=null && v instanceof CompositeRuler) { 556 CompositeRuler c= (CompositeRuler) v; 557 558 if(!fShowLineNumber){ 559 if(fLineNumberColumn!=null){ 560 c.removeDecorator(fLineNumberColumn); 561 } 562 } else { 563 if(fLineNumberColumn==null){ 564 fLineNumberColumn = new LineNumberRulerColumn(); 565 updateLineNumberColumnPresentation(false); 566 } 567 c.addDecorator(0, fLineNumberColumn); 568 } 569 } 570 } 571 572 private void updateLineNumberColumnPresentation(boolean refresh) { 573 if (fLineNumberColumn == null) 574 return; 575 RGB rgb= getColorFromStore(EditorsUI.getPreferenceStore(), AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR); 576 if (rgb == null) 577 rgb= new RGB(0, 0, 0); 578 ISharedTextColors sharedColors= getSharedColors(); 579 fLineNumberColumn.setForeground(sharedColors.getColor(rgb)); 580 if (refresh) { 581 fLineNumberColumn.redraw(); 582 } 583 } 584 585 private void layoutViewer() { 586 Control parent= getControl(); 587 if (parent instanceof Composite && !parent.isDisposed()) 588 ((Composite) parent).layout(true); 589 } 590 591 private ISharedTextColors getSharedColors() { 592 return EditorsUI.getSharedTextColors(); 593 } 594 595 private RGB getColorFromStore(IPreferenceStore store, String key) { 596 RGB rgb= null; 597 if (store.contains(key)) { 598 if (store.isDefault(key)) 599 rgb= PreferenceConverter.getDefaultColor(store, key); 600 else 601 rgb= PreferenceConverter.getColor(store, key); 602 } 603 return rgb; 604 } 605 606 609 private void toggleLineNumberRuler() 610 { 611 fShowLineNumber=!fShowLineNumber; 612 613 updateLineNumberRuler(); 614 } 615 616 public void addTextAction(IAction textEditorPropertyAction) { 617 textActions.add(textEditorPropertyAction); 618 } 619 620 public void addAction(String id, IAction action) { 621 fActions.put(id, action); 622 } 623 624 private IOperationHistory getHistory() { 625 if (PlatformUI.getWorkbench() == null) { 626 return null; 627 } 628 return PlatformUI.getWorkbench().getOperationSupport() 629 .getOperationHistory(); 630 } 631 632 public void historyNotification(OperationHistoryEvent event) { 633 IUndoContext context = getUndoContext(); 636 if (context != null && event.getOperation().hasContext(context)) { 637 Display.getDefault().asyncExec(new Runnable () { 638 public void run() { 639 updateContentDependantActions(); 640 } 641 }); 642 } 643 } 644 645 private IUndoContext getUndoContext() { 646 IUndoManager undoManager = getUndoManager(); 647 if (undoManager instanceof IUndoManagerExtension) 648 return ((IUndoManagerExtension)undoManager).getUndoContext(); 649 return null; 650 } 651 } 652 | Popular Tags |