/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.ui.internal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IEditorActionDelegate;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.internal.registry.RegistryReader;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.xmind.ui.mindmap.MindMapUI;
import org.xmind.ui.util.Logger;
public class ImageActionExtensionManager extends RegistryReader implements
IWorkbenchRegistryConstants {
public static class ActionBuilder implements IActionBuilder {
private IConfigurationElement element;
private String id;
private IEditorActionDelegate delegate;
private boolean delegateFailed = false;
private ImageDescriptor icon;
private boolean iconFailed = false;
private ImageDescriptor disabledIcon;
private boolean disabledIconFailed = false;
public ActionBuilder(IConfigurationElement element)
throws CoreException {
this.element = element;
if (getClassValue(element, ATT_CLASS) == null)
throw new CoreException(new Status(IStatus.ERROR, element
.getNamespaceIdentifier(),
"Invalid extension (missing class)")); //$NON-NLS-1$
this.id = element.getAttribute(ATT_ID);
}
/*
* (non-Javadoc)
*
* @see org.xmind.ui.internal.IActionBuilder#getId()
*/
public String getId() {
return id;
}
/*
* (non-Javadoc)
*
* @see org.xmind.ui.internal.IActionBuilder#getLabel()
*/
public String getLabel() {
return element.getAttribute(ATT_LABEL);
}
/*
* (non-Javadoc)
*
* @see org.xmind.ui.internal.IActionBuilder#getDelegate()
*/
public IEditorActionDelegate getDelegate() {
if (delegate == null && !delegateFailed) {
delegate = createDelegate();
if (delegate == null)
delegateFailed = true;
}
return delegate;
}
private IEditorActionDelegate createDelegate() {
try {
return (IEditorActionDelegate) element
.createExecutableExtension(ATT_CLASS);
} catch (CoreException e) {
Logger.log(e);
return null;
}
}
/*
* (non-Javadoc)
*
* @see org.xmind.ui.internal.IActionBuilder#getDefinitionId()
*/
public String getDefinitionId() {
return element.getAttribute(ATT_DEFINITION_ID);
}
/*
* (non-Javadoc)
*
* @see org.xmind.ui.internal.IActionBuilder#getTooltip()
*/
public String getTooltip() {
return element.getAttribute(ATT_TOOLTIP);
}
/*
* (non-Javadoc)
*
* @see org.xmind.ui.internal.IActionBuilder#getIcon()
*/
public ImageDescriptor getIcon() {
if (icon == null && !iconFailed) {
icon = createIcon();
if (icon == null)
iconFailed = true;
}
return icon;
}
private ImageDescriptor createIcon() {
String iconPath = element.getAttribute(ATT_ICON);
if (iconPath != null) {
return AbstractUIPlugin.imageDescriptorFromPlugin(element
.getNamespaceIdentifier(), iconPath);
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.xmind.ui.internal.IActionBuilder#getDisabledIcon()
*/
public ImageDescriptor getDisabledIcon() {
if (disabledIcon == null && !disabledIconFailed) {
disabledIcon = createDisabledIcon();
if (disabledIcon == null)
disabledIconFailed = true;
}
return disabledIcon;
}
private ImageDescriptor createDisabledIcon() {
String iconPath = element.getAttribute(ATT_DISABLEDICON);
if (iconPath != null) {
return AbstractUIPlugin.imageDescriptorFromPlugin(element
.getNamespaceIdentifier(), iconPath);
}
return null;
}
public IWorkbenchAction createAction(IWorkbenchPage page) {
return new DelegatedAction(this, page);
}
}
private static class DelegatedAction extends Action implements
IWorkbenchAction, IPartListener, ISelectionListener {
private IWorkbenchPage page;
private IActionBuilder builder;
private IEditorPart targetEditor;
public DelegatedAction(IActionBuilder builder, IWorkbenchPage page) {
this.builder = builder;
this.page = page;
setId(builder.getId());
setText(builder.getLabel());
setToolTipText(builder.getTooltip());
setImageDescriptor(builder.getIcon());
setDisabledImageDescriptor(builder.getDisabledIcon());
setActionDefinitionId(builder.getDefinitionId());
page.addPartListener(this);
page.addSelectionListener(this);
}
public void run() {
IEditorActionDelegate delegate = builder.getDelegate();
if (delegate != null)
delegate.run(this);
}
public void dispose() {
page.removeSelectionListener(this);
page.removePartListener(this);
}
public void partActivated(IWorkbenchPart part) {
if (part instanceof IEditorPart) {
this.targetEditor = (IEditorPart) part;
IEditorActionDelegate delegate = builder.getDelegate();
if (delegate != null)
delegate.setActiveEditor(this, targetEditor);
}
}
public void partBroughtToTop(IWorkbenchPart part) {
}
public void partClosed(IWorkbenchPart part) {
if (part == this.targetEditor) {
IEditorActionDelegate delegate = builder.getDelegate();
if (delegate != null)
delegate.setActiveEditor(this, null);
}
}
public void partDeactivated(IWorkbenchPart part) {
}
public void partOpened(IWorkbenchPart part) {
}
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
if (part == this.targetEditor) {
IEditorActionDelegate delegate = builder.getDelegate();
if (delegate != null)
delegate.selectionChanged(this, selection);
}
}
}
private static final ImageActionExtensionManager instance = new ImageActionExtensionManager();
private List<IActionBuilder> actionBuilders;
private ImageActionExtensionManager() {
}
public List<IActionBuilder> getActionBuilders() {
ensureLoaded();
return actionBuilders;
}
private void ensureLoaded() {
if (actionBuilders != null)
return;
lazyLoad();
if (actionBuilders == null)
actionBuilders = Collections.emptyList();
}
private void lazyLoad() {
readRegistry(Platform.getExtensionRegistry(), MindMapUI.PLUGIN_ID,
"imageActions"); //$NON-NLS-1$
}
protected boolean readElement(IConfigurationElement element) {
String name = element.getName();
if (TAG_ACTION.equals(name)) {
readChooser(element);
readElementChildren(element);
return true;
}
return false;
}
private void readChooser(IConfigurationElement element) {
try {
IActionBuilder actionBuilder = new ActionBuilder(element);
register(actionBuilder);
} catch (CoreException e) {
Logger.log(e);
}
}
private void register(IActionBuilder actionBuilder) {
if (actionBuilders == null)
actionBuilders = new ArrayList<IActionBuilder>();
actionBuilders.add(actionBuilder);
}
public static ImageActionExtensionManager getInstance() {
return instance;
}
}