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.designpattern;
0043:
0044: import java.awt.Dimension;
0045: import java.awt.FontMetrics;
0046: import java.awt.Graphics;
0047: import java.awt.GridBagConstraints;
0048: import java.awt.GridBagLayout;
0049: import java.awt.Insets;
0050: import java.awt.SystemColor;
0051: import java.awt.event.ActionEvent;
0052: import java.io.File;
0053: import java.util.Collection;
0054: import java.util.Enumeration;
0055: import java.util.Hashtable;
0056: import java.util.Vector;
0057:
0058: import javax.swing.Icon;
0059: import javax.swing.JLabel;
0060: import javax.swing.JPanel;
0061: import javax.swing.JScrollPane;
0062: import javax.swing.JTable;
0063: import javax.swing.JTextField;
0064: import javax.swing.JTree;
0065: import javax.swing.SwingUtilities;
0066: import javax.swing.table.DefaultTableModel;
0067: import javax.swing.tree.TreeNode;
0068: import javax.swing.tree.TreePath;
0069:
0070: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
0071: import org.netbeans.modules.uml.core.metamodel.core.foundation.INamedElement;
0072: import org.netbeans.modules.uml.core.metamodel.dynamics.Message;
0073: import org.netbeans.modules.uml.core.metamodel.structure.IProject;
0074: import org.netbeans.modules.uml.core.support.umlsupport.StringUtilities;
0075: import org.netbeans.modules.uml.core.support.umlutils.ETArrayList;
0076: import org.netbeans.modules.uml.core.support.umlutils.ETList;
0077: import org.netbeans.modules.uml.core.support.umlutils.ElementLocator;
0078: import org.netbeans.modules.uml.core.support.umlutils.IElementLocator;
0079: import org.netbeans.modules.uml.ui.support.commondialogs.IErrorDialog;
0080: import org.netbeans.modules.uml.ui.support.commondialogs.MessageIconKindEnum;
0081: import org.netbeans.modules.uml.ui.support.commonresources.CommonResourceManager;
0082: import org.netbeans.modules.uml.ui.support.commonresources.ICommonResourceManager;
0083: import org.netbeans.modules.uml.ui.support.wizard.IWizardSheet;
0084: import org.netbeans.modules.uml.ui.support.wizard.WizardInteriorPage;
0085: import org.netbeans.modules.uml.ui.swing.commondialogs.SwingErrorDialog;
0086: import org.netbeans.modules.uml.ui.swing.treetable.JDefaultMutableTreeNode;
0087: import org.netbeans.modules.uml.ui.swing.treetable.JTreeTable;
0088:
0089: public class WizardRoles extends WizardInteriorPage {
0090:
0091: private static final String PG_CAPTION = DefaultDesignPatternResource
0092: .getString("IDS_WIZARDCAPTION");
0093: private static final String PG_TITLE = DefaultDesignPatternResource
0094: .getString("IDS_CHOOSEPARTICIPANTS");
0095: private static final String PG_SUBTITLE = DefaultDesignPatternResource
0096: .getString("IDS_CHOOSEPARTICIPANTSHELP");
0097:
0098: private Wizard m_Wizard = null;
0099:
0100: private JDefaultMutableTreeNode m_Root = null;
0101: private RoleTreeTableModel m_Model = null;
0102: private JTreeTable m_Tree = null;
0103:
0104: private ICommonResourceManager m_ResourceMgr = CommonResourceManager
0105: .instance();
0106:
0107: // map of element type to element name to element id
0108: private Hashtable<String, Hashtable> m_TypeMap = new Hashtable<String, Hashtable>();
0109:
0110: //this variable captures the row where user right clicked.
0111: private int m_RightClickRow = 0;
0112:
0113: public WizardRoles(IWizardSheet parent, String caption,
0114: String headerTitle, String headerSubTitle) {
0115: super (parent, caption, headerTitle, headerSubTitle);
0116: createUI();
0117: }
0118:
0119: public WizardRoles(IWizardSheet parent) {
0120: this (parent, PG_CAPTION, PG_TITLE, PG_SUBTITLE);
0121: }
0122:
0123: protected void createUI() {
0124: super .createUI();
0125:
0126: this .addActionListeners();
0127: this .onInitDialog();
0128: }
0129:
0130: private void addActionListeners() {
0131: }
0132:
0133: /**
0134: * Called when dialog is initialized
0135: *
0136: *
0137: *
0138: * @return BOOL
0139: *
0140: */
0141: protected boolean onInitDialog() {
0142: super .onInitDialog();
0143:
0144: IWizardSheet parent = getParentSheet();
0145: m_Wizard = (Wizard) parent;
0146:
0147: populateGrid();
0148:
0149: return true; // return TRUE unless you set the focus to a control
0150: }
0151:
0152: /**
0153: * Called when the page becomes active
0154: *
0155: *
0156: *
0157: * @return BOOL
0158: */
0159: public void onSetActive() {
0160: if (m_Wizard != null) {
0161: populateGrid();
0162: }
0163: super .onSetActive();
0164: }
0165:
0166: /**
0167: * Populate the grid
0168: *
0169: * @return HRESULT
0170: */
0171: private void populateGrid() {
0172: m_Root = new JDefaultMutableTreeNode("Root");
0173: //
0174: // get the roles from the pattern details and have each one add itself
0175: //
0176: if (m_Wizard != null) {
0177: IDesignPatternDetails pDetails = m_Wizard.getDetails();
0178: if (pDetails != null) {
0179: ETList<IDesignPatternRole> pRoles = pDetails.getRoles();
0180: if (pRoles != null) {
0181: int count = pRoles.size();
0182: for (int x = 0; x < count; x++) {
0183: IDesignPatternRole pRole = pRoles.get(x);
0184: if (pRole != null) {
0185: if (!addRoleToGrid(pRole)) {
0186: break;
0187: }
0188: }
0189: }
0190: m_Model = null;
0191: m_Model = new RoleTreeTableModel(m_Root, this );
0192: m_Tree = null;
0193: m_Tree = new JRoleTreeTable(m_Model, this );
0194: FontMetrics metrics = m_Tree.getFontMetrics(m_Tree
0195: .getFont());
0196: m_Tree.setRowHeight(metrics.getHeight() + 6);
0197: m_Tree.getTree().setRootVisible(false);
0198: m_Tree.getAccessibleContext().setAccessibleName(
0199: DefaultDesignPatternResource
0200: .getString("ACSN_ROLETREE"));
0201: m_Tree
0202: .getAccessibleContext()
0203: .setAccessibleDescription(
0204: DefaultDesignPatternResource
0205: .getString("ACSD_ROLETREE"));
0206: m_Model.setTreeTable(m_Tree);
0207: int count2 = m_Model.getChildCount(m_Root);
0208: for (int i = count2 - 1; i >= 0; i--) {
0209: m_Model.expand(i, true);
0210: }
0211: prepareToShow();
0212: }
0213: }
0214: }
0215: }
0216:
0217: public void prepareToShow() {
0218: pnlContents.setLayout(new GridBagLayout());
0219: pnlContents.removeAll();
0220: if (m_Tree != null) {
0221: JScrollPane pane = new JScrollPane(m_Tree);
0222: GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
0223: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
0224: gridBagConstraints.weightx = 1.0;
0225: gridBagConstraints.weighty = 0.8;
0226: gridBagConstraints.gridx = 0;
0227: gridBagConstraints.gridy = 0;
0228: gridBagConstraints.insets = new Insets(12, 10, 12, 10);
0229: pnlContents.add(pane, gridBagConstraints);
0230: refresh();
0231: }
0232: }
0233:
0234: /**
0235: *
0236: */
0237: public void refresh() {
0238: Graphics g = this .getGraphics();
0239: if (g != null) {
0240: this .paintAll(g);
0241: }
0242: }
0243:
0244: /**
0245: * Called when the user clicks back
0246: *
0247: *
0248: *
0249: * @return LRESULT Whether or not to continue to the next page
0250: *
0251: */
0252: public void onWizardBack() {
0253:
0254: if (m_Wizard != null) {
0255: m_Wizard.m_RefreshPages = false;
0256: }
0257: super .onWizardBack();
0258: }
0259:
0260: /**
0261: * Called when the user clicks next
0262: *
0263: *
0264: *
0265: * @return LRESULT Whether or not to continue to the next page
0266: *
0267: */
0268: public void onWizardNext() {
0269: // store it on the pattern details
0270: if (storeParticipants()) {
0271: // validate the page information
0272: ETList<String> errorList = validatePage();
0273: if (errorList != null && errorList.size() == 0) {
0274: super .onWizardNext();
0275: } else if (errorList != null && errorList.size() > 0) {
0276: // display the errors
0277: String msg = DesignPatternUtilities
0278: .formatErrorMessage(errorList);
0279: DesignPatternUtilities.displayErrorMessage(m_Wizard,
0280: msg);
0281: }
0282: }
0283: }
0284:
0285: /**
0286: * Add the passed in design pattern role to the grid for display
0287: *
0288: * @param[in] pRole The object representing the role
0289: *
0290: * @return HRESULT
0291: */
0292: private boolean addRoleToGrid(IDesignPatternRole pRole) {
0293: boolean result = true;
0294: //
0295: // get the information from the role
0296: //
0297: if (pRole != null) {
0298: String roleName = pRole.getName();
0299: int mult = pRole.getMultiplicity();
0300: //
0301: // add the item to the grid
0302: //
0303: WizardRoleObject obj = new WizardRoleObject("", pRole);
0304: JDefaultMutableTreeNode node = new JDefaultMutableTreeNode(
0305: obj, true);
0306: m_Root.add(node);
0307: if (mult > 1) {
0308: // if the role has been designated having the ability to have more than one
0309: // participant fulfilling it, we will add the participants as child nodes
0310: result = addChildNodeForRole(node, pRole);
0311: } else {
0312: // the role can only be played by one participant, so figure out the name
0313: // and put it in the grid cell
0314: calculateName(node, obj);
0315: }
0316: }
0317: return result;
0318: }
0319:
0320: /**
0321: * Builds the maps used by the dialog. Used for performance reasons
0322: * to build the list of element names to display in the picklist for
0323: * a particular role (element type)
0324: *
0325: * @param[in] pRole The object representing the role
0326: *
0327: * @return HRESULT
0328: */
0329: private void buildRoleMaps(IDesignPatternRole pRole) {
0330: if (pRole != null) {
0331: Hashtable<String, Vector<String>> eleNameToIDMap = new Hashtable<String, Vector<String>>();
0332:
0333: String type = pRole.getTypeID();
0334: if (type == null || type.length() == 0) {
0335: type = "Classifier";
0336: }
0337: Hashtable ht = m_TypeMap.get(type);
0338: if (ht == null || type == null || type.length() == 0) {
0339: // otherwise, populate the combo list box of the grid cell with
0340: // similar element types of the role
0341: String pattern = "";
0342: if (type.equals("Classifier")) {
0343: pattern = "//*[name() = \'UML:Class\'";
0344: pattern += " or name() = \'UML:Activity\'";
0345: pattern += " or name() = \'UML:Actor\'";
0346: pattern += " or name() = \'UML:Aggregation\'";
0347: pattern += " or name() = \'UML:Artifact\'";
0348: pattern += " or name() = \'UML:Association\'";
0349: pattern += " or name() = \'UML:Collaboration\'";
0350: pattern += " or name() = \'UML:Component\'";
0351: pattern += " or name() = \'UML:DataType\'";
0352: pattern += " or name() = \'UML:Interface\'";
0353: pattern += " or name() = \'UML:Node\'";
0354: pattern += " or name() = \'UML:UseCase\'";
0355: pattern += "]";
0356: } else {
0357: pattern = "//UML:";
0358: pattern += type;
0359: }
0360: // get the names of the element's matching the type of the participant role
0361: if (m_Wizard != null) {
0362: IDesignPatternDetails pDetails = m_Wizard
0363: .getDetails();
0364: if (pDetails != null) {
0365: IProject pProject = pDetails.getProject();
0366: if (pProject != null) {
0367: ETList<String> pStrings = DesignPatternUtilities
0368: .getElementNames(pProject, pattern,
0369: false);
0370: ETList<String> pStrings2 = DesignPatternUtilities
0371: .getElementNames(pProject, pattern,
0372: true);
0373: if (pStrings != null) {
0374: // turn the names into a string that the grid knows about
0375: String formattedStr = formatElementNames(pStrings);
0376: // store what we found in the project in a map for fast lookup
0377: int count = pStrings.size();
0378: for (int x = 0; x < count; x++) {
0379: String str = pStrings.get(x);
0380: String id = pStrings2.get(x);
0381: if (id != null && id.length() > 0) {
0382: Vector<String> v = eleNameToIDMap
0383: .get(str);
0384: if (v == null) {
0385: v = new Vector<String>();
0386: }
0387: v.add(id);
0388: eleNameToIDMap.put(str, v);
0389: }
0390: }
0391: m_TypeMap.put(type, eleNameToIDMap);
0392: }
0393: }
0394: }
0395: }
0396: }
0397: }
0398: }
0399:
0400: /**
0401: * Adds another node to the grid representing the passed in role
0402: *
0403: * @param[in] row The row in which to add the new node to
0404: * @param[in] pRole The role that the new node will represent
0405: *
0406: * @return HRESULT
0407: */
0408: private boolean addChildNodeForRole(JDefaultMutableTreeNode node,
0409: IDesignPatternRole pRole) {
0410: boolean result = true;
0411: if (pRole != null) {
0412: // get the role name
0413: String roleName = pRole.getName();
0414: // get the role multiplicity
0415: int mult = pRole.getMultiplicity();
0416: // determine if we should add another role
0417: int children = node.getChildCount();
0418: if (children < mult) {
0419: // add a child node
0420: WizardRoleObject obj = new WizardRoleObject(roleName,
0421: pRole);
0422: JDefaultMutableTreeNode pnode = new JDefaultMutableTreeNode(
0423: obj, true);
0424: node.add(pnode);
0425: if (mult > 1) {
0426: // figure out the new name
0427: calculateName(pnode, obj);
0428: }
0429: } else {
0430: IErrorDialog pTemp = new SwingErrorDialog(m_Wizard);
0431: if (pTemp != null) {
0432: Integer i = new Integer(mult);
0433: String cstr = DesignPatternUtilities
0434: .translateString("IDS_INVALIDROLECOUNT");
0435: cstr = StringUtilities.replaceSubString(cstr, "%d",
0436: i.toString());
0437: String title = DesignPatternUtilities
0438: .translateString("IDS_TITLE1");
0439: pTemp.display(cstr,
0440: MessageIconKindEnum.EDIK_ICONINFORMATION,
0441: title);
0442: }
0443: }
0444: }
0445: return result;
0446: }
0447:
0448: /**
0449: * Remove the node in the grid at the passed in row
0450: *
0451: * @param[in] row The row which to remove
0452: *
0453: * @return HRESULT
0454: */
0455: private void removeChildNodeForRole(int row) {
0456: JDefaultMutableTreeNode pNode = getNodeAtGridRow(row);
0457: if (pNode != null) {
0458: JDefaultMutableTreeNode parentNode = (JDefaultMutableTreeNode) pNode
0459: .getParent();
0460: if (parentNode != null) {
0461: // if there is a parent of the node that was the current node
0462: // when the user hit the delete key
0463: // do not allow the user to delete all of the children, must
0464: // have at least one
0465: int cnt = parentNode.getChildCount();
0466: if (cnt > 1) {
0467: // get the node on the row in which they clicked
0468: // and remove it
0469: parentNode.remove(pNode);
0470: }
0471: }
0472: }
0473: }
0474:
0475: /**
0476: * While the user is assigning participants to roles, we figure out a default name
0477: * for the participant.
0478: *
0479: * @param[in] row Row where the name needs to be determined
0480: * @param[in] pRole Role of the participant whose name needs to be determined
0481: * @param[out] sName The calculated name
0482: *
0483: * @return HRESULT
0484: */
0485: public void calculateName(JDefaultMutableTreeNode node,
0486: WizardRoleObject pObj) {
0487: String sName = "";
0488: if (pObj != null) {
0489: IDesignPatternRole pRole = pObj.getRole();
0490: if (pRole != null) {
0491: // get some information from the role
0492: String roleID = pRole.getID();
0493: String roleName = pRole.getName();
0494: int mult = pRole.getMultiplicity();
0495: // default the calculated name to the role name
0496: if (mult > 1) {
0497: if (node.getParent() == null) {
0498: } else if (node.getParent().equals(m_Root)) {
0499: } else {
0500: sName = roleName;
0501: }
0502: } else {
0503: sName = roleName;
0504: }
0505: // now do some more work to determine the name
0506: // the first attempt will be to take the rolename and make
0507: // it unique based on the number of child nodes
0508: int children = 0;
0509: TreeNode parentNode = node.getParent();
0510: if (parentNode != null && !parentNode.equals(m_Root)) {
0511: // does this node have any children
0512: if (parentNode.getChildCount() > 1) {
0513: // yes, it has children, so take the number of children
0514: // and append it to the rolename, this will make the name
0515: // unique
0516: Integer i = new Integer(parentNode
0517: .getChildCount());
0518: sName += i.toString();
0519: }
0520: }
0521: // No matter what, the name is now either only the role name, or it is the
0522: // rolename with a number appended to it
0523:
0524: // This next case will set the name if there are already designated participants
0525: // so it will take the participant name and make it unique by adding a number
0526: IDesignPatternDetails pDetails = m_Wizard.getDetails();
0527: if (pDetails != null) {
0528: ETList<String> pNames = pDetails
0529: .getParticipantNames(roleID);
0530: if (pNames != null) {
0531: int count = pNames.size();
0532: if (count > 0) {
0533: String name2 = pNames.get(0);
0534: // this could be a name or an id, if it is an id, we need to transform it to
0535: // a name
0536: IProject pProject = pDetails.getProject();
0537: String pattern = "//*[@xmi.id=\"" + name2
0538: + "\"]";
0539: INamedElement pElement = getElement(
0540: pProject, pattern);
0541: if (pElement != null) {
0542: sName = pElement.getQualifiedName();
0543: pObj.setChosenID(name2);
0544: } else {
0545: sName = name2;
0546: }
0547: if (children > 1) {
0548: Integer i = new Integer(children);
0549: String buffer = i.toString();
0550: sName += buffer;
0551: }
0552: }
0553: }
0554: }
0555: }
0556: }
0557: pObj.setChosenName(sName);
0558: }
0559:
0560: /**
0561: * Turn the array of passed in strings into a format that the grid understands
0562: *
0563: * @param[in] pStrings An array of strings
0564: * @param[out] pStr A "|" concatenated string
0565: *
0566: * @return HRESULT
0567: */
0568: private String formatElementNames(ETList<String> pStrings) {
0569: String pStr = "";
0570: if (pStrings != null) {
0571: int count = pStrings.size();
0572: if (count > 0) {
0573: pStr += "|";
0574: }
0575: for (int x = 0; x < count; x++) {
0576: String str = pStrings.get(x);
0577: pStr += str;
0578: pStr += "|";
0579: }
0580: }
0581: return pStr;
0582: }
0583:
0584: /**
0585: * Get the element from the project that matches the pattern
0586: *
0587: *
0588: * @param pProject[in] The project to look in
0589: * @param pattern[in] The xpath query to use in the search
0590: * @param pElement[out] The found element
0591: *
0592: * @return HRESULT
0593: *
0594: */
0595: private INamedElement getElement(IProject pProject, String pattern) {
0596: INamedElement pElement = null;
0597: if (pProject != null) {
0598: // use the element locator to do this
0599: IElementLocator pLocator = new ElementLocator();
0600: if (pLocator != null) {
0601: // find any elements matching the xpath query
0602: ETList<IElement> pElements = pLocator
0603: .findElementsByDeepQuery(pProject, pattern);
0604: if (pElements != null) {
0605: // put one of them into the out param
0606: int count = pElements.size();
0607: for (int x = 0; x < count; x++) {
0608: IElement pEle = pElements.get(x);
0609: if (pEle != null) {
0610: if (pEle instanceof INamedElement) {
0611: pElement = (INamedElement) pEle;
0612: break;
0613: }
0614: }
0615: }
0616: }
0617: }
0618: }
0619: return pElement;
0620: }
0621:
0622: /**
0623: * Grid event - called before the grid cell enters edit mode
0624: *
0625: *
0626: * @param Row[in] The row of the grid cell
0627: * @param Col[in] The column of the grid cell
0628: * @param Cancel[out] Whether or not to cancel the edit
0629: *
0630: * @return
0631: */
0632: private void onBeforeEditGrid(int Row, int Col) {
0633: // See TreeTableCellEditor.getTableCellEditorComponent for
0634: // this code
0635: }
0636:
0637: /**
0638: * Grid event - called when the user clicks on the button that is displayed in the grid cell
0639: *
0640: *
0641: * @param Row[in] The row of the grid cell
0642: * @param Col[in] The column of the grid cell
0643: *
0644: * @return
0645: */
0646: public void onCellButtonClickGrid(int Row, int Col) {
0647: WizardRoleObject wro = getObjectAtGridRow(Row);
0648: if (wro != null) {
0649: IDesignPatternRole pRole = wro.getRole();
0650: JTree tree = m_Tree.getTree();
0651: TreePath path = tree.getPathForRow(Row);
0652: if (path != null) {
0653: Object obj = path.getLastPathComponent();
0654: if (obj instanceof JDefaultMutableTreeNode) {
0655: JDefaultMutableTreeNode node = (JDefaultMutableTreeNode) obj;
0656: addChildNodeForRole(node, pRole);
0657: refreshTree(node, Row);
0658: }
0659: }
0660: }
0661: }
0662:
0663: private void refreshTree(JDefaultMutableTreeNode node, int row) {
0664: m_Tree.getTree().updateUI();
0665: m_Model.expand(row, true);
0666: if (node != null) {
0667: node.setExpanded(true);
0668: int childCount = node.getChildCount();
0669: m_Model.expand(row + childCount, true);
0670: }
0671: }
0672:
0673: /**
0674: * Called when a cell is entered in the grid - grid event
0675: */
0676: private void onEnterCell() {
0677: // Not needed in java
0678: }
0679:
0680: /**
0681: * Called when a key is pressed in the grid - grid event
0682: *
0683: * @param[in] KeyAscii The key that was pressed
0684: * @param[in] Shift Whether the Shift key was down
0685: *
0686: * @return VOID
0687: *
0688: */
0689: private void onKeyDownGrid(/*short FAR* KeyAscii, short Shift*/) {
0690: /* TODO
0691: long row;
0692: _VH(m_Grid->get_Row(&row));
0693: // did they press the return key
0694: if (*KeyAscii == VK_RETURN)
0695: {
0696: // will want to expand or collapse the node accordingly
0697: CComPtr < IVSFlexNode > node;
0698: _VH(m_Grid->GetNode(CComVariant(row), &node));
0699: if (node)
0700: {
0701: CollapsedSettings is;
0702: _VH(m_Grid->get_IsCollapsed(row, &is));
0703: if (is == flexOutlineCollapsed)
0704: {
0705: _VH(node->put_Expanded(TRUE));
0706: }
0707: }
0708: }
0709: // did they press the left arrow key
0710: else if (*KeyAscii == VK_LEFT)
0711: {
0712: // yes, so collapse the grid node
0713: CComPtr < IVSFlexNode > node;
0714: _VH(m_Grid->GetNode(CComVariant(row), &node));
0715: if (node)
0716: {
0717: _VH(node->put_Expanded(FALSE));
0718: }
0719: }
0720: // did they press the right arrow key
0721: else if (*KeyAscii == VK_RIGHT)
0722: {
0723: // yes, so expand the grid node
0724: CComPtr < IVSFlexNode > node;
0725: _VH(m_Grid->GetNode(CComVariant(row), &node));
0726: if (node)
0727: {
0728: _VH(node->put_Expanded(TRUE));
0729: }
0730: }
0731: // did they press the insert key
0732: else if (*KeyAscii == VK_INSERT)
0733: {
0734: CComVariant pVar;
0735: _VH(m_Grid->get_Cell(flexcpData, CComVariant(row), CComVariant(0), vtMissing, vtMissing, &pVar));
0736: if (pVar.vt == VT_DISPATCH)
0737: {
0738: // get the role object that is hidden on the cell
0739: CComQIPtr < IDesignPatternRole > pRole( (pVar.pdispVal) );
0740: if (pRole)
0741: {
0742: // check multiplicity of role
0743: long mult;
0744: _VH(pRole->get_Multiplicity(&mult));
0745: if (mult > 1)
0746: {
0747: // role is a multiple
0748: long parentRow;
0749: m_Grid->GetNodeRow(row, flexNTRoot, &parentRow);
0750: if ( parentRow > -1 )
0751: {
0752: // so add a child node for it
0753: hr = AddChildNodeForRole(parentRow, pRole);
0754: }
0755: }
0756: }
0757: }
0758: }
0759: // did they press the delete key
0760: else if (*KeyAscii == VK_DELETE)
0761: {
0762: hr = RemoveChildNodeForRole(row);
0763: }
0764: else
0765: {
0766: }
0767: */
0768: }
0769:
0770: /**
0771: * Called when the create menu button is clicked
0772: *
0773: * @return
0774: */
0775: public void onPopupCreate(int curRow) {
0776: JDefaultMutableTreeNode node = getNodeAtGridRow(curRow);
0777: if (node != null) {
0778: // now get its parent
0779: JDefaultMutableTreeNode parentNode = (JDefaultMutableTreeNode) node
0780: .getParent();
0781: if (parentNode != null) {
0782: if (parentNode.getParent() == null) {
0783: onCellButtonClickGrid(curRow, 1);
0784: } else {
0785: int parentRow = parentNode.getRow();
0786: onCellButtonClickGrid(parentRow - 1, 1);
0787: }
0788: }
0789: }
0790:
0791: updateUI();
0792: }
0793:
0794: /**
0795: * Called when the delete menu button is clicked
0796: *
0797: * @return
0798: */
0799: public void onPopupDelete(int row) {
0800: removeChildNodeForRole(row);
0801: JTree tree = m_Tree.getTree();
0802: TreePath path = tree.getPathForRow(row);
0803: if (path != null) {
0804: Object obj = path.getLastPathComponent();
0805: if (obj instanceof JDefaultMutableTreeNode) {
0806: JDefaultMutableTreeNode node = (JDefaultMutableTreeNode) obj;
0807: refreshTree(node, row);
0808: }
0809: }
0810:
0811: updateUI();
0812: }
0813:
0814: /**
0815: * Called when the rename menu button is clicked
0816: *
0817: * @return
0818: */
0819: public void onPopupRename(int row) {
0820: m_Tree.editCellAt(row, 2);
0821: }
0822:
0823: /**
0824: * Called before the mouse click is registered with the grid - grid event
0825: *
0826: * @param[in] Button
0827: * @param[in] Shift
0828: * @param[in] X
0829: * @param[in] Y
0830: * @param Cancel
0831: *
0832: * @return VOID
0833: *
0834: */
0835: private void onBeforeMouseDownGrid(/*short Button, short Shift, float X, float Y, BOOL FAR* Cancel */) {
0836: // See show menu for c++ functionality
0837: }
0838:
0839: public ETList<String> showMenu(int row) {
0840: ETList<String> pStrs = new ETArrayList<String>();
0841: // figure out which menu to display
0842: // if on a single row, just display Rename
0843: // if on a row that can have multiple children, display create
0844: // if on a row that is a child of a multiple, display create, delete and rename
0845: boolean isMult = isMultipleParticipant(row);
0846: boolean isMultInst = isMultipleParticipantInstance(row);
0847: String createStr = DefaultDesignPatternResource
0848: .getString("IDS_CREATE");
0849: String delStr = DefaultDesignPatternResource
0850: .getString("IDS_DELETE");
0851: String renStr = DefaultDesignPatternResource
0852: .getString("IDS_RENAME");
0853: if (isMult) {
0854: pStrs.add(createStr);
0855: } else if (isMultInst) {
0856: pStrs.add(createStr);
0857: pStrs.add(delStr);
0858: //pStrs.add(renStr);
0859: } else {
0860: //pStrs.add(renStr);
0861: }
0862: return pStrs;
0863: }
0864:
0865: /**
0866: * Returns list of supported key events
0867: * @param row row number
0868: * @return ETList of supported key events.
0869: */
0870: public ETList<Integer> handleKeys(int row) {
0871: ETList<Integer> pKeys = new ETArrayList<Integer>();
0872: // figure out which key event should be handled
0873: // if on a row that can have multiple children, handle INSERT
0874: // if on a row that is a child of a multiple, handle INSERT and DELETE
0875: boolean isMult = isMultipleParticipant(row);
0876: boolean isMultInst = isMultipleParticipantInstance(row);
0877: if (isMult) {
0878: pKeys.add(new Integer(java.awt.event.KeyEvent.VK_INSERT));
0879: } else if (isMultInst) {
0880: pKeys.add(new Integer(java.awt.event.KeyEvent.VK_INSERT));
0881: pKeys.add(new Integer(java.awt.event.KeyEvent.VK_DELETE));
0882: }
0883: return pKeys;
0884: }
0885:
0886: /**
0887: * Grid event when something in the combo list changes
0888: *
0889: *
0890: *
0891: * @return
0892: *
0893: */
0894: private void onChangeEditGrid() {
0895: // Handled by JRoleTextField and JRoleComboBox and getIDForElementNamed
0896: }
0897:
0898: public String getIDForElementNamed(String name, WizardRoleObject obj) {
0899: String str = "";
0900: if (obj != null) {
0901: IDesignPatternRole pRole = obj.getRole();
0902: if (pRole != null) {
0903: // need to loop through the TypeMap's name-to-id map
0904: // and find this value
0905: // if found, store the id of what was found in the hidden column
0906: // to be used later to populate the pattern details
0907: //
0908: String type = pRole.getTypeID();
0909: if (type == null || type.length() == 0) {
0910: type = "Classifier";
0911: }
0912: Hashtable ht = m_TypeMap.get(type);
0913: if (ht != null) {
0914: Object nameObj = ht.get(name);
0915: if (nameObj != null) {
0916: Vector names = (Vector) nameObj;
0917: if (names != null && names.size() > 0) {
0918: Object strObj = names.get(0);
0919: if (strObj instanceof String) {
0920: str = (String) strObj;
0921: }
0922: }
0923: }
0924: }
0925: }
0926: }
0927: return str;
0928: }
0929:
0930: /**
0931: * Determines whether or not the role at the passed in role can have multiple
0932: * participants associated with it
0933: *
0934: *
0935: * @param row[in] The row to process
0936: * @param bMult[out] Whether or not the role can have multiple participants
0937: *
0938: * @return HRESULT
0939: *
0940: */
0941: private boolean isMultipleParticipant(int row) {
0942: boolean bMult = false;
0943: WizardRoleObject pObj = getObjectAtGridRow(row);
0944: if (pObj != null) {
0945: IDesignPatternRole pRole = pObj.getRole();
0946: if (pRole != null) {
0947: JDefaultMutableTreeNode pNode = getNodeAtGridRow(row);
0948: if (pNode != null) {
0949: // trying to determine if we can add to this row or not, default is no
0950: int mult = pRole.getMultiplicity();
0951: if ((mult > 1) && pNode.getParent().equals(m_Root)) {
0952: bMult = true;
0953: }
0954: }
0955: }
0956: }
0957: return bMult;
0958: }
0959:
0960: /**
0961: * Determines whether or not the role at the passed in role is a participant of a multiple
0962: * participant role
0963: *
0964: *
0965: * @param row[in] The row to process
0966: * @param bMult[out] Whether or not the role is a multiple participant
0967: *
0968: * @return HRESULT
0969: *
0970: */
0971: private boolean isMultipleParticipantInstance(int row) {
0972: boolean bMult = false;
0973: WizardRoleObject pObj = getObjectAtGridRow(row);
0974: if (pObj != null) {
0975: // if it is a role
0976: IDesignPatternRole pRole = pObj.getRole();
0977: if (pRole != null) {
0978: JDefaultMutableTreeNode pNode = getNodeAtGridRow(row);
0979: if (pNode != null) {
0980: // trying to determine if we can add to this row or not, default is no
0981: int mult = pRole.getMultiplicity();
0982: if ((mult > 1)
0983: && (!(pNode.getParent().equals(m_Root)))) {
0984: bMult = true;
0985: }
0986: }
0987: }
0988: }
0989: return bMult;
0990: }
0991:
0992: /**
0993: * Performs page validations -
0994: *
0995: *
0996: * @param errList[out] An array of errors that occurred on the page
0997: *
0998: * @return HRESULT
0999: *
1000: */
1001: private ETList<String> validatePage() {
1002: ETList<String> tempList = new ETArrayList<String>();
1003: if (m_Wizard != null) {
1004: IDesignPatternDetails pDetails = m_Wizard.getDetails();
1005: if (pDetails != null) {
1006: IDesignPatternManager pManager = m_Wizard.getManager();
1007: if (pManager != null) {
1008: pManager.setDetails(pDetails);
1009: int hr = pManager.validatePattern(pDetails);
1010: if (hr == -1) {
1011: } else {
1012: String msg = DesignPatternUtilities
1013: .translateString("IDS_MISSINGPARTICIPANT");
1014: tempList.add(msg);
1015: }
1016: }
1017: }
1018: }
1019: return tempList;
1020: }
1021:
1022: /**
1023: * Store the participant information from the GUI
1024: *
1025: * @return bool
1026: */
1027: private boolean storeParticipants() {
1028: boolean result = true;
1029: if (m_Wizard != null) {
1030: IDesignPatternDetails pDetails = m_Wizard.getDetails();
1031: if (pDetails != null) {
1032: pDetails.clearParticipantNames();
1033: // loop through the participant grid
1034: int count = m_Tree.getRowCount();
1035: for (int i = 0; i < count; i++) {
1036: // get the data from the cell on each row
1037: WizardRoleObject pObj = getObjectAtGridRow(i);
1038: if (pObj != null) {
1039: IDesignPatternRole pRole = pObj.getRole();
1040: if (pRole != null) {
1041: // store the roleID and the participant name on the details
1042: // for processing the apply pattern logic
1043: String roleID = pRole.getID();
1044: String part = pObj.getChosenName();
1045: String id = pObj.getChosenID();
1046: if (id != null && id.length() > 0) {
1047: // if an id has been set, use it
1048: // it would have been set by the user going into edit mode in a text field
1049: // or picking something from the combo box
1050: pDetails.addParticipantName(roleID, id);
1051: } else {
1052: if (part != null && part.length() > 0) {
1053: // do one more check to see if the name that is chosen exists in the system
1054: // because otherwise we were creating duplicate elements
1055: //buildRoleMap(pRole);
1056: //String name = getIDForElementNamed(part, pObj);
1057: //if (name != null && name.length() > 0)
1058: //{
1059: // pDetails.addParticipantName(roleID, name);
1060: //}
1061: //else
1062: //{
1063: pDetails.addParticipantName(roleID,
1064: part);
1065: //}
1066: }
1067: }
1068: }
1069: }
1070: }
1071: }
1072: }
1073: return result;
1074: }
1075:
1076: private void setPicture(IDesignPatternRole pRole, int row) {
1077: if (pRole != null) {
1078: // add the icon to the role
1079: String type = "PartFacade";
1080: String typeID = pRole.getTypeID();
1081: type += typeID;
1082: Icon hicon = m_ResourceMgr.getIconForElementType(type);
1083: if (hicon != null) {
1084: /* TODO
1085: CPictureHolder pic;
1086: pic.CreateFromIcon(hicon, FALSE);
1087: LPDISPATCH pPic = pic.GetPictureDispatch();
1088: CComVariant vpic(pPic);
1089: m_Grid->put_Cell(flexcpPicture, CComVariant(row), CComVariant(0), vtMissing, vtMissing, vpic);
1090: pPic->Release();
1091: ::DestroyIcon( hicon );
1092: */
1093: }
1094: }
1095: }
1096:
1097: public String buildRoleMap(IDesignPatternRole pRole) {
1098: String str = "";
1099: if (pRole != null) {
1100: String type = pRole.getTypeID();
1101: if (type == null || type.length() == 0) {
1102: type = "Classifier";
1103: }
1104: Hashtable ht = m_TypeMap.get(type);
1105: if (ht == null) {
1106: DesignPatternUtilities.startWaitCursor(m_Tree);
1107: buildRoleMaps(pRole);
1108: DesignPatternUtilities.endWaitCursor(m_Tree);
1109: }
1110: ht = m_TypeMap.get(type);
1111: if (ht != null) {
1112: Enumeration e = ht.keys();
1113: while (e.hasMoreElements()) {
1114: Object obj = e.nextElement();
1115: String s = (String) obj;
1116: str += "|";
1117: str += s;
1118: }
1119: }
1120: }
1121: return str;
1122: }
1123:
1124: /**
1125: * Shortcut method to retrieve the data from the grid cell which is in the form of a WizardRoleObject
1126: *
1127: * @param[in] row The row to retrieve the property element from
1128: * @param[out] pEle The found WizardRoleObject
1129: *
1130: * @return HRESULT
1131: *
1132: */
1133: public WizardRoleObject getObjectAtGridRow(int row) {
1134: WizardRoleObject retEle = null;
1135: JTree tree = m_Tree.getTree();
1136: TreePath path = tree.getPathForRow(row);
1137: if (path != null) {
1138: Object obj = path.getLastPathComponent();
1139: if (obj instanceof JDefaultMutableTreeNode) {
1140: JDefaultMutableTreeNode node = (JDefaultMutableTreeNode) obj;
1141: retEle = (WizardRoleObject) node.getUserObject();
1142: }
1143: }
1144: return retEle;
1145: }
1146:
1147: public JDefaultMutableTreeNode getNodeAtGridRow(int row) {
1148: JDefaultMutableTreeNode retNode = null;
1149:
1150: if (row >= 0 && m_Tree != null) {
1151: JTree tree = m_Tree.getTree();
1152: TreePath path = tree.getPathForRow(row);
1153: if (path != null) {
1154: Object obj = path.getLastPathComponent();
1155: if (obj instanceof JDefaultMutableTreeNode) {
1156: retNode = (JDefaultMutableTreeNode) obj;
1157: }
1158: }
1159: }
1160: return retNode;
1161: }
1162:
1163: public void setRightClickRow(int newRow) {
1164: m_RightClickRow = newRow;
1165: }
1166:
1167: }
|