/* ******************************************************************************
* 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.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.IconTipDecorator;
import org.xmind.ui.mindmap.IIconTipPart;
import org.xmind.ui.mindmap.ISelectionFeedbackHelper;
import org.xmind.ui.mindmap.ITopicPart;
import org.xmind.ui.resources.ColorUtils;
import org.xmind.ui.resources.FontUtils;
import org.xmind.ui.resources.ImageReference;
public class IconTipPart extends MindMapPartBase
implements IIconTipPart, IPropertyChangeListener {
public static final String TEXT_COLOR = "#2e2e2e"; //$NON-NLS-1$
private IAction action;
private IMenuManager menu;
private String actionId;
private ImageReference imageRef = null;
public IconTipPart() {
setDecorator(IconTipDecorator.getInstance());
}
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 SizeableImageFigure getImageFigure() {
return (SizeableImageFigure) super.getFigure();
}
public IMenuManager getPopupMenu() {
TopicPart topicPart = (TopicPart) getParent();
ITopic topic = topicPart.getTopic();
IconTip iconTip = (IconTip) IconTipPart.this.getModel();
final List<IAction> actions = iconTip.getInfoItemContributor()
.getPopupMenuActions(topicPart, topic);
if (actions == null || actions.isEmpty()) {
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 ITopicPart getTopicPart() {
if (getParent() instanceof ITopicPart)
return (ITopicPart) getParent();
return null;
}
public void setParent(IPart parent) {
if (getParent() instanceof TopicPart) {
((TopicPart) getParent()).removeIconTip(this);
}
super.setParent(parent);
if (getParent() instanceof TopicPart) {
((TopicPart) getParent()).addIconTip(this);
}
}
protected void register() {
super.register();
if (getModel() instanceof IconTip) {
setAction(((IconTip) getModel()).getAction());
}
}
protected void unregister() {
setAction(null);
super.unregister();
}
public 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) {
ITopicPart topicPart = getTopicPart();
if (topicPart == null)
return;
IActionRegistry actionRegistry = (IActionRegistry) topicPart
.getAdapter(IActionRegistry.class);
if (actionRegistry == null)
return;
if (actionRegistry.getAction(actionId) == action) {
actionRegistry.removeAction(actionId);
}
}
private void registerAction(IAction action) {
ITopicPart topicPart = getTopicPart();
if (topicPart == null)
return;
IActionRegistry actionRegistry = (IActionRegistry) topicPart
.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.getImageDescriptor();
if (oldImageDescriptor != newImageDescriptor
&& (oldImageDescriptor == null
|| !oldImageDescriptor.equals(newImageDescriptor))) {
if (imageRef != null) {
imageRef.dispose();
}
imageRef = newImageDescriptor == null ? null
: new ImageReference(newImageDescriptor, false);
}
}
protected void onDeactivated() {
if (imageRef != null) {
imageRef.dispose();
imageRef = null;
}
super.onDeactivated();
}
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 (actionId != null
// && actionId.equals(MindMapActionFactory.EDIT_NOTES
// .getId())) {
// text = null;
// }
if (text != null) {
text = Action.removeAcceleratorText(text);
text = Action.removeMnemonics(text);
Label title = new Label(text);
title.setFont(
FontUtils.getBold(JFaceResources.DEFAULT_FONT));
title.setForegroundColor(ColorConstants.darkGray);
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,
350));
description.setFont(FontUtils.getRelativeHeight(
JFaceResources.DEFAULT_FONT, -1));
// description.setForegroundColor(ColorConstants.gray);
description.setForegroundColor(
ColorUtils.getColor(TEXT_COLOR));
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();
}
}
public String getActionId() {
return actionId;
}
}