blob: 9aa3e1ebeb11612a87ebbdee05eb0ff090929b90 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.compare.internal;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.compare.*;
import org.eclipse.core.runtime.*;
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.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.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.*;
import org.eclipse.ui.*;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.services.IServiceLocator;
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 {
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 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 int state = UNINITIALIZED;
private final EditorCompareContainer fContainer = new EditorCompareContainer();
private class EditorCompareContainer extends CompareContainer {
/* (non-Javadoc)
* @see org.eclipse.compare.ICompareContainer#registerContextMenu(org.eclipse.jface.action.MenuManager, org.eclipse.jface.viewers.ISelectionProvider)
*/
public void registerContextMenu(MenuManager menu, ISelectionProvider provider) {
getSite().registerContextMenu(menu, provider);
}
/* (non-Javadoc)
* @see org.eclipse.compare.ICompareContainer#setStatusMessage(java.lang.String)
*/
public void setStatusMessage(String message) {
if (fActionBars != null) {
IStatusLineManager slm= fActionBars.getStatusLineManager();
if (slm != null) {
slm.setMessage(message);
}
}
}
/* (non-Javadoc)
* @see org.eclipse.compare.ICompareContainer#getServiceLocator()
*/
public IServiceLocator getServiceLocator() {
return getSite();
}
/* (non-Javadoc)
* @see org.eclipse.compare.internal.CompareContainer#createWorkerJob()
*/
protected WorkerJob createWorkerJob() {
WorkerJob workerJob = new WorkerJob(getWorkerJobName()) {
public boolean belongsTo(Object family) {
if (family == CompareEditor.this)
return true;
return super.belongsTo(family);
}
};
return workerJob;
}
/* (non-Javadoc)
* @see org.eclipse.compare.internal.CompareContainer#getWorkerJobName()
*/
protected String getWorkerJobName() {
return NLS.bind(CompareMessages.CompareEditor_11, getTitle());
}
}
/**
* No-argument constructor required for extension points.
*/
public CompareEditor() {
// empty default implementation
}
/* (non-Javadoc)
* Method declared on IAdaptable
*/
public Object getAdapter(Class key) {
if (key.equals(IContentOutlinePage.class)) {
Object object= getCompareConfiguration().getProperty(CompareConfiguration.USE_OUTLINE_VIEW);
if (object instanceof Boolean && ((Boolean)object).booleanValue()) {
IEditorInput input= getEditorInput();
if (input instanceof CompareEditorInput) {
fOutlinePage= new CompareOutlinePage((CompareEditorInput) input);
return fOutlinePage;
}
}
}
return super.getAdapter(key);
}
/*
* Helper method used by ComapreEditorConfiguration to get at the compare configuration of the editor
*/
/* package */ CompareConfiguration getCompareConfiguration() {
IEditorInput input= getEditorInput();
if (input instanceof CompareEditorInput)
return ((CompareEditorInput)input).getCompareConfiguration();
return null;
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
*/
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);
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
*/
public void setInput(IEditorInput input) {
try {
doSetInput(input);
// Need to refresh the contributor (see #67888)
IEditorSite editorSite= getEditorSite();
if (editorSite != null) {
IEditorActionBarContributor actionBarContributor= editorSite.getActionBarContributor();
if (actionBarContributor != null) {
actionBarContributor.setActiveEditor(null);
actionBarContributor.setActiveEditor(this);
}
}
} catch (CoreException x) {
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, x.getStatus());
}
}
private void doSetInput(IEditorInput input) throws CoreException {
if (!(input instanceof CompareEditorInput)) {
IStatus s= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, Utilities.getString("CompareEditor.invalidInput"), null); //$NON-NLS-1$
throw new CoreException(s);
}
IEditorInput oldInput= getEditorInput();
if (oldInput instanceof IPropertyChangeNotifier)
((IPropertyChangeNotifier)input).removePropertyChangeListener(this);
ISaveablesLifecycleListener lifecycleListener= null;
if (oldInput != null) {
lifecycleListener= (ISaveablesLifecycleListener) getSite().getService(ISaveablesLifecycleListener.class);
lifecycleListener.handleLifecycleEvent(
new SaveablesLifecycleEvent(this, SaveablesLifecycleEvent.POST_CLOSE, getSaveables(), false));
}
super.setInput(input);
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);
state = cei.getCompareResult() == null ? INITIALIZING : INITIALIZED;
Point oldSize = null;
if (oldInput != null) {
if (fControl != null && !fControl.isDisposed()) {
oldSize= fControl.getSize();
fControl.dispose();
fControl = null;
}
}
if (fPageBook != null)
createCompareControl();
if (fControl != null && oldSize != null)
fControl.setSize(oldSize);
Job.getJobManager().cancel(this);
if (cei.getCompareResult() == null) {
initializeInBackground(cei);
}
firePropertyChange(IWorkbenchPartConstants.PROP_INPUT);
if (lifecycleListener != null) {
lifecycleListener.handleLifecycleEvent(
new SaveablesLifecycleEvent(this, SaveablesLifecycleEvent.POST_OPEN, getSaveables(), false));
}
}
protected void initializeInBackground(final CompareEditorInput cei) {
// Need to cancel any running jobs associated with the oldInput
Job job = new Job(CompareMessages.CompareEditor_0) {
protected IStatus run(IProgressMonitor monitor) {
IStatus status;
try {
status = CompareUIPlugin.getDefault().prepareInput(cei, monitor);
if (status.isOK()) {
// We need to update the saveables list
state = INITIALIZED;
Saveable[] saveables = getSaveables();
if (saveables.length > 0) {
ISaveablesLifecycleListener listener= (ISaveablesLifecycleListener) getSite().getService(ISaveablesLifecycleListener.class);
if (listener != null) {
listener.handleLifecycleEvent(
new SaveablesLifecycleEvent(CompareEditor.this, SaveablesLifecycleEvent.POST_OPEN, saveables, false));
}
}
return Status.OK_STATUS;
}
if (status.getCode() == CompareUIPlugin.NO_DIFFERENCE) {
state = NO_DIFF;
return Status.OK_STATUS;
}
state = ERROR;
} catch (OperationCanceledException e) {
state= CANCELED;
status = Status.CANCEL_STATUS;
} finally {
if (monitor.isCanceled())
state= CANCELED;
Display.getDefault().asyncExec(new Runnable() {
public void run() {
createCompareControl();
}
});
}
return status;
}
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;
}
/*
* Set the action bars so the Utilities class can access it.
*/
/* package */ void setActionBars(IActionBars actionBars) {
fActionBars= actionBars;
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {
parent.setData(this);
fPageBook = new PageBook(parent, SWT.NONE);
createCompareControl();
}
private void createCompareControl() {
if (fPageBook.isDisposed())
return;
IEditorInput input= getEditorInput();
if (input instanceof CompareEditorInput) {
CompareEditorInput ci = (CompareEditorInput) input;
if (ci.getCompareResult() == null) {
if (state == INITIALIZING) {
if (initializingPage == null) {
initializingPage = getInitializingMessagePane(fPageBook);
}
fPageBook.showPage(initializingPage);
} else if (state == CANCELED) {
// Close the editor when we are canceled
closeEditor();
} else if (state == NO_DIFF) {
closeEditor();
} else if (state == ERROR) {
// If an error occurred, close the editor
// (the message would be displayed by the progress view)
closeEditor();
}
} else {
fControl= (ci).createContents(fPageBook);
fPageBook.showPage(fControl);
PlatformUI.getWorkbench().getHelpSystem().setHelp(fControl, ICompareContextIds.COMPARE_EDITOR);
}
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#dispose()
*/
public void dispose() {
IEditorInput input= getEditorInput();
if (input instanceof IPropertyChangeNotifier)
((IPropertyChangeNotifier)input).removePropertyChangeListener(this);
super.dispose();
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#setFocus()
*/
public void setFocus() {
IEditorInput input= getEditorInput();
if (input instanceof CompareEditorInput)
((CompareEditorInput)input).setFocus();
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
*/
public boolean isSaveAsAllowed() {
return false;
}
/* (non-Javadoc)
* Always throws an AssertionFailedException.
* @see org.eclipse.ui.part.EditorPart#doSaveAs()
*/
public void doSaveAs() {
Assert.isTrue(false); // Save As not supported for CompareEditor
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
*/
public void doSave(IProgressMonitor progressMonitor) {
final IEditorInput input= getEditorInput();
WorkspaceModifyOperation operation= new WorkspaceModifyOperation() {
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$
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.EditorPart#isDirty()
*/
public boolean isDirty() {
IEditorInput input= getEditorInput();
if (input instanceof ISaveablesSource) {
ISaveablesSource sms= (ISaveablesSource) input;
Saveable[] models= sms.getSaveables();
for (int i= 0; i < models.length; i++) {
Saveable model= models[i];
if (model.isDirty())
return true;
}
}
if (input instanceof CompareEditorInput)
return ((CompareEditorInput)input).isSaveNeeded();
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
*/
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());
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.ISaveablesSource#getModels()
*/
public Saveable[] getSaveables() {
IEditorInput input= getEditorInput();
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;
}
/* (non-Javadoc)
* @see org.eclipse.ui.ISaveablesSource#getActiveModels()
*/
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 {
public String getName() {
return CompareEditor.this.getPartName();
}
public String getToolTipText() {
return CompareEditor.this.getTitleToolTip();
}
public ImageDescriptor getImageDescriptor() {
return ImageDescriptor.createFromImage(CompareEditor.this.getTitleImage());
}
public void doSave(IProgressMonitor monitor) throws CoreException {
CompareEditor.this.doSave(monitor);
}
public boolean isDirty() {
return CompareEditor.this.isDirty();
}
public boolean equals(Object object) {
return object == this;
}
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);
}
}