blob: ffe637c5d40655bf2fb8e3ad3b5108ef137ca05e [file] [log] [blame]
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.eclipse.org/org/documents/epl-v10.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.ide.eclipse.adt.internal.editors.uimodel;
import com.android.ide.common.xml.XmlAttributeSortOrder;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.forms.IManagedForm;
import org.w3c.dom.Node;
/**
* Represents an XML attribute that can be modified by the XML editor's user interface.
* <p/>
* The characteristics of an {@link UiAttributeNode} are declared by a
* corresponding {@link AttributeDescriptor}.
* <p/>
* This is an abstract class. Derived classes must implement the creation of the UI
* and manage its synchronization with the XML.
*/
public abstract class UiAttributeNode implements Comparable<UiAttributeNode> {
private AttributeDescriptor mDescriptor;
private UiElementNode mUiParent;
private boolean mIsDirty;
private boolean mHasError;
/** Creates a new {@link UiAttributeNode} linked to a specific {@link AttributeDescriptor}
* and the corresponding runtime {@link UiElementNode} parent. */
public UiAttributeNode(AttributeDescriptor attributeDescriptor, UiElementNode uiParent) {
mDescriptor = attributeDescriptor;
mUiParent = uiParent;
}
/** Returns the {@link AttributeDescriptor} specific to this UI attribute node */
public final AttributeDescriptor getDescriptor() {
return mDescriptor;
}
/** Returns the {@link UiElementNode} that owns this {@link UiAttributeNode} */
public final UiElementNode getUiParent() {
return mUiParent;
}
/** Returns the current value of the node. */
public abstract String getCurrentValue();
/**
* @return True if the attribute has been changed since it was last loaded
* from the XML model.
*/
public final boolean isDirty() {
return mIsDirty;
}
/**
* Sets whether the attribute is dirty and also notifies the editor some part's dirty
* flag as changed.
* <p/>
* Subclasses should set the to true as a result of user interaction with the widgets in
* the section and then should set to false when the commit() method completed.
*
* @param isDirty the new value to set the dirty-flag to
*/
public void setDirty(boolean isDirty) {
boolean wasDirty = mIsDirty;
mIsDirty = isDirty;
// TODO: for unknown attributes, getParent() != null && getParent().getEditor() != null
if (wasDirty != isDirty) {
AndroidXmlEditor editor = getUiParent().getEditor();
if (editor != null) {
editor.editorDirtyStateChanged();
}
}
}
/**
* Sets the error flag value.
* @param errorFlag the error flag
*/
public final void setHasError(boolean errorFlag) {
mHasError = errorFlag;
}
/**
* Returns whether this node has errors.
*/
public final boolean hasError() {
return mHasError;
}
/**
* Called once by the parent user interface to creates the necessary
* user interface to edit this attribute.
* <p/>
* This method can be called more than once in the life cycle of an UI node,
* typically when the UI is part of a master-detail tree, as pages are swapped.
*
* @param parent The composite where to create the user interface.
* @param managedForm The managed form owning this part.
*/
public abstract void createUiControl(Composite parent, IManagedForm managedForm);
/**
* Used to get a list of all possible values for this UI attribute.
* <p/>
* This is used, among other things, by the XML Content Assists to complete values
* for an attribute.
* <p/>
* Implementations that do not have any known values should return null.
*
* @param prefix An optional prefix string, which is whatever the user has already started
* typing. Can be null or an empty string. The implementation can use this to filter choices
* and only return strings that match this prefix. A lazy or default implementation can
* simply ignore this and return everything.
* @return A list of possible completion values, and empty array or null.
*/
public abstract String[] getPossibleValues(String prefix);
/**
* Called when the XML is being loaded or has changed to
* update the value held by this user interface attribute node.
* <p/>
* The XML Node <em>may</em> be null, which denotes that the attribute is not
* specified in the XML model. In general, this means the "default" value of the
* attribute should be used.
* <p/>
* The caller doesn't really know if attributes have changed,
* so it will call this to refresh the attribute anyway. It's up to the
* UI implementation to minimize refreshes.
*
* @param node the node to read the value from
*/
public abstract void updateValue(Node node);
/**
* Called by the user interface when the editor is saved or its state changed
* and the modified attributes must be committed (i.e. written) to the XML model.
* <p/>
* Important behaviors:
* <ul>
* <li>The caller *must* have called IStructuredModel.aboutToChangeModel before.
* The implemented methods must assume it is safe to modify the XML model.
* <li>On success, the implementation *must* call setDirty(false).
* <li>On failure, the implementation can fail with an exception, which
* is trapped and logged by the caller, or do nothing, whichever is more
* appropriate.
* </ul>
*/
public abstract void commit();
// ---- Implements Comparable ----
@Override
public int compareTo(UiAttributeNode o) {
return XmlAttributeSortOrder.compareAttributes(mDescriptor.getXmlLocalName(),
o.mDescriptor.getXmlLocalName());
}
}