diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiElementDetail.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiElementDetail.java | 494 |
1 files changed, 0 insertions, 494 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiElementDetail.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiElementDetail.java deleted file mode 100644 index 2aa56a826..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiElementDetail.java +++ /dev/null @@ -1,494 +0,0 @@ -/* - * 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.ui.tree; - -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper; -import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper.ManifestSectionPart; -import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ITreeSelection; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.forms.IDetailsPage; -import org.eclipse.ui.forms.IFormPart; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.events.ExpansionEvent; -import org.eclipse.ui.forms.events.IExpansionListener; -import org.eclipse.ui.forms.widgets.FormText; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.Section; -import org.eclipse.ui.forms.widgets.SharedScrolledComposite; -import org.eclipse.ui.forms.widgets.TableWrapData; -import org.eclipse.ui.forms.widgets.TableWrapLayout; - -import java.util.Collection; -import java.util.HashSet; - -/** - * Details page for the {@link UiElementNode} nodes in the tree view. - * <p/> - * See IDetailsBase for more details. - */ -class UiElementDetail implements IDetailsPage { - - /** The master-detail part, composed of a main tree and an auxiliary detail part */ - private ManifestSectionPart mMasterPart; - - private Section mMasterSection; - private UiElementNode mCurrentUiElementNode; - private Composite mCurrentTable; - private boolean mIsDirty; - - private IManagedForm mManagedForm; - - private final UiTreeBlock mTree; - - public UiElementDetail(UiTreeBlock tree) { - mTree = tree; - mMasterPart = mTree.getMasterPart(); - mManagedForm = mMasterPart.getManagedForm(); - } - - /* (non-java doc) - * Initializes the part. - */ - @Override - public void initialize(IManagedForm form) { - mManagedForm = form; - } - - /* (non-java doc) - * Creates the contents of the page in the provided parent. - */ - @Override - public void createContents(Composite parent) { - mMasterSection = createMasterSection(parent); - } - - /* (non-java doc) - * Called when the provided part has changed selection state. - * <p/> - * Only reply when our master part originates the selection. - */ - @Override - public void selectionChanged(IFormPart part, ISelection selection) { - if (part == mMasterPart && - !selection.isEmpty() && - selection instanceof ITreeSelection) { - ITreeSelection tree_selection = (ITreeSelection) selection; - - Object first = tree_selection.getFirstElement(); - if (first instanceof UiElementNode) { - UiElementNode ui_node = (UiElementNode) first; - createUiAttributeControls(mManagedForm, ui_node); - } - } - } - - /* (non-java doc) - * Instructs it to commit the new (modified) data back into the model. - */ - @Override - public void commit(boolean onSave) { - - mTree.getEditor().wrapEditXmlModel(new Runnable() { - @Override - public void run() { - try { - if (mCurrentUiElementNode != null) { - mCurrentUiElementNode.commit(); - } - - // Finally reset the dirty flag if everything was saved properly - mIsDirty = false; - } catch (Exception e) { - AdtPlugin.log(e, "Detail node failed to commit XML attribute!"); //$NON-NLS-1$ - } - } - }); - } - - @Override - public void dispose() { - // pass - } - - - /* (non-java doc) - * Returns true if the part has been modified with respect to the data - * loaded from the model. - */ - @Override - public boolean isDirty() { - if (mCurrentUiElementNode != null && mCurrentUiElementNode.isDirty()) { - markDirty(); - } - return mIsDirty; - } - - @Override - public boolean isStale() { - // pass - return false; - } - - /** - * Called by the master part when the tree is refreshed after the framework resources - * have been reloaded. - */ - @Override - public void refresh() { - if (mCurrentTable != null) { - mCurrentTable.dispose(); - mCurrentTable = null; - } - mCurrentUiElementNode = null; - mMasterSection.getParent().pack(true /* changed */); - } - - @Override - public void setFocus() { - // pass - } - - @Override - public boolean setFormInput(Object input) { - // pass - return false; - } - - /** - * Creates a TableWrapLayout in the DetailsPage, which in turns contains a Section. - * - * All the UI should be created in a layout which parent is the mSection itself. - * The hierarchy is: - * <pre> - * DetailPage - * + TableWrapLayout - * + Section (with title/description && fill_grab horizontal) - * + TableWrapLayout [*] - * + Labels/Forms/etc... [*] - * </pre> - * Both items marked with [*] are created by the derived classes to fit their needs. - * - * @param parent Parent of the mSection (from createContents) - * @return The new Section - */ - private Section createMasterSection(Composite parent) { - TableWrapLayout layout = new TableWrapLayout(); - layout.topMargin = 0; - parent.setLayout(layout); - - FormToolkit toolkit = mManagedForm.getToolkit(); - Section section = toolkit.createSection(parent, Section.TITLE_BAR); - section.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.TOP)); - return section; - } - - /** - * Create the ui attribute controls to edit the attributes for the given - * ElementDescriptor. - * <p/> - * This is called by the constructor. - * Derived classes can override this if necessary. - * - * @param managedForm The managed form - */ - private void createUiAttributeControls( - final IManagedForm managedForm, - final UiElementNode ui_node) { - - final ElementDescriptor elem_desc = ui_node.getDescriptor(); - mMasterSection.setText(String.format("Attributes for %1$s", ui_node.getShortDescription())); - - if (mCurrentUiElementNode != ui_node) { - // Before changing the table, commit all dirty state. - if (mIsDirty) { - commit(false); - } - if (mCurrentTable != null) { - mCurrentTable.dispose(); - mCurrentTable = null; - } - - // To iterate over all attributes, we use the {@link ElementDescriptor} instead - // of the {@link UiElementNode} because the attributes order is guaranteed in the - // descriptor but not in the node itself. - AttributeDescriptor[] attr_desc_list = ui_node.getAttributeDescriptors(); - - // If the attribute list contains at least one SeparatorAttributeDescriptor, - // sub-sections will be used. This needs to be known early as it influences the - // creation of the master table. - boolean useSubsections = false; - for (AttributeDescriptor attr_desc : attr_desc_list) { - if (attr_desc instanceof SeparatorAttributeDescriptor) { - // Sub-sections will be used. The default sections should no longer be - useSubsections = true; - break; - } - } - - FormToolkit toolkit = managedForm.getToolkit(); - Composite masterTable = SectionHelper.createTableLayout(mMasterSection, - toolkit, useSubsections ? 1 : 2 /* numColumns */); - mCurrentTable = masterTable; - - mCurrentUiElementNode = ui_node; - - if (elem_desc.getTooltip() != null) { - String tooltip; - if (Sdk.getCurrent() != null && - Sdk.getCurrent().getDocumentationBaseUrl() != null) { - tooltip = DescriptorsUtils.formatFormText(elem_desc.getTooltip(), - elem_desc, - Sdk.getCurrent().getDocumentationBaseUrl()); - } else { - tooltip = elem_desc.getTooltip(); - } - - try { - FormText text = SectionHelper.createFormText(masterTable, toolkit, - true /* isHtml */, tooltip, true /* setupLayoutData */); - text.addHyperlinkListener(mTree.getEditor().createHyperlinkListener()); - Image icon = elem_desc.getCustomizedIcon(); - if (icon != null) { - text.setImage(DescriptorsUtils.IMAGE_KEY, icon); - } - } catch(Exception e) { - // The FormText parser is really really basic and will fail as soon as the - // HTML javadoc is ever so slightly malformatted. - AdtPlugin.log(e, - "Malformed javadoc, rejected by FormText for node %1$s: '%2$s'", //$NON-NLS-1$ - ui_node.getDescriptor().getXmlName(), - tooltip); - - // Fallback to a pure text tooltip, no fancy HTML - tooltip = DescriptorsUtils.formatTooltip(elem_desc.getTooltip()); - SectionHelper.createLabel(masterTable, toolkit, tooltip, tooltip); - } - } - - Composite table = useSubsections ? null : masterTable; - - for (AttributeDescriptor attr_desc : attr_desc_list) { - if (attr_desc instanceof XmlnsAttributeDescriptor) { - // Do not show hidden attributes - continue; - } else if (table == null || attr_desc instanceof SeparatorAttributeDescriptor) { - String title = null; - if (attr_desc instanceof SeparatorAttributeDescriptor) { - // xmlName is actually the label of the separator - title = attr_desc.getXmlLocalName(); - } else { - title = String.format("Attributes from %1$s", elem_desc.getUiName()); - } - - table = createSubSectionTable(toolkit, masterTable, title); - if (attr_desc instanceof SeparatorAttributeDescriptor) { - continue; - } - } - - UiAttributeNode ui_attr = ui_node.findUiAttribute(attr_desc); - - if (ui_attr != null) { - ui_attr.createUiControl(table, managedForm); - - if (ui_attr.getCurrentValue() != null && - ui_attr.getCurrentValue().length() > 0) { - ((Section) table.getParent()).setExpanded(true); - } - } else { - // The XML has an extra unknown attribute. - // This is not expected to happen so it is ignored. - AdtPlugin.log(IStatus.INFO, - "Attribute %1$s not declared in node %2$s, ignored.", //$NON-NLS-1$ - attr_desc.getXmlLocalName(), - ui_node.getDescriptor().getXmlName()); - } - } - - // Create a sub-section for the unknown attributes. - // It is initially hidden till there are some attributes to show here. - final Composite unknownTable = createSubSectionTable(toolkit, masterTable, - "Unknown XML Attributes"); - unknownTable.getParent().setVisible(false); // set section to not visible - final HashSet<UiAttributeNode> reference = new HashSet<UiAttributeNode>(); - - final IUiUpdateListener updateListener = new IUiUpdateListener() { - @Override - public void uiElementNodeUpdated(UiElementNode uiNode, UiUpdateState state) { - if (state == UiUpdateState.ATTR_UPDATED) { - updateUnknownAttributesSection(uiNode, unknownTable, managedForm, - reference); - } - } - }; - ui_node.addUpdateListener(updateListener); - - // remove the listener when the UI is disposed - unknownTable.addDisposeListener(new DisposeListener() { - @Override - public void widgetDisposed(DisposeEvent e) { - ui_node.removeUpdateListener(updateListener); - } - }); - - updateUnknownAttributesSection(ui_node, unknownTable, managedForm, reference); - - mMasterSection.getParent().pack(true /* changed */); - } - } - - /** - * Create a sub Section and its embedding wrapper table with 2 columns. - * @return The table, child of a new section. - */ - private Composite createSubSectionTable(FormToolkit toolkit, - Composite masterTable, String title) { - - // The Section composite seems to ignore colspan when assigned a TableWrapData so - // if the parent is a table with more than one column an extra table with one column - // is inserted to respect colspan. - int parentNumCol = ((TableWrapLayout) masterTable.getLayout()).numColumns; - if (parentNumCol > 1) { - masterTable = SectionHelper.createTableLayout(masterTable, toolkit, 1); - TableWrapData twd = new TableWrapData(TableWrapData.FILL_GRAB); - twd.maxWidth = AndroidXmlEditor.TEXT_WIDTH_HINT; - twd.colspan = parentNumCol; - masterTable.setLayoutData(twd); - } - - Composite table; - Section section = toolkit.createSection(masterTable, - Section.TITLE_BAR | Section.TWISTIE); - - // Add an expansion listener that will trigger a reflow on the parent - // ScrolledPageBook (which is actually a SharedScrolledComposite). This will - // recompute the correct size and adjust the scrollbar as needed. - section.addExpansionListener(new IExpansionListener() { - @Override - public void expansionStateChanged(ExpansionEvent e) { - reflowMasterSection(); - } - - @Override - public void expansionStateChanging(ExpansionEvent e) { - // pass - } - }); - - section.setText(title); - section.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, - TableWrapData.TOP)); - table = SectionHelper.createTableLayout(section, toolkit, 2 /* numColumns */); - return table; - } - - /** - * Reflow the parent ScrolledPageBook (which is actually a SharedScrolledComposite). - * This will recompute the correct size and adjust the scrollbar as needed. - */ - private void reflowMasterSection() { - for(Composite c = mMasterSection; c != null; c = c.getParent()) { - if (c instanceof SharedScrolledComposite) { - ((SharedScrolledComposite) c).reflow(true /* flushCache */); - break; - } - } - } - - /** - * Updates the unknown attributes section for the UI Node. - */ - private void updateUnknownAttributesSection(UiElementNode ui_node, - final Composite unknownTable, final IManagedForm managedForm, - HashSet<UiAttributeNode> reference) { - Collection<UiAttributeNode> ui_attrs = ui_node.getUnknownUiAttributes(); - Section section = ((Section) unknownTable.getParent()); - boolean needs_reflow = false; - - // The table was created hidden, show it if there are unknown attributes now - if (ui_attrs.size() > 0 && !section.isVisible()) { - section.setVisible(true); - needs_reflow = true; - } - - // Compare the new attribute set with the old "reference" one - boolean has_differences = ui_attrs.size() != reference.size(); - if (!has_differences) { - for (UiAttributeNode ui_attr : ui_attrs) { - if (!reference.contains(ui_attr)) { - has_differences = true; - break; - } - } - } - - if (has_differences) { - needs_reflow = true; - reference.clear(); - - // Remove all children of the table - for (Control c : unknownTable.getChildren()) { - c.dispose(); - } - - // Recreate all attributes UI - for (UiAttributeNode ui_attr : ui_attrs) { - reference.add(ui_attr); - ui_attr.createUiControl(unknownTable, managedForm); - - if (ui_attr.getCurrentValue() != null && ui_attr.getCurrentValue().length() > 0) { - section.setExpanded(true); - } - } - } - - if (needs_reflow) { - reflowMasterSection(); - } - } - - /** - * Marks the part dirty. Called as a result of user interaction with the widgets in the - * section. - */ - private void markDirty() { - if (!mIsDirty) { - mIsDirty = true; - mManagedForm.dirtyStateChanged(); - } - } -} - - |