1 11 package org.eclipse.compare.internal; 12 13 import java.lang.reflect.InvocationTargetException ; 14 import java.util.ArrayList ; 15 import java.util.HashSet ; 16 17 import org.eclipse.compare.*; 18 import org.eclipse.core.runtime.*; 19 import org.eclipse.core.runtime.jobs.Job; 20 import org.eclipse.jface.action.IStatusLineManager; 21 import org.eclipse.jface.action.MenuManager; 22 import org.eclipse.jface.dialogs.ErrorDialog; 23 import org.eclipse.jface.dialogs.MessageDialog; 24 import org.eclipse.jface.resource.ImageDescriptor; 25 import org.eclipse.jface.text.IFindReplaceTarget; 26 import org.eclipse.jface.util.IPropertyChangeListener; 27 import org.eclipse.jface.util.PropertyChangeEvent; 28 import org.eclipse.jface.viewers.ISelectionProvider; 29 import org.eclipse.osgi.util.NLS; 30 import org.eclipse.swt.SWT; 31 import org.eclipse.swt.graphics.Color; 32 import org.eclipse.swt.graphics.Point; 33 import org.eclipse.swt.layout.GridData; 34 import org.eclipse.swt.layout.GridLayout; 35 import org.eclipse.swt.widgets.*; 36 import org.eclipse.ui.*; 37 import org.eclipse.ui.actions.WorkspaceModifyOperation; 38 import org.eclipse.ui.contexts.IContextService; 39 import org.eclipse.ui.part.*; 40 import org.eclipse.ui.services.IServiceLocator; 41 import org.eclipse.ui.views.contentoutline.IContentOutlinePage; 42 43 47 public class CompareEditor extends EditorPart implements IReusableEditor, ISaveablesSource, IPropertyChangeListener, ISaveablesLifecycleListener { 48 49 public final static String CONFIRM_SAVE_PROPERTY= "org.eclipse.compare.internal.CONFIRM_SAVE_PROPERTY"; 51 private static final int UNINITIALIZED = 0; 52 private static final int INITIALIZING = 1; 53 private static final int NO_DIFF = 2; 54 private static final int CANCELED = 3; 55 private static final int INITIALIZED = 4; 56 private static final int ERROR = 5; 57 private static final int STILL_INITIALIZING = 6; 58 private static final int CREATING_CONTROL = 7; 59 private static final int DONE = 8; 60 61 private IActionBars fActionBars; 62 63 private PageBook fPageBook; 64 65 66 private Control fControl; 67 68 private CompareOutlinePage fOutlinePage; 69 70 private CompareSaveable fSaveable; 71 72 private Control initializingPage; 73 private Control emptyPage; 74 75 private int state = UNINITIALIZED; 76 private HashSet knownSaveables; 77 78 private final EditorCompareContainer fContainer = new EditorCompareContainer(); 79 80 private class EditorCompareContainer extends CompareContainer { 81 82 85 public void registerContextMenu(MenuManager menu, ISelectionProvider provider) { 86 if (getSite() instanceof IEditorSite) { 87 IEditorSite es = (IEditorSite) getSite(); 88 es.registerContextMenu(menu, provider, false); 89 } 90 } 91 92 95 public void setStatusMessage(String message) { 96 if (fActionBars != null) { 97 IStatusLineManager slm= fActionBars.getStatusLineManager(); 98 if (slm != null) { 99 slm.setMessage(message); 100 } 101 } 102 } 103 104 107 public IServiceLocator getServiceLocator() { 108 return getSite(); 109 } 110 111 114 protected WorkerJob createWorkerJob() { 115 WorkerJob workerJob = new WorkerJob(getWorkerJobName()) { 116 public boolean belongsTo(Object family) { 117 if (family == CompareEditor.this) 118 return true; 119 return super.belongsTo(family); 120 } 121 }; 122 return workerJob; 123 } 124 125 128 protected String getWorkerJobName() { 129 return NLS.bind(CompareMessages.CompareEditor_11, getTitle()); 130 } 131 132 135 public IWorkbenchPart getWorkbenchPart() { 136 return CompareEditor.this; 137 } 138 139 142 public IActionBars getActionBars() { 143 return CompareEditor.this.getActionBars(); 144 } 145 } 146 147 150 public CompareEditor() { 151 } 153 154 157 public Object getAdapter(Class key) { 158 159 if (key.equals(IContentOutlinePage.class)) { 160 Object object= getCompareConfiguration().getProperty(CompareConfiguration.USE_OUTLINE_VIEW); 161 if (object instanceof Boolean && ((Boolean )object).booleanValue()) { 162 if (fOutlinePage != null) { 163 if (fOutlinePage.getControl() != null && fOutlinePage.getControl().isDisposed()) { 164 fOutlinePage = null; 165 } else { 166 return fOutlinePage; 167 } 168 } 169 fOutlinePage= new CompareOutlinePage(this); 170 return fOutlinePage; 171 } 172 } 173 174 if (key == IShowInSource.class 175 || key == OutlineViewerCreator.class 176 || key == IFindReplaceTarget.class) { 177 Object input = getEditorInput(); 178 if (input != null) { 179 return Utilities.getAdapter(input, key); 180 } 181 } 182 183 return super.getAdapter(key); 184 } 185 186 189 CompareConfiguration getCompareConfiguration() { 190 IEditorInput input= getEditorInput(); 191 if (input instanceof CompareEditorInput) 192 return ((CompareEditorInput)input).getCompareConfiguration(); 193 return null; 194 } 195 196 199 public void init(IEditorSite site, IEditorInput input) throws PartInitException { 200 201 if (!(input instanceof CompareEditorInput)) 202 throw new PartInitException(Utilities.getString("CompareEditor.invalidInput")); 204 setSite(site); 205 setInput(input); 206 } 207 208 211 public void setInput(IEditorInput input) { 212 if (!(input instanceof CompareEditorInput)) { 213 IStatus s= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, Utilities.getString("CompareEditor.invalidInput"), null); String title= Utilities.getString("CompareEditor.error.setinput.title"); String msg= Utilities.getString("CompareEditor.error.setinput.message"); ErrorDialog.openError(getSite().getShell(), title, msg, s); 217 return; 218 } 219 doSetInput(input); 220 refreshActionBarsContributor(); 222 } 223 224 private void refreshActionBarsContributor() { 225 IEditorSite editorSite= getEditorSite(); 226 if (editorSite != null) { 227 IEditorActionBarContributor actionBarContributor= editorSite.getActionBarContributor(); 228 if (actionBarContributor != null) { 229 actionBarContributor.setActiveEditor(null); 230 actionBarContributor.setActiveEditor(this); 231 } 232 } 233 } 234 235 private void doSetInput(IEditorInput input) { 236 IEditorInput oldInput= getEditorInput(); 237 disconnectFromInput(oldInput); 238 Point oldSize = null; 239 if (oldInput != null) { 240 if (fControl != null && !fControl.isDisposed()) { 241 oldSize= fControl.getSize(); 242 if (emptyPage == null) 243 emptyPage = new Composite(fPageBook, SWT.NONE); 244 fPageBook.showPage(emptyPage); 245 fControl.dispose(); 246 fControl = null; 247 } 248 } 249 250 super.setInput(input); 251 252 if (fOutlinePage != null) 253 fOutlinePage.reset(); 254 255 final CompareEditorInput cei= (CompareEditorInput) input; 256 cei.setContainer(fContainer); 257 setTitleImage(cei.getTitleImage()); 258 setPartName(cei.getTitle()); 259 setTitleToolTip(cei.getToolTipText()); 260 261 if (input instanceof IPropertyChangeNotifier) 262 ((IPropertyChangeNotifier)input).addPropertyChangeListener(this); 263 264 setState(cei.getCompareResult() == null ? INITIALIZING : INITIALIZED); 265 if (fPageBook != null) 266 createCompareControl(); 267 if (fControl != null && oldSize != null) 268 fControl.setSize(oldSize); 269 270 Job.getJobManager().cancel(this); 271 if (cei.getCompareResult() == null) { 272 initializeInBackground(cei); 273 } 274 275 firePropertyChange(IWorkbenchPartConstants.PROP_INPUT); 276 277 if (oldInput != null) { 279 ISaveablesLifecycleListener lifecycleListener= (ISaveablesLifecycleListener) getSite().getService(ISaveablesLifecycleListener.class); 280 lifecycleListener.handleLifecycleEvent( 281 new SaveablesLifecycleEvent(this, SaveablesLifecycleEvent.POST_OPEN, internalGetSaveables(true), false)); 282 } 283 } 284 285 private void disconnectFromInput(IEditorInput oldInput) { 286 if (oldInput != null) { 287 288 if (oldInput instanceof IPropertyChangeNotifier) 289 ((IPropertyChangeNotifier)oldInput).removePropertyChangeListener(this); 290 291 if (knownSaveables != null && !knownSaveables.isEmpty()) { 293 ISaveablesLifecycleListener lifecycleListener= (ISaveablesLifecycleListener) getSite().getService(ISaveablesLifecycleListener.class); 294 lifecycleListener.handleLifecycleEvent( 295 new SaveablesLifecycleEvent(this, SaveablesLifecycleEvent.POST_CLOSE, (Saveable[]) knownSaveables.toArray(new Saveable[knownSaveables.size()]), false)); 296 knownSaveables.clear(); 297 } 298 } 299 } 300 301 protected void initializeInBackground(final CompareEditorInput cei) { 302 Job job = new Job(CompareMessages.CompareEditor_0) { 304 protected IStatus run(IProgressMonitor monitor) { 305 IStatus status; 306 try { 307 status = CompareUIPlugin.getDefault().prepareInput(cei, monitor); 308 if (status.isOK()) { 309 setState(INITIALIZED); 311 return Status.OK_STATUS; 312 } 313 if (status.getCode() == CompareUIPlugin.NO_DIFFERENCE) { 314 setState(NO_DIFF); 315 return Status.OK_STATUS; 316 } 317 setState(ERROR); 318 } catch (OperationCanceledException e) { 319 setState(CANCELED); 320 status = Status.CANCEL_STATUS; 321 } finally { 322 if (monitor.isCanceled()) 323 setState(CANCELED); 324 Display.getDefault().asyncExec(new Runnable () { 325 public void run() { 326 createCompareControl(); 327 } 328 }); 329 monitor.done(); 330 } 331 return status; 332 } 333 public boolean belongsTo(Object family) { 334 if (family == CompareEditor.this || family == cei) 335 return true; 336 return cei.belongsTo(family); 337 } 338 }; 339 job.setUser(true); 340 Utilities.schedule(job, getSite()); 341 } 342 343 346 public IActionBars getActionBars() { 347 return fActionBars; 348 } 349 350 353 void setActionBars(IActionBars actionBars) { 354 fActionBars= actionBars; 355 } 356 357 360 public void createPartControl(Composite parent) { 361 parent.setData(this); 362 fPageBook = new PageBook(parent, SWT.NONE); 363 createCompareControl(); 364 IContextService service = (IContextService)getSite().getService(IContextService.class); 365 if (service != null) 366 service.activateContext("org.eclipse.compare.compareEditorScope"); } 368 369 private void createCompareControl() { 370 if (fPageBook.isDisposed()) 371 return; 372 IEditorInput input= getEditorInput(); 373 if (input instanceof CompareEditorInput) { 374 CompareEditorInput ci = (CompareEditorInput) input; 375 if (ci.getCompareResult() == null) { 376 if (getState() == INITIALIZING) { 377 setPageLater(); 378 } else if (getState() == STILL_INITIALIZING) { 379 if (initializingPage == null) { 380 initializingPage = getInitializingMessagePane(fPageBook); 381 } 382 fPageBook.showPage(initializingPage); 383 } else if (getState() == CANCELED) { 384 closeEditor(); 386 } else if (getState() == NO_DIFF) { 387 setState(DONE); 389 closeEditor(); 390 CompareUIPlugin.getDefault().handleNoDifference(); 391 } else if (getState() == ERROR) { 392 closeEditor(); 395 } 396 } else if (fControl == null && getState() != CREATING_CONTROL) { 397 setState(CREATING_CONTROL); 399 fControl= (ci).createContents(fPageBook); 400 fPageBook.showPage(fControl); 401 PlatformUI.getWorkbench().getHelpSystem().setHelp(fControl, ICompareContextIds.COMPARE_EDITOR); 402 if (isActive()) { 403 setFocus(); 404 } 405 setState(INITIALIZED); 406 } 407 } 408 } 409 410 private boolean isActive() { 411 return getSite().getPage().getActivePart() == this; 412 } 413 414 private void setPageLater() { 415 Display.getCurrent().timerExec(1000, new Runnable () { 416 public void run() { 417 synchronized(CompareEditor.this) { 418 if (getState() == INITIALIZING) { 419 setState(STILL_INITIALIZING); 420 createCompareControl(); 421 } 422 } 423 } 424 }); 425 } 426 427 430 public void dispose() { 431 432 IEditorInput input= getEditorInput(); 433 if (input instanceof IPropertyChangeNotifier) 434 ((IPropertyChangeNotifier)input).removePropertyChangeListener(this); 435 436 super.dispose(); 437 } 438 439 442 public void setFocus() { 443 IEditorInput input= getEditorInput(); 444 if (input instanceof CompareEditorInput) 445 ((CompareEditorInput)input).setFocus(); 446 } 447 448 451 public boolean isSaveAsAllowed() { 452 return false; 453 } 454 455 459 public void doSaveAs() { 460 Assert.isTrue(false); } 462 463 466 public void doSave(IProgressMonitor progressMonitor) { 467 468 final IEditorInput input= getEditorInput(); 469 470 WorkspaceModifyOperation operation= new WorkspaceModifyOperation() { 471 public void execute(IProgressMonitor pm) throws CoreException { 472 if (input instanceof CompareEditorInput) 473 ((CompareEditorInput)input).saveChanges(pm); 474 } 475 }; 476 477 Shell shell= getSite().getShell(); 478 479 try { 480 481 operation.run(progressMonitor); 482 483 firePropertyChange(PROP_DIRTY); 484 485 } catch (InterruptedException x) { 486 } catch (OperationCanceledException x) { 488 } catch (InvocationTargetException x) { 490 String title= Utilities.getString("CompareEditor.saveError.title"); String reason= x.getTargetException().getMessage(); 492 MessageDialog.openError(shell, title, Utilities.getFormattedString("CompareEditor.cantSaveError", reason)); } 494 } 495 496 499 public boolean isDirty() { 500 IEditorInput input= getEditorInput(); 501 if (input instanceof CompareEditorInput) 502 return ((CompareEditorInput)input).isDirty(); 503 return false; 504 } 505 506 509 public void propertyChange(PropertyChangeEvent event) { 510 if (event.getProperty().equals(CompareEditorInput.DIRTY_STATE)) { 511 Object old_value= event.getOldValue(); 512 Object new_value= event.getNewValue(); 513 if (old_value == null || new_value == null || !old_value.equals(new_value)) 514 firePropertyChange(PROP_DIRTY); 515 } else if (event.getProperty().equals(CompareEditorInput.PROP_TITLE)) { 516 setPartName(((CompareEditorInput)getEditorInput()).getTitle()); 517 setTitleToolTip(((CompareEditorInput)getEditorInput()).getToolTipText()); 518 } else if (event.getProperty().equals(CompareEditorInput.PROP_TITLE_IMAGE)) { 519 setTitleImage(((CompareEditorInput)getEditorInput()).getTitleImage()); 520 } 521 } 522 523 526 public Saveable[] getSaveables() { 527 return internalGetSaveables(knownSaveables == null); 528 } 529 530 private Saveable[] internalGetSaveables(boolean init) { 531 IEditorInput input= getEditorInput(); 532 Saveable[] sourceSaveables = getSaveables(input); 533 if (init || knownSaveables == null) { 534 recordSaveables(sourceSaveables); 535 } else { 536 for (int i = 0; i < sourceSaveables.length; i++) { 537 Saveable saveable = sourceSaveables[i]; 538 if (!knownSaveables.contains(saveable)) { 539 CompareUIPlugin.logErrorMessage(NLS.bind("Saveable {0} was not added using a saveables lifecycle event.", saveable.getName())); knownSaveables.add(saveable); 541 } 542 } 543 if (sourceSaveables.length != knownSaveables.size()) { 544 CompareUIPlugin.logErrorMessage("Saveables were removed without an appropriate event"); knownSaveables.clear(); 546 recordSaveables(sourceSaveables); 547 } 548 } 549 return sourceSaveables; 550 } 551 552 private void recordSaveables(Saveable[] sourceSaveables) { 553 if (knownSaveables == null) 554 knownSaveables = new HashSet (); 555 for (int i = 0; i < sourceSaveables.length; i++) { 556 Saveable saveable = sourceSaveables[i]; 557 knownSaveables.add(saveable); 558 } 559 } 560 561 private Saveable[] getSaveables(IEditorInput input) { 562 if (input instanceof ISaveablesSource) { 563 ISaveablesSource source= (ISaveablesSource) input; 564 return source.getSaveables(); 565 } 566 return new Saveable[] { getSaveable() }; 567 } 568 569 private Saveable getSaveable() { 570 if (fSaveable == null) { 571 fSaveable= new CompareSaveable(); 572 } 573 return fSaveable; 574 } 575 576 579 public Saveable[] getActiveSaveables() { 580 IEditorInput input= getEditorInput(); 581 if (input instanceof ISaveablesSource) { 582 ISaveablesSource source= (ISaveablesSource) input; 583 return source.getActiveSaveables(); 584 } 585 return new Saveable[] { getSaveable() }; 586 } 587 588 private class CompareSaveable extends Saveable { 589 590 public String getName() { 591 return CompareEditor.this.getPartName(); 592 } 593 594 public String getToolTipText() { 595 return CompareEditor.this.getTitleToolTip(); 596 } 597 598 public ImageDescriptor getImageDescriptor() { 599 return ImageDescriptor.createFromImage(CompareEditor.this.getTitleImage()); 600 } 601 602 public void doSave(IProgressMonitor monitor) throws CoreException { 603 CompareEditor.this.doSave(monitor); 604 } 605 606 public boolean isDirty() { 607 return CompareEditor.this.isDirty(); 608 } 609 610 public boolean equals(Object object) { 611 return object == this; 612 } 613 614 public int hashCode() { 615 return CompareEditor.this.hashCode(); 616 } 617 } 618 619 private Composite getInitializingMessagePane(Composite parent) { 620 Composite composite = new Composite(parent, SWT.NONE); 621 composite.setBackground(getBackgroundColor(parent)); 622 GridLayout layout = new GridLayout(); 623 layout.numColumns = 3; 624 composite.setLayout(layout); 625 626 createDescriptionLabel(composite, CompareMessages.CompareEditor_1); 627 return composite; 628 } 629 630 private Color getBackgroundColor(Composite parent) { 631 return parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND); 632 } 633 634 private Label createDescriptionLabel(Composite parent, String text) { 635 Label description = new Label(parent, SWT.WRAP); 636 GridData data = new GridData(GridData.FILL_HORIZONTAL); 637 data.horizontalSpan = 2; 638 description.setLayoutData(data); 639 description.setText(text); 640 description.setBackground(getBackgroundColor(parent)); 641 return description; 642 } 643 644 private void closeEditor() { 645 getSite().getPage().closeEditor(CompareEditor.this, false); 646 } 647 648 private synchronized void setState(int state) { 649 this.state = state; 650 } 651 652 private int getState() { 653 return state; 654 } 655 656 public void handleLifecycleEvent(SaveablesLifecycleEvent event) { 657 ISaveablesLifecycleListener lifecycleListener= (ISaveablesLifecycleListener) getSite().getService(ISaveablesLifecycleListener.class); 658 if (event.getEventType() == SaveablesLifecycleEvent.POST_CLOSE) { 659 if (knownSaveables == null || knownSaveables.isEmpty()) 662 return; 663 java.util.List result = new ArrayList (); 664 Saveable[] all = event.getSaveables(); 665 for (int i = 0; i < all.length; i++) { 666 Saveable saveable = all[i]; 667 if (knownSaveables.contains(saveable)) 668 result.add(saveable); 669 knownSaveables.remove(saveable); 670 } 671 if (result.isEmpty()) 672 return; 673 event = new SaveablesLifecycleEvent(this, 674 SaveablesLifecycleEvent.POST_CLOSE, 675 (Saveable[]) result.toArray(new Saveable[result.size()]), 676 false); 677 } else if (event.getEventType() == SaveablesLifecycleEvent.POST_OPEN) { 678 recordSaveables(event.getSaveables()); 679 } 680 lifecycleListener.handleLifecycleEvent(event); 681 } 682 683 } 684 685 | Popular Tags |