UiActionspublic abstract class UiActions extends Object implements ICommitXmlPerforms basic actions on an XML tree: add node, remove node, move up/down. |
Constructors Summary |
---|
public UiActions()
|
Methods Summary |
---|
public com.android.ide.eclipse.editors.uimodel.UiElementNode | addElement(com.android.ide.eclipse.editors.uimodel.UiElementNode uiParent, com.android.ide.eclipse.editors.uimodel.UiElementNode uiSibling, com.android.ide.eclipse.editors.descriptors.ElementDescriptor descriptor, boolean updateLayout)Adds a new XML element based on the {@link ElementDescriptor} to the given parent
{@link UiElementNode}, and then select it.
If the parent is a document root which already contains a root element, the inner
root element is used as the actual parent. This ensure you can't create a broken
XML file with more than one root element.
If a sibling is given and that sibling has the same parent, the new node is added
right after that sibling. Otherwise the new node is added at the end of the parent
child list.
if (uiParent instanceof UiDocumentNode && uiParent.getUiChildren().size() > 0) {
uiParent = uiParent.getUiChildren().get(0);
}
if (uiSibling != null && uiSibling.getUiParent() != uiParent) {
uiSibling = null;
}
UiElementNode uiNew = addNewTreeElement(uiParent, uiSibling, descriptor, updateLayout);
selectUiNode(uiNew);
return uiNew;
| private com.android.ide.eclipse.editors.uimodel.UiElementNode | addNewTreeElement(com.android.ide.eclipse.editors.uimodel.UiElementNode uiParent, com.android.ide.eclipse.editors.uimodel.UiElementNode uiSibling, com.android.ide.eclipse.editors.descriptors.ElementDescriptor descriptor, boolean updateLayout)Adds a new element of the given descriptor's type to the given UI parent node.
This actually creates the corresponding XML node in the XML model, which in turn
will refresh the current tree view.
commitPendingXmlChanges();
int index = 0;
for (UiElementNode uiChild : uiParent.getUiChildren()) {
if (uiChild == uiSibling) {
break;
}
index++;
}
final UiElementNode uiNew = uiParent.insertNewUiChild(index, descriptor);
UiElementNode rootNode = getRootNode();
rootNode.getEditor().editXmlModel(new Runnable() {
public void run() {
DescriptorsUtils.setDefaultLayoutAttributes(uiNew, updateLayout);
Node xmlNode = uiNew.createXmlNode();
}
});
return uiNew;
| public abstract void | commitPendingXmlChanges()Commits pending data before the XML model is modified.
| public void | doAdd(com.android.ide.eclipse.editors.uimodel.UiElementNode uiNode, org.eclipse.swt.widgets.Shell shell)Called when the "Add..." button next to the tree view is selected.
This simplified version of doAdd does not support descriptor filters and creates
a new {@link UiModelTreeLabelProvider} for each call.
doAdd(uiNode, null /* descriptorFilters */, shell, new UiModelTreeLabelProvider());
| public void | doAdd(com.android.ide.eclipse.editors.uimodel.UiElementNode uiNode, com.android.ide.eclipse.editors.descriptors.ElementDescriptor[] descriptorFilters, org.eclipse.swt.widgets.Shell shell, org.eclipse.jface.viewers.ILabelProvider labelProvider)Called when the "Add..." button next to the tree view is selected.
Displays a selection dialog that lets the user select which kind of node
to create, depending on the current selection.
// If the root node is a document with already a root, use it as the root node
UiElementNode rootNode = getRootNode();
if (rootNode instanceof UiDocumentNode && rootNode.getUiChildren().size() > 0) {
rootNode = rootNode.getUiChildren().get(0);
}
NewItemSelectionDialog dlg = new NewItemSelectionDialog(
shell,
labelProvider,
descriptorFilters,
uiNode, rootNode);
dlg.open();
Object[] results = dlg.getResult();
if (results != null && results.length > 0) {
addElement(dlg.getChosenRootNode(), null, (ElementDescriptor) results[0],
true /*updateLayout*/);
}
| public void | doDown(java.util.List nodes)Called when the "Down" button is selected.
If the tree has a selection, move it down, either in the same child list or as the
first child of the next parent.
if (nodes == null || nodes.size() < 1) {
return;
}
final Node[] select_xml_node = { null };
UiElementNode last_node = null;
UiElementNode search_root = null;
for (int i = nodes.size() - 1; i >= 0; i--) {
final UiElementNode node = last_node = nodes.get(i);
// the node will move either down to its parent or grand-parent
search_root = node.getUiParent();
if (search_root != null && search_root.getUiParent() != null) {
search_root = search_root.getUiParent();
}
commitPendingXmlChanges();
getRootNode().getEditor().editXmlModel(new Runnable() {
public void run() {
Node xml_node = node.getXmlNode();
if (xml_node != null) {
Node xml_parent = xml_node.getParentNode();
if (xml_parent != null) {
UiElementNode uiNext = node.getUiNextSibling();
if (uiNext != null && uiNext.getXmlNode() != null) {
// This node is not the last one of the parent, so it can be
// removed and then inserted after its next sibling.
// If the next sibling is a node that can have children, though,
// then the node is inserted as the first child.
Node xml_next = uiNext.getXmlNode();
if (uiNext.getDescriptor().hasChildren()) {
// Note: insertBefore works as append if the ref node is
// null, i.e. when the node doesn't have children yet.
xml_next.insertBefore(xml_parent.removeChild(xml_node),
xml_next.getFirstChild());
select_xml_node[0] = xml_node;
} else {
// Insert "before after next" ;-)
xml_parent.insertBefore(xml_parent.removeChild(xml_node),
xml_next.getNextSibling());
select_xml_node[0] = xml_node;
}
} else if (!(xml_parent instanceof Document) &&
xml_parent.getParentNode() != null &&
!(xml_parent.getParentNode() instanceof Document)) {
// This node is the last node of its parent.
// If neither the parent nor the grandparent is a document,
// then the node can be insert right after the parent.
Node grand_parent = xml_parent.getParentNode();
grand_parent.insertBefore(xml_parent.removeChild(xml_node),
xml_parent.getNextSibling());
select_xml_node[0] = xml_node;
}
}
}
}
});
}
if (select_xml_node[0] == null) {
// The XML node has not been moved, we can just select the same UI node
selectUiNode(last_node);
} else {
// The XML node has moved. At this point the UI model has been reloaded
// and the XML node has been affected to a new UI node. Find that new UI
// node and select it.
if (search_root == null) {
search_root = last_node.getUiRoot();
}
if (search_root != null) {
selectUiNode(search_root.findXmlNode(select_xml_node[0]));
}
}
| public void | doRemove(java.util.List nodes, org.eclipse.swt.widgets.Shell shell)Called when the "Remove" button is selected.
If the tree has a selection, remove it.
This simply deletes the XML node attached to the UI node: when the XML model fires the
update event, the tree will get refreshed.
if (nodes == null || nodes.size() == 0) {
return;
}
final int len = nodes.size();
StringBuilder sb = new StringBuilder();
for (UiElementNode node : nodes) {
sb.append("\n- "); //$NON-NLS-1$
sb.append(node.getBreadcrumbTrailDescription(false /* include_root */));
}
if (MessageDialog.openQuestion(shell,
len > 1 ? "Remove elements from Android XML" // title
: "Remove element from Android XML",
String.format("Do you really want to remove %1$s?", sb.toString()))) {
commitPendingXmlChanges();
getRootNode().getEditor().editXmlModel(new Runnable() {
public void run() {
UiElementNode previous = null;
UiElementNode parent = null;
for (int i = len - 1; i >= 0; i--) {
UiElementNode node = nodes.get(i);
previous = node.getUiPreviousSibling();
parent = node.getUiParent();
// delete node
node.deleteXmlNode();
}
// try to select the last previous sibling or the last parent
if (previous != null) {
selectUiNode(previous);
} else if (parent != null) {
selectUiNode(parent);
}
}
});
}
| public void | doUp(java.util.List nodes)Called when the "Up" button is selected.
If the tree has a selection, move it up, either in the child list or as the last child
of the previous parent.
if (nodes == null || nodes.size() < 1) {
return;
}
final Node[] select_xml_node = { null };
UiElementNode last_node = null;
UiElementNode search_root = null;
for (int i = 0; i < nodes.size(); i++) {
final UiElementNode node = last_node = nodes.get(i);
// the node will move either up to its parent or grand-parent
search_root = node.getUiParent();
if (search_root != null && search_root.getUiParent() != null) {
search_root = search_root.getUiParent();
}
commitPendingXmlChanges();
getRootNode().getEditor().editXmlModel(new Runnable() {
public void run() {
Node xml_node = node.getXmlNode();
if (xml_node != null) {
Node xml_parent = xml_node.getParentNode();
if (xml_parent != null) {
UiElementNode ui_prev = node.getUiPreviousSibling();
if (ui_prev != null && ui_prev.getXmlNode() != null) {
// This node is not the first one of the parent, so it can be
// removed and then inserted before its previous sibling.
// If the previous sibling can have children, though, then it
// is inserted at the end of the children list.
Node xml_prev = ui_prev.getXmlNode();
if (ui_prev.getDescriptor().hasChildren()) {
xml_prev.appendChild(xml_parent.removeChild(xml_node));
select_xml_node[0] = xml_node;
} else {
xml_parent.insertBefore(
xml_parent.removeChild(xml_node),
xml_prev);
select_xml_node[0] = xml_node;
}
} else if (!(xml_parent instanceof Document) &&
xml_parent.getParentNode() != null &&
!(xml_parent.getParentNode() instanceof Document)) {
// If the node is the first one of the child list of its
// parent, move it up in the hierarchy as previous sibling
// to the parent. This is only possible if the parent of the
// parent is not a document.
Node grand_parent = xml_parent.getParentNode();
grand_parent.insertBefore(xml_parent.removeChild(xml_node),
xml_parent);
select_xml_node[0] = xml_node;
}
}
}
}
});
}
if (select_xml_node[0] == null) {
// The XML node has not been moved, we can just select the same UI node
selectUiNode(last_node);
} else {
// The XML node has moved. At this point the UI model has been reloaded
// and the XML node has been affected to a new UI node. Find that new UI
// node and select it.
if (search_root == null) {
search_root = last_node.getUiRoot();
}
if (search_root != null) {
selectUiNode(search_root.findXmlNode(select_xml_node[0]));
}
}
| protected abstract com.android.ide.eclipse.editors.uimodel.UiElementNode | getRootNode()Returns the UiDocumentNode for the current model.
| protected abstract void | selectUiNode(com.android.ide.eclipse.editors.uimodel.UiElementNode uiNode)Utility method to select an outline item based on its model node
|
|