0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.modules.uml.ui.products.ad.drawengines;
0043:
0044: import java.awt.Color;
0045: import java.awt.Point;
0046: import java.awt.event.ActionEvent;
0047:
0048: import org.dom4j.Attribute;
0049: import org.dom4j.Element;
0050: import org.dom4j.Node;
0051:
0052: import com.tomsawyer.editor.TSEColor;
0053: import com.tomsawyer.editor.TSEEdge;
0054: import com.tomsawyer.editor.TSENode;
0055: import com.tomsawyer.graph.TSEdge;
0056: import com.tomsawyer.graph.TSNode; //import com.tomsawyer.util.TSConstPoint;
0057: import com.tomsawyer.drawing.geometry.TSConstPoint; //import com.tomsawyer.util.TSConstRect;
0058: import com.tomsawyer.drawing.geometry.TSConstRect; //import com.tomsawyer.util.TSPoint;
0059: import com.tomsawyer.drawing.geometry.TSPoint; //import com.tomsawyer.util.TSRect;
0060: import com.tomsawyer.drawing.geometry.TSRect;
0061:
0062: import org.netbeans.modules.uml.common.generics.ETPairT;
0063: import org.netbeans.modules.uml.common.generics.ETTripleT;
0064: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
0065: import org.netbeans.modules.uml.core.metamodel.core.foundation.IMultiplicity;
0066: import org.netbeans.modules.uml.core.metamodel.core.foundation.IPresentationElement;
0067: import org.netbeans.modules.uml.core.metamodel.core.foundation.UMLXMLManip;
0068: import org.netbeans.modules.uml.core.metamodel.diagrams.IGraphEventKind;
0069: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IAggregation;
0070: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IAssociation;
0071: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IAssociationEnd;
0072: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IClassifier;
0073: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.INavigableEnd;
0074: import org.netbeans.modules.uml.core.metamodel.structure.IAssociationClass;
0075: import org.netbeans.modules.uml.core.support.umlsupport.ETPoint;
0076: import org.netbeans.modules.uml.core.support.umlsupport.IETRect;
0077: import org.netbeans.modules.uml.core.support.umlsupport.XMLManip;
0078: import org.netbeans.modules.uml.core.support.umlutils.ETList;
0079: import org.netbeans.modules.uml.ui.products.ad.application.IMenuManager;
0080: import org.netbeans.modules.uml.ui.products.ad.application.action.ContextMenuActionClass;
0081: import org.netbeans.modules.uml.ui.products.ad.drawEngineManagers.IAssociationClassEventManager;
0082: import org.netbeans.modules.uml.ui.products.ad.drawEngineManagers.IBridgeElements;
0083: import org.netbeans.modules.uml.ui.support.NodeEndKindEnum;
0084: import org.netbeans.modules.uml.ui.support.applicationmanager.IAssociationEdgePresentation;
0085: import org.netbeans.modules.uml.ui.support.applicationmanager.IEdgePresentation;
0086: import org.netbeans.modules.uml.ui.support.applicationmanager.ILabelPresentation;
0087: import org.netbeans.modules.uml.ui.support.applicationmanager.IProductGraphPresentation;
0088: import org.netbeans.modules.uml.ui.support.viewfactorysupport.DrawEngineArrowheadKindEnum;
0089: import org.netbeans.modules.uml.ui.support.viewfactorysupport.DrawEngineLineKindEnum;
0090: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IDrawEngine;
0091: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IDrawInfo;
0092: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IETGraphObject;
0093: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IEventManager;
0094: import org.netbeans.modules.uml.ui.support.viewfactorysupport.ILabelManager;
0095: import org.netbeans.modules.uml.ui.support.viewfactorysupport.ISupportEnums;
0096: import org.netbeans.modules.uml.ui.support.viewfactorysupport.ITSGraphObject;
0097: import org.netbeans.modules.uml.ui.support.viewfactorysupport.PointConversions;
0098: import org.netbeans.modules.uml.ui.support.viewfactorysupport.TSLabelKind;
0099: import org.netbeans.modules.uml.ui.support.viewfactorysupport.TypeConversions;
0100: import org.netbeans.modules.uml.ui.swing.drawingarea.IDrawingAreaControl;
0101:
0102: /*
0103: * @author KevinM
0104: *
0105: */
0106: public class ETAssociationEdgeDrawEngine extends ETEdgeDrawEngine {
0107: protected IAssociationEnd m_StartEnd = null;
0108: protected IAssociationEnd m_FinishEnd = null;
0109: protected int m_ContextMenuLocation = CMPK_MIDDLE;
0110:
0111: public static int CMPK_START = 0;
0112: public static int CMPK_END = 1;
0113: public static int CMPK_MIDDLE = 2;
0114:
0115: public ETAssociationEdgeDrawEngine() {
0116: super ();
0117: }
0118:
0119: public String getElementType() {
0120: String type = super .getElementType();
0121: if (type == null) {
0122: type = new String("Association");
0123: }
0124: return type;
0125: }
0126:
0127: protected int getStartArrowKind() {
0128: return DrawEngineArrowheadKindEnum.DEAK_NO_ARROWHEAD;
0129: }
0130:
0131: protected int getEndArrowKind() {
0132: return DrawEngineArrowheadKindEnum.DEAK_NO_ARROWHEAD;
0133: }
0134:
0135: public void doDraw(IDrawInfo drawInfo) {
0136: try {
0137: boolean bDidDraw = false;
0138: TSEColor edgeColor = this .getStateColor(); // getColor(getResourceID(CK_BORDERCOLOR));
0139:
0140: // At extreeme zoom levels we don't want to hit the metadata, so just
0141: // draw a line. SimpleDrawEdge looks at the zoom and draws just an edge
0142: // if the user can't see an arrowhead anyway.
0143: if (simpleDrawEdge(drawInfo, getLineKind()) == false) {
0144: IElement pModelElement = null;
0145: IEdgePresentation pPE = getIEdgePresentation();
0146:
0147: if (pPE != null) {
0148: pModelElement = pPE.getFirstSubject();
0149: }
0150:
0151: if (pModelElement == null)
0152: pModelElement = getUI().getModelElement();
0153:
0154: if (pModelElement != null) {
0155: String sElementType = pModelElement
0156: .getElementType();
0157:
0158: IAggregation pAggregation = getIAggregation(pModelElement);
0159:
0160: if (pAggregation != null) {
0161: bDidDraw = drawAggregation(drawInfo, pPE,
0162: pAggregation, edgeColor);
0163: } else if (sElementType.equals("Association")) {
0164: IAssociation pAssociation = getIAssociation(pModelElement);
0165:
0166: if (pAssociation != null) {
0167: bDidDraw = drawAssociation(drawInfo, pPE,
0168: pAssociation, edgeColor);
0169: }
0170: } else if (sElementType.equals("AssociationClass")) {
0171: IAssociationClass pAssociationClass = getIAssociationClass(pModelElement);
0172: if (pAssociationClass != null) {
0173: bDidDraw = drawAssociationClass(drawInfo,
0174: pPE, pAssociationClass, edgeColor);
0175: }
0176: }
0177: }
0178: } else
0179: bDidDraw = true;
0180:
0181: if (bDidDraw == false) {
0182: // Some error happened, draw a line
0183: super .doDraw(drawInfo);
0184: }
0185: } catch (Exception e) {
0186: e.printStackTrace();
0187: // ( err );
0188: }
0189: }
0190:
0191: /*
0192: * Draw aggregation edges
0193: */
0194: protected boolean drawAggregation(IDrawInfo drawInfo,
0195: IEdgePresentation pPE, IAggregation pAggregation,
0196: TSEColor edgeColor) {
0197: boolean bDidDraw = false;
0198: try {
0199: if (drawInfo == null || pAggregation == null)
0200: return false;
0201:
0202: IAssociationEnd pAggregateEnd = pAggregation
0203: .getAggregateEnd();
0204: IAssociationEnd pPartEnd = pAggregation.getPartEnd();
0205: boolean bIsComposite = pAggregation.getIsComposite();
0206:
0207: if (pAggregateEnd != null && pPartEnd != null) {
0208: // See if the aggregation end is a diamond filled or unfilled
0209: int nEndKind = pPE.getNodeEnd2(pAggregateEnd);
0210:
0211: // Now we can figure out how to draw.
0212: int startArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_NO_ARROWHEAD;
0213: int endArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_NO_ARROWHEAD;
0214:
0215: boolean bIsNavigable = false;
0216: if (nEndKind == NodeEndKindEnum.NEK_FROM
0217: || nEndKind == NodeEndKindEnum.NEK_BOTH) {
0218: setEnds(pAggregateEnd, pPartEnd);
0219:
0220: bIsNavigable = m_StartEnd.getIsNavigable();
0221:
0222: if (bIsNavigable) {
0223: startArrowheadKind = (bIsComposite) ? DrawEngineArrowheadKindEnum.DEAK_FILLEDDIAMOND_NAVIGABLE
0224: : DrawEngineArrowheadKindEnum.DEAK_UNFILLEDDIAMOND_NAVIGABLE;
0225: } else {
0226: startArrowheadKind = (bIsComposite) ? DrawEngineArrowheadKindEnum.DEAK_FILLEDDIAMOND
0227: : DrawEngineArrowheadKindEnum.DEAK_UNFILLEDDIAMOND;
0228: }
0229:
0230: // Now how do we draw the other side?
0231: INavigableEnd pNavEnd = getINavigableEnd(pPartEnd);
0232: if (pNavEnd != null) {
0233: endArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_UNFILLEDARROW;
0234: }
0235: } else if (nEndKind == NodeEndKindEnum.NEK_TO) {
0236: setEnds(pPartEnd, pAggregateEnd);
0237:
0238: bIsNavigable = m_FinishEnd.getIsNavigable();
0239:
0240: if (bIsNavigable) {
0241: endArrowheadKind = (bIsComposite) ? DrawEngineArrowheadKindEnum.DEAK_FILLEDDIAMOND_NAVIGABLE
0242: : DrawEngineArrowheadKindEnum.DEAK_UNFILLEDDIAMOND_NAVIGABLE;
0243: } else {
0244: endArrowheadKind = (bIsComposite) ? DrawEngineArrowheadKindEnum.DEAK_FILLEDDIAMOND
0245: : DrawEngineArrowheadKindEnum.DEAK_UNFILLEDDIAMOND;
0246: }
0247:
0248: // Now how do we draw the other side?
0249: INavigableEnd pNavEnd = getINavigableEnd(pPartEnd);
0250: if (pNavEnd != null) {
0251: startArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_UNFILLEDARROW;
0252: }
0253: }
0254:
0255: this .drawEdge(drawInfo, startArrowheadKind,
0256: endArrowheadKind, getLineKind());
0257: bDidDraw = true;
0258: }
0259: } catch (Exception e) {
0260: e.printStackTrace();
0261: bDidDraw = false;
0262: }
0263:
0264: return bDidDraw;
0265: }
0266:
0267: /*
0268: * Draw Association
0269: */
0270: protected boolean drawAssociation(IDrawInfo drawInfo,
0271: IEdgePresentation pPE, IAssociation pAssociation,
0272: TSEColor edgeColor) {
0273: boolean bDidDraw = false;
0274:
0275: try {
0276: if (drawInfo != null && pAssociation != null) {
0277: ETList<IAssociationEnd> pAssociationEnds = pAssociation
0278: .getEnds();
0279: int numEnds = pAssociationEnds.size();
0280:
0281: if (numEnds == 2) {
0282: IAssociationEnd pFirstEnd = pAssociationEnds.get(0);
0283: IAssociationEnd pSecondEnd = pAssociationEnds
0284: .get(1);
0285:
0286: // See if either end is navigable (shown with an arrowhead)
0287: INavigableEnd pNavFirstEnd = getINavigableEnd(pFirstEnd);
0288: INavigableEnd pNavSecondEnd = getINavigableEnd(pSecondEnd);
0289:
0290: if (pFirstEnd != null && pSecondEnd != null) {
0291: // See if the aggregation end is a diamond filled or unfilled
0292: int nEndKind = NodeEndKindEnum.NEK_UNKNOWN;
0293:
0294: nEndKind = pPE.getNodeEnd(pFirstEnd);
0295:
0296: int startArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_NO_ARROWHEAD;
0297: int endArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_NO_ARROWHEAD;
0298: if (nEndKind == NodeEndKindEnum.NEK_FROM
0299: || nEndKind == NodeEndKindEnum.NEK_BOTH) {
0300: setEnds(pFirstEnd, pSecondEnd);
0301:
0302: if (pNavFirstEnd != null) {
0303: startArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_UNFILLEDARROW;
0304: }
0305:
0306: if (pNavSecondEnd != null) {
0307: endArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_UNFILLEDARROW;
0308: }
0309: } else if (nEndKind == NodeEndKindEnum.NEK_TO) {
0310: setEnds(pSecondEnd, pFirstEnd);
0311:
0312: if (pNavFirstEnd != null) {
0313: endArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_UNFILLEDARROW;
0314: }
0315:
0316: if (pNavSecondEnd != null) {
0317: startArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_UNFILLEDARROW;
0318: }
0319: }
0320:
0321: bDidDraw = drawEdge(drawInfo,
0322: startArrowheadKind, endArrowheadKind,
0323: getLineKind());
0324: }
0325: }
0326: }
0327: } catch (Exception e) {
0328: e.printStackTrace();
0329: }
0330: return bDidDraw;
0331: }
0332:
0333: /*
0334: * Draws the association class.
0335: */
0336: protected boolean drawAssociationClass(IDrawInfo drawInfo,
0337: IEdgePresentation pPE, IAssociationClass pAssociationClass,
0338: TSEColor edgeColor) {
0339: boolean bDidDraw = false;
0340:
0341: boolean hr = true;
0342: try {
0343: ETTripleT<IAssociationEnd, IAssociationEnd, Integer> result = getAssociationEnd();
0344: IAssociationEnd pThisEnd = result.getParamOne();
0345: IAssociationEnd pOtherEnd = result.getParamTwo();
0346: int nOurIndex = result.getParamThree() != null ? result
0347: .getParamThree().intValue() : 0;
0348:
0349: // We are either the dashed line or the one of the solid lines associated
0350: // with the source or target association end.
0351: if (pThisEnd != null) {
0352: // We are one of the end segments. Treat as if we're near the end of a normal association
0353: // link.
0354: if (nOurIndex == 0) {
0355: setEnds(pThisEnd, pOtherEnd);
0356: } else if (nOurIndex == 1) {
0357: setEnds(pOtherEnd, pThisEnd);
0358: }
0359:
0360: bDidDraw = drawAssociationEnd(drawInfo, pPE,
0361: pAssociationClass, pThisEnd, edgeColor);
0362: } else if (pThisEnd == null || pOtherEnd == null) {
0363: IDrawEngine pFromDrawEngine = pPE != null ? pPE
0364: .getEdgeFromDrawEngine() : null;
0365: IDrawEngine pToDrawEngine = pPE != null ? pPE
0366: .getEdgeToDrawEngine() : null;
0367:
0368: if (pFromDrawEngine == null || pToDrawEngine == null) {
0369: // We are reconnecting, just draw a solid line
0370: drawEdge(
0371: drawInfo,
0372: DrawEngineArrowheadKindEnum.DEAK_NO_ARROWHEAD,
0373: DrawEngineArrowheadKindEnum.DEAK_NO_ARROWHEAD,
0374: this .getLineKind());
0375: bDidDraw = true;
0376: } else {
0377: drawEdge(
0378: drawInfo,
0379: DrawEngineArrowheadKindEnum.DEAK_NO_ARROWHEAD,
0380: DrawEngineArrowheadKindEnum.DEAK_NO_ARROWHEAD,
0381: DrawEngineLineKindEnum.DELK_DASH);
0382: bDidDraw = true;
0383: }
0384: }
0385: } catch (Exception e) {
0386: e.printStackTrace();
0387: }
0388: return bDidDraw;
0389: }
0390:
0391: /**
0392: * Draws an associationend
0393: */
0394: protected boolean drawAssociationEnd(IDrawInfo info,
0395: IEdgePresentation pPE, IAssociationClass pAssociationClass,
0396: IAssociationEnd pAssociationEnd, TSEColor edgeColor) {
0397: boolean bDidDraw = false;
0398:
0399: try {
0400: if (pAssociationEnd != null && pPE != null
0401: && pAssociationClass != null) {
0402: //
0403: // AssociationClasses in the Pre UML 2.0 spec don't support aggregations because
0404: // they are derived off of IAssociation so they don't support IAggregation. So in
0405: // Describe 6.5 and the release of the UML 2.0 spec we will fix this - IAggregation and
0406: // the end types disappear so they've changed stuff.
0407: //
0408: // For sp1 we go to the xml directly to get the aggregation properties. We'll fix this
0409: // after IAssociation is changed to match the UML 2.0 release.
0410: //
0411: boolean bHasIsComposite = false;
0412: boolean bIsComposite = false;
0413: boolean bThisIsAggregateEnd = false;
0414: String sAggregateEnd = "";
0415: String sPartEnd = "";
0416:
0417: getAssociationClassAggregationHack(pAssociationClass,
0418: pAssociationEnd, bHasIsComposite, bIsComposite,
0419: bThisIsAggregateEnd, sAggregateEnd, sPartEnd);
0420:
0421: // See if either end is navigable (shown with an arrowhead)
0422: INavigableEnd pNavEnd = pAssociationEnd instanceof INavigableEnd ? (INavigableEnd) pAssociationEnd
0423: : null;
0424:
0425: String sDrawEngineID = null;
0426: int startArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_NO_ARROWHEAD;
0427: int endArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_NO_ARROWHEAD;
0428:
0429: IDrawEngine pFromNode = pPE
0430: .getEdgeFromDrawEngineWithID("AssociationClassConnectorDrawEngine");
0431: IDrawEngine pToNode = pPE
0432: .getEdgeToDrawEngineWithID("AssociationClassConnectorDrawEngine");
0433:
0434: if (bHasIsComposite) {
0435: // Setup the start arrowhead
0436: if (bThisIsAggregateEnd) {
0437: if (pFromNode != null && pNavEnd != null) {
0438: endArrowheadKind = (bIsComposite) ? DrawEngineArrowheadKindEnum.DEAK_FILLEDDIAMOND_NAVIGABLE
0439: : DrawEngineArrowheadKindEnum.DEAK_UNFILLEDDIAMOND_NAVIGABLE;
0440: } else if (pFromNode != null
0441: && bThisIsAggregateEnd) {
0442: endArrowheadKind = (bIsComposite) ? DrawEngineArrowheadKindEnum.DEAK_FILLEDDIAMOND
0443: : DrawEngineArrowheadKindEnum.DEAK_UNFILLEDDIAMOND;
0444: }
0445: } else {
0446: if (pFromNode != null && pNavEnd != null) {
0447: endArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_UNFILLEDARROW;
0448: }
0449: }
0450:
0451: // Setup the finish arrowhead
0452: if (bThisIsAggregateEnd) {
0453: if (pToNode != null && pNavEnd != null) {
0454: startArrowheadKind = (bIsComposite) ? DrawEngineArrowheadKindEnum.DEAK_FILLEDDIAMOND_NAVIGABLE
0455: : DrawEngineArrowheadKindEnum.DEAK_UNFILLEDDIAMOND_NAVIGABLE;
0456: } else if (pToNode != null
0457: && bThisIsAggregateEnd) {
0458: startArrowheadKind = (bIsComposite) ? DrawEngineArrowheadKindEnum.DEAK_FILLEDDIAMOND
0459: : DrawEngineArrowheadKindEnum.DEAK_UNFILLEDDIAMOND;
0460: }
0461: } else {
0462: if (pToNode != null && pNavEnd != null) {
0463: startArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_UNFILLEDARROW;
0464: }
0465: }
0466: } else {
0467: if (pFromNode != null && pNavEnd != null) {
0468: endArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_UNFILLEDARROW;
0469: }
0470: if (pToNode != null && pNavEnd != null) {
0471: startArrowheadKind = DrawEngineArrowheadKindEnum.DEAK_UNFILLEDARROW;
0472: }
0473: }
0474:
0475: drawEdge(info, startArrowheadKind, endArrowheadKind,
0476: this .getLineKind());
0477: bDidDraw = true;
0478: }
0479: } catch (Exception e) {
0480: e.printStackTrace();
0481: }
0482: return bDidDraw;
0483: }
0484:
0485: //
0486: // Interface Crackers.
0487: //
0488:
0489: protected IAggregation getIAggregation(IElement pModelElement) {
0490: if (pModelElement instanceof IAggregation) {
0491: return (IAggregation) pModelElement;
0492: }
0493: return null;
0494: }
0495:
0496: protected IAssociation getIAssociation(IElement pModelElement) {
0497: if (pModelElement instanceof IAssociation) {
0498: return (IAssociation) pModelElement;
0499: }
0500: return null;
0501: }
0502:
0503: protected IAssociationClass getIAssociationClass(
0504: IElement pModelElement) {
0505: if (pModelElement instanceof IAssociationClass) {
0506: return (IAssociationClass) pModelElement;
0507: }
0508: return null;
0509: }
0510:
0511: protected INavigableEnd getINavigableEnd(IAssociationEnd pEnd) {
0512: if (pEnd instanceof INavigableEnd) {
0513: return (INavigableEnd) pEnd;
0514: }
0515: return null;
0516: }
0517:
0518: protected void setEnds(IAssociationEnd pStartEnd,
0519: IAssociationEnd pFinishEnd) {
0520: m_StartEnd = pStartEnd;
0521: m_FinishEnd = pFinishEnd;
0522: }
0523:
0524: protected void setEnd(boolean bStart, IAssociationEnd pEnd) {
0525: if (bStart) {
0526: m_StartEnd = pEnd;
0527: } else {
0528: m_FinishEnd = pEnd;
0529: }
0530: }
0531:
0532: public String getPresentationType() {
0533: IElement element = getUI().getModelElement();
0534: if (element == null)
0535: return null;
0536: if (getIAssociation(element) != null
0537: || getIAssociationClass(element) != null) {
0538: return new String("AssociationEdgePresentation");
0539: }
0540: return new String("AggregationEdgePresentation");
0541: }
0542:
0543: public void onContextMenu(IMenuManager manager) {
0544: m_ContextMenuLocation = CMPK_MIDDLE;
0545: // See what side of the edge we're on
0546: TSEEdge pTSEdge = getEdge();
0547: IElement modEle = getFirstModelElement();
0548: IAssociation pAssociation = null;
0549: IAssociationClass pAssociationClass = null;
0550: IAggregation pAggregation = null;
0551: //Point pt = manager.getLocation();
0552:
0553: if (modEle != null) {
0554: if (modEle instanceof IAssociation) {
0555: pAssociation = (IAssociation) modEle;
0556: }
0557: if (modEle instanceof IAssociationClass) {
0558: pAssociationClass = (IAssociationClass) modEle;
0559: }
0560: if (modEle instanceof IAggregation) {
0561: pAggregation = (IAggregation) modEle;
0562: }
0563: }
0564:
0565: if (pAssociationClass != null) {
0566: ETTripleT<IAssociationEnd, IAssociationEnd, Integer> result = getAssociationEnd();
0567: IAssociationEnd pThisEnd = result.getParamOne();
0568: IAssociationEnd pOtherEnd = result.getParamTwo();
0569: int nOurIndex = result.getParamThree() != null ? result
0570: .getParamThree().intValue() : 0;
0571:
0572: if (pThisEnd != null) {
0573: // We are one of the end segments. Treat as if we're near the end of a normal association
0574: // link.
0575: if (nOurIndex == 0) {
0576: m_ContextMenuLocation = CMPK_START;
0577: setEnds(pThisEnd, pOtherEnd);
0578: } else if (nOurIndex == 1) {
0579: m_ContextMenuLocation = CMPK_END;
0580: setEnds(pThisEnd, pOtherEnd);
0581: }
0582: } else {
0583: // We are the dashed line. Treat as if we're in the center of an association link
0584: m_ContextMenuLocation = CMPK_MIDDLE;
0585: setEnds(null, null);
0586: m_StartEnd = pAssociation.getEndAtIndex(0);
0587: m_FinishEnd = pAssociation.getEndAtIndex(1);
0588: }
0589: } else {
0590: if (pTSEdge != null) {
0591: TSConstRect rect = pTSEdge.getBounds(); // getBoundingRect();
0592: TSRect scaledBoundingRect = new TSRect(rect);
0593:
0594: scaledBoundingRect.setHeight(rect.getHeight() / 4);
0595: scaledBoundingRect.setWidth(rect.getWidth() / 4);
0596:
0597: // Get the current point
0598: Point devicePt = manager.getLocation();
0599: // Use the logical space.
0600: TSPoint pt = PointConversions.newTSPoint(
0601: getDrawingArea(), new ETPoint(devicePt));
0602: boolean bWeAreNearMiddle = true;
0603:
0604: // (LLS) Adding the buildContext logic to support A11Y issues. The
0605: // user should be able to use the CTRL-F10 keystroke to activate
0606: // the context menu. In the case of the keystroke the location
0607: // will not be valid. Therefore, we have to just check if the
0608: // compartment is selected.
0609: if (pt != null) {
0610: bWeAreNearMiddle = isPointNearTheMiddle(pt,
0611: scaledBoundingRect);
0612: }
0613:
0614: if (bWeAreNearMiddle == false) {
0615: determineTheClosestEnd(pt, pTSEdge);
0616: }
0617: }
0618: }
0619:
0620: // Add the label menu items
0621: addAssociationAndAggregationEdgeMenuItems(manager, modEle);
0622: if (m_ContextMenuLocation == CMPK_MIDDLE) {
0623: addAssociationMultiLabelSelectionsPullright(manager, true);
0624: } else {
0625: addAssociationEndLabelsPullright(manager);
0626: if (pAssociationClass == null) {
0627: // Don't allow assciationclasses to add qualifiers
0628: addQualifiersButton(manager);
0629: }
0630: addAssociationMultiLabelSelectionsPullright(manager, false);
0631: addAssociationEndSetMultiplicityMenuItems(manager);
0632: }
0633:
0634: // Add the stereotype label pullright
0635: addStandardLabelsToPullright(StandardLabelKind.SLK_STEREOTYPE,
0636: manager);
0637:
0638: // Call the base class
0639: super .onContextMenu(manager);
0640: }
0641:
0642: private void determineTheClosestEnd(final TSPoint pt,
0643: final TSEEdge pTSEdge) {
0644: // We're on the border of the edge. Find what side.
0645: TSConstPoint fromPoint = pTSEdge.getSourcePoint();
0646: TSConstPoint toPoint = pTSEdge.getTargetPoint();
0647:
0648: if (fromPoint != null && toPoint != null) {
0649: TSENode pNodeClosestToPoint = null;
0650:
0651: double fromPointDistance = fromPoint.distanceSquared(pt);
0652: double toPointDistance = toPoint.distanceSquared(pt);
0653:
0654: if (fromPointDistance < toPointDistance) {
0655: m_ContextMenuLocation = CMPK_START;
0656: pNodeClosestToPoint = (TSENode) pTSEdge.getSourceNode();
0657: } else {
0658: m_ContextMenuLocation = CMPK_END;
0659: pNodeClosestToPoint = (TSENode) pTSEdge.getTargetNode();
0660: }
0661:
0662: if (pNodeClosestToPoint != null
0663: && (pTSEdge.getSourceNode() != pTSEdge
0664: .getTargetNode())) {
0665:
0666: IElement pElementNearPoint = TypeConversions
0667: .getElement((TSNode) pNodeClosestToPoint);
0668:
0669: if (pElementNearPoint != null) {
0670: IClassifier pClassifierNearPoint = pElementNearPoint instanceof IClassifier ? (IClassifier) pElementNearPoint
0671: : null;
0672: if (pClassifierNearPoint != null) {
0673: m_ContextMenuLocation = CMPK_END;
0674: if (m_StartEnd != null) {
0675: boolean bIsSame = m_StartEnd
0676: .isSameParticipant(pClassifierNearPoint);
0677:
0678: if (bIsSame) {
0679: m_ContextMenuLocation = CMPK_START;
0680: }
0681: }
0682: }
0683: }
0684: }
0685: }
0686: }
0687:
0688: protected boolean isPointNearTheMiddle(final TSPoint pt,
0689: final TSRect scaledBoundingRect) {
0690:
0691: // We scale the bounding rect by 1/2. If the point is inside the scaled rect
0692: // then we consider that we're too close to the middle to determine the edge so
0693: // we keep the flag indicating we're in the middle
0694: double nWidth = scaledBoundingRect.getWidth();
0695: double nHeight = scaledBoundingRect.getHeight();
0696:
0697: // Use the width and height to determine if we've got a close-to horizontal or
0698: // close to vertical edge
0699: boolean bWeAreNearMiddle = true;
0700: if (nWidth < 3) {
0701: if (!(scaledBoundingRect.getTop() >= pt.getY() && scaledBoundingRect
0702: .getBottom() <= pt.getY())) {
0703: bWeAreNearMiddle = false;
0704: }
0705: } else if (nHeight < 3) {
0706: if (!(scaledBoundingRect.getLeft() <= pt.getX() && scaledBoundingRect
0707: .getRight() >= pt.getX())) {
0708: bWeAreNearMiddle = false;
0709: }
0710: } else if (scaledBoundingRect.contains(pt) == false) {
0711: bWeAreNearMiddle = false;
0712: }
0713: return bWeAreNearMiddle;
0714: }
0715:
0716: /**
0717: * Returns the IAssociationEnd we represent (used for AssociationClasses)
0718: */
0719: private ETTripleT<IAssociationEnd, IAssociationEnd, Integer> getAssociationEnd() {
0720: IAssociationEnd pThisEnd = null;
0721: IAssociationEnd pOtherEnd = null;
0722: int nOurIndex = 0;
0723:
0724: // We are either the dashed line or the one of the solid lines associated
0725: // with the source or target association end.
0726: IEdgePresentation pPE = getIEdgePresentation();
0727: if (pPE != null) {
0728: IDrawEngine fromDrawEngine = null;
0729: IDrawEngine toDrawEngine = null;
0730: IElement fromEle = null;
0731: IElement toEle = null;
0732: IElement pThisEle = TypeConversions.getElement(this );
0733:
0734: ETPairT<IDrawEngine, IDrawEngine> result = pPE
0735: .getEdgeFromAndToDrawEngines();
0736: if (result != null) {
0737: fromDrawEngine = result.getParamOne();
0738: toDrawEngine = result.getParamTwo();
0739: }
0740:
0741: fromEle = TypeConversions.getElement(fromDrawEngine);
0742: toEle = TypeConversions.getElement(toDrawEngine);
0743:
0744: if (fromEle != null && toEle != null
0745: && pThisEle instanceof IAssociation) {
0746: IAssociation pAssocClassAsAssoc = (IAssociation) pThisEle;
0747:
0748: boolean isSame = pAssocClassAsAssoc.isSame(fromEle);
0749: IElement pParticipandDrawEngineEle = null;
0750: if (!isSame) {
0751: pParticipandDrawEngineEle = fromEle;
0752: } else {
0753: isSame = pAssocClassAsAssoc.isSame(toEle);
0754: if (!isSame) {
0755: pParticipandDrawEngineEle = toEle;
0756: }
0757: }
0758:
0759: if (pParticipandDrawEngineEle != null) {
0760: // The from draw engine is pointing to a different element. Get the association
0761: // end and draw
0762: boolean isReflexive = pAssocClassAsAssoc
0763: .getIsReflexive();
0764: if (isReflexive) {
0765: // This is complicated. We need to figure out what side of the
0766: // reflexive link we represent. We use the event manager and have it tell us
0767: IEventManager pEventManager = getEventManager();
0768: IAssociationClassEventManager pAssocEventManager = pEventManager instanceof IAssociationClassEventManager ? (IAssociationClassEventManager) pEventManager
0769: : null;
0770: if (pAssocEventManager != null) {
0771: IBridgeElements bridgeElements = pAssocEventManager
0772: .getBridgeElements();
0773: IETGraphObject pSourceEdge = bridgeElements
0774: .getSourceEdge();
0775: IETGraphObject pSmallNode = bridgeElements
0776: .getSmallNode();
0777: IETGraphObject pTargetEdge = bridgeElements
0778: .getTargetEdge();
0779: IETGraphObject pDottedEdge = bridgeElements
0780: .getDottedEdge();
0781: IETGraphObject pSourceNode = bridgeElements
0782: .getSourceNode();
0783: IETGraphObject pTargetNode = bridgeElements
0784: .getTargetNode();
0785: IDrawEngine pSourceEdgeDrawEngine = TypeConversions
0786: .getDrawEngine(pSourceEdge);
0787:
0788: if (pSourceEdgeDrawEngine != null) {
0789: if (pSourceEdgeDrawEngine == this ) {
0790: // We are end #0
0791: pThisEnd = pAssocClassAsAssoc
0792: .getEndAtIndex(0);
0793: nOurIndex = 0;
0794: pOtherEnd = pAssocClassAsAssoc
0795: .getEndAtIndex(1);
0796: }
0797: }
0798:
0799: if (pThisEnd == null) {
0800: // We are end #1
0801: pThisEnd = pAssocClassAsAssoc
0802: .getEndAtIndex(1);
0803: nOurIndex = 1;
0804: pOtherEnd = pAssocClassAsAssoc
0805: .getEndAtIndex(0);
0806: }
0807: }
0808: } else {
0809: pThisEnd = pAssocClassAsAssoc
0810: .getFirstEndWithParticipant(pParticipandDrawEngineEle);
0811: if (pThisEnd != null) {
0812: nOurIndex = pAssocClassAsAssoc
0813: .getEndIndex(pThisEnd);
0814: if (nOurIndex == 0) {
0815: pOtherEnd = pAssocClassAsAssoc
0816: .getEndAtIndex(1);
0817: } else {
0818: pOtherEnd = pAssocClassAsAssoc
0819: .getEndAtIndex(0);
0820: }
0821: }
0822: }
0823: }
0824: }
0825: }
0826: return new ETTripleT<IAssociationEnd, IAssociationEnd, Integer>(
0827: pThisEnd, pOtherEnd, new Integer(nOurIndex));
0828: }
0829:
0830: /*
0831: * (non-Javadoc)
0832: * @see org.netbeans.modules.uml.ui.products.ad.application.action.IETContextMenuHandler#setSensitivityAndCheck(java.lang.String, org.netbeans.modules.uml.ui.products.ad.application.action.ContextMenuActionClass)
0833: */
0834: public boolean setSensitivityAndCheck(String id,
0835: ContextMenuActionClass actionClass) {
0836: boolean retVal = handleStandardLabelSensitivityAndCheck(id,
0837: actionClass);
0838:
0839: if (!retVal) {
0840: boolean isReadOnly = isParentDiagramReadOnly();
0841: boolean bFlag = false;
0842: ILabelManager labelMgr = getLabelManager();
0843: ITSGraphObject pETElement = getParentETElement();
0844: IElement pElement = null;
0845: if (pETElement != null) {
0846: pElement = TypeConversions
0847: .getElement((IETGraphObject) pETElement);
0848: }
0849: IAssociation pAssociation = null;
0850: IAssociationClass pAssociationClass = null;
0851: IAggregation pAggregation = null;
0852: if (pElement instanceof IAssociation) {
0853: pAssociation = (IAssociation) pElement;
0854: }
0855: if (pElement instanceof IAssociationClass) {
0856: pAssociationClass = (IAssociationClass) pElement;
0857: }
0858: if (pElement instanceof IAggregation) {
0859: pAggregation = (IAggregation) pElement;
0860: }
0861:
0862: // Get the nearest end
0863: IAssociationEnd pNearestEnd = null;
0864: if (m_ContextMenuLocation == CMPK_START) {
0865: pNearestEnd = m_StartEnd;
0866: } else if (m_ContextMenuLocation == CMPK_END) {
0867: pNearestEnd = m_FinishEnd;
0868: }
0869:
0870: // Get the index of the nearest end
0871: int index = 0;
0872: if (pNearestEnd != null && pAssociation != null) {
0873: index = pAssociation.getEndIndex(pNearestEnd);
0874: }
0875:
0876: //set the check state
0877: if (id.equals("MBK_LINK_END_ORDINARY_AGGREGATE")
0878: || id.equals("MBK_LINK_END_COMPOSITE_AGGREGATE")) {
0879: if (pAggregation != null && pNearestEnd != null) {
0880: boolean isAggEnd = pAggregation
0881: .isAggregateEnd(pNearestEnd);
0882: if (isAggEnd) {
0883: boolean isComposite = pAggregation
0884: .getIsComposite();
0885: if (id
0886: .equals("MBK_LINK_END_ORDINARY_AGGREGATE")) {
0887: if (!isComposite) {
0888: actionClass.setChecked(true);
0889: } else {
0890: bFlag = isReadOnly ? false : true;
0891: }
0892: } else if (id
0893: .equals("MBK_LINK_END_COMPOSITE_AGGREGATE")) {
0894: if (isComposite) {
0895: actionClass.setChecked(true);
0896: } else {
0897: bFlag = isReadOnly ? false : true;
0898: }
0899: }
0900: }
0901: } else if (pAssociationClass != null
0902: && pNearestEnd != null) {
0903: boolean hasIsComposite = false;
0904: boolean isComposite = false;
0905: boolean this IsAggEnd = false;
0906: String aggEnd = "";
0907: String partEnd = "";
0908:
0909: // Get the Aggregation stuff for the AssociationClass which is fixed in UML 2.0, but not SP1
0910: getAssociationClassAggregationHack(
0911: pAssociationClass, pNearestEnd,
0912: hasIsComposite, isComposite, this IsAggEnd,
0913: aggEnd, partEnd);
0914: if (this IsAggEnd && hasIsComposite) {
0915: if (id
0916: .equals("MBK_LINK_END_ORDINARY_AGGREGATE")) {
0917: if (!isComposite) {
0918: actionClass.setChecked(true);
0919: } else {
0920: bFlag = isReadOnly ? false : true;
0921: }
0922: } else if (id
0923: .equals("MBK_LINK_END_COMPOSITE_AGGREGATE")) {
0924: if (isComposite) {
0925: actionClass.setChecked(true);
0926: } else {
0927: bFlag = isReadOnly ? false : true;
0928: }
0929: }
0930: } else {
0931: bFlag = isReadOnly ? false : true;
0932: }
0933: } else if (pAggregation == null && pNearestEnd != null) {
0934: bFlag = isReadOnly ? false : true;
0935: }
0936: } else if (id.equals("MBK_LINK_END_NAVIGABLE")) {
0937: if (pNearestEnd != null
0938: && pNearestEnd instanceof INavigableEnd) {
0939: actionClass.setChecked(true);
0940: }
0941:
0942: // Valid if we're on an end.
0943: if (m_ContextMenuLocation == CMPK_START
0944: || m_ContextMenuLocation == CMPK_END) {
0945: bFlag = isReadOnly ? false : true;
0946: }
0947: } else if (id.equals("MBK_SHOW_ASSOCIATION_NAME")) {
0948: boolean isDisplayed = false;
0949: if (labelMgr != null) {
0950: isDisplayed = labelMgr
0951: .isDisplayed(TSLabelKind.TSLK_ASSOCIATION_NAME);
0952: }
0953: actionClass.setChecked(isDisplayed);
0954: bFlag = isReadOnly ? false : true;
0955: } else if (id.equals("MBK_SHOW_ROLENAME")) {
0956: boolean isDisplayed = false;
0957: if (labelMgr != null && pNearestEnd != null
0958: && pAssociation != null) {
0959: isDisplayed = labelMgr
0960: .isDisplayed((index == 0) ? TSLabelKind.TSLK_ASSOCIATION_END0_ROLE_NAME
0961: : TSLabelKind.TSLK_ASSOCIATION_END1_ROLE_NAME);
0962: }
0963: actionClass.setChecked(isDisplayed);
0964: bFlag = isReadOnly ? false : true;
0965: } else if (id.equals("MBK_SHOW_MULTIPLICITY")) {
0966: boolean isDisplayed = false;
0967: if (labelMgr != null && pNearestEnd != null
0968: && pAssociation != null) {
0969: isDisplayed = labelMgr
0970: .isDisplayed((index == 0) ? TSLabelKind.TSLK_ASSOCIATION_END0_MULTIPLICITY
0971: : TSLabelKind.TSLK_ASSOCIATION_END1_MULTIPLICITY);
0972: }
0973: actionClass.setChecked(isDisplayed);
0974: bFlag = isReadOnly ? false : true;
0975: } else if (id.equals("MBK_SHOW_BOTH_ROLENAMES")) {
0976: boolean isDisplayed1 = false;
0977: boolean isDisplayed2 = false;
0978: if (labelMgr != null) {
0979: isDisplayed1 = labelMgr
0980: .isDisplayed(TSLabelKind.TSLK_ASSOCIATION_END0_ROLE_NAME);
0981: isDisplayed2 = labelMgr
0982: .isDisplayed(TSLabelKind.TSLK_ASSOCIATION_END1_ROLE_NAME);
0983: }
0984: if (isDisplayed1 && isDisplayed2) {
0985: actionClass.setChecked(true);
0986: }
0987: bFlag = isReadOnly ? false : true;
0988: } else if (id.equals("MBK_SHOW_BOTH_MULTIPLICITIES")) {
0989: boolean isDisplayed1 = false;
0990: boolean isDisplayed2 = false;
0991: if (labelMgr != null) {
0992: isDisplayed1 = labelMgr
0993: .isDisplayed(TSLabelKind.TSLK_ASSOCIATION_END0_MULTIPLICITY);
0994: isDisplayed2 = labelMgr
0995: .isDisplayed(TSLabelKind.TSLK_ASSOCIATION_END1_MULTIPLICITY);
0996: }
0997: if (isDisplayed1 && isDisplayed2) {
0998: actionClass.setChecked(true);
0999: }
1000: bFlag = isReadOnly ? false : true;
1001: } else if (id.equals("MBK_QUALIFIERS")) {
1002: IPresentationElement pPE = getPresentationElement();
1003: if (pPE != null
1004: && pPE instanceof IAssociationEdgePresentation) {
1005: IPresentationElement pQualPE = null;
1006: if (m_ContextMenuLocation == CMPK_START) {
1007: pQualPE = ((IAssociationEdgePresentation) pPE)
1008: .getSourceQualifier();
1009: } else if (m_ContextMenuLocation == CMPK_END) {
1010: pQualPE = ((IAssociationEdgePresentation) pPE)
1011: .getTargetQualifier();
1012: }
1013:
1014: if (pQualPE != null) {
1015: actionClass.setChecked(true);
1016: }
1017: }
1018: bFlag = isReadOnly ? false : true;
1019: }
1020:
1021: //set the sensitivities for remaining ids.
1022: if (id.equals("MBK_LINK_END_REMOVE_AGGREGATE")) {
1023: if (pAggregation != null && pNearestEnd != null) {
1024: boolean isAggEnd = pAggregation
1025: .isAggregateEnd(pNearestEnd);
1026: if (isAggEnd) {
1027: bFlag = isReadOnly ? false : true;
1028: }
1029: } else if (pAssociationClass != null
1030: && pNearestEnd != null) {
1031: boolean hasIsComposite = false;
1032: boolean isComposite = false;
1033: boolean this IsAggEnd = false;
1034: String aggEnd = "";
1035: String partEnd = "";
1036:
1037: // Get the Aggregation stuff for the AssociationClass which is fixed in UML 2.0, but not SP1
1038: getAssociationClassAggregationHack(
1039: pAssociationClass, pNearestEnd,
1040: hasIsComposite, isComposite, this IsAggEnd,
1041: aggEnd, partEnd);
1042:
1043: if (hasIsComposite && this IsAggEnd) {
1044: bFlag = isReadOnly ? false : true;
1045: }
1046: }
1047: } else if (id.equals("MBK_LINK_END_REVERSE_ENDS")
1048: || id.equals("MBK_SET_MULTIPLICITY_0_1")
1049: || id.equals("MBK_SET_MULTIPLICITY_0_STAR")
1050: || id.equals("MBK_SET_MULTIPLICITY_STAR")
1051: || id.equals("MBK_SET_MULTIPLICITY_1")
1052: || id.equals("MBK_SET_MULTIPLICITY_1_STAR")) {
1053: bFlag = isReadOnly ? false : true;
1054: }
1055:
1056: retVal = bFlag;
1057: }
1058:
1059: if (!retVal) {
1060: retVal = super .setSensitivityAndCheck(id, actionClass);
1061: }
1062:
1063: return retVal;
1064: }
1065:
1066: /**
1067: * Get the Aggregation stuff for the AssociationClass which is fixed in UML 2.0, but not SP1
1068: */
1069: private void getAssociationClassAggregationHack(
1070: IAssociationClass pAssociationClass,
1071: IAssociationEnd pNearestEnd, boolean hasIsComposite,
1072: boolean isComposite, boolean this IsAggEnd, String aggEnd,
1073: String partEnd) {
1074: if (pAssociationClass != null && pNearestEnd != null) {
1075: Node pNode = pAssociationClass.getNode();
1076: if (pNode != null) {
1077: Node value = XMLManip
1078: .getAttribute(pNode, "isComposite");
1079: if (value != null) {
1080: hasIsComposite = true;
1081: isComposite = XMLManip.getAttributeBooleanValue(
1082: pNode, "isComposite");
1083: partEnd = XMLManip.getAttributeValue(pNode,
1084: "partEnd");
1085: aggEnd = XMLManip.getAttributeValue(pNode,
1086: "aggregateEnd");
1087:
1088: // See if this end we're drawing is the aggregate end
1089: String xmiid = pNearestEnd.getXMIID();
1090: if (xmiid.equals(aggEnd)) {
1091: this IsAggEnd = true;
1092: }
1093: }
1094: }
1095: }
1096: }
1097:
1098: /*
1099: * (non-Javadoc)
1100: * @see org.netbeans.modules.uml.ui.products.ad.application.action.IETContextMenuHandler#onHandleButton(java.awt.event.ActionEvent, java.lang.String)
1101: */
1102: public boolean onHandleButton(ActionEvent e, String id) {
1103: boolean handled = handleStandardLabelSelection(e, id);
1104:
1105: if (!handled) {
1106: IDrawingAreaControl pDiagram = getDrawingArea();
1107: IETGraphObject pETElement = (IETGraphObject) getParentETElement();
1108: ILabelManager labelMgr = getLabelManager();
1109: IPresentationElement pPE = getPresentationElement();
1110: IElement pElement = null;
1111: if (pETElement != null) {
1112: pElement = TypeConversions.getElement(pETElement);
1113: }
1114:
1115: //get the nearest end
1116: IAssociationEnd pNearestEnd = null;
1117: if (m_ContextMenuLocation == CMPK_START) {
1118: pNearestEnd = m_StartEnd;
1119: } else if (m_ContextMenuLocation == CMPK_END) {
1120: pNearestEnd = m_FinishEnd;
1121: }
1122:
1123: IAssociation pAssociation = null;
1124: IAssociationClass pAssociationClass = null;
1125: IAggregation pAggregation = null;
1126: if (pElement instanceof IAssociation) {
1127: pAssociation = (IAssociation) pElement;
1128: }
1129: if (pElement instanceof IAssociationClass) {
1130: pAssociationClass = (IAssociationClass) pElement;
1131: }
1132: if (pElement instanceof IAggregation) {
1133: pAggregation = (IAggregation) pElement;
1134: }
1135:
1136: if (pETElement != null && pDiagram != null) {
1137: if (id.equals("MBK_LINK_END_ORDINARY_AGGREGATE")) {
1138: if (pAssociationClass != null) {
1139: handleAssociationClassTransformHack(id,
1140: pAssociationClass, pNearestEnd);
1141: } else {
1142: // Transforms the link to an aggregation. The end we're currently on remains an
1143: // a non-composite
1144: pDiagram.transform(pETElement, "Aggregation");
1145: }
1146: } else if (id
1147: .equals("MBK_LINK_END_COMPOSITE_AGGREGATE")) {
1148: if (pAssociationClass != null) {
1149: handleAssociationClassTransformHack(id,
1150: pAssociationClass, pNearestEnd);
1151: } else {
1152: // Transforms the link to an aggregation. The end we're currently on remains an
1153: // a composite
1154: pDiagram.transform(pETElement,
1155: "Composite Aggregation");
1156: }
1157: } else if (id.equals("MBK_LINK_END_REMOVE_AGGREGATE")) {
1158: if (pAssociationClass != null) {
1159: handleAssociationClassTransformHack(id,
1160: pAssociationClass, pNearestEnd);
1161: } else {
1162: // Transforms the link to an association
1163: pDiagram.transform(pETElement, "Association");
1164: }
1165: } else if (id.equals("MBK_LINK_END_NAVIGABLE")) {
1166: // Transforms the end to be navigable.
1167: if (pNearestEnd != null) {
1168: if (pNearestEnd instanceof INavigableEnd) {
1169: IAssociationEnd pEnd = ((INavigableEnd) pNearestEnd)
1170: .makeNonNavigable();
1171: if (m_ContextMenuLocation == CMPK_START) {
1172: setEnd(true, pEnd);
1173: } else if (m_ContextMenuLocation == CMPK_END) {
1174: setEnd(false, pEnd);
1175: }
1176: } else {
1177: INavigableEnd pEnd = pNearestEnd
1178: .makeNavigable();
1179: if (m_ContextMenuLocation == CMPK_START) {
1180: setEnd(true, pEnd);
1181: } else if (m_ContextMenuLocation == CMPK_END) {
1182: setEnd(false, pEnd);
1183: }
1184: }
1185: }
1186: } else if (id.equals("MBK_LINK_END_REVERSE_ENDS")) {
1187: if (pAssociationClass != null) {
1188: Node pNode = pAssociationClass.getNode();
1189: String partEndVal = XMLManip.getAttributeValue(
1190: pNode, "partEnd");
1191: String aggEndVal = XMLManip.getAttributeValue(
1192: pNode, "aggregateEnd");
1193: if (partEndVal != null && aggEndVal != null) {
1194: //switch the ends
1195: UMLXMLManip.setAttributeValue(
1196: pAssociationClass, "partEnd",
1197: aggEndVal);
1198: UMLXMLManip.setAttributeValue(
1199: pAssociationClass, "aggregateEnd",
1200: partEndVal);
1201: }
1202: } else {
1203: //reverse the ends
1204: if (pAggregation != null) {
1205: pAggregation.reverseEnds();
1206: }
1207: }
1208:
1209: // Switch the navigability of the ends
1210: INavigableEnd startEnd = null;
1211: INavigableEnd finishEnd = null;
1212: if (m_StartEnd instanceof INavigableEnd) {
1213: startEnd = (INavigableEnd) m_StartEnd;
1214: }
1215: if (m_FinishEnd instanceof INavigableEnd) {
1216: finishEnd = (INavigableEnd) m_FinishEnd;
1217: }
1218:
1219: if ((startEnd == null && finishEnd != null)
1220: || (finishEnd == null && startEnd != null)) {
1221: IAssociationEnd pNewEnd = null;
1222: INavigableEnd pNewNavEnd = null;
1223: if (startEnd != null) {
1224: pNewEnd = startEnd.makeNonNavigable();
1225: pNewNavEnd = m_FinishEnd.makeNavigable();
1226: setEnds(pNewEnd, pNewNavEnd);
1227: } else if (finishEnd != null) {
1228: pNewNavEnd = m_StartEnd.makeNavigable();
1229: pNewEnd = finishEnd.makeNonNavigable();
1230: setEnds(pNewNavEnd, pNewEnd);
1231: }
1232: }
1233:
1234: // reverse edge flow on graph objects 78321
1235: if (pPE != null
1236: && pPE instanceof IAssociationEdgePresentation) {
1237: IAssociationEdgePresentation assocEdgePE = (IAssociationEdgePresentation) pPE;
1238: assocEdgePE.reverseEnds();
1239: }
1240: } else if (id.equals("MBK_SHOW_ASSOCIATION_NAME")) {
1241: if (labelMgr != null) {
1242: boolean isDisplayed = labelMgr
1243: .isDisplayed(TSLabelKind.TSLK_ASSOCIATION_NAME);
1244: labelMgr.showLabel(
1245: TSLabelKind.TSLK_ASSOCIATION_NAME,
1246: isDisplayed ? false : true);
1247:
1248: if (!isDisplayed) {
1249: IPresentationElement presEle = labelMgr
1250: .getLabel(TSLabelKind.TSLK_ASSOCIATION_NAME);
1251: if (presEle != null
1252: && presEle instanceof ILabelPresentation) {
1253: pDiagram
1254: .postEditLabel((ILabelPresentation) presEle);
1255: }
1256: }
1257: }
1258: } else if (id.equals("MBK_SHOW_ROLENAME")) {
1259: if (labelMgr != null && pNearestEnd != null
1260: && pAssociation != null) {
1261: // Get the index of the nearest end
1262: int index = pAssociation
1263: .getEndIndex(pNearestEnd);
1264:
1265: boolean isDisplayed = labelMgr
1266: .isDisplayed((index == 0) ? TSLabelKind.TSLK_ASSOCIATION_END0_ROLE_NAME
1267: : TSLabelKind.TSLK_ASSOCIATION_END1_ROLE_NAME);
1268: labelMgr
1269: .showLabel(
1270: (index == 0) ? TSLabelKind.TSLK_ASSOCIATION_END0_ROLE_NAME
1271: : TSLabelKind.TSLK_ASSOCIATION_END1_ROLE_NAME,
1272: isDisplayed ? false : true);
1273:
1274: if (!isDisplayed) {
1275: IPresentationElement presEle = labelMgr
1276: .getLabel((index == 0) ? TSLabelKind.TSLK_ASSOCIATION_END0_ROLE_NAME
1277: : TSLabelKind.TSLK_ASSOCIATION_END1_ROLE_NAME);
1278: if (presEle != null
1279: && presEle instanceof ILabelPresentation) {
1280: pDiagram
1281: .postEditLabel((ILabelPresentation) presEle);
1282: }
1283: }
1284: }
1285: } else if (id.equals("MBK_SHOW_MULTIPLICITY")) {
1286: if (labelMgr != null && pNearestEnd != null
1287: && pAssociation != null) {
1288: // Get the index of the nearest end
1289: int index = pAssociation
1290: .getEndIndex(pNearestEnd);
1291:
1292: boolean isDisplayed = labelMgr
1293: .isDisplayed((index == 0) ? TSLabelKind.TSLK_ASSOCIATION_END0_MULTIPLICITY
1294: : TSLabelKind.TSLK_ASSOCIATION_END1_MULTIPLICITY);
1295: labelMgr
1296: .showLabel(
1297: (index == 0) ? TSLabelKind.TSLK_ASSOCIATION_END0_MULTIPLICITY
1298: : TSLabelKind.TSLK_ASSOCIATION_END1_MULTIPLICITY,
1299: isDisplayed ? false : true);
1300:
1301: if (!isDisplayed) {
1302: IPresentationElement presEle = labelMgr
1303: .getLabel((index == 0) ? TSLabelKind.TSLK_ASSOCIATION_END0_MULTIPLICITY
1304: : TSLabelKind.TSLK_ASSOCIATION_END1_MULTIPLICITY);
1305: if (presEle != null
1306: && presEle instanceof ILabelPresentation) {
1307: pDiagram
1308: .postEditLabel((ILabelPresentation) presEle);
1309: }
1310: }
1311: }
1312: } else if (id.equals("MBK_SHOW_BOTH_ROLENAMES")) {
1313: if (labelMgr != null) {
1314: boolean isDisplayed = labelMgr
1315: .isDisplayed(TSLabelKind.TSLK_ASSOCIATION_END0_ROLE_NAME);
1316: labelMgr
1317: .showLabel(
1318: TSLabelKind.TSLK_ASSOCIATION_END0_ROLE_NAME,
1319: isDisplayed ? false : true);
1320: labelMgr
1321: .showLabel(
1322: TSLabelKind.TSLK_ASSOCIATION_END1_ROLE_NAME,
1323: isDisplayed ? false : true);
1324: }
1325: } else if (id.equals("MBK_SHOW_BOTH_MULTIPLICITIES")) {
1326: if (labelMgr != null) {
1327: boolean isDisplayed = labelMgr
1328: .isDisplayed(TSLabelKind.TSLK_ASSOCIATION_END0_MULTIPLICITY);
1329: labelMgr
1330: .showLabel(
1331: TSLabelKind.TSLK_ASSOCIATION_END0_MULTIPLICITY,
1332: isDisplayed ? false : true);
1333: labelMgr
1334: .showLabel(
1335: TSLabelKind.TSLK_ASSOCIATION_END1_MULTIPLICITY,
1336: isDisplayed ? false : true);
1337: }
1338: } else if (id.equals("MBK_SET_MULTIPLICITY_0_1")
1339: || id.equals("MBK_SET_MULTIPLICITY_0_STAR")
1340: || id.equals("MBK_SET_MULTIPLICITY_STAR")
1341: || id.equals("MBK_SET_MULTIPLICITY_1")
1342: || id.equals("MBK_SET_MULTIPLICITY_1_STAR")) {
1343: if (labelMgr != null && pNearestEnd != null) {
1344: IMultiplicity pMult = pNearestEnd
1345: .getMultiplicity();
1346: if (pMult != null) {
1347: if (id.equals("MBK_SET_MULTIPLICITY_0_1")) {
1348: pMult.setRange2("0", "1");
1349: } else if (id
1350: .equals("MBK_SET_MULTIPLICITY_0_STAR")) {
1351: pMult.setRange2("0", "*");
1352: } else if (id
1353: .equals("MBK_SET_MULTIPLICITY_STAR")) {
1354: pMult.setRange("*");
1355: } else if (id
1356: .equals("MBK_SET_MULTIPLICITY_1")) {
1357: pMult.setRange2("1", "1");
1358: } else if (id
1359: .equals("MBK_SET_MULTIPLICITY_1_STAR")) {
1360: pMult.setRange2("1", "*");
1361: }
1362:
1363: if (m_ContextMenuLocation == CMPK_START) {
1364: labelMgr
1365: .showLabel(
1366: TSLabelKind.TSLK_ASSOCIATION_END0_MULTIPLICITY,
1367: true);
1368: labelMgr.resetLabelsText();
1369: } else {
1370: labelMgr
1371: .showLabel(
1372: TSLabelKind.TSLK_ASSOCIATION_END1_MULTIPLICITY,
1373: true);
1374: labelMgr.resetLabelsText();
1375: }
1376: }
1377: }
1378: } else if (id.equals("MBK_QUALIFIERS")) {
1379: if (pPE != null
1380: && pPE instanceof IAssociationEdgePresentation) {
1381: IAssociationEdgePresentation assocEdgePE = (IAssociationEdgePresentation) pPE;
1382: IPresentationElement pQualPE = null;
1383: if (m_ContextMenuLocation == CMPK_START) {
1384: pQualPE = assocEdgePE.getSourceQualifier();
1385: if (pQualPE != null) {
1386: assocEdgePE
1387: .removeQualifierNodeAtSourceLocation();
1388: } else {
1389: assocEdgePE
1390: .createQualifierNodeAtSourceLocation();
1391: }
1392: } else if (m_ContextMenuLocation == CMPK_END) {
1393: pQualPE = assocEdgePE.getTargetQualifier();
1394: if (pQualPE != null) {
1395: assocEdgePE
1396: .removeQualifierNodeAtTargetLocation();
1397: } else {
1398: assocEdgePE
1399: .createQualifierNodeAtTargetLocation();
1400: }
1401: }
1402: }
1403: }
1404:
1405: pDiagram.refresh(false);
1406: }
1407: }
1408:
1409: if (!handled) {
1410: handled = super .onHandleButton(e, id);
1411: }
1412: return handled;
1413: }
1414:
1415: /**
1416: * Handles the transformation of the association class ends. Will be fixed with UML 2.0.
1417: */
1418: private void handleAssociationClassTransformHack(String id,
1419: IAssociationClass pAssociationClass,
1420: IAssociationEnd pNearestEnd) {
1421: if (pAssociationClass != null && pNearestEnd != null
1422: && m_StartEnd != null && m_FinishEnd != null) {
1423: Node pNode = pAssociationClass.getNode();
1424:
1425: String startEnd = m_StartEnd.getXMIID();
1426: String finishEnd = m_FinishEnd.getXMIID();
1427: String nearestEnd = pNearestEnd.getXMIID();
1428:
1429: if (id.equals("MBK_LINK_END_ORDINARY_AGGREGATE")) {
1430: // Typical XML Fragment-
1431: // <UML:AssociationClass xmlns:UML="omg.org/UML/1.4" xmi.id="_0.0-6452.17688..148_"
1432: // name="a15" visibility="public" isAbstract="false"
1433: // owner="DCE.906DB957-ECF2-4F5A-93A9-DF99353F8C66" isTransient="false"
1434: // isFinal="false" aggregateEnd="_0.0-3133.8975..148_AE0001" isComposite="false"
1435: // partEnd="_0.0-3133.8975..148_AE0002">
1436: // - <UML:Association.end>
1437: // - <UML:AssociationEnd xmi.id="_0.0-3133.8975..148_AE0001" name="" visibility="public"
1438: // appliedStereotype="" type="_0.0-2284.6860..148_" association="_0.0-6452.17688..148_">
1439: // - <UML:TypedElement.multiplicity>
1440: // <UML:Multiplicity xmi.id="MULT__0.0-3133.8975..148_AE0001" />
1441: // </UML:TypedElement.multiplicity>
1442: // </UML:AssociationEnd>
1443: // - <UML:NavigableEnd xmi.id="_0.0-3133.8975..148_AE0002" name="" visibility="public"
1444: // aggregation="none" appliedStereotype="" type="_0.0-2405.7204..148_"
1445: // association="_0.0-6452.17688..148_">
1446: // - <UML:TypedElement.multiplicity>
1447: // <UML:Multiplicity xmi.id="MULT__0.0-3133.8975..148_AE0002" />
1448: // </UML:TypedElement.multiplicity>
1449: // </UML:NavigableEnd>
1450: // </UML:Association.end>
1451: Node value = XMLManip
1452: .getAttribute(pNode, "isComposite");
1453: if (value != null) {
1454: UMLXMLManip.setAttributeValue(pAssociationClass,
1455: "isComposite", "false");
1456: } else {
1457: // Create the attributes that make this an attribute
1458: UMLXMLManip.setAttributeValue(pAssociationClass,
1459: "isComposite", "false");
1460: UMLXMLManip.setAttributeValue(pAssociationClass,
1461: "aggregateEnd", nearestEnd);
1462:
1463: if (nearestEnd.equals(startEnd)) {
1464: UMLXMLManip
1465: .setAttributeValue(pAssociationClass,
1466: "partEnd", finishEnd);
1467: } else {
1468: UMLXMLManip.setAttributeValue(
1469: pAssociationClass, "partEnd", startEnd);
1470: }
1471: }
1472: } else if (id.equals("MBK_LINK_END_COMPOSITE_AGGREGATE")) {
1473: // Typical XML Fragment-
1474: // <UML:AssociationClass xmlns:UML="omg.org/UML/1.4" xmi.id="_0.0-6452.17688..148_"
1475: // name="a15" visibility="public" isAbstract="false"
1476: // owner="DCE.906DB957-ECF2-4F5A-93A9-DF99353F8C66" isTransient="false"
1477: // isFinal="false" aggregateEnd="_0.0-3133.8975..148_AE0001" isComposite="true"
1478: // partEnd="_0.0-3133.8975..148_AE0002">
1479: // - <UML:Association.end>
1480: // - <UML:AssociationEnd xmi.id="_0.0-3133.8975..148_AE0001" name="" visibility="public"
1481: // appliedStereotype="" type="_0.0-2284.6860..148_" association="_0.0-6452.17688..148_">
1482: // - <UML:TypedElement.multiplicity>
1483: // <UML:Multiplicity xmi.id="MULT__0.0-3133.8975..148_AE0001" />
1484: // </UML:TypedElement.multiplicity>
1485: // </UML:AssociationEnd>
1486: // - <UML:NavigableEnd xmi.id="_0.0-3133.8975..148_AE0002" name="" visibility="public"
1487: // aggregation="none" appliedStereotype="" type="_0.0-2405.7204..148_"
1488: // association="_0.0-6452.17688..148_">
1489: // - <UML:TypedElement.multiplicity>
1490: // <UML:Multiplicity xmi.id="MULT__0.0-3133.8975..148_AE0002" />
1491: // </UML:TypedElement.multiplicity>
1492: // </UML:NavigableEnd>
1493: // </UML:Association.end>
1494: Node value = XMLManip
1495: .getAttribute(pNode, "isComposite");
1496: if (value != null) {
1497: UMLXMLManip.setAttributeValue(pAssociationClass,
1498: "isComposite", "true");
1499: } else {
1500: // Create the attributes that make this an attribute
1501: UMLXMLManip.setAttributeValue(pAssociationClass,
1502: "isComposite", "true");
1503: UMLXMLManip.setAttributeValue(pAssociationClass,
1504: "aggregateEnd", nearestEnd);
1505:
1506: if (nearestEnd.equals(startEnd)) {
1507: UMLXMLManip
1508: .setAttributeValue(pAssociationClass,
1509: "partEnd", finishEnd);
1510: } else {
1511: UMLXMLManip.setAttributeValue(
1512: pAssociationClass, "partEnd", startEnd);
1513: }
1514: }
1515: } else if (id.equals("MBK_LINK_END_REMOVE_AGGREGATE")) {
1516: // Typical XML Fragment-
1517: // <UML:AssociationClass xmlns:UML="omg.org/UML/1.4"
1518: // xmi.id="DCE.367193D4-5C37-4F51-8B38-4633D1CD70A5"
1519: // owner="DCE.82254AB6-7BB1-4D1D-AB66-649F4E6FAF79" name="new">
1520: // - <UML:Association.end>
1521: // - <UML:AssociationEnd xmi.id="DCE.159414ED-DD5D-4A11-8052-92EEF90A3F7E"
1522: // visibility="private" association="DCE.367193D4-5C37-4F51-8B38-4633D1CD70A5"
1523: // type="DCE.D3166D20-FCF1-49F1-A76E-8CEB0BDB7086">
1524: // - <UML:TypedElement.multiplicity>
1525: // <UML:Multiplicity xmi.id="DCE.34038187-A16B-4874-8B8D-C6D08010018D" />
1526: // </UML:TypedElement.multiplicity>
1527: // </UML:AssociationEnd>
1528: // - <UML:AssociationEnd xmi.id="DCE.1BEEA0FD-78E8-456F-9927-065EB70477FC"
1529: // visibility="private" association="DCE.367193D4-5C37-4F51-8B38-4633D1CD70A5"
1530: // type="DCE.462E082E-25D2-452C-B450-4213BEE2F206">
1531: // - <UML:TypedElement.multiplicity>
1532: // <UML:Multiplicity xmi.id="DCE.1F0FB772-D3DE-4DEC-9116-C1A217A21D04" />
1533: // </UML:TypedElement.multiplicity>
1534: // </UML:AssociationEnd>
1535: // </UML:Association.end>
1536: // </UML:AssociationClass>
1537: Element pNodeEle = (Element) pNode;
1538: Attribute attr = pNodeEle.attribute("aggregateEnd");
1539: if (attr != null) {
1540: pNodeEle.remove(attr);
1541: }
1542: attr = pNodeEle.attribute("partEnd");
1543: if (attr != null) {
1544: pNodeEle.remove(attr);
1545: }
1546: attr = pNodeEle.attribute("isComposite");
1547: if (attr != null) {
1548: pNodeEle.remove(attr);
1549: }
1550: }
1551: }
1552: }
1553:
1554: public String getDrawEngineID() {
1555: return "AssociationEdgeDrawEngine";
1556: }
1557:
1558: protected final static String NN_NN_META_TYPE = "NN NN";
1559: protected final static String NN_NA_META_TYPE = "NN NA";
1560: protected final static String CO_NN_META_TYPE = "CO NN";
1561: protected final static String AG_NN_META_TYPE = "AG NN";
1562: protected final static String CO_NA_META_TYPE = "CO NA";
1563: protected final static String AG_NA_META_TYPE = "AG NA";
1564:
1565: public String getMetaTypeInitString() {
1566: return NN_NN_META_TYPE;
1567: }
1568:
1569: /* (non-Javadoc)
1570: * @see org.netbeans.modules.uml.ui.products.ad.drawengines.ETDrawEngine#getManagerType(int)
1571: */
1572: public String getManagerMetaType(int nManagerKind) {
1573: String sManager = null;
1574:
1575: //NL TODO The following looks a bit weird (why not use an if else?) but I am leaving it as is
1576: String metaType = getMetaTypeOfElement();
1577: if (metaType != null && !metaType.equals("AssociationClass")) {
1578: if (nManagerKind == MK_LABELMANAGER) {
1579: sManager = "AssociationLabelManager";
1580: }
1581: }
1582:
1583: if (metaType != null && metaType.equals("AssociationClass")) {
1584: // Override if we've got an association class
1585: if (nManagerKind == MK_LABELMANAGER) {
1586: sManager = "AssociationClassLabelManager";
1587: } else if (nManagerKind == MK_EVENTMANAGER) {
1588: sManager = "AssociationClassEventManager";
1589: }
1590: }
1591:
1592: return sManager;
1593: }
1594:
1595: /* (non-Javadoc)
1596: * @see org.netbeans.modules.uml.ui.support.viewfactorysupport.IDrawEngine#isDrawEngineValidForModelElement()
1597: */
1598: public boolean isDrawEngineValidForModelElement() {
1599:
1600: String currentMetaType = getMetaTypeOfElement();
1601: return (currentMetaType != null && (currentMetaType
1602: .equals("Association")
1603: || currentMetaType.equals("Aggregation") || currentMetaType
1604: .equals("AssociationEnd")));
1605: }
1606:
1607: /* (non-Javadoc)
1608: * @see org.netbeans.modules.uml.ui.support.viewfactorysupport.IEdgeDrawEngine#verifyEdgeEnds()
1609: */
1610: public void verifyEdgeEnds() {
1611: try {
1612: IElement pModelElement = this .getPresentation()
1613: .getFirstSubject();
1614:
1615: setEnds(null, null);
1616:
1617: IAssociation pAssociation = pModelElement instanceof IAssociation ? (IAssociation) pModelElement
1618: : null;
1619: IAssociationClass pAssociationClass = pModelElement instanceof IAssociationClass ? (IAssociationClass) pModelElement
1620: : null;
1621:
1622: if (pAssociationClass == null && pAssociation != null) {
1623: ETList<IAssociationEnd> pAssociationEnds = pAssociation
1624: .getEnds();
1625: long numEnds = pAssociation.getNumEnds();
1626:
1627: if (numEnds == 2) {
1628: IAssociationEnd pFirstEnd = pAssociationEnds.get(0);
1629: IAssociationEnd pSecondEnd = pAssociationEnds
1630: .get(1);
1631:
1632: // See if either end is navigable (shown with an arrowhead)
1633: INavigableEnd pNavFirstEnd = pFirstEnd instanceof INavigableEnd ? (INavigableEnd) pFirstEnd
1634: : null;
1635: INavigableEnd pNavSecondEnd = pSecondEnd instanceof INavigableEnd ? (INavigableEnd) pSecondEnd
1636: : null;
1637:
1638: //assert (pFirstEnd &pSecondEnd);
1639: if (pFirstEnd != null && pSecondEnd != null) {
1640: // See if the aggregation end is a diamond filled or unfilled
1641: int nEndKind = this .getIEdgePresentation()
1642: .getNodeEnd(pFirstEnd);
1643:
1644: if (nEndKind == NodeEndKindEnum.NEK_TO) {
1645: if (!parentDiagramIsReadOnly()) {
1646: // This is wrong. It ends up with an incorrect parent/child relationship.
1647: // Switch it unless the diagram is readonly
1648: postSwapEdgeEnds();
1649: }
1650: }
1651: }
1652: }
1653: }
1654: } catch (Exception e) {
1655: e.printStackTrace();
1656: }
1657: }
1658:
1659: /* (non-Javadoc)
1660: * @see org.netbeans.modules.uml.ui.support.viewfactorysupport.IDrawEngine#onGraphEvent(int)
1661: */
1662: public void onGraphEvent(int nKind) {
1663: super .onGraphEvent(nKind);
1664: if (nKind == IGraphEventKind.GEK_PRE_DELETEGATHERSELECTED) {
1665: selectAllAttachedQualifiers(true);
1666: }
1667: }
1668:
1669: /**
1670: * Selects all the qualifiers
1671: *
1672: * @param bSelect [in] true to select all the qualifiers, otherwise deselect
1673: */
1674: public void selectAllAttachedQualifiers(boolean bSelect) {
1675: try {
1676: IPresentationElement pThisPE = getPresentationElement();
1677:
1678: IAssociationEdgePresentation pAssociationEdgePE = pThisPE instanceof IAssociationEdgePresentation ? (IAssociationEdgePresentation) pThisPE
1679: : null;
1680:
1681: //assert (pAssociationEdgePE);
1682: if (pAssociationEdgePE != null) {
1683: IPresentationElement pQualifierPE = pAssociationEdgePE
1684: .getSourceQualifier();
1685:
1686: IProductGraphPresentation pGraphPE = pQualifierPE instanceof IProductGraphPresentation ? (IProductGraphPresentation) pQualifierPE
1687: : null;
1688: if (pGraphPE != null) {
1689: pGraphPE.setSelected(true);
1690: }
1691:
1692: pQualifierPE = pAssociationEdgePE.getTargetQualifier();
1693:
1694: pGraphPE = pQualifierPE instanceof IProductGraphPresentation ? (IProductGraphPresentation) pQualifierPE
1695: : null;
1696: if (pGraphPE != null) {
1697: pGraphPE.setSelected(true);
1698: }
1699: }
1700: } catch (Exception e) {
1701: e.printStackTrace();
1702: }
1703: }
1704:
1705: /* (non-Javadoc)
1706: * @see org.netbeans.modules.uml.ui.support.viewfactorysupport.IDrawEngine#initResources()
1707: */
1708: public void initResources() {
1709: this .setLineColor("associationedgecolor", Color.BLACK);
1710: super.initResources();
1711: }
1712: }
|