Home | History | Annotate | Download | only in uimodel
      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 
     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
     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
     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      */
     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      */
     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
    102     public boolean isValid() {
    103         return mText != null;
    104     }
    105 
    106     @Override
    107     public String getTextWidgetValue() {
    108         if (mText != null) {
    109             return mText.getText();
    110         }
    111 
    112         return null;
    113     }
    114 
    115     @Override
    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      */
    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      */
    187     protected void onAddValidators(Text text) {
    188     }
    189 
    190     /**
    191      * Returns the text widget.
    192      */
    193     protected final Text getTextWidget() {
    194         return mText;
    195     }
    196 }
    197