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-2006 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:
042: package org.netbeans.modules.form;
043:
044: import java.awt.datatransfer.Transferable;
045: import java.util.ArrayList;
046: import java.util.LinkedList;
047: import java.util.List;
048: import javax.swing.Action;
049: import org.openide.nodes.*;
050: import org.openide.util.actions.SystemAction;
051:
052: import org.netbeans.modules.form.actions.*;
053: import org.openide.actions.PasteAction;
054: import org.openide.actions.ReorderAction;
055: import org.openide.util.datatransfer.PasteType;
056:
057: /**
058: * This class represents the root node of the form (displayed as root in
059: * Component Inspector).
060: *
061: * @author Tomas Pavek
062: */
063:
064: class FormRootNode extends FormNode {
065: private Node.Property[] codeGenProperties;
066: private Node.Property[] resourceProperties;
067: private Node.Property[] allProperties;
068:
069: public FormRootNode(FormModel formModel) {
070: super (new RootChildren(formModel), formModel);
071: setName("Form Root Node"); // NOI18N
072: setIconBaseWithExtension("org/netbeans/modules/form/resources/formDesigner.gif"); // NOI18N
073: updateName(formModel.getName());
074: }
075:
076: // TODO: icons for visual and non-visual forms
077: // public Image getIcon(int iconType) {
078: // }
079:
080: @Override
081: public boolean canRename() {
082: return false;
083: }
084:
085: @Override
086: public boolean canDestroy() {
087: return false;
088: }
089:
090: @Override
091: public Action[] getActions(boolean context) {
092: if (actions == null) { // from AbstractNode
093: List<Action> l = new ArrayList<Action>();
094: if (isModifiableContainer()) {
095: l.add(SystemAction.get(AddAction.class));
096: l.add(null);
097: l.add(SystemAction.get(PasteAction.class));
098: l.add(null);
099: l.add(SystemAction.get(ReorderAction.class));
100: l.add(null);
101: }
102: l.add(SystemAction.get(ReloadAction.class));
103: l.add(null);
104: for (Action a : super .getActions(context)) {
105: l.add(a);
106: }
107: actions = l.toArray(new Action[l.size()]);
108: }
109: return actions;
110: }
111:
112: void updateName(String name) {
113: setDisplayName(FormUtils.getFormattedBundleString(
114: "FMT_FormNodeName", // NOI18N
115: new Object[] { name }));
116: }
117:
118: FormOthersNode getOthersNode() {
119: return ((RootChildren) getChildren()).othersNode;
120: }
121:
122: @Override
123: public Node.PropertySet[] getPropertySets() {
124: Node.PropertySet codeSet = new Node.PropertySet(
125: "codeGeneration", // NOI18N
126: FormUtils.getBundleString("CTL_SyntheticTab"), // NOI18N
127: FormUtils.getBundleString("CTL_SyntheticTabHint")) // NOI18N
128: {
129: public Node.Property[] getProperties() {
130: return getCodeGenProperties();
131: }
132: };
133: Node.PropertySet resourceSet = new Node.PropertySet(
134: "resources", // NOI18N
135: FormUtils.getBundleString("CTL_ResourceTab"), // NOI18N
136: FormUtils.getBundleString("CTL_ResourceTabHint")) // NOI18N
137: {
138: public Node.Property[] getProperties() {
139: return getResourceProperties();
140: }
141: };
142: return new Node.PropertySet[] { codeSet, resourceSet };
143: }
144:
145: Node.Property[] getCodeGenProperties() {
146: if (codeGenProperties == null)
147: codeGenProperties = createCodeGenProperties();
148: return codeGenProperties;
149: }
150:
151: private Node.Property[] createCodeGenProperties() {
152: return FormEditor.getCodeGenerator(getFormModel())
153: .getSyntheticProperties(null);
154: }
155:
156: Node.Property[] getResourceProperties() {
157: if (resourceProperties == null)
158: resourceProperties = createResourceProperties();
159: return resourceProperties;
160: }
161:
162: private Node.Property[] createResourceProperties() {
163: return FormEditor.getResourceSupport(getFormModel())
164: .createFormProperties();
165: }
166:
167: Node.Property[] getAllProperties() {
168: if (allProperties == null) {
169: int codeGenCount = getCodeGenProperties().length;
170: int resCount = getResourceProperties().length;
171: allProperties = new Node.Property[codeGenCount + resCount];
172: System.arraycopy(codeGenProperties, 0, allProperties, 0,
173: codeGenCount);
174: System.arraycopy(resourceProperties, 0, allProperties,
175: codeGenCount, resCount);
176: }
177: return allProperties;
178: }
179:
180: @Override
181: protected void createPasteTypes(Transferable t,
182: java.util.List<PasteType> s) {
183: if (isModifiableContainer()) {
184: CopySupport.createPasteTypes(t, s, getFormModel(), null);
185: }
186: }
187:
188: /**
189: * Returns whether "other components" can be added under this node (i.e.
190: * there is no Other Components node, the components appear directly under
191: * root node).
192: */
193: private boolean isModifiableContainer() {
194: return !getFormModel().isReadOnly()
195: && !shouldHaveOthersNode(getFormModel());
196: }
197:
198: /**
199: * Returns true if the Other Components node should be used, or false if all
200: * the "other" components should be shown directly under the root node. The
201: * latter is the case when the root component either does not exists (the
202: * form class extends Object) or if it is not a visual container. Here all
203: * the components can be presented on the same level. OTOH if the root
204: * component is a visual container (e.g. extends JPanel or JFrame), then it
205: * has its hierarchy (the node can be expanded) and it seems better to have
206: * the other components presented separately under Other Components node.
207: */
208: private static boolean shouldHaveOthersNode(FormModel formModel) {
209: return formModel.getTopRADComponent() instanceof RADVisualContainer;
210: }
211:
212: // ----------------
213:
214: /**
215: * The children nodes of the root node can have 3 variants:
216: */
217: static class RootChildren extends FormNodeChildren {
218:
219: static final Object OTHERS_ROOT = new Object();
220:
221: private FormModel formModel;
222: private FormOthersNode othersNode;
223:
224: protected RootChildren(FormModel formModel) {
225: this .formModel = formModel;
226: updateKeys();
227: }
228:
229: // FormNodeChildren implementation
230: @Override
231: protected void updateKeys() {
232: othersNode = null;
233:
234: List<Object> keys = new LinkedList<Object>();
235: boolean otherComps = shouldHaveOthersNode(formModel);
236: if (otherComps) {
237: keys.add(OTHERS_ROOT);
238: }
239: RADComponent rootComp = formModel.getTopRADComponent();
240: if (rootComp != null) {
241: keys.add(rootComp);
242: }
243: if (!otherComps) {
244: keys.addAll(formModel.getOtherComponents());
245: }
246: setKeys(keys.toArray());
247: }
248:
249: protected Node[] createNodes(Object key) {
250: Node node;
251: if (key == OTHERS_ROOT) {
252: node = othersNode = new FormOthersNode(formModel);
253: } else {
254: node = new RADComponentNode((RADComponent) key);
255: }
256: node.getChildren().getNodes(); // enforce subnodes creation
257: return new Node[] { node };
258: }
259:
260: protected final FormModel getFormModel() {
261: return formModel;
262: }
263: }
264:
265: }
|