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.beans.BeanInfo;
045: import java.beans.PropertyChangeListener;
046: import java.beans.PropertyChangeSupport;
047: import java.util.logging.Level;
048: import java.util.logging.Logger;
049: import java.util.prefs.BackingStoreException;
050: import java.util.prefs.Preferences;
051: import org.netbeans.spi.palette.PaletteController;
052: import org.openide.filesystems.FileObject;
053: import org.openide.loaders.DataFolder;
054: import org.openide.loaders.DataObject;
055: import org.openide.nodes.Node;
056: import org.openide.util.Lookup;
057: import org.openide.util.NbPreferences;
058: import org.openide.util.Utilities;
059:
060: /**
061: * Palette settings to be remembered over IDE restarts.
062: * There's an instance of these settings for each palette model instance.
063: *
064: * @author S. Aubrecht
065: */
066: public final class DefaultSettings implements Settings, ModelListener,
067: CategoryListener {
068:
069: private static final String NODE_ATTR_PREFIX = "psa_";
070:
071: private static final String NULL_VALUE = "null";
072:
073: private static final String XML_ROOT = "root";
074: private static final String XML_CATEGORY = "category";
075: private static final String XML_ITEM = "item";
076:
077: private static final String XML_ATTR_NAME = "name";
078:
079: private static final String[] KNOWN_PROPERTIES = new String[] {
080: NODE_ATTR_PREFIX + PaletteController.ATTR_ICON_SIZE,
081: NODE_ATTR_PREFIX + PaletteController.ATTR_IS_EXPANDED,
082: NODE_ATTR_PREFIX + PaletteController.ATTR_IS_VISIBLE,
083: NODE_ATTR_PREFIX + PaletteController.ATTR_SHOW_ITEM_NAMES };
084:
085: private static final int ICON_SIZE_ATTR_INDEX = 0;
086: private static final int IS_EXPANDED_ATTR_INDEX = 1;
087: private static final int IS_VISIBLE_ATTR_INDEX = 2;
088: private static final int SHOW_ITEM_NAMES_ATTR_INDEX = 3;
089:
090: private Model model;
091: private PropertyChangeSupport propertySupport = new PropertyChangeSupport(
092: this );
093:
094: private String prefsName;
095:
096: private static Logger ERR = Logger
097: .getLogger("org.netbeans.modules.palette"); // NOI18N
098:
099: public DefaultSettings(Model model) {
100: this .model = model;
101: prefsName = constructPrefsFileName(model);
102: if (Utilities.isWindows())
103: prefsName = prefsName.toLowerCase();
104: model.addModelListener(this );
105: Category[] categories = model.getCategories();
106: for (int i = 0; i < categories.length; i++) {
107: categories[i].addCategoryListener(this );
108: }
109: load();
110: }
111:
112: private String constructPrefsFileName(Model model) {
113: DataFolder dof = (DataFolder) model.getRoot().lookup(
114: DataFolder.class);
115: if (null != dof) {
116: FileObject fo = dof.getPrimaryFile();
117: if (null != fo) {
118: return fo.getPath();
119: }
120: }
121: return model.getName();
122: }
123:
124: private Preferences getPreferences() {
125: return NbPreferences.forModule(DefaultSettings.class).node(
126: "CommonPaletteSettings").node(prefsName); //NOI18N
127: }
128:
129: public void addPropertyChangeListener(PropertyChangeListener l) {
130: propertySupport.addPropertyChangeListener(l);
131: }
132:
133: public void removePropertyChangeListener(PropertyChangeListener l) {
134: propertySupport.removePropertyChangeListener(l);
135: }
136:
137: public boolean isVisible(Item item) {
138: Node node = getNode(item.getLookup());
139: return get(node, PaletteController.ATTR_IS_VISIBLE, true);
140: }
141:
142: public void setVisible(Item item, boolean visible) {
143: Node node = getNode(item.getLookup());
144: set(node, PaletteController.ATTR_IS_VISIBLE, visible, true);
145: }
146:
147: public boolean isVisible(Category category) {
148: Node node = getNode(category.getLookup());
149: return get(node, PaletteController.ATTR_IS_VISIBLE, true);
150: }
151:
152: public void setVisible(Category category, boolean visible) {
153: Node node = getNode(category.getLookup());
154: set(node, PaletteController.ATTR_IS_VISIBLE, visible, true);
155: }
156:
157: public boolean isNodeVisible(Node node) {
158: return get(node, PaletteController.ATTR_IS_VISIBLE, true);
159: }
160:
161: public void setNodeVisible(Node node, boolean visible) {
162: set(node, PaletteController.ATTR_IS_VISIBLE, visible, true);
163: }
164:
165: public boolean isExpanded(Category category) {
166: Node node = getNode(category.getLookup());
167: return get(node, PaletteController.ATTR_IS_EXPANDED, false);
168: }
169:
170: public void setExpanded(Category category, boolean expanded) {
171: Node node = getNode(category.getLookup());
172: set(node, PaletteController.ATTR_IS_EXPANDED, expanded, false);
173: }
174:
175: public int getIconSize() {
176: Node node = getNode(model.getRoot());
177: return get(node, PaletteController.ATTR_ICON_SIZE,
178: BeanInfo.ICON_COLOR_16x16);
179: }
180:
181: public void setIconSize(int iconSize) {
182: Node node = getNode(model.getRoot());
183: set(node, PaletteController.ATTR_ICON_SIZE, iconSize,
184: BeanInfo.ICON_COLOR_16x16);
185: }
186:
187: public void setShowItemNames(boolean showNames) {
188: Node node = getNode(model.getRoot());
189: set(node, PaletteController.ATTR_SHOW_ITEM_NAMES, showNames,
190: true);
191: }
192:
193: public boolean getShowItemNames() {
194: Node node = getNode(model.getRoot());
195: return get(node, PaletteController.ATTR_SHOW_ITEM_NAMES, true);
196: }
197:
198: private Node getNode(Lookup lkp) {
199: return (Node) lkp.lookup(Node.class);
200: }
201:
202: private boolean get(Node node, String attrName, boolean defaultValue) {
203: Object value = get(node, attrName, Boolean
204: .valueOf(defaultValue));
205: return null == value ? defaultValue : Boolean.valueOf(
206: value.toString()).booleanValue();
207: }
208:
209: private int get(Node node, String attrName, int defaultValue) {
210: Object value = get(node, attrName, Integer
211: .valueOf(defaultValue));
212: try {
213: if (null != value)
214: return Integer.parseInt(value.toString());
215: } catch (NumberFormatException nfE) {
216: //ignore
217: }
218: return defaultValue;
219: }
220:
221: private Object get(Node node, String attrName, Object defaultValue) {
222: Object res = null;
223: if (null != node) {
224: res = node.getValue(NODE_ATTR_PREFIX + attrName);
225: if (null == res || NULL_VALUE.equals(res)) {
226: res = getNodeDefaultValue(node, attrName);
227: }
228: }
229: if (null == res) {
230: res = defaultValue;
231: }
232: return res;
233: }
234:
235: private Object getNodeDefaultValue(Node node, String attrName) {
236: Object res = node.getValue(attrName);
237: if (null == res) {
238: DataObject dobj = (DataObject) node
239: .getCookie(DataObject.class);
240: if (null != dobj) {
241: res = dobj.getPrimaryFile().getAttribute(attrName);
242: }
243: }
244: return res;
245: }
246:
247: private void set(Node node, String attrName, boolean newValue,
248: boolean defaultValue) {
249: set(node, attrName, Boolean.valueOf(newValue), Boolean
250: .valueOf(defaultValue));
251: }
252:
253: private void set(Node node, String attrName, int newValue,
254: int defaultValue) {
255: set(node, attrName, Integer.valueOf(newValue), Integer
256: .valueOf(defaultValue));
257: }
258:
259: private void set(Node node, String attrName, Object newValue,
260: Object defaultValue) {
261: if (null == node)
262: return;
263: Object oldValue = get(node, attrName, defaultValue);
264: if (oldValue.equals(newValue)) {
265: return;
266: }
267: node.setValue(NODE_ATTR_PREFIX + attrName, newValue);
268: store();
269: propertySupport
270: .firePropertyChange(attrName, oldValue, newValue);
271: }
272:
273: public void categoryModified(Category src) {
274: store();
275: }
276:
277: public void categoriesRemoved(Category[] removedCategories) {
278: for (int i = 0; i < removedCategories.length; i++) {
279: removedCategories[i].removeCategoryListener(this );
280: }
281: store();
282: }
283:
284: public void categoriesAdded(Category[] addedCategories) {
285: for (int i = 0; i < addedCategories.length; i++) {
286: addedCategories[i].addCategoryListener(this );
287: }
288: store();
289: }
290:
291: public void propertyChange(java.beans.PropertyChangeEvent evt) {
292: //not interested
293: }
294:
295: public void categoriesReordered() {
296: //not interested
297: }
298:
299: private boolean isLoading = false;
300:
301: private void load() {
302: try {
303: isLoading = true;
304: Preferences pref = getPreferences();
305: setIconSize(pref.getInt(PaletteController.ATTR_ICON_SIZE,
306: getIconSize()));
307: setShowItemNames(pref.getBoolean(
308: PaletteController.ATTR_SHOW_ITEM_NAMES,
309: getShowItemNames()));
310:
311: for (Category category : model.getCategories()) {
312: setVisible(category, pref.getBoolean(category.getName()
313: + '-' + PaletteController.ATTR_IS_VISIBLE,
314: isVisible(category)));
315: setExpanded(category, pref.getBoolean(category
316: .getName()
317: + '-' + PaletteController.ATTR_IS_EXPANDED,
318: isExpanded(category)));
319:
320: for (Item item : category.getItems()) {
321: setVisible(item, pref.getBoolean(category.getName()
322: + '-' + item.getName() + '-'
323: + PaletteController.ATTR_IS_VISIBLE,
324: isVisible(item)));
325: }
326: }
327: } finally {
328: isLoading = false;
329: }
330: }
331:
332: private void store() {
333: if (isLoading)
334: return;
335: Preferences pref = getPreferences();
336: try {
337: pref.clear();
338: } catch (BackingStoreException bsE) {
339: ERR.log(Level.INFO, Utils
340: .getBundleString("Err_StoreSettings"), bsE); //NOI18N
341: }
342: pref.putInt(PaletteController.ATTR_ICON_SIZE, getIconSize());
343: pref.putBoolean(PaletteController.ATTR_SHOW_ITEM_NAMES,
344: getShowItemNames());
345:
346: for (Category category : model.getCategories()) {
347: pref.putBoolean(category.getName() + '-'
348: + PaletteController.ATTR_IS_VISIBLE,
349: isVisible(category));
350: pref.putBoolean(category.getName() + '-'
351: + PaletteController.ATTR_IS_EXPANDED,
352: isExpanded(category));
353:
354: for (Item item : category.getItems()) {
355: pref.putBoolean(category.getName() + '-'
356: + item.getName() + '-'
357: + PaletteController.ATTR_IS_VISIBLE,
358: isVisible(item));
359: }
360: }
361: }
362:
363: public int getItemWidth() {
364: Node node = getNode(model.getRoot());
365: return get(node, PaletteController.ATTR_ITEM_WIDTH, -1);
366: }
367:
368: public void reset() {
369: Node root = (Node) model.getRoot().lookup(Node.class);
370: clearAttributes(root);
371: Category[] categories = model.getCategories();
372: for (int i = 0; i < categories.length; i++) {
373: Node cat = (Node) categories[i].getLookup().lookup(
374: Node.class);
375: clearAttributes(cat);
376: Item[] items = categories[i].getItems();
377: for (int j = 0; j < items.length; j++) {
378: Node it = (Node) items[j].getLookup()
379: .lookup(Node.class);
380: clearAttributes(it);
381: }
382: }
383: try {
384: getPreferences().removeNode();
385: } catch (BackingStoreException bsE) {
386: ERR.log(Level.INFO, Utils
387: .getBundleString("Err_StoreSettings"), bsE); //NOI18N
388: }
389: }
390:
391: private void clearAttributes(Node node) {
392: for (int i = 0; i < KNOWN_PROPERTIES.length; i++) {
393: node.setValue(KNOWN_PROPERTIES[i], NULL_VALUE);
394: }
395: }
396: }
|