package org.xmind.ui.internal.mindmap;
import java.util.List;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.xmind.core.ITopic;
import org.xmind.gef.GEF;
import org.xmind.gef.draw2d.RotatableWrapLabel;
import org.xmind.gef.draw2d.SizeableImageFigure;
import org.xmind.gef.part.IPart;
import org.xmind.gef.part.IRequestHandler;
import org.xmind.gef.policy.NullEditPolicy;
import org.xmind.gef.service.IFeedback;
import org.xmind.gef.ui.actions.IActionRegistry;
import org.xmind.ui.internal.decorators.InfoItemIconDecorator;
import org.xmind.ui.mindmap.IInfoItemPart;
import org.xmind.ui.mindmap.IInfoPart;
import org.xmind.ui.mindmap.ISelectionFeedbackHelper;
import org.xmind.ui.mindmap.ITopicPart;
import org.xmind.ui.resources.FontUtils;
import org.xmind.ui.resources.ImageReference;
public class InfoItemIconPart extends MindMapPartBase
implements IInfoItemPart, IPropertyChangeListener {
private IAction action;
private IMenuManager menu;
private String actionId;
private ImageReference imageRef = null;
public InfoItemIconPart() {
setDecorator(InfoItemIconDecorator.getInstance());
}
@Override
protected IFigure createFigure() {
return new SizeableImageFigure();
}
public IAction getAction() {
return action;
}
public Image getImage() {
if (imageRef != null && !imageRef.isDisposed())
return imageRef.getImage();
return null;
}
public IMenuManager getPopupMenu() {
InfoPart infoPart = (InfoPart) getParent();
ITopicPart topicPart = infoPart.getTopicPart();
ITopic topic = infoPart.getTopic();
InfoItemIcon infoItem = (InfoItemIcon) InfoItemIconPart.this.getModel();
final List<IAction> actions = infoItem.getContributor()
.getPopupMenuActions(topicPart, topic);
if (actions == null) {
return null;
} else {
if (menu == null) {
menu = new MenuManager();
menu.setRemoveAllWhenShown(true);
menu.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
for (IAction action : actions) {
menu.add(action);
}
}
});
}
}
return menu;
}
public ITopic getTopic() {
return (ITopic) super.getRealModel();
}
public IInfoPart getInforPart() {
if (getParent() instanceof IInfoPart)
return (IInfoPart) getParent();
return null;
}
public ITopicPart getTopicPart() {
if (getInforPart() != null)
return getInforPart().getTopicPart();
return null;
}
@Override
public void setParent(IPart parent) {
if (getParent() instanceof InfoPart)
((InfoPart) getParent()).removeInfoItemIcon(this);
super.setParent(parent);
if (getParent() instanceof InfoPart)
((InfoPart) getParent()).addInfoItemIcon(this);
}
@Override
protected void register() {
super.register();
if (getModel() instanceof InfoItemIcon)
setAction(((InfoItemIcon) getModel()).getAction());
}
@Override
protected void unregister() {
setAction(null);
super.unregister();
}
private void setAction(IAction action) {
if (action == this.action)
return;
if (this.action != null)
this.action.removePropertyChangeListener(this);
if (actionId != null)
unregisterAction(actionId, this.action);
this.action = action;
actionId = action == null ? null : action.getId();
if (actionId != null)
registerAction(action);
if (action != null)
action.addPropertyChangeListener(this);
updateImage();
}
private void unregisterAction(String actionId, IAction action) {
IInfoPart branchPart = getInforPart();
if (branchPart == null)
return;
IActionRegistry actionRegistry = (IActionRegistry) branchPart
.getAdapter(IActionRegistry.class);
if (actionRegistry == null)
return;
if (actionRegistry.getAction(actionId) == action) {
actionRegistry.removeAction(actionId);
}
}
private void registerAction(IAction action) {
IInfoPart infoPart = getInforPart();
if (infoPart == null)
return;
IActionRegistry actionRegistry = (IActionRegistry) infoPart
.getAdapter(IActionRegistry.class);
if (actionRegistry == null)
return;
actionRegistry.addAction(action);
}
private void updateImage() {
ImageDescriptor oldImageDescriptor = imageRef == null ? null
: imageRef.getImageDescriptor();
ImageDescriptor newImageDescriptor = null;
if (action != null)
newImageDescriptor = action.isEnabled()
? action.getImageDescriptor()
: action.getDisabledImageDescriptor();
if (oldImageDescriptor != newImageDescriptor
&& (oldImageDescriptor == null
|| !oldImageDescriptor.equals(newImageDescriptor))) {
if (imageRef != null) {
imageRef.dispose();
}
imageRef = newImageDescriptor == null ? null
: new ImageReference(newImageDescriptor, false);
}
}
@Override
protected void onDeactivated() {
if (imageRef != null) {
imageRef.dispose();
imageRef = null;
}
super.onDeactivated();
}
@Override
protected void updateView() {
super.updateView();
updateToolTip();
updateImage();
}
protected IFigure createToolTip() {
if (action != null) {
String text = action.getText();
String tooltip = action.getToolTipText();
if (text != null || tooltip != null) {
IFigure fig = new Figure();
fig.setBorder(new MarginBorder(1, 3, 1, 3));
ToolbarLayout layout = new ToolbarLayout(false);
layout.setMinorAlignment(ToolbarLayout.ALIGN_TOPLEFT);
layout.setSpacing(7);
fig.setLayoutManager(layout);
if (text != null) {
text = Action.removeAcceleratorText(text);
text = Action.removeMnemonics(text);
Label title = new Label(text);
title.setFont(
FontUtils.getBold(JFaceResources.DEFAULT_FONT));
fig.add(title);
}
if (tooltip != null) {
RotatableWrapLabel description = new RotatableWrapLabel(
tooltip, RotatableWrapLabel.NORMAL);
description.setTextAlignment(PositionConstants.LEFT);
description.setPrefWidth(Math.min(
Display.getCurrent().getClientArea().width / 3,
128));
description.setFont(FontUtils.getRelativeHeight(
JFaceResources.DEFAULT_FONT, -1));
description.setForegroundColor(ColorConstants.gray);
fig.add(description);
}
return fig;
}
}
return super.createToolTip();
}
@SuppressWarnings("unchecked")
public Object getAdapter(Class adapter) {
if (adapter.isAssignableFrom(ITopic.class))
return getTopic();
if (adapter == Image.class)
return getImage();
if (adapter == IAction.class)
return getAction();
if (adapter == IMenuManager.class)
return getPopupMenu();
return super.getAdapter(adapter);
}
protected void declareEditPolicies(IRequestHandler reqHandler) {
super.declareEditPolicies(reqHandler);
reqHandler.installEditPolicy(GEF.ROLE_SELECTABLE,
NullEditPolicy.getInstance());
}
protected IFeedback createFeedback() {
return new SimpleSelectionFeedback(this);
}
protected ISelectionFeedbackHelper createSelectionFeedbackHelper() {
return new SelectionFeedbackHelper();
}
public void propertyChange(PropertyChangeEvent event) {
String property = event.getProperty();
if (IAction.TEXT.equals(property)
|| IAction.TOOL_TIP_TEXT.equals(property)) {
updateToolTip();
} else if (IAction.IMAGE.equals(property)) {
updateImage();
update();
}
}
}