blob: ec36c16b836421feea82a6cd4f7df55f4d3d687a [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
* Brock Janiczak (brockj_eclipse@ihug.com.au) - handler registration
*******************************************************************************/
package org.eclipse.ui.internal.registry;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveFactory;
import org.eclipse.ui.IPluginContribution;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.IWorkbenchConstants;
import org.eclipse.ui.internal.IWorkbenchGraphicConstants;
import org.eclipse.ui.internal.WorkbenchImages;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.plugin.AbstractUIPlugin;
/**
* PerspectiveDescriptor.
* <p>
* A PerspectiveDesciptor has 3 states:
* </p>
* <ol>
* <li>It <code>isPredefined()</code>, in which case it was defined from an
* extension point.</li>
* <li>It <code>isPredefined()</code> and <code>hasCustomFile</code>, in
* which case the user has customized a predefined perspective.</li>
* <li>It <code>hasCustomFile</code>, in which case the user created a new
* perspective.</li>
* </ol>
*
*/
public class PerspectiveDescriptor implements IPerspectiveDescriptor,
IPluginContribution {
private String id;
private String pluginId;
private String originalId;
private String label;
private String className;
private String description;
private boolean singleton;
private boolean fixed;
private ImageDescriptor image;
private IConfigurationElement configElement;
/**
* Create a new empty descriptor.
*
* @param id
* the id of the new descriptor
* @param label
* the label of the new descriptor
* @param originalDescriptor
* the descriptor that this descriptor is based on
*/
public PerspectiveDescriptor(String id, String label,
PerspectiveDescriptor originalDescriptor) {
this.id = id;
this.label = label;
if (originalDescriptor != null) {
this.originalId = originalDescriptor.getOriginalId();
this.image = originalDescriptor.image;
// This perspective is based on a perspective in some bundle -- if
// that
// bundle goes away then I think it makes sense to treat this
// perspective
// the same as any other -- so store it with the original
// descriptor's
// bundle's list.
//
// It might also make sense the other way...removing the following
// line
// will allow the perspective to stay around when the originating
// bundle
// is unloaded.
//
// This might also have an impact on upgrade cases -- should we
// really be
// destroying all user customized perspectives when the older
// version is
// removed?
//
// I'm leaving this here for now since its a good example, but
// wouldn't be
// surprised if we ultimately decide on the opposite.
//
// The reason this line is important is that this is the value used
// to
// put the object into the UI level registry. When that bundle goes
// away,
// the registry will remove the entire list of objects. So if this
// desc
// has been put into that list -- it will go away.
this.pluginId = originalDescriptor.getPluginId();
}
}
/**
* Create a descriptor from a config element.
*
* @param id
* the id of the element to create
* @param configElement
* the element to base this perspective on
* @throws CoreException
* thrown if there are any missing attributes
*/
public PerspectiveDescriptor(String id, IConfigurationElement configElement)
throws CoreException {
this.configElement = configElement;
this.id = id;
// Sanity check.
if ((getId() == null) || (getLabel() == null)
|| (getClassName() == null)) {
throw new CoreException(
new Status(
IStatus.ERROR,
WorkbenchPlugin.PI_WORKBENCH,
0,
"Invalid extension (missing label, id or class name): " + getId(),//$NON-NLS-1$
null));
}
}
/**
* Creates a factory for a predefined perspective. If the perspective is not
* predefined return <code>null</code>.
*
* @return the IPerspectiveFactory or <code>null</code>
* @throws CoreException
* if the object could not be instantiated.
*/
public IPerspectiveFactory createFactory() throws CoreException {
// if there is an originalId, then use that descriptor instead
if (originalId != null) {
// Get the original descriptor to create the factory. If the
// original is gone then nothing can be done.
IPerspectiveDescriptor target = ((PerspectiveRegistry) WorkbenchPlugin
.getDefault().getPerspectiveRegistry())
.findPerspectiveWithId(originalId);
return target == null ? null : ((PerspectiveDescriptor) target)
.createFactory();
}
// otherwise try to create the executable extension
if (configElement != null) {
try {
return (IPerspectiveFactory) configElement
.createExecutableExtension(IWorkbenchRegistryConstants.ATT_CLASS);
} catch (CoreException e) {
// do nothing
}
}
return null;
}
/**
* Deletes the custom definition for a perspective..
*/
public void deleteCustomDefinition() {
((PerspectiveRegistry) WorkbenchPlugin.getDefault()
.getPerspectiveRegistry()).deleteCustomDefinition(this);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPerspectiveDescriptor#getDescription()
*/
public String getDescription() {
return configElement == null ? description : RegistryReader
.getDescription(configElement);
}
/**
* Returns whether or not this perspective is fixed.
*
* @return whether or not this perspective is fixed
*/
public boolean getFixed() {
return configElement == null ? fixed : Boolean.valueOf(
configElement
.getAttribute(IWorkbenchRegistryConstants.ATT_FIXED))
.booleanValue();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPerspectiveDescriptor#getId()
*/
public String getId() {
return id;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPerspectiveDescriptor#getImageDescriptor()
*/
public ImageDescriptor getImageDescriptor() {
if (image == null) {
if (configElement != null) {
String icon = configElement
.getAttribute(IWorkbenchRegistryConstants.ATT_ICON);
if (icon != null) {
image = AbstractUIPlugin.imageDescriptorFromPlugin(
configElement.getNamespace(), icon);
}
if (image == null) {
image = WorkbenchImages
.getImageDescriptor(IWorkbenchGraphicConstants.IMG_ETOOL_DEF_PERSPECTIVE);
}
}
}
return image;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPerspectiveDescriptor#getLabel()
*/
public String getLabel() {
return configElement == null ? label : configElement
.getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
}
/**
* Return the original id of this descriptor.
*
* @return the original id of this descriptor
*/
public String getOriginalId() {
if (originalId == null) {
return getId();
}
return originalId;
}
/**
* Returns <code>true</code> if this perspective has a custom definition.
*
* @return whether this perspective has a custom definition
*/
public boolean hasCustomDefinition() {
return ((PerspectiveRegistry) WorkbenchPlugin.getDefault()
.getPerspectiveRegistry()).hasCustomDefinition(this);
}
/**
* Returns <code>true</code> if this perspective wants to be default.
*
* @return whether this perspective wants to be default
*/
public boolean hasDefaultFlag() {
if (configElement == null) {
return false;
}
return Boolean.valueOf(
configElement
.getAttribute(IWorkbenchRegistryConstants.ATT_DEFAULT))
.booleanValue();
}
/**
* Returns <code>true</code> if this perspective is predefined by an
* extension.
*
* @return boolean whether this perspective is predefined by an extension
*/
public boolean isPredefined() {
return getClassName() != null && configElement != null;
}
/**
* Returns <code>true</code> if this perspective is a singleton.
*
* @return whether this perspective is a singleton
*/
public boolean isSingleton() {
return configElement == null ? singleton
: configElement
.getAttributeAsIs(IWorkbenchRegistryConstants.ATT_SINGLETON) != null;
}
/**
* Restore the state of a perspective from a memento.
*
* @param memento
* the memento to restore from
* @return the <code>IStatus</code> of the operation
* @see org.eclipse.ui.IPersistableElement
*/
public IStatus restoreState(IMemento memento) {
IMemento childMem = memento
.getChild(IWorkbenchConstants.TAG_DESCRIPTOR);
if (childMem != null) {
id = childMem.getString(IWorkbenchConstants.TAG_ID);
originalId = childMem.getString(IWorkbenchConstants.TAG_DESCRIPTOR);
label = childMem.getString(IWorkbenchConstants.TAG_LABEL);
className = childMem.getString(IWorkbenchConstants.TAG_CLASS);
singleton = (childMem.getInteger(IWorkbenchConstants.TAG_SINGLETON) != null);
// Find a descriptor in the registry.
IPerspectiveDescriptor descriptor = WorkbenchPlugin.getDefault()
.getPerspectiveRegistry().findPerspectiveWithId(
getOriginalId());
if (descriptor != null) {
// Copy the state from the registred descriptor.
image = descriptor.getImageDescriptor();
}
}
return new Status(IStatus.OK, PlatformUI.PLUGIN_ID, 0, "", null); //$NON-NLS-1$
}
/**
* Revert to the predefined extension template. Does nothing if this
* descriptor is user defined.
*/
public void revertToPredefined() {
if (isPredefined()) {
deleteCustomDefinition();
}
}
/**
* Save the state of a perspective to a memento.
*
* @param memento
* the memento to restore from
* @return the <code>IStatus</code> of the operation
* @see org.eclipse.ui.IPersistableElement
*/
public IStatus saveState(IMemento memento) {
IMemento childMem = memento
.createChild(IWorkbenchConstants.TAG_DESCRIPTOR);
childMem.putString(IWorkbenchConstants.TAG_ID, getId());
if (originalId != null) {
childMem.putString(IWorkbenchConstants.TAG_DESCRIPTOR, originalId);
}
childMem.putString(IWorkbenchConstants.TAG_LABEL, getLabel());
childMem.putString(IWorkbenchConstants.TAG_CLASS, getClassName());
if (singleton) {
childMem.putInteger(IWorkbenchConstants.TAG_SINGLETON, 1);
}
return new Status(IStatus.OK, PlatformUI.PLUGIN_ID, 0, "", null); //$NON-NLS-1$
}
/**
* Return the configuration element used to create this perspective, if one
* was used.
*
* @return the configuration element used to create this perspective
* @since 3.0
*/
public IConfigurationElement getConfigElement() {
return configElement;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.activities.support.IPluginContribution#getLocalId()
*/
public String getLocalId() {
return getId();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.activities.support.IPluginContribution#getPluginId()
*/
public String getPluginId() {
return configElement == null ? pluginId : configElement.getNamespace();
}
/**
* Returns the factory class name for this descriptor.
*
* @return the factory class name for this descriptor
* @since 3.1
*/
public String getClassName() {
return configElement == null ? className : RegistryReader
.getClassValue(configElement,
IWorkbenchRegistryConstants.ATT_CLASS);
}
}