1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ide.eclipse.adt.internal.editors.uimodel; 18 19 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; 20 import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; 21 import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; 22 import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; 23 import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper; 24 25 import org.eclipse.swt.events.DisposeEvent; 26 import org.eclipse.swt.events.DisposeListener; 27 import org.eclipse.swt.events.ModifyEvent; 28 import org.eclipse.swt.events.ModifyListener; 29 import org.eclipse.swt.layout.GridData; 30 import org.eclipse.swt.widgets.Composite; 31 import org.eclipse.swt.widgets.Text; 32 import org.eclipse.ui.forms.IManagedForm; 33 import org.eclipse.ui.forms.widgets.TableWrapData; 34 35 /** 36 * Represents an XML attribute in that can be modified using a simple text field 37 * in the XML editor's user interface. 38 * <p/> 39 * The XML attribute has no default value. When unset, the text field is blank. 40 * When updating the XML, if the field is empty, the attribute will be removed 41 * from the XML element. 42 * <p/> 43 * See {@link UiAttributeNode} for more information. 44 */ 45 public class UiTextAttributeNode extends UiAbstractTextAttributeNode { 46 47 /** Text field */ 48 private Text mText; 49 /** The managed form, set only once createUiControl has been called. */ 50 private IManagedForm mManagedForm; 51 UiTextAttributeNode(AttributeDescriptor attributeDescriptor, UiElementNode uiParent)52 public UiTextAttributeNode(AttributeDescriptor attributeDescriptor, UiElementNode uiParent) { 53 super(attributeDescriptor, uiParent); 54 } 55 56 /* (non-java doc) 57 * Creates a label widget and an associated text field. 58 * <p/> 59 * As most other parts of the android manifest editor, this assumes the 60 * parent uses a table layout with 2 columns. 61 */ 62 @Override createUiControl(Composite parent, IManagedForm managedForm)63 public void createUiControl(Composite parent, IManagedForm managedForm) { 64 setManagedForm(managedForm); 65 TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor(); 66 Text text = SectionHelper.createLabelAndText(parent, managedForm.getToolkit(), 67 desc.getUiName(), getCurrentValue(), 68 DescriptorsUtils.formatTooltip(desc.getTooltip())); 69 70 setTextWidget(text); 71 } 72 73 /** 74 * No completion values for this UI attribute. 75 * 76 * {@inheritDoc} 77 */ 78 @Override getPossibleValues(String prefix)79 public String[] getPossibleValues(String prefix) { 80 return null; 81 } 82 83 /** 84 * Sets the internal managed form. 85 * This is usually set by createUiControl. 86 */ setManagedForm(IManagedForm managedForm)87 protected void setManagedForm(IManagedForm managedForm) { 88 mManagedForm = managedForm; 89 } 90 91 /** 92 * @return The managed form, set only once createUiControl has been called. 93 */ getManagedForm()94 protected IManagedForm getManagedForm() { 95 return mManagedForm; 96 } 97 98 /* (non-java doc) 99 * Returns if the attribute node is valid, and its UI has been created. 100 */ 101 @Override isValid()102 public boolean isValid() { 103 return mText != null; 104 } 105 106 @Override getTextWidgetValue()107 public String getTextWidgetValue() { 108 if (mText != null) { 109 return mText.getText(); 110 } 111 112 return null; 113 } 114 115 @Override setTextWidgetValue(String value)116 public void setTextWidgetValue(String value) { 117 if (mText != null) { 118 mText.setText(value); 119 } 120 } 121 122 /** 123 * Sets the Text widget object, and prepares it to handle modification and synchronization 124 * with the XML node. 125 * @param textWidget 126 */ setTextWidget(Text textWidget)127 protected final void setTextWidget(Text textWidget) { 128 mText = textWidget; 129 130 if (textWidget != null) { 131 // Sets the with hint for the text field. Derived classes can always override it. 132 // This helps the grid layout to resize correctly on smaller screen sizes. 133 Object data = textWidget.getLayoutData(); 134 if (data == null) { 135 } else if (data instanceof GridData) { 136 ((GridData)data).widthHint = AndroidXmlEditor.TEXT_WIDTH_HINT; 137 } else if (data instanceof TableWrapData) { 138 ((TableWrapData)data).maxWidth = 100; 139 } 140 141 mText.addModifyListener(new ModifyListener() { 142 /** 143 * Sent when the text is modified, whether by the user via manual 144 * input or programmatic input via setText(). 145 * <p/> 146 * Simply mark the attribute as dirty if it really changed. 147 * The container SectionPart will collect these flag and manage them. 148 */ 149 @Override 150 public void modifyText(ModifyEvent e) { 151 if (!isInInternalTextModification() && 152 !isDirty() && 153 mText != null && 154 getCurrentValue() != null && 155 !mText.getText().equals(getCurrentValue())) { 156 setDirty(true); 157 } 158 } 159 }); 160 161 // Remove self-reference when the widget is disposed 162 mText.addDisposeListener(new DisposeListener() { 163 @Override 164 public void widgetDisposed(DisposeEvent e) { 165 mText = null; 166 } 167 }); 168 } 169 170 onAddValidators(mText); 171 } 172 173 /** 174 * Called after the text widget as been created. 175 * <p/> 176 * Derived classes typically want to: 177 * <li> Create a new {@link ModifyListener} and attach it to the given {@link Text} widget. 178 * <li> In the modify listener, call getManagedForm().getMessageManager().addMessage() 179 * and getManagedForm().getMessageManager().removeMessage() as necessary. 180 * <li> Call removeMessage in a new text.addDisposeListener. 181 * <li> Call the validator once to setup the initial messages as needed. 182 * <p/> 183 * The base implementation does nothing. 184 * 185 * @param text The {@link Text} widget to validate. 186 */ onAddValidators(Text text)187 protected void onAddValidators(Text text) { 188 } 189 190 /** 191 * Returns the text widget. 192 */ getTextWidget()193 protected final Text getTextWidget() { 194 return mText; 195 } 196 } 197