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.editor.options;
043:
044: import java.beans.*;
045: import java.awt.Image;
046: import java.lang.reflect.Method;
047: import java.util.Collection;
048: import java.util.HashMap;
049:
050: import org.openide.util.NbBundle;
051:
052: import org.netbeans.editor.BaseCaret;
053: import org.openide.modules.ModuleInfo;
054: import org.openide.util.Lookup;
055:
056: /** BeanInfo for base options
057: *
058: * @author Miloslav Metelka, Ales Novak
059: */
060: public class BaseOptionsBeanInfo extends SimpleBeanInfo {
061:
062: /** Prefix of the icon location. */
063: private String iconPrefix;
064:
065: /** Prefix for getting localized strings for property name and hint */
066: private String bundlePrefix;
067:
068: /** Icons for compiler settings objects. */
069: private Image icon;
070: private Image icon32;
071:
072: private HashMap names2PD;
073:
074: /** Propertydescriptors */
075: PropertyDescriptor[] descriptors;
076:
077: private static final String[] EXPERT_PROP_NAMES = new String[] {
078: BaseOptions.CARET_BLINK_RATE_PROP,
079: BaseOptions.CARET_TYPE_INSERT_MODE_PROP,
080: BaseOptions.CARET_TYPE_OVERWRITE_MODE_PROP,
081: BaseOptions.CARET_COLOR_INSERT_MODE_PROP,
082: BaseOptions.CARET_COLOR_OVERWRITE_MODE_PROP,
083: BaseOptions.HIGHLIGHT_CARET_ROW_PROP,
084: BaseOptions.HIGHLIGHT_MATCHING_BRACKET_PROP,
085: BaseOptions.LINE_HEIGHT_CORRECTION_PROP,
086: BaseOptions.MARGIN_PROP,
087: BaseOptions.SCROLL_JUMP_INSETS_PROP,
088: BaseOptions.SCROLL_FIND_INSETS_PROP,
089: BaseOptions.STATUS_BAR_CARET_DELAY_PROP,
090: BaseOptions.STATUS_BAR_VISIBLE_PROP,
091: BaseOptions.TEXT_LIMIT_LINE_COLOR_PROP,
092: BaseOptions.TEXT_LIMIT_LINE_VISIBLE_PROP,
093: BaseOptions.TEXT_LIMIT_WIDTH_PROP,
094: BaseOptions.TEXT_ANTIALIASING_PROP };
095:
096: public BaseOptionsBeanInfo() {
097: this ("/org/netbeans/modules/editor/resources/baseOptions"); // NOI18N
098: }
099:
100: public BaseOptionsBeanInfo(String iconPrefix) {
101: this (iconPrefix, ""); // NOI18N
102: }
103:
104: public BaseOptionsBeanInfo(String iconPrefix, String bundlePrefix) {
105: this .iconPrefix = iconPrefix;
106: this .bundlePrefix = bundlePrefix;
107: }
108:
109: /*
110: * @return Returns an array of PropertyDescriptors
111: * describing the editable properties supported by this bean.
112: */
113: public @Override
114: PropertyDescriptor[] getPropertyDescriptors() {
115: if (descriptors == null) {
116: String[] propNames = getPropNames();
117: PropertyDescriptor[] pds = new PropertyDescriptor[propNames.length];
118:
119: for (int i = 0; i < propNames.length; i++) {
120: pds[i] = createPropertyDescriptor(propNames[i]);
121: // Set display-name and short-description
122: pds[i].setDisplayName(getString("PROP_" + bundlePrefix
123: + propNames[i])); // NOI18N
124: pds[i].setShortDescription(getString("HINT_"
125: + bundlePrefix + propNames[i])); // NOI18N
126: }
127:
128: descriptors = pds; // now the array are inited
129:
130: // Now various properties of the descriptors can be updated
131: updatePropertyDescriptors();
132: }
133: return descriptors;
134: }
135:
136: /** Create property descriptor for a particular property-name. */
137: protected PropertyDescriptor createPropertyDescriptor(
138: String propName) {
139: PropertyDescriptor pd;
140: try {
141: pd = new PropertyDescriptor(propName, getBeanClass());
142:
143: } catch (IntrospectionException e) {
144: try {
145: // Create property without read/write methods
146: pd = new PropertyDescriptor(propName, null, null);
147: } catch (IntrospectionException e2) {
148: throw new IllegalStateException(
149: "Invalid property name=" + propName); // NOI18N
150: }
151:
152: // Try a simple search for get/set methods - just by name
153: // Successor can customize it if necessary
154: String cap = capitalize(propName);
155: Method m = findMethod("get" + cap); // NOI18N
156: if (m != null) {
157: try {
158: pd.setReadMethod(m);
159: } catch (IntrospectionException e2) {
160: }
161: }
162: m = findMethod("set" + cap); // NOI18N
163: if (m != null) {
164: try {
165: pd.setWriteMethod(m);
166: } catch (IntrospectionException e2) {
167: }
168: }
169: }
170:
171: return pd;
172: }
173:
174: private Method findMethod(String name) {
175: try {
176: Method[] ma = getBeanClass().getDeclaredMethods();
177: for (int i = 0; i < ma.length; i++) {
178: if (name.equals(ma[i].getName())) {
179: return ma[i];
180: }
181: }
182: } catch (SecurityException e) {
183: }
184: return null;
185: }
186:
187: private static String capitalize(String s) {
188: if (s.length() == 0) {
189: return s;
190: }
191: char chars[] = s.toCharArray();
192: chars[0] = Character.toUpperCase(chars[0]);
193: return new String(chars);
194: }
195:
196: /** Update various properties of the property descriptors. */
197: protected void updatePropertyDescriptors() {
198: setPropertyEditor(BaseOptions.ABBREV_MAP_PROP,
199: AbbrevsEditor.class, false);
200: setPropertyEditor(BaseOptions.CARET_TYPE_INSERT_MODE_PROP,
201: CaretTypeEditor.class);
202: setPropertyEditor(BaseOptions.CARET_TYPE_OVERWRITE_MODE_PROP,
203: CaretTypeEditor.class);
204: setPropertyEditor(BaseOptions.KEY_BINDING_LIST_PROP,
205: KeyBindingsEditor.class, false);
206: setPropertyEditor(BaseOptions.COLORING_MAP_PROP,
207: ColoringArrayEditor.class, false);
208: setPropertyEditor(BaseOptions.SCROLL_JUMP_INSETS_PROP,
209: ScrollInsetsEditor.class);
210: setPropertyEditor(BaseOptions.SCROLL_FIND_INSETS_PROP,
211: ScrollInsetsEditor.class);
212: setPropertyEditor(BaseOptions.MACRO_MAP_PROP,
213: MacrosEditor.class, false);
214:
215: setExpert(EXPERT_PROP_NAMES);
216: boolean usesNewOptions = usesNewOptions();
217:
218: String hidden[] = (usesNewOptions) ? new String[] {
219: BaseOptions.ABBREV_MAP_PROP,
220: BaseOptions.CARET_BLINK_RATE_PROP,
221: BaseOptions.CARET_COLOR_INSERT_MODE_PROP,
222: BaseOptions.CARET_COLOR_OVERWRITE_MODE_PROP,
223: BaseOptions.CARET_ITALIC_INSERT_MODE_PROP,
224: BaseOptions.CARET_ITALIC_OVERWRITE_MODE_PROP,
225: BaseOptions.CARET_TYPE_INSERT_MODE_PROP,
226: BaseOptions.CARET_TYPE_OVERWRITE_MODE_PROP,
227: BaseOptions.CODE_FOLDING_PROPS_PROP,
228: BaseOptions.COLORING_MAP_PROP,
229: BaseOptions.EXPAND_TABS_PROP,
230: BaseOptions.FONT_SIZE_PROP,
231: BaseOptions.HIGHLIGHT_CARET_ROW_PROP,
232: BaseOptions.HIGHLIGHT_MATCHING_BRACKET_PROP,
233: BaseOptions.KEY_BINDING_LIST_PROP,
234: BaseOptions.MACRO_MAP_PROP, BaseOptions.MARGIN_PROP,
235: BaseOptions.OPTIONS_VERSION_PROP,
236: BaseOptions.PAIR_CHARACTERS_COMPLETION,
237: BaseOptions.SCROLL_FIND_INSETS_PROP,
238: BaseOptions.SCROLL_JUMP_INSETS_PROP,
239: BaseOptions.SPACES_PER_TAB_PROP,
240: BaseOptions.TAB_SIZE_PROP,
241: BaseOptions.TEXT_LIMIT_LINE_COLOR_PROP,
242: BaseOptions.TEXT_LIMIT_LINE_VISIBLE_PROP,
243: BaseOptions.TEXT_LIMIT_WIDTH_PROP, } : new String[] {
244: BaseOptions.CARET_ITALIC_INSERT_MODE_PROP,
245: BaseOptions.CARET_ITALIC_OVERWRITE_MODE_PROP,
246: BaseOptions.EXPAND_TABS_PROP,
247: BaseOptions.HIGHLIGHT_CARET_ROW_PROP,
248: BaseOptions.HIGHLIGHT_MATCHING_BRACKET_PROP,
249: BaseOptions.MARGIN_PROP,
250: BaseOptions.OPTIONS_VERSION_PROP,
251: BaseOptions.SCROLL_FIND_INSETS_PROP,
252: BaseOptions.SCROLL_JUMP_INSETS_PROP,
253: BaseOptions.SPACES_PER_TAB_PROP, };
254:
255: setHidden(hidden);
256:
257: }
258:
259: protected boolean usesNewOptions() {
260: Collection<? extends ModuleInfo> infos = Lookup.getDefault()
261: .lookupAll(ModuleInfo.class);
262: for (ModuleInfo mi : infos) {
263: if (mi.getCodeNameBase().startsWith(
264: "org.netbeans.modules.options.editor")
265: && //NOI18N
266: mi.isEnabled()) {
267: return true;
268: }
269: }
270: return false;
271: }
272:
273: protected Class getBeanClass() {
274: return BaseOptions.class;
275: }
276:
277: protected String[] getPropNames() {
278: return BaseOptions.BASE_PROP_NAMES;
279: }
280:
281: protected synchronized PropertyDescriptor getPD(String propName) {
282: if (names2PD == null) {
283: names2PD = new HashMap(37);
284: PropertyDescriptor[] pds = getPropertyDescriptors();
285: for (int i = pds.length - 1; i >= 0; i--) {
286: names2PD.put(pds[i].getName(), pds[i]);
287: }
288: }
289: return (PropertyDescriptor) names2PD.get(propName);
290: }
291:
292: protected void setPropertyEditor(String propName, Class propEditor,
293: boolean canEditAsText) {
294: PropertyDescriptor pd = getPD(propName);
295: if (pd != null) {
296: pd.setPropertyEditorClass(propEditor);
297: pd.setValue("canEditAsText", canEditAsText ? Boolean.TRUE
298: : Boolean.FALSE); //NOI18N
299: }
300: }
301:
302: protected void setPropertyEditor(String propName, Class propEditor) {
303: setPropertyEditor(propName, propEditor, true);
304: }
305:
306: protected void setExpert(String[] propNames) {
307: for (int i = 0; i < propNames.length; i++) {
308: PropertyDescriptor pd = getPD(propNames[i]);
309: if (pd != null) {
310: pd.setExpert(true);
311: }
312: }
313: }
314:
315: protected void setHidden(String[] propNames) {
316: for (int i = 0; i < propNames.length; i++) {
317: PropertyDescriptor pd = getPD(propNames[i]);
318: if (pd != null) {
319: pd.setHidden(true);
320: }
321: }
322: }
323:
324: /* @param type Desired type of the icon
325: * @return returns the Java loader's icon
326: */
327: public @Override
328: Image getIcon(final int type) {
329: if ((type == BeanInfo.ICON_COLOR_16x16)
330: || (type == BeanInfo.ICON_MONO_16x16)) {
331: if (icon == null)
332: icon = loadImage(iconPrefix + ".gif"); // NOI18N
333: return icon;
334: } else {
335: if (icon32 == null)
336: icon32 = loadImage(iconPrefix + "32.gif"); // NOI18N
337: return icon32;
338: }
339: }
340:
341: /**
342: * Get localized string for the given key.
343: *
344: * @param key the key string for which the localized
345: * text is being retrieved. The localized string
346: * for the key must exist otherwise
347: * {@link java.util.MissingResourceException}
348: * gets thrown.
349: * @return localized string
350: */
351: protected String getString(String key) {
352: return NbBundle.getMessage(BaseOptionsBeanInfo.class, key);
353: }
354:
355: // ------------------------ carets --------------------------------
356:
357: public static class CaretTypeEditor extends PropertyEditorSupport {
358:
359: private static String[] tags = new String[] {
360: BaseCaret.LINE_CARET, BaseCaret.THIN_LINE_CARET,
361: BaseCaret.BLOCK_CARET };
362:
363: private static String[] locTags = new String[] {
364: getString("LINE_CARET"), // NOI18N
365: getString("THIN_LINE_CARET"), // NOI18N
366: getString("BLOCK_CARET") // NOI18N
367: };
368:
369: public @Override
370: String[] getTags() {
371: return locTags;
372: }
373:
374: public @Override
375: void setAsText(String txt) {
376: for (int i = 0; i < locTags.length; i++) {
377: if (locTags[i].equals(txt)) {
378: setValue(tags[i]);
379: break;
380: }
381: }
382: }
383:
384: public @Override
385: String getAsText() {
386: String val = (String) getValue();
387: for (int i = 0; i < tags.length; i++) {
388: if (tags[i].equals(val)) {
389: return locTags[i];
390: }
391: }
392: throw new IllegalStateException();
393: }
394:
395: static String getString(String s) {
396: return NbBundle.getMessage(BaseOptionsBeanInfo.class, s);
397: }
398:
399: }
400: }
|