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.vmd.midp.propertyeditors;
043:
044: import java.awt.BorderLayout;
045: import java.awt.event.ActionEvent;
046: import java.awt.event.ActionListener;
047: import java.util.ArrayList;
048: import java.util.Collection;
049: import java.util.Collections;
050: import java.util.List;
051: import java.util.Map;
052: import java.util.TreeMap;
053: import javax.swing.DefaultComboBoxModel;
054: import javax.swing.JComboBox;
055: import javax.swing.JComponent;
056: import javax.swing.JPanel;
057: import javax.swing.JRadioButton;
058: import org.netbeans.modules.vmd.api.model.DesignComponent;
059: import org.netbeans.modules.vmd.api.model.DesignDocument;
060: import org.netbeans.modules.vmd.api.model.PropertyValue;
061: import org.netbeans.modules.vmd.api.model.TypeID;
062: import org.netbeans.modules.vmd.midp.components.MidpDocumentSupport;
063: import org.netbeans.modules.vmd.midp.components.MidpTypes;
064: import org.netbeans.modules.vmd.midp.components.MidpValueSupport;
065: import org.netbeans.modules.vmd.midp.components.categories.CommandsCategoryCD;
066: import org.netbeans.modules.vmd.midp.components.commands.CommandCD;
067: import org.netbeans.modules.vmd.midp.components.displayables.DisplayableCD;
068: import org.netbeans.modules.vmd.midp.components.items.ItemCD;
069: import org.netbeans.modules.vmd.midp.components.sources.CommandEventSourceCD;
070: import org.netbeans.modules.vmd.midp.components.sources.ItemCommandEventSourceCD;
071: import org.netbeans.modules.vmd.midp.propertyeditors.api.usercode.PropertyEditorElement;
072: import org.netbeans.modules.vmd.midp.propertyeditors.api.usercode.PropertyEditorUserCode;
073: import org.openide.awt.Mnemonics;
074: import org.openide.util.NbBundle;
075:
076: /**
077: *
078: * @author Karol Harezlak
079: * @author Anton Chechel
080: */
081: public final class PropertyEditorDefaultCommand extends
082: PropertyEditorUserCode implements PropertyEditorElement {
083:
084: private static final String NONE_ITEM = NbBundle.getMessage(
085: PropertyEditorDefaultCommand.class,
086: "LBL_SELECTCOMMAND_NONE"); // NOI18N
087: private final List<String> tags = new ArrayList<String>();
088: private final Map<String, DesignComponent> values = new TreeMap<String, DesignComponent>();
089: private CustomEditor customEditor;
090: private JRadioButton radioButton;
091: private TypeID parentTypeID;
092:
093: private PropertyEditorDefaultCommand(TypeID parentTypeID) {
094: super (NbBundle.getMessage(PropertyEditorDefaultCommand.class,
095: "LBL_DEF_COMMAND_UCLABEL")); // NOI18N
096: this .parentTypeID = parentTypeID;
097: initComponents();
098: initElements(Collections
099: .<PropertyEditorElement> singleton(this ));
100: }
101:
102: public static PropertyEditorDefaultCommand createInstance() {
103: return new PropertyEditorDefaultCommand(null);
104: }
105:
106: /**
107: * Crates instance of PropertyEditorDefaultCommand NOT editable for given parent component TypeID.
108: * @param parentTypeID parent components typeID
109: */
110: public static PropertyEditorDefaultCommand createInstance(
111: TypeID parentTypeID) {
112: return new PropertyEditorDefaultCommand(parentTypeID);
113: }
114:
115: private void initComponents() {
116: radioButton = new JRadioButton();
117: Mnemonics.setLocalizedText(radioButton, NbBundle.getMessage(
118: PropertyEditorDefaultCommand.class,
119: "LBL_DEF_COMMAND_STR")); // NOI18N
120: customEditor = new CustomEditor();
121: radioButton.addActionListener(customEditor);
122: }
123:
124: public JComponent getCustomEditorComponent() {
125: return customEditor;
126: }
127:
128: public JRadioButton getRadioButton() {
129: return radioButton;
130: }
131:
132: public boolean isInitiallySelected() {
133: return true;
134: }
135:
136: public boolean isVerticallyResizable() {
137: return false;
138: }
139:
140: @Override
141: public String getAsText() {
142: if (isCurrentValueAUserCodeType()) {
143: return USER_CODE_TEXT;
144: } else if (isCurrentValueANull()) {
145: return NONE_ITEM;
146: }
147: PropertyValue value = (PropertyValue) super .getValue();
148: return getDecodeValue(value);
149: }
150:
151: @Override
152: public Boolean canEditAsText() {
153: return null;
154: }
155:
156: public void setTextForPropertyValue(String text) {
157: saveValue(text);
158: }
159:
160: public String getTextForPropertyValue() {
161: return null;
162: }
163:
164: public void updateState(PropertyValue value) {
165: customEditor.updateModel();
166: if (isCurrentValueANull() || value == null) {
167: customEditor.setValue(null);
168: } else {
169: customEditor.setValue(value);
170: }
171: radioButton.setSelected(!isCurrentValueAUserCodeType());
172: }
173:
174: private void saveValue(String text) {
175: if (text.length() > 0) {
176: if (NONE_ITEM.equals(text)) {
177: super .setValue(NULL_VALUE);
178: } else {
179: final DesignComponent command = values.get(text);
180: if (command != null) { // user code
181: final DesignComponent[] itemCommandSource = new DesignComponent[1];
182: itemCommandSource[0] = getItemCommandEvenSource(text);
183: if (itemCommandSource[0] == null) {
184: if (component != null
185: && component.get() != null) {
186: component.get().getDocument()
187: .getTransactionManager()
188: .writeAccess(new Runnable() {
189:
190: public void run() {
191: itemCommandSource[0] = MidpDocumentSupport
192: .attachCommandToItem(
193: component
194: .get(),
195: command);
196: }
197: });
198: }
199: }
200: super
201: .setValue(PropertyValue
202: .createComponentReference(itemCommandSource[0]));
203: }
204: }
205: }
206: }
207:
208: @Override
209: public void customEditorOKButtonPressed() {
210: super .customEditorOKButtonPressed();
211: if (radioButton.isSelected()) {
212: saveValue(customEditor.getText());
213: }
214: }
215:
216: @Override
217: public String[] getTags() {
218: tags.clear();
219: if (isCurrentValueAUserCodeType()) {
220: tags.add(PropertyEditorUserCode.USER_CODE_TEXT);
221: } else {
222: tags.add(NONE_ITEM);
223: values.clear();
224: values.put(NONE_ITEM, null);
225:
226: if (component != null && component.get() != null) {
227: final DesignComponent itemComponent = component.get();
228: itemComponent.getDocument().getTransactionManager()
229: .readAccess(new Runnable() {
230:
231: public void run() {
232: DesignComponent parentComponent = itemComponent
233: .getParentComponent();
234: if (parentComponent != null) {
235: List<PropertyValue> formCmdESValues = parentComponent
236: .readProperty(
237: DisplayableCD.PROP_COMMANDS)
238: .getArray();
239: List<DesignComponent> formCommands = new ArrayList<DesignComponent>(
240: formCmdESValues.size());
241:
242: for (PropertyValue esValue : formCmdESValues) {
243: DesignComponent command = esValue
244: .getComponent()
245: .readProperty(
246: CommandEventSourceCD.PROP_COMMAND)
247: .getComponent();
248: if (command != null) {
249: PropertyValue ordinaryValue = command
250: .readProperty(CommandCD.PROP_ORDINARY);
251: if (MidpTypes
252: .getBoolean(ordinaryValue)) {
253: formCommands
254: .add(command);
255: }
256: }
257: }
258:
259: Collection<DesignComponent> components = MidpDocumentSupport
260: .getCategoryComponent(
261: itemComponent
262: .getDocument(),
263: CommandsCategoryCD.TYPEID)
264: .getComponents();
265: Collection<DesignComponent> commands = new ArrayList<DesignComponent>(
266: components.size());
267: for (DesignComponent command : components) {
268: PropertyValue ordinaryValue = command
269: .readProperty(CommandCD.PROP_ORDINARY);
270: if (MidpTypes
271: .getBoolean(ordinaryValue)) {
272: commands.add(command);
273: }
274: }
275: commands.removeAll(formCommands);
276:
277: for (DesignComponent command : commands) {
278: String displayName = getComponentDisplayName(command);
279: tags.add(displayName);
280: values
281: .put(displayName,
282: command);
283: }
284: }
285: }
286: });
287: }
288: }
289: return tags.toArray(new String[tags.size()]);
290: }
291:
292: private String getComponentDisplayName(DesignComponent component) {
293: return MidpValueSupport.getHumanReadableString(component);
294: }
295:
296: private String getDecodeValue(final PropertyValue value) {
297: final String[] decodeValue = new String[1];
298: if (component != null && component.get() != null) {
299: final DesignDocument document = component.get()
300: .getDocument();
301: document.getTransactionManager().readAccess(new Runnable() {
302:
303: public void run() {
304: decodeValue[0] = getComponentDisplayName(value
305: .getComponent());
306: }
307: });
308: }
309: return decodeValue[0];
310: }
311:
312: private DesignComponent getItemCommandEvenSource(final String name) {
313: final DesignComponent[] itemCommandEvenSource = new DesignComponent[1];
314: if (component != null && component.get() != null) {
315: final DesignComponent itemComponent = component.get();
316: itemComponent.getDocument().getTransactionManager()
317: .readAccess(new Runnable() {
318:
319: public void run() {
320: DesignComponent command = values.get(name);
321: List<PropertyValue> itemESValues = itemComponent
322: .readProperty(ItemCD.PROP_COMMANDS)
323: .getArray();
324: for (PropertyValue esValue : itemESValues) {
325: DesignComponent existingES = esValue
326: .getComponent();
327: if (existingES
328: .readProperty(
329: ItemCommandEventSourceCD.PROP_COMMAND)
330: .getComponent().equals(command)) {
331: itemCommandEvenSource[0] = existingES;
332: break;
333: }
334: }
335: }
336: });
337: }
338: return itemCommandEvenSource[0];
339: }
340:
341: @Override
342: public boolean canWrite() {
343: if (!isWriteableByParentType()) {
344: return false;
345: }
346:
347: return super .canWrite();
348: }
349:
350: @Override
351: public boolean supportsCustomEditor() {
352: if (!isWriteableByParentType()) {
353: return false;
354: }
355:
356: return super .supportsCustomEditor();
357: }
358:
359: private boolean isWriteableByParentType() {
360: if (component == null || component.get() == null) {
361: return false;
362: }
363:
364: if (parentTypeID != null) {
365: final DesignComponent _component = component.get();
366: final DesignComponent[] parent = new DesignComponent[1];
367: _component.getDocument().getTransactionManager()
368: .readAccess(new Runnable() {
369:
370: public void run() {
371: parent[0] = _component.getParentComponent();
372: }
373: });
374:
375: if (parent[0] != null
376: && parentTypeID.equals(parent[0].getType())) {
377: return false;
378: }
379: }
380: return true;
381: }
382:
383: private class CustomEditor extends JPanel implements ActionListener {
384:
385: private JComboBox combobox;
386:
387: public CustomEditor() {
388: initComponents();
389: }
390:
391: private void initComponents() {
392: setLayout(new BorderLayout());
393: combobox = new JComboBox();
394: combobox.setModel(new DefaultComboBoxModel());
395: combobox.addActionListener(this );
396: add(combobox, BorderLayout.CENTER);
397: }
398:
399: public void setValue(final PropertyValue value) {
400: if (value == null) {
401: combobox.setSelectedItem(NONE_ITEM);
402: return;
403: }
404:
405: final PropertyValue[] cmdValue = new PropertyValue[1];
406: if (component != null && component.get() != null) {
407: DesignDocument document = component.get().getDocument();
408: document.getTransactionManager().readAccess(
409: new Runnable() {
410:
411: public void run() {
412: cmdValue[0] = value
413: .getComponent()
414: .readProperty(
415: ItemCommandEventSourceCD.PROP_COMMAND);
416: }
417: });
418: }
419: if (cmdValue[0] == null) {
420: return;
421: }
422:
423: DesignComponent command = cmdValue[0].getComponent();
424: for (String key : values.keySet()) {
425: DesignComponent tmpCommand = values.get(key);
426: if (tmpCommand != null && tmpCommand.equals(command)) {
427: combobox.setSelectedItem(key);
428: break;
429: }
430: }
431: }
432:
433: public String getText() {
434: return (String) combobox.getSelectedItem();
435: }
436:
437: public void updateModel() {
438: DefaultComboBoxModel model = (DefaultComboBoxModel) combobox
439: .getModel();
440: model.removeAllElements();
441: for (String tag : tags) {
442: model.addElement(tag);
443: }
444: }
445:
446: public void actionPerformed(ActionEvent evt) {
447: radioButton.setSelected(true);
448: }
449: }
450: }
|