aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2012-08-28 07:54:48 -0700
committerandroid code review <noreply-gerritcodereview@google.com>2012-08-28 07:54:48 -0700
commit18e5aa8d6e911965b69c9cec1244c97a695f84f5 (patch)
tree13ace958f8f6e9d8f7a821af750f4a19920fc1b1
parent41cb01a48b44f35adf98f40c116b5e6654b34e16 (diff)
parent774424394537c69975f8fc0044765db8c252f66f (diff)
downloadsdk-18e5aa8d6e911965b69c9cec1244c97a695f84f5.zip
sdk-18e5aa8d6e911965b69c9cec1244c97a695f84f5.tar.gz
sdk-18e5aa8d6e911965b69c9cec1244c97a695f84f5.tar.bz2
Merge "Fix property sheet value completion"
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java9
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/EnumValueCompleter.java56
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/FlagValueCompleter.java80
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/PropertyValueCompleter.java41
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/ResourceValueCompleter.java22
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/ValueCompleter.java186
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlProperty.java23
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlPropertyComposite.java3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlPropertyEditor.java151
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/properties/ValueCompleterTest.java151
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java7
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/PxUsageDetector.java14
12 files changed, 518 insertions, 225 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java
index bcb552f..af8de68 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java
@@ -19,6 +19,9 @@ package com.android.ide.eclipse.adt.internal.editors;
import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_PREFIX;
import static com.android.ide.common.resources.ResourceResolver.PREFIX_RESOURCE_REF;
import static com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor.ATTRIBUTE_ICON_FILENAME;
+import static com.android.tools.lint.detector.api.LintConstants.UNIT_DP;
+import static com.android.tools.lint.detector.api.LintConstants.UNIT_PX;
+import static com.android.tools.lint.detector.api.LintConstants.UNIT_SP;
import com.android.ide.common.api.IAttributeInfo;
import com.android.ide.common.api.IAttributeInfo.Format;
@@ -1138,11 +1141,11 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
* {@link #completeSuffix}.
*/
private static final String[] sDimensionUnits = new String[] {
- "dp", //$NON-NLS-1$
+ UNIT_DP,
"<b>Density-independent Pixels</b> - an abstract unit that is based on the physical "
+ "density of the screen.",
- "sp", //$NON-NLS-1$
+ UNIT_SP,
"<b>Scale-independent Pixels</b> - this is like the dp unit, but it is also scaled by "
+ "the user's font size preference.",
@@ -1155,7 +1158,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
"in", //$NON-NLS-1$
"<b>Inches</b> - based on the physical size of the screen.",
- "px", //$NON-NLS-1$
+ UNIT_PX,
"<b>Pixels</b> - corresponds to actual pixels on the screen. Not recommended.",
};
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/EnumValueCompleter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/EnumValueCompleter.java
deleted file mode 100644
index 4746a72..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/EnumValueCompleter.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 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.layout.properties;
-
-import com.android.ide.eclipse.adt.AdtUtils;
-
-import org.eclipse.jface.fieldassist.ContentProposal;
-import org.eclipse.jface.fieldassist.IContentProposal;
-import org.eclipse.jface.fieldassist.IContentProposalProvider;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Text value completion for the given enum property */
-class EnumValueCompleter implements IContentProposalProvider {
- protected final XmlProperty mProperty;
- private String[] mValues;
-
- EnumValueCompleter(XmlProperty property, String[] values) {
- mProperty = property;
- mValues = values;
- }
-
- @Override
- public IContentProposal[] getProposals(String contents, int position) {
- List<IContentProposal> proposals = new ArrayList<IContentProposal>(mValues.length);
- String prefix = contents;
-
- for (String value : mValues) {
- if (AdtUtils.startsWithIgnoreCase(value, prefix)) {
- proposals.add(new ContentProposal(value));
- }
- }
-
- for (String value : mValues) {
- if (!AdtUtils.startsWithIgnoreCase(value, prefix)) {
- proposals.add(new ContentProposal(value));
- }
- }
-
- return proposals.toArray(new IContentProposal[proposals.size()]);
- }
-} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/FlagValueCompleter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/FlagValueCompleter.java
deleted file mode 100644
index 6958e0f..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/FlagValueCompleter.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2012 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.layout.properties;
-
-import com.android.ide.eclipse.adt.AdtUtils;
-
-import org.eclipse.jface.fieldassist.ContentProposal;
-import org.eclipse.jface.fieldassist.IContentProposal;
-import org.eclipse.jface.fieldassist.IContentProposalProvider;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Text value completion for the given flag property */
-class FlagValueCompleter implements IContentProposalProvider {
- protected final XmlProperty mProperty;
- private String[] mValues;
-
- FlagValueCompleter(XmlProperty property, String[] values) {
- mProperty = property;
- mValues = values;
- }
-
- @Override
- public IContentProposal[] getProposals(String contents, int position) {
- List<IContentProposal> proposals = new ArrayList<IContentProposal>(mValues.length);
- String prefix = contents;
- int flagStart = prefix.lastIndexOf('|');
- String prepend = null;
- if (flagStart != -1) {
- prepend = prefix.substring(0, flagStart + 1);
- prefix = prefix.substring(flagStart + 1).trim();
- }
-
- boolean exactMatch = false;
- for (String value : mValues) {
- if (prefix.equals(value)) {
- exactMatch = true;
- proposals.add(new ContentProposal(contents));
-
- break;
- }
- }
-
- if (exactMatch) {
- prepend = contents + '|';
- prefix = "";
- }
-
- for (String value : mValues) {
- if (AdtUtils.startsWithIgnoreCase(value, prefix)) {
- if (prepend != null && prepend.contains(value)) {
- continue;
- }
- String match;
- if (prepend != null) {
- match = prepend + value;
- } else {
- match = value;
- }
- proposals.add(new ContentProposal(match));
- }
- }
-
- return proposals.toArray(new IContentProposal[proposals.size()]);
- }
-} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/PropertyValueCompleter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/PropertyValueCompleter.java
new file mode 100644
index 0000000..f2bf073
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/PropertyValueCompleter.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012 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.layout.properties;
+
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlEditor;
+import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
+
+class PropertyValueCompleter extends ValueCompleter {
+ private final XmlProperty mProperty;
+
+ PropertyValueCompleter(XmlProperty property) {
+ mProperty = property;
+ }
+
+ @Override
+ @Nullable
+ protected CommonXmlEditor getEditor() {
+ return mProperty.getXmlEditor();
+ }
+
+ @Override
+ @NonNull
+ protected AttributeDescriptor getDescriptor() {
+ return mProperty.getDescriptor();
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/ResourceValueCompleter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/ResourceValueCompleter.java
index 19dc0bc..a5e3f64 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/ResourceValueCompleter.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/ResourceValueCompleter.java
@@ -17,7 +17,9 @@ package com.android.ide.eclipse.adt.internal.editors.layout.properties;
import static com.android.ide.common.layout.LayoutConstants.NEW_ID_PREFIX;
import static com.android.ide.common.resources.ResourceResolver.PREFIX_ANDROID_RESOURCE_REF;
+import static com.android.ide.common.resources.ResourceResolver.PREFIX_ANDROID_THEME_REF;
import static com.android.ide.common.resources.ResourceResolver.PREFIX_RESOURCE_REF;
+import static com.android.ide.common.resources.ResourceResolver.PREFIX_THEME_REF;
import static com.android.ide.eclipse.adt.AdtConstants.ANDROID_PKG;
import com.android.ide.common.resources.ResourceItem;
@@ -98,12 +100,21 @@ class ResourceValueCompleter implements IContentProposalProvider {
ResourceRepository repository = data.getFrameworkResources();
addMatches(repository, prefix, true /* isSystem */, results);
}
+ } else if (prefix.startsWith("?") && //$NON-NLS-1$
+ prefix.regionMatches(true /* ignoreCase */, 0, PREFIX_ANDROID_THEME_REF, 0,
+ Math.min(prefix.length() - 1, PREFIX_ANDROID_THEME_REF.length()))) {
+ AndroidTargetData data = editor.getTargetData();
+ if (data != null) {
+ ResourceRepository repository = data.getFrameworkResources();
+ addMatches(repository, prefix, true /* isSystem */, results);
+ }
}
+
// When completing project resources skip framework resources unless
// the prefix possibly completes both, such as "@an" which can match
// both the project resource @animator as well as @android:string
- if (!prefix.startsWith("@and")) { //$NON-NLS-1$
+ if (!prefix.startsWith("@and") && !prefix.startsWith("?and")) { //$NON-NLS-1$ //$NON-NLS-2$
IProject project = editor.getProject();
if (project != null) {
// get the resource repository for this project and the system resources.
@@ -136,7 +147,14 @@ class ResourceValueCompleter implements IContentProposalProvider {
if (prefix.regionMatches(typeStart, type.getName(), 0,
Math.min(type.getName().length(), prefix.length() - typeStart))) {
StringBuilder sb = new StringBuilder();
- sb.append(PREFIX_RESOURCE_REF);
+ if (prefix.length() == 0 || prefix.startsWith(PREFIX_RESOURCE_REF)) {
+ sb.append(PREFIX_RESOURCE_REF);
+ } else {
+ if (type != ResourceType.ATTR) {
+ continue;
+ }
+ sb.append(PREFIX_THEME_REF);
+ }
if (type == ResourceType.ID && prefix.startsWith(NEW_ID_PREFIX)) {
sb.append('+');
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/ValueCompleter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/ValueCompleter.java
new file mode 100644
index 0000000..944b889
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/ValueCompleter.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2012 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.layout.properties;
+
+import static com.android.ide.common.api.IAttributeInfo.Format.BOOLEAN;
+import static com.android.ide.common.api.IAttributeInfo.Format.DIMENSION;
+import static com.android.ide.common.api.IAttributeInfo.Format.ENUM;
+import static com.android.ide.common.api.IAttributeInfo.Format.FLAG;
+import static com.android.ide.common.api.IAttributeInfo.Format.FLOAT;
+import static com.android.ide.common.api.IAttributeInfo.Format.INTEGER;
+import static com.android.ide.common.api.IAttributeInfo.Format.REFERENCE;
+import static com.android.ide.common.api.IAttributeInfo.Format.STRING;
+import static com.android.ide.common.layout.LayoutConstants.VALUE_FALSE;
+import static com.android.ide.common.layout.LayoutConstants.VALUE_TRUE;
+import static com.android.ide.common.resources.ResourceResolver.PREFIX_RESOURCE_REF;
+import static com.android.ide.common.resources.ResourceResolver.PREFIX_THEME_REF;
+import static com.android.tools.lint.detector.api.LintConstants.ATTR_TEXT_SIZE;
+import static com.android.tools.lint.detector.api.LintConstants.UNIT_DP;
+import static com.android.tools.lint.detector.api.LintConstants.UNIT_SP;
+
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.ide.common.api.IAttributeInfo;
+import com.android.ide.common.api.IAttributeInfo.Format;
+import com.android.ide.eclipse.adt.AdtUtils;
+import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlEditor;
+import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
+
+import org.eclipse.jface.fieldassist.ContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+
+/**
+ * An {@link IContentProposalProvider} which completes possible property values
+ * for Android properties, completing resource strings, flag values, enum
+ * values, as well as dimension units.
+ */
+abstract class ValueCompleter implements IContentProposalProvider {
+ @Nullable
+ protected abstract CommonXmlEditor getEditor();
+
+ @NonNull
+ protected abstract AttributeDescriptor getDescriptor();
+
+ @Override
+ public IContentProposal[] getProposals(String contents, int position) {
+ AttributeDescriptor descriptor = getDescriptor();
+ IAttributeInfo info = descriptor.getAttributeInfo();
+ EnumSet<Format> formats = info.getFormats();
+
+ List<IContentProposal> proposals = new ArrayList<IContentProposal>();
+
+ String prefix = contents; // TODO: Go back to position inside the array?
+
+ // TODO: If the user is typing in a number, or a number plus a prefix of a dimension unit,
+ // then propose that number plus the completed dimension unit (using sp for text, dp
+ // for other properties and maybe both if I'm not sure)
+ if (formats.contains(STRING)
+ && !contents.isEmpty()
+ && (formats.size() > 1 && formats.contains(REFERENCE) ||
+ formats.size() > 2)
+ && !contents.startsWith(PREFIX_RESOURCE_REF)
+ && !contents.startsWith(PREFIX_THEME_REF)) {
+ proposals.add(new ContentProposal(contents));
+ }
+
+ if (!contents.isEmpty() && Character.isDigit(contents.charAt(0))
+ && (formats.contains(DIMENSION)
+ || formats.contains(INTEGER)
+ || formats.contains(FLOAT))) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0, n = contents.length(); i < n; i++) {
+ char c = contents.charAt(i);
+ if (Character.isDigit(c)) {
+ sb.append(c);
+ } else {
+ break;
+ }
+ }
+
+ String number = sb.toString();
+ if (formats.contains(Format.DIMENSION)) {
+ if (descriptor.getXmlLocalName().equals(ATTR_TEXT_SIZE)) {
+ proposals.add(new ContentProposal(number + UNIT_SP));
+ }
+ proposals.add(new ContentProposal(number + UNIT_DP));
+ } else if (formats.contains(Format.INTEGER)) {
+ proposals.add(new ContentProposal(number));
+ }
+ // Perhaps offer other units too -- see AndroidContentAssist.sDimensionUnits
+ }
+
+ if (formats.contains(REFERENCE) || contents.startsWith(PREFIX_RESOURCE_REF)
+ || contents.startsWith(PREFIX_THEME_REF)) {
+ CommonXmlEditor editor = getEditor();
+ if (editor != null) {
+ String[] matches = ResourceValueCompleter.computeResourceStringMatches(
+ editor,
+ descriptor, contents.substring(0, position));
+ for (String match : matches) {
+ proposals.add(new ContentProposal(match));
+ }
+ }
+ }
+
+ if (formats.contains(FLAG)) {
+ String[] values = info.getFlagValues();
+ if (values != null) {
+ // Flag completion
+ int flagStart = prefix.lastIndexOf('|');
+ String prepend = null;
+ if (flagStart != -1) {
+ prepend = prefix.substring(0, flagStart + 1);
+ prefix = prefix.substring(flagStart + 1).trim();
+ }
+
+ boolean exactMatch = false;
+ for (String value : values) {
+ if (prefix.equals(value)) {
+ exactMatch = true;
+ proposals.add(new ContentProposal(contents));
+
+ break;
+ }
+ }
+
+ if (exactMatch) {
+ prepend = contents + '|';
+ prefix = "";
+ }
+
+ for (String value : values) {
+ if (AdtUtils.startsWithIgnoreCase(value, prefix)) {
+ if (prepend != null && prepend.contains(value)) {
+ continue;
+ }
+ String match;
+ if (prepend != null) {
+ match = prepend + value;
+ } else {
+ match = value;
+ }
+ proposals.add(new ContentProposal(match));
+ }
+ }
+ }
+ } else if (formats.contains(ENUM)) {
+ String[] values = info.getEnumValues();
+ if (values != null) {
+ for (String value : values) {
+ if (AdtUtils.startsWithIgnoreCase(value, prefix)) {
+ proposals.add(new ContentProposal(value));
+ }
+ }
+
+ for (String value : values) {
+ if (!AdtUtils.startsWithIgnoreCase(value, prefix)) {
+ proposals.add(new ContentProposal(value));
+ }
+ }
+ }
+ } else if (formats.contains(BOOLEAN)) {
+ proposals.add(new ContentProposal(VALUE_TRUE));
+ proposals.add(new ContentProposal(VALUE_FALSE));
+ }
+
+ return proposals.toArray(new IContentProposal[proposals.size()]);
+ }
+} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlProperty.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlProperty.java
index d3985a9..2a756c9 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlProperty.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlProperty.java
@@ -21,7 +21,6 @@ import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_PREFIX;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.api.IAttributeInfo;
-import com.android.ide.common.api.IAttributeInfo.Format;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
@@ -43,7 +42,6 @@ import org.eclipse.wb.internal.core.model.property.table.PropertyTooltipTextProv
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
-import java.util.EnumSet;
import java.util.Map;
/**
@@ -66,24 +64,29 @@ class XmlProperty extends Property {
mDescriptor = descriptor;
}
+ @NonNull
public PropertyFactory getFactory() {
return mFactory;
}
+ @NonNull
public UiViewElementNode getNode() {
return mNode;
}
+ @NonNull
public AttributeDescriptor getDescriptor() {
return mDescriptor;
}
@Override
+ @NonNull
public String getName() {
return mDescriptor.getXmlLocalName();
}
@Override
+ @NonNull
public String getTitle() {
String name = mDescriptor.getXmlLocalName();
int nameLength = name.length();
@@ -137,12 +140,7 @@ class XmlProperty extends Property {
} else if (adapter == IContentProposalProvider.class) {
IAttributeInfo info = mDescriptor.getAttributeInfo();
if (info != null) {
- EnumSet<Format> formats = info.getFormats();
- if (formats.contains(Format.FLAG)) {
- return adapter.cast(new FlagValueCompleter(this, info.getFlagValues()));
- } else if (formats.contains(Format.ENUM)) {
- return adapter.cast(new EnumValueCompleter(this, info.getEnumValues()));
- }
+ return adapter.cast(new PropertyValueCompleter(this));
}
// Fallback: complete values on resource values
return adapter.cast(new ResourceValueCompleter(this));
@@ -183,6 +181,7 @@ class XmlProperty extends Property {
return s != null && s.toString().length() > 0;
}
+ @Nullable
public String getStringValue() {
Element element = (Element) mNode.getXmlNode();
if (element == null) {
@@ -217,6 +216,7 @@ class XmlProperty extends Property {
}
@Override
+ @Nullable
public Object getValue() throws Exception {
return getStringValue();
}
@@ -242,6 +242,7 @@ class XmlProperty extends Property {
}
@Override
+ @NonNull
public Property getComposite(Property[] properties) {
return XmlPropertyComposite.create(properties);
}
@@ -251,7 +252,8 @@ class XmlProperty extends Property {
return mFactory.getGraphicalEditor();
}
- @Nullable CommonXmlEditor getXmlEditor() {
+ @Nullable
+ CommonXmlEditor getXmlEditor() {
GraphicalEditorPart graphicalEditor = getGraphicalEditor();
if (graphicalEditor != null) {
return graphicalEditor.getEditorDelegate().getEditor();
@@ -260,11 +262,12 @@ class XmlProperty extends Property {
return null;
}
+ @Nullable
public Property getParent() {
return mParent;
}
- public void setParent(Property parent) {
+ public void setParent(@Nullable Property parent) {
mParent = parent;
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlPropertyComposite.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlPropertyComposite.java
index 7abc91c..af9e13b 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlPropertyComposite.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlPropertyComposite.java
@@ -16,6 +16,7 @@
package com.android.ide.eclipse.adt.internal.editors.layout.properties;
+import com.android.annotations.NonNull;
import com.google.common.base.Objects;
import org.eclipse.wb.internal.core.model.property.Property;
@@ -46,6 +47,7 @@ class XmlPropertyComposite extends XmlProperty {
}
@Override
+ @NonNull
public String getTitle() {
return mProperties[0].getTitle();
}
@@ -103,6 +105,7 @@ class XmlPropertyComposite extends XmlProperty {
}
}
+ @NonNull
public static XmlPropertyComposite create(Property... properties) {
// Cast from Property into XmlProperty
XmlProperty[] xmlProperties = new XmlProperty[properties.length];
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlPropertyEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlPropertyEditor.java
index a7a863c..7cb3f66 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlPropertyEditor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/XmlPropertyEditor.java
@@ -17,6 +17,10 @@
package com.android.ide.eclipse.adt.internal.editors.layout.properties;
import static com.android.ide.common.layout.LayoutConstants.ATTR_ID;
+import static com.android.ide.common.resources.ResourceResolver.PREFIX_ANDROID_RESOURCE_REF;
+import static com.android.ide.common.resources.ResourceResolver.PREFIX_ANDROID_THEME_REF;
+import static com.android.ide.common.resources.ResourceResolver.PREFIX_RESOURCE_REF;
+import static com.android.ide.common.resources.ResourceResolver.PREFIX_THEME_REF;
import static com.android.ide.eclipse.adt.AdtConstants.DOT_PNG;
import static com.android.ide.eclipse.adt.AdtConstants.DOT_XML;
@@ -120,22 +124,29 @@ class XmlPropertyEditor extends AbstractTextPropertyEditor {
if (text.startsWith("@") || text.startsWith("?")) { //$NON-NLS-1$ //$NON-NLS-2$
// Yes, try to resolve it in order to show better info
XmlProperty xmlProperty = (XmlProperty) property;
- ResourceResolver resolver = xmlProperty.getGraphicalEditor().getResourceResolver();
- boolean isFramework = text.startsWith("@android:") || text.startsWith("?android:");
- resValue = resolver.findResValue(text, isFramework);
- while (resValue != null && resValue.getValue() != null) {
- String value = resValue.getValue();
- if (value.startsWith("@") || value.startsWith("?")) {
- // TODO: do I have to strip off the @ too?
- isFramework = isFramework || value.startsWith("@android:") || value.startsWith("?android:");;
- ResourceValue v = resolver.findResValue(text, isFramework);
- if (v != null && !value.equals(v.getValue())) {
- resValue = v;
+ GraphicalEditorPart graphicalEditor = xmlProperty.getGraphicalEditor();
+ if (graphicalEditor != null) {
+ ResourceResolver resolver = graphicalEditor.getResourceResolver();
+ boolean isFramework = text.startsWith(PREFIX_ANDROID_RESOURCE_REF)
+ || text.startsWith(PREFIX_ANDROID_THEME_REF);
+ resValue = resolver.findResValue(text, isFramework);
+ while (resValue != null && resValue.getValue() != null) {
+ String value = resValue.getValue();
+ if (value.startsWith(PREFIX_RESOURCE_REF)
+ || value.startsWith(PREFIX_THEME_REF)) {
+ // TODO: do I have to strip off the @ too?
+ isFramework = isFramework
+ || value.startsWith(PREFIX_ANDROID_RESOURCE_REF)
+ || value.startsWith(PREFIX_ANDROID_THEME_REF);;
+ ResourceValue v = resolver.findResValue(text, isFramework);
+ if (v != null && !value.equals(v.getValue())) {
+ resValue = v;
+ } else {
+ break;
+ }
} else {
break;
}
- } else {
- break;
}
}
} else if (text.startsWith("#") && text.matches("#\\p{XDigit}+")) { //$NON-NLS-1$
@@ -149,34 +160,36 @@ class XmlPropertyEditor extends AbstractTextPropertyEditor {
if (value.startsWith("#") || value.endsWith(DOT_XML) //$NON-NLS-1$
&& value.contains("res/color")) { //$NON-NLS-1$ // TBD: File.separator?
XmlProperty xmlProperty = (XmlProperty) property;
- ResourceResolver resolver =
- xmlProperty.getGraphicalEditor().getResourceResolver();
- RGB rgb = ResourceHelper.resolveColor(resolver, resValue);
- if (rgb != null) {
- Color color = new Color(gc.getDevice(), rgb);
- // draw color sample
- Color oldBackground = gc.getBackground();
- Color oldForeground = gc.getForeground();
- try {
- int width_c = SAMPLE_SIZE;
- int height_c = SAMPLE_SIZE;
- int x_c = x;
- int y_c = y + (height - height_c) / 2;
- // update rest bounds
- int delta = SAMPLE_SIZE + SAMPLE_MARGIN;
- x += delta;
- width -= delta;
- // fill
- gc.setBackground(color);
- gc.fillRectangle(x_c, y_c, width_c, height_c);
- // draw line
- gc.setForeground(IColorConstants.gray);
- gc.drawRectangle(x_c, y_c, width_c, height_c);
- } finally {
- gc.setBackground(oldBackground);
- gc.setForeground(oldForeground);
+ GraphicalEditorPart graphicalEditor = xmlProperty.getGraphicalEditor();
+ if (graphicalEditor != null) {
+ ResourceResolver resolver = graphicalEditor.getResourceResolver();
+ RGB rgb = ResourceHelper.resolveColor(resolver, resValue);
+ if (rgb != null) {
+ Color color = new Color(gc.getDevice(), rgb);
+ // draw color sample
+ Color oldBackground = gc.getBackground();
+ Color oldForeground = gc.getForeground();
+ try {
+ int width_c = SAMPLE_SIZE;
+ int height_c = SAMPLE_SIZE;
+ int x_c = x;
+ int y_c = y + (height - height_c) / 2;
+ // update rest bounds
+ int delta = SAMPLE_SIZE + SAMPLE_MARGIN;
+ x += delta;
+ width -= delta;
+ // fill
+ gc.setBackground(color);
+ gc.fillRectangle(x_c, y_c, width_c, height_c);
+ // draw line
+ gc.setForeground(IColorConstants.gray);
+ gc.drawRectangle(x_c, y_c, width_c, height_c);
+ } finally {
+ gc.setBackground(oldBackground);
+ gc.setForeground(oldForeground);
+ }
+ color.dispose();
}
- color.dispose();
}
} else {
Image swtImage = null;
@@ -350,37 +363,38 @@ class XmlPropertyEditor extends AbstractTextPropertyEditor {
// Multiple resource types (such as string *and* boolean):
// just use a reference chooser
GraphicalEditorPart graphicalEditor = xmlProperty.getGraphicalEditor();
- LayoutEditorDelegate delegate = graphicalEditor.getEditorDelegate();
- IProject project = delegate.getEditor().getProject();
- if (project != null) {
- // get the resource repository for this project and the system resources.
- ResourceRepository projectRepository =
- ResourceManager.getInstance().getProjectResources(project);
- Shell shell = AdtPlugin.getDisplay().getActiveShell();
- ReferenceChooserDialog dlg = new ReferenceChooserDialog(
- project,
- projectRepository,
- shell);
- dlg.setPreviewHelper(new ResourcePreviewHelper(dlg, graphicalEditor));
-
- String currentValue = (String) property.getValue();
- dlg.setCurrentResource(currentValue);
-
- if (dlg.open() == Window.OK) {
- String resource = dlg.getCurrentResource();
- if (resource != null) {
- // Returns null for cancel, "" for clear and otherwise a new value
- if (resource.length() > 0) {
- property.setValue(resource);
- } else {
- property.setValue(null);
+ if (graphicalEditor != null) {
+ LayoutEditorDelegate delegate = graphicalEditor.getEditorDelegate();
+ IProject project = delegate.getEditor().getProject();
+ if (project != null) {
+ // get the resource repository for this project and the system resources.
+ ResourceRepository projectRepository =
+ ResourceManager.getInstance().getProjectResources(project);
+ Shell shell = AdtPlugin.getDisplay().getActiveShell();
+ ReferenceChooserDialog dlg = new ReferenceChooserDialog(
+ project,
+ projectRepository,
+ shell);
+ dlg.setPreviewHelper(new ResourcePreviewHelper(dlg, graphicalEditor));
+
+ String currentValue = (String) property.getValue();
+ dlg.setCurrentResource(currentValue);
+
+ if (dlg.open() == Window.OK) {
+ String resource = dlg.getCurrentResource();
+ if (resource != null) {
+ // Returns null for cancel, "" for clear and otherwise a new value
+ if (resource.length() > 0) {
+ property.setValue(resource);
+ } else {
+ property.setValue(null);
+ }
}
}
- }
- return;
+ return;
+ }
}
-
} else if (type != null) {
// Single resource type: use a resource chooser
GraphicalEditorPart graphicalEditor = xmlProperty.getGraphicalEditor();
@@ -418,7 +432,8 @@ class XmlPropertyEditor extends AbstractTextPropertyEditor {
@NonNull
private static Map<String, Image> getImageCache(@NonNull Property property) {
XmlProperty xmlProperty = (XmlProperty) property;
- IProject project = xmlProperty.getGraphicalEditor().getProject();
+ GraphicalEditorPart graphicalEditor = xmlProperty.getGraphicalEditor();
+ IProject project = graphicalEditor.getProject();
try {
Map<String, Image> cache = (Map<String, Image>) project.getSessionProperty(CACHE_NAME);
if (cache == null) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/properties/ValueCompleterTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/properties/ValueCompleterTest.java
new file mode 100644
index 0000000..bbe82e3
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/properties/ValueCompleterTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2012 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.layout.properties;
+
+import static com.android.tools.lint.detector.api.LintConstants.ANDROID_URI;
+
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.ide.common.api.IAttributeInfo;
+import com.android.ide.common.api.IAttributeInfo.Format;
+import com.android.ide.common.layout.TestAttributeInfo;
+import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlEditor;
+import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
+import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
+
+import org.eclipse.jface.fieldassist.IContentProposal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings("javadoc")
+public class ValueCompleterTest extends TestCase {
+ private void checkCompletion(String text, int offset,
+ String property, EnumSet<Format> formats, String[] values,
+ List<String> expected) {
+ assertTrue(text.length() >= offset);
+
+ TestAttributeInfo info =
+ new TestAttributeInfo(property, formats, "unittest", values, values, null);
+ TestValueCompleter completer = new TestValueCompleter(
+ new TestTextAttributeDescriptor(property, info));
+ IContentProposal[] proposals = completer.getProposals(text, offset);
+ List<String> actual = new ArrayList<String>();
+ for (IContentProposal proposal : proposals) {
+ String content = proposal.getContent();
+ actual.add(content);
+ }
+ assertEquals(expected.toString(), actual.toString());
+ }
+
+ public void test() throws Exception {
+ checkCompletion("@android:string", 3, "text",
+ EnumSet.of(Format.REFERENCE), null,
+ Arrays.asList(new String[] { }));
+ }
+
+ public void test1a() throws Exception {
+ checkCompletion("matc", 4, "layout_width",
+ EnumSet.of(Format.DIMENSION, Format.ENUM),
+ new String[] { "fill_parent", "match_parent", "wrap_content" },
+
+ Arrays.asList(new String[] { "match_parent", "fill_parent", "wrap_content" }));
+ }
+
+ public void test1b() throws Exception {
+ checkCompletion("fi", 2, "layout_width",
+ EnumSet.of(Format.DIMENSION, Format.ENUM),
+ new String[] { "fill_parent", "match_parent", "wrap_content" },
+
+ Arrays.asList(new String[] { "fill_parent", "match_parent", "wrap_content" }));
+ }
+
+ public void test2() throws Exception {
+ checkCompletion("50", 2, "layout_width",
+ EnumSet.of(Format.DIMENSION, Format.ENUM),
+ new String[] { "fill_parent", "match_parent", "wrap_content" },
+
+ Arrays.asList(new String[] { "50dp", "fill_parent", "match_parent",
+ "wrap_content" }));
+ }
+
+ public void test3() throws Exception {
+ checkCompletion("42", 2, "textSize",
+ EnumSet.of(Format.DIMENSION),
+ null,
+
+ Arrays.asList(new String[] { "42sp", "42dp" }));
+ }
+
+ public void test4() throws Exception {
+ checkCompletion("", 0, "gravity",
+ EnumSet.of(Format.FLAG),
+ new String[] { "top", "bottom", "left", "right", "center" },
+
+ Arrays.asList(new String[] { "top", "bottom", "left", "right", "center" }));
+ }
+
+ public void test5() throws Exception {
+ checkCompletion("left", 4, "gravity",
+ EnumSet.of(Format.FLAG),
+ new String[] { "top", "bottom", "left", "right", "center" },
+
+ Arrays.asList(new String[] {
+ "left", "left|top", "left|bottom", "left|right", "left|center" }));
+ }
+
+ public void test6() throws Exception {
+ checkCompletion("left|top", 8, "gravity",
+ EnumSet.of(Format.FLAG),
+ new String[] { "top", "bottom", "left", "right", "center" },
+
+ Arrays.asList(new String[] {
+ "left|top", "left|top|bottom", "left|top|right", "left|top|center" }));
+ }
+
+ // TODO ?android
+
+ private class TestTextAttributeDescriptor extends TextAttributeDescriptor {
+ public TestTextAttributeDescriptor(String xmlLocalName, IAttributeInfo attrInfo) {
+ super(xmlLocalName, ANDROID_URI, attrInfo);
+ }
+ }
+
+ private class TestValueCompleter extends ValueCompleter {
+ private final AttributeDescriptor mDescriptor;
+
+ TestValueCompleter(AttributeDescriptor descriptor) {
+ mDescriptor = descriptor;
+ assert descriptor.getAttributeInfo() != null;
+ }
+
+ @Override
+ @Nullable
+ protected CommonXmlEditor getEditor() {
+ return null;
+ }
+
+ @Override
+ @NonNull
+ protected AttributeDescriptor getDescriptor() {
+ return mDescriptor;
+ }
+ }
+}
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java
index 40b468d..c43a8ed 100644
--- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java
+++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java
@@ -149,6 +149,7 @@ public class LintConstants {
public static final String ATTR_ID = "id"; //$NON-NLS-1$
public static final String ATTR_TEXT = "text"; //$NON-NLS-1$
+ public static final String ATTR_TEXT_SIZE = "textSize"; //$NON-NLS-1$
public static final String ATTR_LABEL = "label"; //$NON-NLS-1$
public static final String ATTR_HINT = "hint"; //$NON-NLS-1$
public static final String ATTR_PROMPT = "prompt"; //$NON-NLS-1$
@@ -257,6 +258,12 @@ public class LintConstants {
public static final String VALUE_IF_ROOM = "ifRoom"; //$NON-NLS-1$
public static final String VALUE_ALWAYS = "always"; //$NON-NLS-1$
+ // Units
+ public static final String UNIT_DP = "dp"; //$NON-NLS-1$
+ public static final String UNIT_DIP = "dip"; //$NON-NLS-1$
+ public static final String UNIT_SP = "sp"; //$NON-NLS-1$
+ public static final String UNIT_PX = "px"; //$NON-NLS-1$
+
// Filenames and folder names
public static final String ANDROID_MANIFEST_XML = "AndroidManifest.xml"; //$NON-NLS-1$
public static final String OLD_PROGUARD_FILE = "proguard.cfg"; //$NON-NLS-1$
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/PxUsageDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/PxUsageDetector.java
index 6734592..c7d688f 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/PxUsageDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/PxUsageDetector.java
@@ -17,8 +17,12 @@
package com.android.tools.lint.checks;
import static com.android.tools.lint.detector.api.LintConstants.ATTR_NAME;
+import static com.android.tools.lint.detector.api.LintConstants.ATTR_TEXT_SIZE;
import static com.android.tools.lint.detector.api.LintConstants.TAG_ITEM;
import static com.android.tools.lint.detector.api.LintConstants.TAG_STYLE;
+import static com.android.tools.lint.detector.api.LintConstants.UNIT_DIP;
+import static com.android.tools.lint.detector.api.LintConstants.UNIT_DP;
+import static com.android.tools.lint.detector.api.LintConstants.UNIT_PX;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
@@ -42,8 +46,6 @@ import java.util.Collections;
/**
* Check for px dimensions instead of dp dimensions.
* Also look for non-"sp" text sizes.
- * <p>
- * TODO: Look in themes as well (text node usages).
*/
public class PxUsageDetector extends LayoutDetector {
/** The main issue discovered by this detector */
@@ -123,7 +125,7 @@ public class PxUsageDetector extends LayoutDetector {
}
String value = attribute.getValue();
- if (value.endsWith("px") && value.matches("\\d+px")) { //$NON-NLS-1$ //$NON-NLS-2$
+ if (value.endsWith(UNIT_PX) && value.matches("\\d+px")) { //$NON-NLS-1$
if (value.charAt(0) == '0') {
// 0px is fine. 0px is 0dp regardless of density...
return;
@@ -132,8 +134,8 @@ public class PxUsageDetector extends LayoutDetector {
context.report(PX_ISSUE, attribute, context.getLocation(attribute),
"Avoid using \"px\" as units; use \"dp\" instead", null);
}
- } else if ("textSize".equals(attribute.getLocalName())
- && (value.endsWith("dp") || value.endsWith("dip")) //$NON-NLS-1$ //$NON-NLS-2$
+ } else if (ATTR_TEXT_SIZE.equals(attribute.getLocalName())
+ && (value.endsWith(UNIT_DP) || value.endsWith(UNIT_DIP))
&& (value.matches("\\d+di?p"))) {
if (context.isEnabled(DP_ISSUE)) {
context.report(DP_ISSUE, attribute, context.getLocation(attribute),
@@ -185,7 +187,7 @@ public class PxUsageDetector extends LayoutDetector {
|| text.charAt(j - 1) == 'i')) { // ends with dp or di
text = text.trim();
String name = item.getAttribute(ATTR_NAME);
- if ((name.equals("textSize") //$NON-NLS-1$
+ if ((name.equals(ATTR_TEXT_SIZE)
|| name.equals("android:textSize")) //$NON-NLS-1$
&& text.matches("\\d+di?p")) { //$NON-NLS-1$
if (context.isEnabled(DP_ISSUE)) {