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.spi.palette;
043:
044: import java.awt.datatransfer.DataFlavor;
045: import java.beans.PropertyChangeListener;
046: import java.beans.PropertyChangeSupport;
047: import org.netbeans.modules.palette.Category;
048: import org.netbeans.modules.palette.Item;
049: import org.netbeans.modules.palette.Model;
050: import org.netbeans.modules.palette.ModelListener;
051: import org.netbeans.modules.palette.Settings;
052: import org.openide.util.Lookup;
053:
054: /**
055: * <p>PaletteController provides access to data in the palette. If an instance
056: * of this class is in the <code>Lookup</code> of any <code>TopComponent</code>
057: * then the palette window opens and displays a new content when that
058: * <code>TopComponent</code> opens/activates.
059: * <br>
060: * Use <code>PaletteFactory</code> to construct a new instance of this class.</p>
061: *
062: * <p>There's a number of attributes that can override the default palette behavior.
063: * If the palette data are defined in the layers then the palette looks for attributes
064: * of the folders and files (<code>FileObject.getAttribute</code>). If the palette
065: * data are defined as Nodes then the attributes are extracted using <code>Node.getValue</code>.</p>
066: *
067: * <p>User can override attribute values in palette's user interface. Attribute values
068: * are persisted and restored after IDE restarts.</p>
069: *
070: * @author S. Aubrecht
071: */
072:
073: public final class PaletteController {
074:
075: /**
076: * <code>DataFlavor</code> of palette items dragged from palette to editor.
077: * The trasfer data returned from <code>Transferable</code> for this
078: * <code>DataFlavor</code> is the <code>Lookup</code> of the <code>Node</code>
079: * representing the palette item being dragged.
080: */
081: public static final DataFlavor ITEM_DATA_FLAVOR;
082: static {
083: try {
084: ITEM_DATA_FLAVOR = new DataFlavor(
085: "application/x-java-openide-paletteitem;class=org.openide.util.Lookup", // NOI18N
086: "Paste Item", // XXX missing I18N!
087: Lookup.class.getClassLoader());
088: } catch (ClassNotFoundException e) {
089: throw new AssertionError(e);
090: }
091: }
092:
093: // Names of attributes of palette items and categories that the palette supports.
094: // User can override their values in palette's user interface. Attribute values
095: // are persisted and restored after IDE restarts.
096: //
097: // Palette clients can override these attributes in their palette model
098: // (folder and file attributes in layers or Node attributes) to change
099: // palette's initial state.
100:
101: /**
102: * The width of palette items in pixels, if this attribute is set to -1 or is
103: * missing then the item width will be calculated dynamically depending on the length of
104: * item display names and may differ for each category (therefore each category
105: * may have a different number of columns).
106: * This attribute applies to palette's root only and is read-only.
107: * Default value is "-1".
108: */
109: public static final String ATTR_ITEM_WIDTH = "itemWidth";
110: /**
111: * "true" to show item names in the palette panel, "false" to show item icons only.
112: * This attribute applies to palette's root only.
113: * Default value is "true".
114: */
115: public static final String ATTR_SHOW_ITEM_NAMES = "showItemNames";
116: /**
117: * Item icon size.
118: * This attribute applies to palette's root only.
119: * Default value is java.beans.BeanInfo.ICON_COLOR_16x16
120: * @see java.beans.BeanInfo
121: */
122: public static final String ATTR_ICON_SIZE = "iconSize";
123: /**
124: * "true" if palette category is expanded, "false" if category is collapsed.
125: * Default value is "false".
126: */
127: public static final String ATTR_IS_EXPANDED = "isExpanded";
128: /**
129: * "true" if palette category or item is visible in the palette, "false" if
130: * the category or item is visible in palette customizer only.
131: * Default value is "true".
132: */
133: public static final String ATTR_IS_VISIBLE = "isVisible";
134: /**
135: * "true" if the category or item cannot be removed, "false" otherwise.
136: * Users cannot override this attribute's value.
137: * Default value is "false".
138: */
139: public static final String ATTR_IS_READONLY = "isReadonly";
140: /**
141: * Use this attribut for palette's root, category or item to specify its
142: * help id.
143: * Default value is "CommonPalette".
144: */
145: public static final String ATTR_HELP_ID = "helpId";
146:
147: /**
148: * Palette clients should listen to changes of this property if they want to
149: * notified when the selected item in palette has changed.
150: */
151: public static final String PROP_SELECTED_ITEM = Model.PROP_SELECTED_ITEM;
152:
153: /**
154: * Palette data model.
155: */
156: private Model model;
157: /**
158: * Palette user settings (expanded/collapsed categories, hidden/visible items etc).
159: */
160: private Settings settings;
161:
162: private PropertyChangeSupport support;
163:
164: //:::::::::::::::::::::::::::::::::::::
165:
166: private PaletteController() {
167: }
168:
169: /** Create new instance of PaletteController */
170: PaletteController(Model model, Settings settings) {
171: this .model = model;
172: this .settings = settings;
173:
174: support = new PropertyChangeSupport(this );
175: this .model.addModelListener(new ModelListener() {
176: public void propertyChange(
177: java.beans.PropertyChangeEvent evt) {
178: if (Model.PROP_SELECTED_ITEM.equals(evt
179: .getPropertyName())) {
180: Lookup oldValue = null == evt.getOldValue() ? Lookup.EMPTY
181: : ((Item) evt.getOldValue()).getLookup();
182: Lookup newValue = null == evt.getNewValue() ? Lookup.EMPTY
183: : ((Item) evt.getNewValue()).getLookup();
184: support.firePropertyChange(PROP_SELECTED_ITEM,
185: oldValue, newValue);
186: }
187: }
188:
189: public void categoriesRemoved(Category[] removedCategories) {
190: //not interested
191: }
192:
193: public void categoriesAdded(Category[] addedCategories) {
194: //not interested
195: }
196:
197: public void categoriesReordered() {
198: //not interested
199: }
200: });
201: }
202:
203: public void addPropertyChangeListener(
204: PropertyChangeListener listener) {
205: support.addPropertyChangeListener(listener);
206: }
207:
208: public void removePropertyChangeListener(
209: PropertyChangeListener listener) {
210: support.removePropertyChangeListener(listener);
211: }
212:
213: /**
214: * @return Lookup representing the item currently selected in the palette.
215: * The lookup is empty if no item is currently selected.
216: */
217: public Lookup getSelectedItem() {
218: Item selItem = model.getSelectedItem();
219: return null == selItem ? Lookup.EMPTY : selItem.getLookup();
220: }
221:
222: /**
223: * Select a new item in the palette window.
224: *
225: * @param category Lookup of the category that contains the item to be selected.
226: * @param item Item's lookup.
227: */
228: public void setSelectedItem(Lookup category, Lookup item) {
229: model.setSelectedItem(category, item);
230: }
231:
232: /**
233: * @return Lookup representing the category of currently selected item.
234: * The lookup is empty if no item is currently selected.
235: */
236: public Lookup getSelectedCategory() {
237: Category selCategory = model.getSelectedCategory();
238: return null == selCategory ? Lookup.EMPTY : selCategory
239: .getLookup();
240: }
241:
242: /**
243: * Clear selection in palette (i.e. no item is selected)
244: */
245: public void clearSelection() {
246: model.clearSelection();
247: }
248:
249: /**
250: * Refresh the list of categories and items, e.g. when PaletteFilter conditions
251: * have changed.
252: */
253: public void refresh() {
254: model.refresh();
255: }
256:
257: /**
258: * Open the default Palette Manager window to allow user to customize palette's
259: * contents, especially add/import new items to palette.
260: */
261: public void showCustomizer() {
262: model.showCustomizer(this , settings);
263: }
264:
265: /**
266: * @return Lookup representing palette's root folder.
267: */
268: public Lookup getRoot() {
269: return model.getRoot();
270: }
271:
272: Model getModel() {
273: return model;
274: }
275:
276: /**
277: * For unit-testing only.
278: */
279: void setModel(Model model) {
280: this .model = model;
281: }
282:
283: Settings getSettings() {
284: return settings;
285: }
286: }
|