| /******************************************************************************* |
| * Copyright (c) 2000, 2019 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.compare.internal; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashSet; |
| |
| import org.eclipse.compare.CompareConfiguration; |
| import org.eclipse.compare.CompareEditorInput; |
| import org.eclipse.compare.IPropertyChangeNotifier; |
| import org.eclipse.core.runtime.Adapters; |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.jface.action.IStatusLineManager; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.text.IFindReplaceTarget; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.viewers.ISelectionProvider; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.SWTException; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IActionBars; |
| import org.eclipse.ui.IEditorActionBarContributor; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorSite; |
| import org.eclipse.ui.IReusableEditor; |
| import org.eclipse.ui.ISaveablesLifecycleListener; |
| import org.eclipse.ui.ISaveablesSource; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPartConstants; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.Saveable; |
| import org.eclipse.ui.SaveablesLifecycleEvent; |
| import org.eclipse.ui.actions.WorkspaceModifyOperation; |
| import org.eclipse.ui.contexts.IContextService; |
| import org.eclipse.ui.part.EditorPart; |
| import org.eclipse.ui.part.IShowInSource; |
| import org.eclipse.ui.part.PageBook; |
| import org.eclipse.ui.services.IServiceLocator; |
| import org.eclipse.ui.texteditor.ITextEditorExtension3; |
| import org.eclipse.ui.views.contentoutline.IContentOutlinePage; |
| |
| /** |
| * A CompareEditor takes a ICompareEditorInput as input. |
| * Most functionality is delegated to the ICompareEditorInput. |
| */ |
| public class CompareEditor extends EditorPart |
| implements IReusableEditor, ISaveablesSource, IPropertyChangeListener, |
| ISaveablesLifecycleListener { |
| public final static String CONFIRM_SAVE_PROPERTY= "org.eclipse.compare.internal.CONFIRM_SAVE_PROPERTY"; //$NON-NLS-1$ |
| |
| private static final int UNINITIALIZED = 0; |
| private static final int INITIALIZING = 1; |
| private static final int NO_DIFF = 2; |
| private static final int CANCELED = 3; |
| private static final int INITIALIZED = 4; |
| private static final int ERROR = 5; |
| private static final int STILL_INITIALIZING = 6; |
| private static final int CREATING_CONTROL = 7; |
| private static final int DONE = 8; |
| |
| private IActionBars fActionBars; |
| |
| private PageBook fPageBook; |
| |
| /** the SWT control from the compare editor input*/ |
| private Control fControl; |
| /** the outline page */ |
| private CompareOutlinePage fOutlinePage; |
| |
| private CompareSaveable fSaveable; |
| |
| private Control initializingPage; |
| private Control emptyPage; |
| |
| private int state = UNINITIALIZED; |
| private HashSet<Saveable> knownSaveables; |
| |
| private final EditorCompareContainer fContainer = new EditorCompareContainer(); |
| |
| private class EditorCompareContainer extends CompareContainer { |
| @Override |
| public void registerContextMenu(MenuManager menu, ISelectionProvider provider) { |
| if (getSite() instanceof IEditorSite) { |
| IEditorSite es = (IEditorSite) getSite(); |
| es.registerContextMenu(menu, provider, true); |
| } |
| } |
| |
| @Override |
| public void setStatusMessage(String message) { |
| if (fActionBars != null) { |
| IStatusLineManager slm= fActionBars.getStatusLineManager(); |
| if (slm != null) { |
| slm.setMessage(message); |
| } |
| } |
| } |
| |
| @Override |
| public IServiceLocator getServiceLocator() { |
| return getSite(); |
| } |
| |
| @Override |
| protected WorkerJob createWorkerJob() { |
| WorkerJob workerJob = new WorkerJob(getWorkerJobName()) { |
| @Override |
| public boolean belongsTo(Object family) { |
| if (family == CompareEditor.this) |
| return true; |
| return super.belongsTo(family); |
| } |
| }; |
| return workerJob; |
| } |
| |
| @Override |
| protected String getWorkerJobName() { |
| return NLS.bind(CompareMessages.CompareEditor_2, getTitle()); |
| } |
| |
| @Override |
| public IWorkbenchPart getWorkbenchPart() { |
| return CompareEditor.this; |
| } |
| |
| @Override |
| public IActionBars getActionBars() { |
| return CompareEditor.this.getActionBars(); |
| } |
| } |
| |
| /** |
| * No-argument constructor required for extension points. |
| */ |
| public CompareEditor() { |
| // empty default implementation |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> T getAdapter(Class<T> key) { |
| if (key.equals(IContentOutlinePage.class)) { |
| Object object= getCompareConfiguration().getProperty(CompareConfiguration.USE_OUTLINE_VIEW); |
| if (object instanceof Boolean && ((Boolean)object).booleanValue()) { |
| if (fOutlinePage != null) { |
| if (fOutlinePage.getControl() != null && fOutlinePage.getControl().isDisposed()) { |
| fOutlinePage = null; |
| } else { |
| return (T) fOutlinePage; |
| } |
| } |
| fOutlinePage= new CompareOutlinePage(this); |
| return (T) fOutlinePage; |
| } |
| } |
| |
| if (key == IShowInSource.class |
| || key == OutlineViewerCreator.class |
| || key == IFindReplaceTarget.class) { |
| Object input = getEditorInput(); |
| if (input != null) { |
| return Adapters.adapt(input, key); |
| } |
| } |
| |
| if (key == IEditorInput.class) { |
| // return (T) Adapters.adapt(getEditorInput(), IEditorInput.class); |
| // The above call cannot be used because the return type of getEditorInput() |
| // call is IEditorInput and this itself will be returned by the above function. |
| // What we want is to call getAdapter call on this IEditorInput object. |
| return (T) getEditorInput().getAdapter(IEditorInput.class); |
| } |
| |
| if (key == ITextEditorExtension3.class) { |
| return (T) Adapters.adapt(getEditorInput(), ITextEditorExtension3.class); |
| } |
| |
| return super.getAdapter(key); |
| } |
| |
| /* |
| * Helper method used by ComapreEditorConfiguration to get at the compare configuration of the editor |
| */ |
| CompareConfiguration getCompareConfiguration() { |
| IEditorInput input= getEditorInput(); |
| if (input instanceof CompareEditorInput) |
| return ((CompareEditorInput)input).getCompareConfiguration(); |
| return null; |
| } |
| |
| @Override |
| public void init(IEditorSite site, IEditorInput input) throws PartInitException { |
| if (!(input instanceof CompareEditorInput)) |
| throw new PartInitException(Utilities.getString("CompareEditor.invalidInput")); //$NON-NLS-1$ |
| |
| setSite(site); |
| setInput(input); |
| } |
| |
| @Override |
| public void setInput(IEditorInput input) { |
| if (!(input instanceof CompareEditorInput)) { |
| IStatus s= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, Utilities.getString("CompareEditor.invalidInput"), null); //$NON-NLS-1$ |
| String title= Utilities.getString("CompareEditor.error.setinput.title"); //$NON-NLS-1$ |
| String msg= Utilities.getString("CompareEditor.error.setinput.message"); //$NON-NLS-1$ |
| ErrorDialog.openError(getSite().getShell(), title, msg, s); |
| return; |
| } |
| doSetInput(input); |
| // Need to refresh the contributor (see #67888) |
| refreshActionBarsContributor(); |
| } |
| |
| public void refreshActionBarsContributor() { |
| IEditorSite editorSite= getEditorSite(); |
| if (editorSite != null) { |
| IEditorActionBarContributor actionBarContributor= editorSite.getActionBarContributor(); |
| if (actionBarContributor != null) { |
| actionBarContributor.setActiveEditor(null); |
| actionBarContributor.setActiveEditor(this); |
| } |
| } |
| } |
| |
| private void doSetInput(IEditorInput input) { |
| IEditorInput oldInput= getEditorInput(); |
| disconnectFromInput(oldInput); |
| Point oldSize = null; |
| boolean hadPreviousInput = oldInput != null; |
| if (hadPreviousInput) { |
| // Cancel any jobs associated with the old input |
| Job.getJobManager().cancel(this); |
| if (fControl != null && !fControl.isDisposed()) { |
| oldSize= fControl.getSize(); |
| if (emptyPage == null) |
| emptyPage = new Composite(fPageBook, SWT.NONE); |
| fPageBook.showPage(emptyPage); |
| fControl.dispose(); |
| fControl = null; |
| } |
| } |
| |
| super.setInput(input); |
| |
| if (fOutlinePage != null) |
| fOutlinePage.reset(); |
| |
| final CompareEditorInput cei= (CompareEditorInput) input; |
| cei.setContainer(fContainer); |
| setTitleImage(cei.getTitleImage()); |
| setPartName(cei.getTitle()); |
| setTitleToolTip(cei.getToolTipText()); |
| |
| if (input instanceof IPropertyChangeNotifier) |
| ((IPropertyChangeNotifier)input).addPropertyChangeListener(this); |
| |
| setState(cei.getCompareResult() == null ? INITIALIZING : INITIALIZED); |
| if (fPageBook != null) |
| createCompareControl(); |
| if (fControl != null && oldSize != null) |
| fControl.setSize(oldSize); |
| |
| boolean hasResult = cei.getCompareResult() != null; |
| if (!hasResult) { |
| initializeInBackground(cei, hadPreviousInput); |
| } |
| |
| firePropertyChange(IWorkbenchPartConstants.PROP_INPUT); |
| |
| // We only need to notify of new Saveables if we are changing inputs |
| if (hadPreviousInput && hasResult) { |
| registerSaveable(); |
| } |
| } |
| |
| private void registerSaveable() { |
| ISaveablesLifecycleListener lifecycleListener= getSite().getService(ISaveablesLifecycleListener.class); |
| lifecycleListener.handleLifecycleEvent( |
| new SaveablesLifecycleEvent(this, SaveablesLifecycleEvent.POST_OPEN, internalGetSaveables(true), false)); |
| } |
| |
| private void disconnectFromInput(IEditorInput oldInput) { |
| if (oldInput != null) { |
| if (oldInput instanceof IPropertyChangeNotifier) |
| ((IPropertyChangeNotifier)oldInput).removePropertyChangeListener(this); |
| |
| // Let the workbench know that the old input's saveables are no longer needed |
| if (knownSaveables != null && !knownSaveables.isEmpty()) { |
| ISaveablesLifecycleListener lifecycleListener= getSite().getService(ISaveablesLifecycleListener.class); |
| lifecycleListener.handleLifecycleEvent( |
| new SaveablesLifecycleEvent(this, SaveablesLifecycleEvent.POST_CLOSE, knownSaveables.toArray(new Saveable[knownSaveables.size()]), false)); |
| knownSaveables.clear(); |
| } |
| } |
| } |
| |
| protected void initializeInBackground(final CompareEditorInput cei, final boolean hadPreviousInput) { |
| // Need to cancel any running jobs associated with the oldInput |
| Job job = new Job(NLS.bind(CompareMessages.CompareEditor_0, cei.getTitle())) { |
| @Override |
| protected IStatus run(final IProgressMonitor monitor) { |
| final int[] newState = new int[] { ERROR }; |
| try { |
| IStatus status = CompareUIPlugin.getDefault().prepareInput(cei, monitor); |
| if (status.isOK()) { |
| // We need to update the saveables list |
| newState[0] = INITIALIZED; |
| return Status.OK_STATUS; |
| } |
| if (status.getCode() == CompareUIPlugin.NO_DIFFERENCE) { |
| newState[0] = NO_DIFF; |
| return Status.OK_STATUS; |
| } |
| newState[0] = ERROR; |
| return status; |
| } catch (OperationCanceledException e) { |
| newState[0] = CANCELED; |
| return Status.CANCEL_STATUS; |
| } finally { |
| if (monitor.isCanceled()) |
| newState[0] = CANCELED; |
| Display.getDefault().syncExec(() -> { |
| if (fPageBook.isDisposed()) |
| return; |
| // we need to register the saveable if we had a previous input or if |
| // there are knownSaveables (which means that the workbench called |
| // getSaveables and got an empty list |
| if (hadPreviousInput || (knownSaveables != null && !isAllSaveablesKnown())) { |
| registerSaveable(); |
| } |
| setState(newState[0]); |
| createCompareControl(); |
| }); |
| monitor.done(); |
| } |
| } |
| @Override |
| public boolean belongsTo(Object family) { |
| if (family == CompareEditor.this || family == cei) |
| return true; |
| return cei.belongsTo(family); |
| } |
| }; |
| job.setUser(true); |
| Utilities.schedule(job, getSite()); |
| } |
| |
| /* |
| * Helper method used to find an action bars using the Utilities#findActionsBars(Control) |
| */ |
| public IActionBars getActionBars() { |
| return fActionBars; |
| } |
| |
| /** |
| * Sets the action bars so the Utilities class can access it. |
| */ |
| void setActionBars(IActionBars actionBars) { |
| fActionBars= actionBars; |
| } |
| |
| @Override |
| public void createPartControl(Composite parent) { |
| parent.setData(this); |
| fPageBook = new PageBook(parent, SWT.NONE); |
| createCompareControl(); |
| IContextService service = getSite().getService(IContextService.class); |
| if (service != null) { |
| service.activateContext("org.eclipse.compare.compareEditorScope"); //$NON-NLS-1$ |
| service.activateContext("org.eclipse.ui.textEditorScope"); //$NON-NLS-1$ |
| } |
| } |
| |
| private void createCompareControl() { |
| if (fPageBook.isDisposed()) |
| return; |
| IEditorInput input= getEditorInput(); |
| if (input instanceof CompareEditorInput) { |
| CompareEditorInput ci = (CompareEditorInput) input; |
| if (ci.getCompareResult() == null) { |
| if (getState() == INITIALIZING) { |
| getSite().setSelectionProvider(new CompareEditorSelectionProvider()); |
| setPageLater(); |
| } else if (getState() == STILL_INITIALIZING) { |
| if (initializingPage == null) { |
| initializingPage = getInitializingMessagePane(fPageBook); |
| } |
| fPageBook.showPage(initializingPage); |
| } else if (getState() == CANCELED) { |
| // Close the editor when we are canceled |
| closeEditor(); |
| } else if (getState() == NO_DIFF) { |
| // Prompt and close the editor as well |
| setState(DONE); |
| closeEditor(); |
| CompareUIPlugin.getDefault().handleNoDifference(); |
| } else if (getState() == ERROR) { |
| // If an error occurred, close the editor |
| // (the message would be displayed by the progress view) |
| closeEditor(); |
| } |
| } else if (fControl == null && getState() != CREATING_CONTROL) { |
| if (getState() == CANCELED) { |
| // Close the editor when we are canceled, even when compare |
| // result has been already prepared |
| closeEditor(); |
| return; |
| } |
| // Set the state in case this method gets called again |
| setState(CREATING_CONTROL); |
| if (getSite().getSelectionProvider() == null) |
| getSite().setSelectionProvider(new CompareEditorSelectionProvider()); |
| try { |
| fControl = ci.createContents(fPageBook); |
| } catch (SWTException e) { |
| // closed while creating |
| if (e.code == SWT.ERROR_WIDGET_DISPOSED) { |
| setState(CANCELED); |
| return; |
| } |
| } |
| fPageBook.showPage(fControl); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(fControl, ICompareContextIds.COMPARE_EDITOR); |
| if (isActive()) { |
| setFocus(); |
| } |
| setState(INITIALIZED); |
| } |
| } |
| } |
| |
| private boolean isActive() { |
| return getSite().getPage().getActivePart() == this; |
| } |
| |
| private void setPageLater() { |
| Display.getCurrent().timerExec(1000, () -> { |
| synchronized(CompareEditor.this) { |
| if (getState() == INITIALIZING) { |
| setState(STILL_INITIALIZING); |
| createCompareControl(); |
| } |
| } |
| }); |
| } |
| |
| @Override |
| public void dispose() { |
| IEditorInput input= getEditorInput(); |
| if (input instanceof IPropertyChangeNotifier) |
| ((IPropertyChangeNotifier)input).removePropertyChangeListener(this); |
| super.dispose(); |
| } |
| |
| @Override |
| public void setFocus() { |
| IEditorInput input= getEditorInput(); |
| if (input instanceof CompareEditorInput) |
| if (!((CompareEditorInput)input).setFocus2()) |
| fPageBook.setFocus(); |
| } |
| |
| @Override |
| public boolean isSaveAsAllowed() { |
| return false; |
| } |
| |
| @Override |
| public void doSaveAs() { |
| Assert.isTrue(false); // Save As not supported for CompareEditor |
| } |
| |
| @Override |
| public void doSave(IProgressMonitor progressMonitor) { |
| final IEditorInput input= getEditorInput(); |
| |
| WorkspaceModifyOperation operation= new WorkspaceModifyOperation() { |
| @Override |
| public void execute(IProgressMonitor pm) throws CoreException { |
| if (input instanceof CompareEditorInput) |
| ((CompareEditorInput)input).saveChanges(pm); |
| } |
| }; |
| |
| Shell shell= getSite().getShell(); |
| |
| try { |
| operation.run(progressMonitor); |
| firePropertyChange(PROP_DIRTY); |
| } catch (InterruptedException x) { |
| // NeedWork |
| } catch (OperationCanceledException x) { |
| // NeedWork |
| } catch (InvocationTargetException x) { |
| String title= Utilities.getString("CompareEditor.saveError.title"); //$NON-NLS-1$ |
| String reason= x.getTargetException().getMessage(); |
| MessageDialog.openError(shell, title, Utilities.getFormattedString("CompareEditor.cantSaveError", reason)); //$NON-NLS-1$ |
| } |
| } |
| |
| @Override |
| public boolean isDirty() { |
| IEditorInput input= getEditorInput(); |
| if (input instanceof CompareEditorInput) |
| return ((CompareEditorInput)input).isDirty(); |
| return false; |
| } |
| |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| if (event.getProperty().equals(CompareEditorInput.DIRTY_STATE)) { |
| Object old_value= event.getOldValue(); |
| Object new_value= event.getNewValue(); |
| if (old_value == null || new_value == null || !old_value.equals(new_value)) |
| firePropertyChange(PROP_DIRTY); |
| } else if (event.getProperty().equals(CompareEditorInput.PROP_TITLE)) { |
| setPartName(((CompareEditorInput)getEditorInput()).getTitle()); |
| setTitleToolTip(((CompareEditorInput)getEditorInput()).getToolTipText()); |
| } else if (event.getProperty().equals(CompareEditorInput.PROP_TITLE_IMAGE)) { |
| setTitleImage(((CompareEditorInput)getEditorInput()).getTitleImage()); |
| } |
| } |
| |
| @Override |
| public Saveable[] getSaveables() { |
| return internalGetSaveables(knownSaveables == null); |
| } |
| |
| private Saveable[] internalGetSaveables(boolean init) { |
| IEditorInput input= getEditorInput(); |
| Saveable[] sourceSaveables = getSaveables(input); |
| if (init || knownSaveables == null) { |
| recordSaveables(sourceSaveables); |
| } else { |
| for (Saveable saveable : sourceSaveables) { |
| if (!knownSaveables.contains(saveable)) { |
| CompareUIPlugin.logErrorMessage(NLS.bind("Saveable {0} was not added using a saveables lifecycle event.", saveable.getName())); //$NON-NLS-1$ |
| knownSaveables.add(saveable); |
| } |
| } |
| if (sourceSaveables.length != knownSaveables.size()) { |
| CompareUIPlugin.logErrorMessage("Saveables were removed without an appropriate event"); //$NON-NLS-1$ |
| knownSaveables.clear(); |
| recordSaveables(sourceSaveables); |
| } |
| } |
| return sourceSaveables; |
| } |
| |
| private boolean isAllSaveablesKnown() { |
| IEditorInput input= getEditorInput(); |
| Saveable[] sourceSaveables = getSaveables(input); |
| if (knownSaveables == null) { |
| return sourceSaveables.length == 0; |
| } |
| if (sourceSaveables.length != knownSaveables.size()) { |
| return false; |
| } |
| for (Saveable saveable : sourceSaveables) { |
| if (!knownSaveables.contains(saveable)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| private void recordSaveables(Saveable[] sourceSaveables) { |
| if (knownSaveables == null) |
| knownSaveables = new HashSet<>(); |
| Collections.addAll(knownSaveables, sourceSaveables); |
| } |
| |
| private Saveable[] getSaveables(IEditorInput input) { |
| if (input instanceof ISaveablesSource) { |
| ISaveablesSource source= (ISaveablesSource) input; |
| return source.getSaveables(); |
| } |
| return new Saveable[] { getSaveable() }; |
| } |
| |
| private Saveable getSaveable() { |
| if (fSaveable == null) { |
| fSaveable= new CompareSaveable(); |
| } |
| return fSaveable; |
| } |
| |
| @Override |
| public Saveable[] getActiveSaveables() { |
| IEditorInput input= getEditorInput(); |
| if (input instanceof ISaveablesSource) { |
| ISaveablesSource source= (ISaveablesSource) input; |
| return source.getActiveSaveables(); |
| } |
| return new Saveable[] { getSaveable() }; |
| } |
| |
| private class CompareSaveable extends Saveable { |
| |
| @Override |
| public String getName() { |
| return CompareEditor.this.getPartName(); |
| } |
| |
| @Override |
| public String getToolTipText() { |
| return CompareEditor.this.getTitleToolTip(); |
| } |
| |
| @Override |
| public ImageDescriptor getImageDescriptor() { |
| return ImageDescriptor.createFromImage(CompareEditor.this.getTitleImage()); |
| } |
| |
| @Override |
| public void doSave(IProgressMonitor monitor) throws CoreException { |
| CompareEditor.this.doSave(monitor); |
| } |
| |
| @Override |
| public boolean isDirty() { |
| return CompareEditor.this.isDirty(); |
| } |
| |
| @Override |
| public boolean equals(Object object) { |
| return object == this; |
| } |
| |
| @Override |
| public int hashCode() { |
| return CompareEditor.this.hashCode(); |
| } |
| } |
| |
| private Composite getInitializingMessagePane(Composite parent) { |
| Composite composite = new Composite(parent, SWT.NONE); |
| composite.setBackground(getBackgroundColor(parent)); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 3; |
| composite.setLayout(layout); |
| |
| createDescriptionLabel(composite, CompareMessages.CompareEditor_1); |
| return composite; |
| } |
| |
| private Color getBackgroundColor(Composite parent) { |
| return parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND); |
| } |
| |
| private Label createDescriptionLabel(Composite parent, String text) { |
| Label description = new Label(parent, SWT.WRAP); |
| GridData data = new GridData(GridData.FILL_HORIZONTAL); |
| data.horizontalSpan = 2; |
| description.setLayoutData(data); |
| description.setText(text); |
| description.setBackground(getBackgroundColor(parent)); |
| return description; |
| } |
| |
| private void closeEditor() { |
| getSite().getPage().closeEditor(CompareEditor.this, false); |
| } |
| |
| private synchronized void setState(int state) { |
| this.state = state; |
| } |
| |
| private int getState() { |
| return state; |
| } |
| |
| @Override |
| public void handleLifecycleEvent(SaveablesLifecycleEvent event) { |
| ISaveablesLifecycleListener lifecycleListener= |
| getSite().getService(ISaveablesLifecycleListener.class); |
| if (event.getEventType() == SaveablesLifecycleEvent.POST_CLOSE) { |
| // We may get a post close for a saveable that is not known to the workbench. |
| // Only pass on the event for known saveables |
| if (knownSaveables == null || knownSaveables.isEmpty()) |
| return; |
| java.util.List<Saveable> result = new ArrayList<>(); |
| Saveable[] all = event.getSaveables(); |
| for (Saveable saveable : all) { |
| if (knownSaveables.contains(saveable)) |
| result.add(saveable); |
| knownSaveables.remove(saveable); |
| } |
| if (result.isEmpty()) |
| return; |
| event = new SaveablesLifecycleEvent(this, |
| SaveablesLifecycleEvent.POST_CLOSE, |
| result.toArray(new Saveable[result.size()]), |
| false); |
| } else if (event.getEventType() == SaveablesLifecycleEvent.POST_OPEN) { |
| recordSaveables(event.getSaveables()); |
| } |
| lifecycleListener.handleLifecycleEvent(event); |
| } |
| } |