/* ****************************************************************************** * 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.ArrayList; import java.util.List; import java.util.Set; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.LayoutManager; import org.eclipse.draw2d.geometry.Point; import org.eclipse.jface.action.IAction; import org.xmind.core.Core; import org.xmind.core.IImage; import org.xmind.core.INumbering; import org.xmind.core.IRelationship; import org.xmind.core.ITopic; import org.xmind.core.event.CoreEvent; import org.xmind.core.event.ICoreEventRegister; import org.xmind.core.event.ICoreEventSource; import org.xmind.core.marker.IMarkerRef; import org.xmind.gef.GEF; import org.xmind.gef.IViewer; import org.xmind.gef.draw2d.IAnchor; import org.xmind.gef.draw2d.IAnchorListener; import org.xmind.gef.draw2d.ITitledFigure; import org.xmind.gef.draw2d.decoration.IConnectionDecoration; import org.xmind.gef.draw2d.decoration.IDecoration; import org.xmind.gef.part.IGraphicalPart; import org.xmind.gef.part.IPart; import org.xmind.gef.part.IRequestHandler; import org.xmind.gef.policy.NullEditPolicy; import org.xmind.gef.ui.actions.ActionRegistry; import org.xmind.gef.ui.actions.IActionRegistry; import org.xmind.ui.internal.IconTipContributorManager; import org.xmind.ui.internal.decorators.TopicDecorator; import org.xmind.ui.internal.figures.TopicFigure; import org.xmind.ui.internal.graphicalpolicies.TopicGraphicalPolicy; import org.xmind.ui.internal.layouts.TopicLayout; import org.xmind.ui.mindmap.IBranchPart; import org.xmind.ui.mindmap.IConnectionPart; import org.xmind.ui.mindmap.IIconTipContributor; import org.xmind.ui.mindmap.IIconTipPart; import org.xmind.ui.mindmap.IImagePart; import org.xmind.ui.mindmap.IMarkerPart; import org.xmind.ui.mindmap.IMindMapViewer; import org.xmind.ui.mindmap.INumberingPart; import org.xmind.ui.mindmap.IRelationshipPart; import org.xmind.ui.mindmap.ISelectionFeedbackHelper; import org.xmind.ui.mindmap.ISheetPart; import org.xmind.ui.mindmap.ITitleTextPart; import org.xmind.ui.mindmap.ITopicPart; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.util.MindMapUtils; /** * * @author MANGOSOFT */ public class TopicPart extends NodePart implements ITopicPart { private ITitleTextPart title = null; private List<IMarkerPart> markers = null; private List<IIconTipPart> iconTips = null; private IImagePart image = null; private INumberingPart numbering = null; private final ChildSorter sorter = new ChildSorter(this); private IActionRegistry actionRegistry = null; private IAnchor anchor = null; private IAnchorListener anchorListener = null; public TopicPart() { setDecorator(TopicDecorator.getInstance()); setGraphicalPolicy(TopicGraphicalPolicy.getInstance()); } public ITopic getTopic() { return (ITopic) getRealModel(); } public IBranchPart getOwnerBranch() { if (getParent() instanceof IBranchPart) return (IBranchPart) getParent(); return null; } public void setParent(IPart parent) { if (getParent() instanceof BranchPart) { BranchPart branch = (BranchPart) getParent(); if (branch.getTopicPart() == this) { branch.setTopicPart(null); } } super.setParent(parent); if (getParent() instanceof BranchPart) { BranchPart branch = (BranchPart) getParent(); branch.setTopicPart(this); } } protected LayoutManager createLayoutManager() { return new TopicLayout(this); } protected void declareEditPolicies(IRequestHandler reqHandler) { super.declareEditPolicies(reqHandler); reqHandler.installEditPolicy(GEF.ROLE_SELECTABLE, NullEditPolicy.getInstance()); reqHandler.installEditPolicy(GEF.ROLE_NAVIGABLE, MindMapUI.POLICY_TOPIC_NAVIGABLE); reqHandler.installEditPolicy(GEF.ROLE_EDITABLE, MindMapUI.POLICY_EDITABLE); reqHandler.installEditPolicy(GEF.ROLE_MODIFIABLE, MindMapUI.POLICY_MODIFIABLE); reqHandler.installEditPolicy(GEF.ROLE_TRAVERSABLE, MindMapUI.POLICY_TOPIC_TRAVERSABLE); reqHandler.installEditPolicy(GEF.ROLE_DROP_TARGET, MindMapUI.POLICY_DROP_TARGET); reqHandler.installEditPolicy(GEF.ROLE_SORTABLE, MindMapUI.POLICY_SORTABLE); if (!isCentral() && !ITopic.SUMMARY.equals(getTopic().getType())) { reqHandler.installEditPolicy(GEF.ROLE_MOVABLE, MindMapUI.POLICY_TOPIC_MOVABLE); } } private boolean isCentral() { IBranchPart branch = getOwnerBranch(); return branch != null && branch.isCentral(); } // protected void uninstallPolicies(IRequestProcessor reqProc) { // if (reqProc.hasRole(GEF.ROLE_MOVABLE)) // reqProc.uninstallPolicy(GEF.ROLE_MOVABLE); // reqProc.uninstallPolicy(GEF.ROLE_MODIFIABLE); // reqProc.uninstallPolicy(GEF.ROLE_EDITABLE); // reqProc.uninstallPolicy(GEF.ROLE_NAVIGABLE); // reqProc.uninstallPolicy(GEF.ROLE_SELECTABLE); // super.uninstallPolicies(reqProc); // } /* * (non-Javadoc) * * @see * org.xmind.gef.part.GraphicalEditPart#containsPoint(org.eclipse.draw2d * .geometry.Point) */ @Override public boolean containsPoint(Point position) { // TODO Auto-generated method stub return super.containsPoint(position); } public ITitleTextPart getTitle() { return title; } public void setTitle(ITitleTextPart title) { this.title = title; } public List<IMarkerPart> getMarkers() { if (markers == null) { markers = new ArrayList<IMarkerPart>(); } return markers; } public void addMarker(IMarkerPart marker) { getMarkers().add(marker); sorter.sort(getMarkers()); } public void removeMarker(IMarkerPart marker) { getMarkers().remove(marker); } public List<IIconTipPart> getIconTips() { if (iconTips == null) { iconTips = new ArrayList<IIconTipPart>(); } return iconTips; } public void addIconTip(IIconTipPart iconTip) { getIconTips().add(iconTip); sorter.sort(getIconTips()); } public void removeIconTip(IIconTipPart iconTip) { getIconTips().remove(iconTip); } public IImagePart getImagePart() { return image; } public void setImagePart(IImagePart image) { this.image = image; } public INumberingPart getNumberingPart() { return numbering; } public void setNumberingPart(INumberingPart numbering) { this.numbering = numbering; } protected IFigure createFigure() { return new TopicFigure(); } protected ISelectionFeedbackHelper createSelectionFeedbackHelper() { return new DefaultSelectionFeedbackHelper(); } protected void register() { registerModel(getTopic()); // System.out.println(getTopic().getTitleText()); super.register(); } protected void unregister() { super.unregister(); unregisterModel(getTopic()); } protected Object[] getModelChildren(Object model) { List<Object> list = new ArrayList<Object>(); ITopic topic = getTopic(); list.add(new ViewerModel(TopicTitleTextPart.class, topic)); if (getNumberingText() != null) { list.add(new ViewerModel(NumberingPart.class, topic)); } addIconTips(topic, list); Set<IMarkerRef> markerRefs = topic.getMarkerRefs(); if (!markerRefs.isEmpty()) { for (IMarkerRef ref : markerRefs) { list.add(new ViewerModel(MarkerPart.class, ref)); } } if (topic.getImage().getSource() != null || ImageDownloadCenter.getInstance().isDownloading(topic)) { list.add(new ViewerModel(ImagePart.class, topic.getImage())); } return list.toArray(); } private void addIconTips(ITopic topic, List<Object> list) { List<IIconTipContributor> contributors = IconTipContributorManager .getInstance().getContributors(); if (contributors.isEmpty()) return; for (IIconTipContributor contributor : contributors) { IAction action = contributor.createAction(this, topic); if (action != null) { list.add(new IconTip(topic, contributor, action)); } } } public IPart findAt(Point position) { IPart ret = super.findAt(position); if (ret != null) { if (ret == title || ret == numbering) { if (containsPoint(position)) { // Prevent title exceeding topic bounds return this; } else { ret = null; } } } return ret; } @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { if (adapter.isAssignableFrom(ITopic.class)) return getTopic(); if (adapter == TitleTextPart.class || adapter == ITitleTextPart.class) return getTitle(); if (adapter == IBranchPart.class) return getOwnerBranch(); if (adapter == IActionRegistry.class) return getActionRegistry(); return super.getAdapter(adapter); } public IActionRegistry getActionRegistry() { if (actionRegistry == null) { actionRegistry = new ActionRegistry(); IViewer viewer = getSite().getViewer(); if (viewer != null) { actionRegistry.setParent((IActionRegistry) viewer .getProperties().get(IMindMapViewer.VIEWER_ACTIONS)); } } return actionRegistry; } protected void registerCoreEvents(ICoreEventSource source, ICoreEventRegister register) { super.registerCoreEvents(source, register); register.register(Core.MarkerRefAdd); register.register(Core.MarkerRefRemove); if (source instanceof ITopic) { ITopic parent = ((ITopic) source).getParent(); if (parent != null) { if (parent instanceof ICoreEventSource) { register.setNextSource((ICoreEventSource) parent); register.register(Core.TopicAdd); register.register(Core.TopicRemove); } INumbering parentNumbering = parent.getNumbering(); if (parentNumbering instanceof ICoreEventSource) { register.setNextSource((ICoreEventSource) parentNumbering); register.register(Core.NumberFormat); register.register(Core.NumberingPrefix); register.register(Core.NumberingSuffix); register.register(Core.NumberPrepending); } } } IImage imageModel = getTopic().getImage(); if (imageModel instanceof ICoreEventSource) { register.setNextSource((ICoreEventSource) imageModel); register.register(Core.ImageSource); } } public void handleCoreEvent(CoreEvent event) { String type = event.getType(); if (Core.MarkerRefAdd.equals(type) || Core.MarkerRefRemove.equals(type)) { refresh(); } else if (Core.ImageSource.equals(type)) { boolean hasNoImage = event.getNewValue() == null; boolean hadNoImage = event.getOldValue() == null; if ((hasNoImage && !hadNoImage) || (hadNoImage && !hasNoImage)) { refresh(); } } else if (Core.TopicAdd.equals(type) || Core.TopicRemove.equals(type)) { if (ITopic.ATTACHED.equals(event.getData())) { treeRefresh(); } } else if (Core.NumberFormat.equals(type) || Core.NumberingPrefix.equals(type) || Core.NumberingSuffix.equals(type) || Core.NumberPrepending.equals(type)) { treeRefresh(); } else { super.handleCoreEvent(event); } } protected void treeRefresh() { refresh(); IBranchPart branch = getOwnerBranch(); if (branch != null) { for (IBranchPart sub : branch.getSubBranches()) { ITopicPart child = sub.getTopicPart(); if (child instanceof TopicPart) { ((TopicPart) child).treeRefresh(); } } } } protected void onActivated() { super.onActivated(); for (IIconTipContributor iconTipCont : IconTipContributorManager .getInstance().getContributors()) { iconTipCont.topicActivated(this); } } protected void onDeactivated() { for (IIconTipContributor iconTipCont : IconTipContributorManager .getInstance().getContributors()) { iconTipCont.topicDeactivated(this); } super.onDeactivated(); } public void refresh() { super.refresh(); for (IIconTipPart iconTip : getIconTips()) { iconTip.refresh(); } } public void update() { super.update(); for (IIconTipPart iconTip : getIconTips()) { iconTip.update(); } } protected void updateChildren() { super.updateChildren(); if (title != null) { title.update(); } if (numbering != null) { numbering.update(); } if (image != null) { image.update(); } } protected void fillSourceConnections(List<IConnectionPart> list) { IViewer viewer = getSite().getViewer(); if (viewer != null) { ISheetPart sheet = (ISheetPart) viewer.getAdapter(ISheetPart.class); if (sheet != null) { String id = getTopic().getId(); for (IRelationshipPart rel : sheet.getRelationships()) { IRelationship r = rel.getRelationship(); if (r != null) { if (id.equals(r.getEnd1Id())) list.add(rel); } } } } } protected void fillTargetConnections(List<IConnectionPart> list) { IViewer viewer = getSite().getViewer(); if (viewer != null) { ISheetPart sheet = (ISheetPart) viewer.getAdapter(ISheetPart.class); if (sheet != null) { String id = getTopic().getId(); for (IRelationshipPart rel : sheet.getRelationships()) { IRelationship r = rel.getRelationship(); if (r != null) { if (id.equals(r.getEnd2Id())) list.add(rel); } } } } } @Override public void setModel(Object model) { super.setModel(model); setAccessible(new TopicAccessible(this)); } @Override protected void addChild(IPart child, int index) { super.addChild(child, index); update(); } @Override protected void removeChild(IPart child) { super.removeChild(child); update(); } protected void reorderChild(IPart child, int index) { super.reorderChild(child, index); if (getMarkers().contains(child)) { sorter.sort(getMarkers()); } else if (getIconTips().contains(child)) { sorter.sort(getIconTips()); } update(); } protected void addChildView(IPart child, int index) { super.addChildView(child, index); if (getFigure() instanceof ITitledFigure) { if (child instanceof ITitleTextPart) { ((ITitledFigure) getFigure()).setTitle(((ITitleTextPart) child) .getTextFigure()); } } } protected void removeChildView(IPart child) { super.removeChildView(child); if (getFigure() instanceof ITitledFigure) { if (child instanceof ITitleTextPart) { ((ITitledFigure) getFigure()).setTitle(null); } } } public IAnchor getSourceAnchor(IGraphicalPart connection) { return getTopicAnchor(); } public IAnchor getTargetAnchor(IGraphicalPart connection) { return getTopicAnchor(); } protected IAnchor getTopicAnchor() { if (anchor == null) { anchor = new DecoratedAnchor(getFigure()); if (anchorListener == null) { anchorListener = new IAnchorListener() { public void anchorMoved(IAnchor anchor) { topicAnchorMoved(); } }; } anchor.addAnchorListener(anchorListener); } return anchor; } private void topicAnchorMoved() { IBranchPart branch = getOwnerBranch(); if (branch != null) { branch.getConnections().rerouteAll(branch.getFigure()); IBranchPart parentBranch = branch.getParentBranch(); if (parentBranch != null) { IDecoration decoration = parentBranch.getConnections() .getDecoration(branch.getBranchIndex()); if (decoration instanceof IConnectionDecoration) { ((IConnectionDecoration) decoration).reroute(parentBranch .getFigure()); } } } } @Override protected IFigure getShadowSource() { return getFigure(); } public String getNumberingText() { return MindMapUtils.getNumberingText(getTopic(), null); } public String getFullNumberingText() { return MindMapUtils.getFullNumberingText(getTopic(), null); } }