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.palette;
043:
044: import java.awt.Image;
045: import java.awt.datatransfer.DataFlavor;
046: import java.awt.datatransfer.Transferable;
047: import java.awt.datatransfer.UnsupportedFlavorException;
048: import java.beans.BeanInfo;
049: import java.io.IOException;
050: import java.net.URL;
051: import java.util.ArrayList;
052: import java.util.logging.Level;
053: import java.util.logging.Logger;
054: import javax.imageio.ImageIO;
055: import org.openide.loaders.DataNode;
056: import org.openide.loaders.DataObject;
057: import org.openide.nodes.FilterNode;
058: import org.openide.nodes.Node;
059: import org.openide.text.ActiveEditorDrop;
060: import org.openide.util.HelpCtx;
061: import org.openide.util.Lookup;
062: import org.openide.util.NbBundle;
063: import org.openide.util.Utilities;
064: import org.openide.util.datatransfer.ExTransferable;
065: import org.openide.util.lookup.AbstractLookup;
066: import org.openide.util.lookup.InstanceContent;
067:
068: /**
069: *
070: * @author Libor Kotouc
071: */
072: public final class PaletteItemNode extends FilterNode implements
073: Node.Cookie {
074:
075: private static final Node.PropertySet[] NO_PROPERTIES = new Node.PropertySet[0];
076:
077: private String name;
078: private String bundleName;
079: private String displayNameKey;
080: private String className;
081: private String tooltipKey;
082: private String icon16URL;
083: private String icon32URL;
084:
085: private String displayName;
086: private String description;
087: private Image icon16;
088: private Image icon32;
089:
090: PaletteItemNode(DataNode original, String name, String bundleName,
091: String displayNameKey, String className, String tooltipKey,
092: String icon16URL, String icon32URL, InstanceContent content) {
093: super (original, Children.LEAF, new AbstractLookup(content));
094:
095: content.add(this );
096: DataObject dob = original.getCookie(DataObject.class);
097: if (null != dob)
098: content.add(dob);
099: this .name = name;
100: this .bundleName = bundleName;
101: this .displayNameKey = displayNameKey;
102: this .className = className;
103: this .tooltipKey = tooltipKey;
104: this .icon16URL = icon16URL;
105: this .icon32URL = icon32URL;
106: }
107:
108: PaletteItemNode(DataNode original, String name, String displayName,
109: String tooltip, String icon16URL, String icon32URL,
110: InstanceContent content) {
111: super (original, Children.LEAF, new AbstractLookup(content));
112:
113: content.add(this );
114: DataObject dob = original.getCookie(DataObject.class);
115: if (null != dob)
116: content.add(dob);
117: this .name = name;
118: this .bundleName = bundleName;
119: assert null != displayName;
120: this .displayName = displayName;
121: this .description = tooltip;
122: if (null == this .description)
123: description = displayName;
124: this .icon16URL = icon16URL;
125: this .icon32URL = icon32URL;
126: }
127:
128: public String getName() {
129: return name;
130: }
131:
132: public String getDisplayName() {
133: if (displayName == null)
134: displayName = _getDisplayName(bundleName, displayNameKey,
135: className);
136:
137: return displayName;
138: }
139:
140: public String getShortDescription() {
141: if (description == null)
142: description = _getShortDescription(bundleName, tooltipKey,
143: className, displayNameKey);
144:
145: return description;
146: }
147:
148: public Image getIcon(int type) {
149:
150: Image icon = null;
151:
152: if (type == BeanInfo.ICON_COLOR_16x16
153: || type == BeanInfo.ICON_MONO_16x16) {
154: if (icon16 == null) {
155: icon16 = _getIcon(icon16URL);
156: if (icon16 == null)
157: icon16 = Utilities
158: .loadImage("org/netbeans/modules/palette/resources/unknown16.gif"); // NOI18N
159: }
160: icon = icon16;
161: } else if (type == BeanInfo.ICON_COLOR_32x32
162: || type == BeanInfo.ICON_MONO_32x32) {
163: if (icon32 == null) {
164: icon32 = _getIcon(icon32URL);
165: if (icon32 == null)
166: icon32 = Utilities
167: .loadImage("org/netbeans/modules/palette/resources/unknown32.gif"); // NOI18N
168: }
169: icon = icon32;
170: }
171:
172: return icon;
173: }
174:
175: public boolean canRename() {
176: return false;
177: }
178:
179: // TODO properties
180: public Node.PropertySet[] getPropertySets() {
181: return NO_PROPERTIES;
182: }
183:
184: public Transferable clipboardCopy() throws IOException {
185:
186: ExTransferable t = ExTransferable.create(super .clipboardCopy());
187:
188: Lookup lookup = getLookup();
189: ActiveEditorDrop drop = (ActiveEditorDrop) lookup
190: .lookup(ActiveEditorDrop.class);
191: ActiveEditorDropTransferable s = new ActiveEditorDropTransferable(
192: drop);
193: t.put(s);
194:
195: //do not allow external DnD flavors otherwise some items may get interpreted
196: //as an external file dropped into the editor window
197: return new NoExternalDndTransferable(t);
198: }
199:
200: public Transferable drag() throws IOException {
201: return clipboardCopy();
202: }
203:
204: private static class ActiveEditorDropTransferable extends
205: ExTransferable.Single {
206:
207: private ActiveEditorDrop drop;
208:
209: ActiveEditorDropTransferable(ActiveEditorDrop drop) {
210: super (ActiveEditorDrop.FLAVOR);
211:
212: this .drop = drop;
213: }
214:
215: public Object getData() {
216: return drop;
217: }
218:
219: }
220:
221: public String _getDisplayName(String bundleName,
222: String displayNameKey, String instanceName) {
223:
224: String displayName = null;
225: try {
226: displayName = NbBundle.getBundle(bundleName).getString(
227: displayNameKey);
228:
229: if (displayName == null && displayNameKey != null)
230: displayName = displayNameKey;
231:
232: if (displayName == null) {//derive name from the instance name
233: if (instanceName != null
234: && instanceName.trim().length() > 0) {
235: int dotIndex = instanceName.lastIndexOf('.'); // NOI18N
236: displayName = instanceName.substring(dotIndex);
237: }
238: }
239:
240: if (displayName == null) // no name derived from the item
241: displayName = name;
242:
243: } catch (Exception ex) {
244: Logger.getLogger(getClass().getName()).log(Level.INFO,
245: null, ex);
246: }
247:
248: return (displayName == null ? "" : displayName);
249: }
250:
251: public String _getShortDescription(String bundleName,
252: String tooltipKey, String instanceName,
253: String displayNameKey) {
254:
255: String tooltip = null;
256: try {
257: tooltip = NbBundle.getBundle(bundleName).getString(
258: tooltipKey);
259:
260: if (tooltip == null && tooltipKey != null)
261: tooltip = tooltipKey;
262:
263: if (tooltip == null) {//derive name from instance name
264: if (instanceName != null
265: && instanceName.trim().length() > 0) {
266: int dotIndex = instanceName.indexOf('.'); // NOI18N
267: tooltip = instanceName.substring(0, dotIndex)
268: .replace('-', '.'); // NOI18N
269: }
270: }
271:
272: if (tooltip == null) // no tooltip derived from the item
273: tooltip = _getDisplayName(bundleName, displayNameKey,
274: instanceName);
275:
276: } catch (Exception ex) {
277: Logger.getLogger(getClass().getName()).log(Level.INFO,
278: null, ex);
279: }
280:
281: return (tooltip == null ? "" : tooltip);
282: }
283:
284: public Image _getIcon(String iconURL) {
285:
286: Image icon = null;
287: try {
288: icon = Utilities.loadImage(iconURL);
289: } catch (Exception ex) {
290: Logger.getLogger(getClass().getName()).log(Level.INFO,
291: null, ex);
292: }
293: if (null == icon) {
294: try {
295: //the URL may point to an external file
296: icon = ImageIO.read(new URL(iconURL));
297: } catch (IOException ex) {
298: Logger.getLogger(getClass().getName()).log(Level.INFO,
299: null, ex);
300: }
301: }
302:
303: return icon;
304: }
305:
306: public HelpCtx getHelpCtx() {
307: DataNode dn = (DataNode) getOriginal();
308: Object helpId = dn.getDataObject().getPrimaryFile()
309: .getAttribute("helpId"); //NOI18N
310: return (helpId == null ? super .getHelpCtx() : new HelpCtx(
311: helpId.toString()));
312: }
313:
314: /**
315: * Transferable wrapper that does not allow DataFlavors for external drag and drop
316: * (FileListFlavor and URI list flavors)
317: */
318: private static class NoExternalDndTransferable implements
319: Transferable {
320: private Transferable t;
321: private DataFlavor uriListFlavor;
322:
323: public NoExternalDndTransferable(Transferable t) {
324: this .t = t;
325: }
326:
327: public DataFlavor[] getTransferDataFlavors() {
328: DataFlavor[] flavors = t.getTransferDataFlavors();
329: if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)
330: || t.isDataFlavorSupported(getUriListFlavor())) {
331: ArrayList<DataFlavor> tmp = new ArrayList<DataFlavor>(
332: flavors.length);
333: for (int i = 0; i < flavors.length; i++) {
334: if (isDataFlavorSupported(flavors[i]))
335: tmp.add(flavors[i]);
336: }
337: flavors = tmp.toArray(new DataFlavor[tmp.size()]);
338: }
339: return flavors;
340: }
341:
342: public boolean isDataFlavorSupported(DataFlavor flavor) {
343: if (DataFlavor.javaFileListFlavor.equals(flavor)
344: || getUriListFlavor().equals(flavor))
345: return false;
346: return t.isDataFlavorSupported(flavor);
347: }
348:
349: public Object getTransferData(DataFlavor flavor)
350: throws UnsupportedFlavorException, IOException {
351: if (!isDataFlavorSupported(flavor))
352: throw new UnsupportedFlavorException(flavor);
353: return t.getTransferData(flavor);
354: }
355:
356: private DataFlavor getUriListFlavor() {
357: if (null == uriListFlavor) {
358: try {
359: uriListFlavor = new DataFlavor(
360: "text/uri-list;class=java.lang.String");
361: } catch (ClassNotFoundException ex) {
362: //cannot happen
363: throw new AssertionError(ex);
364: }
365: }
366: return uriListFlavor;
367: }
368: }
369: }
|