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
17package com.android.ide.eclipse.adt.internal.editors.uimodel;
18
19import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
20
21import org.w3c.dom.Node;
22
23/**
24 * Represents an XML attribute in that can be modified using a simple text field
25 * in the XML editor's user interface.
26 * <p/>
27 * The XML attribute has no default value. When unset, the text field is blank.
28 * When updating the XML, if the field is empty, the attribute will be removed
29 * from the XML element.
30 * <p/>
31 * See {@link UiAttributeNode} for more information.
32 */
33public abstract class UiAbstractTextAttributeNode extends UiAttributeNode
34    implements IUiSettableAttributeNode {
35
36    protected static final String DEFAULT_VALUE = "";  //$NON-NLS-1$
37
38    /** Prevent internal listener from firing when internally modifying the text */
39    private boolean mInternalTextModification;
40    /** Last value read from the XML model. Cannot be null. */
41    private String mCurrentValue = DEFAULT_VALUE;
42
43    public UiAbstractTextAttributeNode(AttributeDescriptor attributeDescriptor,
44            UiElementNode uiParent) {
45        super(attributeDescriptor, uiParent);
46    }
47
48    /** Returns the current value of the node. */
49    @Override
50    public final String getCurrentValue() {
51        return mCurrentValue;
52    }
53
54    /** Sets the current value of the node. Cannot be null (use an empty string). */
55    @Override
56    public final void setCurrentValue(String value) {
57        mCurrentValue = value;
58    }
59
60    /** Returns if the attribute node is valid, and its UI has been created. */
61    public abstract boolean isValid();
62
63    /** Returns the text value present in the UI. */
64    public abstract String getTextWidgetValue();
65
66    /** Sets the text value to be displayed in the UI. */
67    public abstract void setTextWidgetValue(String value);
68
69
70    /**
71     * Updates the current text field's value when the XML has changed.
72     * <p/>
73     * The caller doesn't really know if attributes have changed,
74     * so it will call this to refresh the attribute anyway. The value
75     * is only set if it has changed.
76     * <p/>
77     * This also resets the "dirty" flag.
78    */
79    @Override
80    public void updateValue(Node xml_attribute_node) {
81        mCurrentValue = DEFAULT_VALUE;
82        if (xml_attribute_node != null) {
83            mCurrentValue = xml_attribute_node.getNodeValue();
84        }
85
86        if (isValid() && !getTextWidgetValue().equals(mCurrentValue)) {
87            try {
88                mInternalTextModification = true;
89                setTextWidgetValue(mCurrentValue);
90                setDirty(false);
91            } finally {
92                mInternalTextModification = false;
93            }
94        }
95    }
96
97    /* (non-java doc)
98     * Called by the user interface when the editor is saved or its state changed
99     * and the modified attributes must be committed (i.e. written) to the XML model.
100     */
101    @Override
102    public void commit() {
103        UiElementNode parent = getUiParent();
104        if (parent != null && isValid() && isDirty()) {
105            String value = getTextWidgetValue();
106            if (parent.commitAttributeToXml(this, value)) {
107                mCurrentValue = value;
108                setDirty(false);
109            }
110        }
111    }
112
113    protected final boolean isInInternalTextModification() {
114        return mInternalTextModification;
115    }
116
117    protected final void setInInternalTextModification(boolean internalTextModification) {
118        mInternalTextModification = internalTextModification;
119    }
120}
121