diff options
| author | Tor Norbye <tnorbye@google.com> | 2011-11-23 17:52:58 -0800 |
|---|---|---|
| committer | Tor Norbye <tnorbye@google.com> | 2011-11-23 17:52:58 -0800 |
| commit | 556f4bc4717cad7d116d85fe41301bc57feec7eb (patch) | |
| tree | e708b5f53ac8611863c1066117e76d6296e31ebf | |
| parent | 840bdbba4423ea844097552d636d7c80efa65ea9 (diff) | |
| download | sdk-556f4bc4717cad7d116d85fe41301bc57feec7eb.zip sdk-556f4bc4717cad7d116d85fe41301bc57feec7eb.tar.gz sdk-556f4bc4717cad7d116d85fe41301bc57feec7eb.tar.bz2 | |
Fix for custom view rendering with auto-format, revisited
This changeset revisits
http://code.google.com/p/android/issues/detail?id=21750
"Layout editor auto-formatting breaks rendering of custom views"
The bug described in the issue is that dragging custom views into the
canvas does not trigger a render until you save the file. My initial
bug fix noted that we actually would get *two* render requests, and
the second render was blank, so I fixed the model notifications such
that only a single notification (triggering a render) was sent.
However, collapsing the two changeModel calls into the DOM model
turned out to have some adverse effects when auto-format was enabled,
so I turned off auto-format until I could track the bug down.
In this changeset I'm turning it back on, and fixing the root cause
which made the custom view not appear: in the XML DOM to UI Model
sync, no descriptor was found for the custom view so the node simply
wasn't added to the model.
We still don't want multiple notifications (and therefore renders), so
I'm also changing the notifications structure a bit. Now a single
notification is made after all the edit hooks are run, and after the
edit lock has been released (it grabs a read lock instead for the
duration of the notification phase).
Change-Id: I2281dc936bf0442e2d38ac2750e81a8f120a924e
3 files changed, 41 insertions, 19 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlEditor.java index 59db8e6..836fdb3 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlEditor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlEditor.java @@ -965,13 +965,13 @@ public abstract class AndroidXmlEditor extends FormEditor implements IResourceCh mIsEditXmlModelPending--; if (model != null) { try { - // Notify the model we're done modifying it. This must *always* be executed. - model.changedModel(); + boolean oldIgnore = mIgnoreXmlUpdate; + try { + mIgnoreXmlUpdate = true; + // Notify the model we're done modifying it. This must *always* be executed. + model.changedModel(); - if (AdtPrefs.getPrefs().getFormatGuiXml() && mFormatNode != null) { - boolean oldIgnore = mIgnoreXmlUpdate; - try { - mIgnoreXmlUpdate = true; + if (AdtPrefs.getPrefs().getFormatGuiXml() && mFormatNode != null) { if (!mFormatNode.hasError()) { if (mFormatNode == getUiRootNode()) { reformatDocument(); @@ -991,17 +991,17 @@ public abstract class AndroidXmlEditor extends FormEditor implements IResourceCh } } } - } finally { - mIgnoreXmlUpdate = oldIgnore; + mFormatNode = null; + mFormatChildren = false; } - mFormatNode = null; - mFormatChildren = false; - } - // Clean up the undo unit. This is done more than once as explained - // above for beginRecording. - for (int i = 0; i < undoReverseCount; i++) { - model.endRecording(this); + // Clean up the undo unit. This is done more than once as explained + // above for beginRecording. + for (int i = 0; i < undoReverseCount; i++) { + model.endRecording(this); + } + } finally { + mIgnoreXmlUpdate = oldIgnore; } } catch (Exception e) { AdtPlugin.log(e, "Failed to clean up undo unit"); @@ -1016,6 +1016,18 @@ public abstract class AndroidXmlEditor extends FormEditor implements IResourceCh } runEditHooks(); + + // Notify listeners + IStructuredModel readModel = getModelForRead(); + if (readModel != null) { + try { + mXmlModelStateListener.modelChanged(readModel); + } catch (Exception e) { + AdtPlugin.log(e, "Error while notifying changes"); //$NON-NLS-1$ + } finally { + readModel.releaseFromRead(); + } + } } } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java index 4a410ad..63a501e 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java @@ -36,6 +36,7 @@ import com.android.ide.eclipse.adt.internal.editors.descriptors.IUnknownDescript import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor; +import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.CustomViewDescriptorService; import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors; import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; import com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors; @@ -45,6 +46,7 @@ import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; import com.android.sdklib.SdkConstants; +import org.eclipse.core.resources.IProject; import org.eclipse.jface.viewers.StyledString; import org.eclipse.ui.views.properties.IPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertySource; @@ -1221,8 +1223,18 @@ public class UiElementNode implements IPropertySource { // Inserting new node ElementDescriptor desc = mDescriptor.findChildrenDescriptor(elementName, false /* recursive */); + if (desc == null && elementName.indexOf('.') != -1) { + IProject project = getEditor().getProject(); + if (project != null) { + desc = CustomViewDescriptorService.getInstance().getDescriptor( + project, elementName); + } + } if (desc == null) { - // Unknown element. Simply ignore it. + // Unknown node. Create a temporary descriptor for it. + // We'll add unknown attributes to it later. + IUnknownDescriptorProvider p = getUnknownDescriptorProvider(); + desc = p.getDescriptor(elementName); } else { structureChanged = true; uiNode = insertNewUiChild(uiIndex, desc); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AdtPrefs.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AdtPrefs.java index a7f4bf6..5acb954 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AdtPrefs.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AdtPrefs.java @@ -437,9 +437,7 @@ public final class AdtPrefs extends AbstractPreferenceInitializer { store.setDefault(PREFS_MONITOR_DENSITY, 0.f); - // Temporarily disabled because it has some issues - //store.setDefault(PREFS_FORMAT_GUI_XML, true); - + store.setDefault(PREFS_FORMAT_GUI_XML, true); store.setDefault(PREFS_USE_CUSTOM_XML_FORMATTER, true); store.setDefault(PREFS_ONE_ATTR_PER_LINE, true); store.setDefault(PREFS_SPACE_BEFORE_CLOSE, true); |
