import com.android.ide.eclipse.editors.manifest.ManifestEditor;
import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
import com.android.ide.eclipse.editors.ui.UiElementPart;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
-import org.w3c.dom.Node;
/**
- * Generic info section part for overview page
+ * Generic info section part for overview page: it displays all the attributes from
+ * the manifest element.
*/
final class OverviewInfoPart extends UiElementPart {
public OverviewInfoPart(Composite body, FormToolkit toolkit, ManifestEditor editor) {
super(body, toolkit, editor,
- null, // uiElementNode
- "General Information", // section title
+ getManifestUiNode(editor), // uiElementNode
+ "Manifest General Attributes", // section title
"Defines general information about the AndroidManifest.xml", // section description
Section.TWISTIE | Section.EXPANDED);
}
}
/**
- * Retrieves the uses-sdk UI node. Since this is a mandatory node, it *always*
- * exists, even if there is no matching XML node.
- */
- private UiElementNode getUsesSdkUiNode(ManifestEditor editor) {
- AndroidManifestDescriptors manifestDescriptors = editor.getManifestDescriptors();
- if (manifestDescriptors != null) {
- ElementDescriptor desc = manifestDescriptors.getUsesSdkElement();
- return editor.getUiRootNode().findUiChildNode(desc.getXmlName());
- }
-
- // No manifest descriptor: we have a dummy UiRootNode, so we return that.
- // The editor will be reloaded once we have the proper descriptors anyway.
- return editor.getUiRootNode();
- }
-
- /**
* Overridden in order to capture the current managed form.
*
* {@inheritDoc}
* SDK has changed.
*/
public void onSdkChanged() {
+ setUiElementNode(getManifestUiNode(getEditor()));
createUiAttributes(mManagedForm);
}
-
- /**
- * Overridden to add the description and the ui attributes of both the
- * manifest and uses-sdk UI nodes.
- * <p/>
- * {@inheritDoc}
- */
- @Override
- protected void fillTable(Composite table, IManagedForm managedForm) {
- int n = 0;
-
- UiElementNode uiNode = getManifestUiNode(getEditor());
- n += insertUiAttributes(uiNode, table, managedForm);
-
- uiNode = getUsesSdkUiNode(getEditor());
- n += insertUiAttributes(uiNode, table, managedForm);
-
- if (n == 0) {
- createLabel(table, managedForm.getToolkit(),
- "No attributes to display, waiting for SDK to finish loading...",
- null /* tooltip */ );
- }
-
- layoutChanged();
- }
-
- /**
- * Overridden to tests whether either the manifest or uses-sdk nodes parts are dirty.
- * <p/>
- * {@inheritDoc}
- *
- * @return <code>true</code> if the part is dirty, <code>false</code>
- * otherwise.
- */
- @Override
- public boolean isDirty() {
- boolean dirty = super.isDirty();
-
- if (!dirty) {
- UiElementNode uiNode = getManifestUiNode(getEditor());
- if (uiNode != null) {
- for (UiAttributeNode ui_attr : uiNode.getUiAttributes()) {
- if (ui_attr.isDirty()) {
- markDirty();
- dirty = true;
- break;
- }
- }
- }
- }
-
- if (!dirty) {
- UiElementNode uiNode = getUsesSdkUiNode(getEditor());
- if (uiNode != null) {
- for (UiAttributeNode ui_attr : uiNode.getUiAttributes()) {
- if (ui_attr.isDirty()) {
- markDirty();
- dirty = true;
- break;
- }
- }
- }
- }
-
- return dirty;
- }
-
- /**
- * Overridden to save both the manifest or uses-sdk nodes.
- * <p/>
- * {@inheritDoc}
- */
- @Override
- public void commit(boolean onSave) {
- final UiElementNode manifestUiNode = getManifestUiNode(getEditor());
- final UiElementNode usesSdkUiNode = getUsesSdkUiNode(getEditor());
-
- getEditor().editXmlModel(new Runnable() {
- public void run() {
- if (manifestUiNode != null && manifestUiNode.isDirty()) {
- for (UiAttributeNode ui_attr : manifestUiNode.getUiAttributes()) {
- ui_attr.commit();
- }
- }
-
- if (usesSdkUiNode != null && usesSdkUiNode.isDirty()) {
- for (UiAttributeNode ui_attr : usesSdkUiNode.getUiAttributes()) {
- ui_attr.commit();
- }
-
- if (!usesSdkUiNode.isDirty()) {
- // Remove the <uses-sdk> XML element if it is empty.
- // Rather than rely on the internal UI state, actually check that the
- // XML element has no attributes and no child element so that we don't
- // trash some user-generated content.
- Node element = usesSdkUiNode.prepareCommit();
- if (element != null &&
- !element.hasAttributes() &&
- !element.hasChildNodes()) {
- // Important note: we MUST NOT use usesSdkUiNode.deleteXmlNode()
- // here, as it would clear the UiAttribute list and thus break the
- // link between the controls and the ui attribute field.
- // Instead what we want is simply to remove the XML node and let the
- // UiElementNode node know.
- Node parent = element.getParentNode();
- if (parent != null) {
- parent.removeChild(element);
- usesSdkUiNode.loadFromXmlNode(null /*xml_node*/);
- }
- }
- }
- }
- }
- });
-
- // We need to call super's commit after we synchronized the nodes to make sure we
- // reset the dirty flag after all the side effects from committing have occurred.
- super.commit(onSave);
- }
}
package com.android.ide.eclipse.editors.manifest.pages;
import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.editors.manifest.ManifestEditor;
+import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
+import com.android.ide.eclipse.editors.ui.tree.UiTreeBlock;
+import com.android.ide.eclipse.editors.uimodel.UiElementNode;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormPage;
-import org.eclipse.ui.forms.widgets.ColumnLayout;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
+import java.util.ArrayList;
+import java.util.HashSet;
+
/**
* Page for overview settings, part of the AndroidManifest form editor.
private OverviewInfoPart mOverviewPart;
/** Overview link part */
private OverviewLinksPart mOverviewLinkPart;
+
+ private UiTreeBlock mTreeBlock;
public OverviewPage(ManifestEditor editor) {
- super(editor, PAGE_ID, "Overview"); // tab's label, user visible, keep it short
+ super(editor, PAGE_ID, "Manifest"); // tab's label, user visible, keep it short
mEditor = editor;
}
protected void createFormContent(IManagedForm managedForm) {
super.createFormContent(managedForm);
ScrolledForm form = managedForm.getForm();
- form.setText("Android Manifest Overview");
+ form.setText("Android Manifest");
form.setImage(AdtPlugin.getAndroidLogo());
Composite body = form.getBody();
FormToolkit toolkit = managedForm.getToolkit();
- ColumnLayout cl = new ColumnLayout();
- cl.minNumColumns = cl.maxNumColumns = 1;
- body.setLayout(cl);
+
+ // Usually we would set a ColumnLayout on body here. However the presence of the
+ // UiTreeBlock forces a GridLayout with one column so we comply with it.
+
mOverviewPart = new OverviewInfoPart(body, toolkit, mEditor);
+ mOverviewPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
managedForm.addPart(mOverviewPart);
- managedForm.addPart(new OverviewExportPart(this, body, toolkit, mEditor));
+
+ newManifestExtrasPart(managedForm);
+
+ OverviewExportPart exportPart = new OverviewExportPart(this, body, toolkit, mEditor);
+ exportPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ managedForm.addPart(exportPart);
+
mOverviewLinkPart = new OverviewLinksPart(body, toolkit, mEditor);
+ mOverviewLinkPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
managedForm.addPart(mOverviewLinkPart);
}
+ private void newManifestExtrasPart(IManagedForm managedForm) {
+ UiElementNode manifest = mEditor.getUiRootNode();
+ mTreeBlock = new UiTreeBlock(mEditor, manifest,
+ true /* autoCreateRoot */,
+ computeManifestExtraFilters(),
+ "Manifest Extras",
+ "Extra manifest elements");
+ mTreeBlock.createContent(managedForm);
+ }
+
/**
* Changes and refreshes the Application UI node handle by the sub parts.
*/
if (mOverviewLinkPart != null) {
mOverviewLinkPart.onSdkChanged();
}
+
+ if (mTreeBlock != null) {
+ UiElementNode manifest = mEditor.getUiRootNode();
+ mTreeBlock.changeRootAndDescriptors(manifest,
+ computeManifestExtraFilters(),
+ true /* refresh */);
+ }
+ }
+
+ private ElementDescriptor[] computeManifestExtraFilters() {
+ UiElementNode manifest = mEditor.getUiRootNode();
+ AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors();
+
+ if (manifestDescriptor == null) {
+ return null;
+ }
+
+ // get the elements we want to exclude
+ HashSet<ElementDescriptor> excludes = new HashSet<ElementDescriptor>();
+ excludes.add(manifestDescriptor.getApplicationElement());
+ excludes.add(manifestDescriptor.getInstrumentationElement());
+ excludes.add(manifestDescriptor.getPermissionElement());
+ excludes.add(manifestDescriptor.getPermissionGroupElement());
+ excludes.add(manifestDescriptor.getPermissionTreeElement());
+ excludes.add(manifestDescriptor.getUsesPermissionElement());
+
+ // walk through the known children of the manifest descriptor and keep what's not excluded
+ ArrayList<ElementDescriptor> descriptorFilters = new ArrayList<ElementDescriptor>();
+ for (ElementDescriptor child : manifest.getDescriptor().getChildren()) {
+ if (!excludes.contains(child)) {
+ descriptorFilters.add(child);
+ }
+ }
+
+ if (descriptorFilters.size() == 0) {
+ return null;
+ }
+ return descriptorFilters.toArray(new ElementDescriptor[descriptorFilters.size()]);
}
}