001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.visualweb.web.ui.dt.component;
042:
043: import com.sun.rave.designtime.DesignBean;
044: import com.sun.rave.designtime.DesignProperty;
045: import com.sun.rave.designtime.Result;
046: import com.sun.rave.designtime.faces.FacesDesignBean;
047: import com.sun.rave.designtime.faces.FacesDesignContext;
048: import com.sun.rave.designtime.markup.BasicMarkupMouseRegion;
049: import com.sun.rave.designtime.markup.MarkupDesignBean;
050: import com.sun.rave.designtime.markup.MarkupDesignInfo;
051: import com.sun.rave.designtime.markup.MarkupMouseRegion;
052: import com.sun.rave.designtime.markup.MarkupPosition;
053: import com.sun.rave.designtime.markup.MarkupRenderContext;
054: import com.sun.rave.web.ui.component.ImageComponent;
055: import com.sun.rave.web.ui.component.TreeNode;
056: import org.netbeans.modules.visualweb.web.ui.dt.AbstractDesignInfo;
057: import org.netbeans.modules.visualweb.web.ui.dt.component.util.DesignUtil;
058: import javax.faces.component.UIGraphic;
059:
060: import org.w3c.dom.DocumentFragment;
061: import org.w3c.dom.Element;
062: import org.w3c.dom.Node;
063: import org.w3c.dom.NodeList;
064:
065: /**
066: * Design time behavior for a <code>TreeNode</code> component.
067: *
068: * @author gjmurphy
069: * @author Edwin Goei
070: */
071:
072: public class TreeNodeDesignInfo extends AbstractDesignInfo implements
073: MarkupDesignInfo {
074:
075: /** Name of the image facet */
076: private static final String IMAGE_FACET = "image"; //NOI18N
077:
078: /** Name of the content facet */
079: private static final String CONTENT_FACET = "content"; //NOI18N
080:
081: /** Name of theme icon for external tree nodes */
082: private static final String TREE_DOCUMENT_ICON = "TREE_DOCUMENT"; //NOI18N
083:
084: /** Name of theme icon for internal tree nodes */
085: private static final String TREE_FOLDER_ICON = "TREE_FOLDER"; //NOI18N
086:
087: public TreeNodeDesignInfo() {
088: super (TreeNode.class);
089: }
090:
091: protected DesignProperty getDefaultBindingProperty(
092: DesignBean targetBean) {
093: return targetBean.getProperty("text"); //NOI18N
094: }
095:
096: public boolean acceptParent(DesignBean parentBean,
097: DesignBean childBean, Class childClass) {
098: Class parentClass = parentBean.getInstance().getClass();
099: if (TreeNode.class.isAssignableFrom(parentClass))
100: return true;
101: return false;
102: }
103:
104: public boolean acceptChild(DesignBean parentBean,
105: DesignBean childBean, Class childClass) {
106: if (childClass.equals(TreeNode.class)
107: || UIGraphic.class.isAssignableFrom(childClass))
108: return true;
109: return false;
110: }
111:
112: public Result beanCreatedSetup(DesignBean bean) {
113: DesignProperty prop;
114:
115: // Set a default display name for the text node
116: String suffix = DesignUtil.getNumericalSuffix(bean
117: .getInstanceName());
118: String displayName = bean.getBeanInfo().getBeanDescriptor()
119: .getDisplayName();
120: bean.getProperty("text").setValue(displayName + " " + suffix); //NOI18N
121:
122: // Add an image component to the image facet, set by default to display
123: // the theme icon for tree nodes
124: FacesDesignContext fdc = (FacesDesignContext) bean
125: .getDesignContext();
126: String imageComponentName = ImageComponent.class.getName();
127: if (fdc.canCreateFacet(IMAGE_FACET, imageComponentName, bean)) {
128: DesignBean imageFacet = fdc.createFacet(IMAGE_FACET,
129: imageComponentName, bean);
130: imageFacet.getProperty("icon").setValue(TREE_DOCUMENT_ICON); //NOI18N
131: } else {
132: return Result.FAILURE;
133: }
134:
135: // If parent componet is a tree node, make it expanded. Also, if it has
136: // an image facet, and the facet's component's icon is set to the document
137: // icon, change it to folder.
138: DesignBean parent = bean.getBeanParent();
139: if (parent.getInstance().getClass().equals(TreeNode.class)) {
140: parent.getProperty("expanded").setValue(Boolean.TRUE); //NOI18N
141: DesignBean imageFacet = ((FacesDesignBean) parent)
142: .getFacet(IMAGE_FACET);
143: if (imageFacet != null
144: && imageFacet.getInstance().getClass().equals(
145: ImageComponent.class)) {
146: DesignProperty iconProperty = imageFacet
147: .getProperty("icon"); //NOI18N
148: if (iconProperty.getValue() != null
149: && iconProperty.getValue().equals(
150: TREE_DOCUMENT_ICON))
151: iconProperty.setValue(TREE_FOLDER_ICON);
152: }
153: }
154:
155: return Result.SUCCESS;
156: }
157:
158: public void customizeRender(final MarkupDesignBean bean,
159: MarkupRenderContext renderContext) {
160:
161: DocumentFragment documentFragment = renderContext
162: .getDocumentFragment();
163: MarkupPosition begin = renderContext.getBeginPosition();
164: MarkupPosition end = renderContext.getEndPosition();
165: if (begin == end)
166: return;
167:
168: // Look for div element that wraps the image and hyperlink which implement
169: // the tree node toggle widget (./div[@class='TreeRow']/div[@class='float'])
170: Node this Node = begin.getBeforeSibling();
171: Node lastNode = end.getBeforeSibling();
172: Element div = null;
173: while (this Node != lastNode && div == null) {
174: if (this Node instanceof Element) {
175: Element e = (Element) this Node;
176: if (e.getLocalName().equals("div")
177: && e.getAttribute("class") != null
178: && e.getAttribute("class").indexOf("TreeRow") != -1)
179: div = e;
180: }
181: this Node = this Node.getNextSibling();
182: }
183: if (div == null)
184: return;
185: NodeList nodeList = div.getElementsByTagName("div");
186: div = null;
187: for (int i = 0; i < nodeList.getLength(); i++) {
188: Element e = (Element) nodeList.item(i);
189: if (e.getAttribute("class") != null
190: && e.getAttribute("class").indexOf("float") != -1)
191: div = e;
192: }
193: if (div == null)
194: return;
195:
196: // Associate a markup mouse region with the tree node toggle markup, which
197: // expands or contracts the node when clicked
198: MarkupMouseRegion region = new BasicMarkupMouseRegion() {
199:
200: public boolean isClickable() {
201: return true;
202: }
203:
204: public Result regionClicked(int clickCount) {
205: DesignProperty property = bean.getProperty("expanded"); // NOI18N
206: property.setValue(property.getValue().equals(
207: Boolean.TRUE) ? Boolean.FALSE : Boolean.TRUE);
208: return Result.SUCCESS;
209: }
210: };
211:
212: renderContext.associateMouseRegion(div, region);
213: }
214:
215: public Result beanDeletedCleanup(DesignBean bean) {
216: // If parent component is a tree node, it has an image facet, and it's
217: // image facet's icon is set to the folder icon, and this is its only
218: // child, change icon to document icon
219: DesignBean parent = bean.getBeanParent();
220: if (parent.getInstance().getClass().equals(TreeNode.class)
221: && parent.getChildBeanCount() == 1) {
222: DesignBean imageFacet = ((FacesDesignBean) parent)
223: .getFacet(IMAGE_FACET);
224: if (imageFacet != null
225: && imageFacet.getInstance().getClass().equals(
226: ImageComponent.class)) {
227: DesignProperty iconProperty = imageFacet
228: .getProperty("icon"); //NOI18N
229: if (iconProperty.getValue() != null
230: && iconProperty.getValue().equals(
231: TREE_FOLDER_ICON))
232: iconProperty.setValue(TREE_DOCUMENT_ICON);
233: }
234: }
235: return Result.SUCCESS;
236: }
237:
238: }
|