aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java523
1 files changed, 0 insertions, 523 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java
deleted file mode 100644
index eb51d3f86..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java
+++ /dev/null
@@ -1,523 +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.uimodel;
-
-import static com.android.SdkConstants.ANDROID_PKG;
-import static com.android.SdkConstants.ANDROID_PREFIX;
-import static com.android.SdkConstants.ANDROID_THEME_PREFIX;
-import static com.android.SdkConstants.ATTR_ID;
-import static com.android.SdkConstants.ATTR_LAYOUT;
-import static com.android.SdkConstants.ATTR_STYLE;
-import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
-import static com.android.SdkConstants.PREFIX_THEME_REF;
-
-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.resources.ResourceItem;
-import com.android.ide.common.resources.ResourceRepository;
-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.TextAttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.ui.ReferenceChooserDialog;
-import com.android.ide.eclipse.adt.internal.ui.ResourceChooser;
-import com.android.resources.ResourceType;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Represents an XML attribute for a resource that can be modified using a simple text field or
- * a dialog to choose an existing resource.
- * <p/>
- * It can be configured to represent any kind of resource, by providing the desired
- * {@link ResourceType} in the constructor.
- * <p/>
- * See {@link UiTextAttributeNode} for more information.
- */
-public class UiResourceAttributeNode extends UiTextAttributeNode {
- private ResourceType mType;
-
- /**
- * Creates a new {@linkplain UiResourceAttributeNode}
- *
- * @param type the associated resource type
- * @param attributeDescriptor the attribute descriptor for this attribute
- * @param uiParent the parent ui node, if any
- */
- public UiResourceAttributeNode(ResourceType type,
- AttributeDescriptor attributeDescriptor, UiElementNode uiParent) {
- super(attributeDescriptor, uiParent);
-
- mType = type;
- }
-
- /* (non-java doc)
- * Creates a label widget and an associated text field.
- * <p/>
- * As most other parts of the android manifest editor, this assumes the
- * parent uses a table layout with 2 columns.
- */
- @Override
- public void createUiControl(final Composite parent, IManagedForm managedForm) {
- setManagedForm(managedForm);
- FormToolkit toolkit = managedForm.getToolkit();
- TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor();
-
- Label label = toolkit.createLabel(parent, desc.getUiName());
- label.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
- SectionHelper.addControlTooltip(label, DescriptorsUtils.formatTooltip(desc.getTooltip()));
-
- Composite composite = toolkit.createComposite(parent);
- composite.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE));
- GridLayout gl = new GridLayout(2, false);
- gl.marginHeight = gl.marginWidth = 0;
- composite.setLayout(gl);
- // Fixes missing text borders under GTK... also requires adding a 1-pixel margin
- // for the text field below
- toolkit.paintBordersFor(composite);
-
- final Text text = toolkit.createText(composite, getCurrentValue());
- GridData gd = new GridData(GridData.FILL_HORIZONTAL);
- gd.horizontalIndent = 1; // Needed by the fixed composite borders under GTK
- text.setLayoutData(gd);
- Button browseButton = toolkit.createButton(composite, "Browse...", SWT.PUSH);
-
- setTextWidget(text);
-
- // TODO Add a validator using onAddModifyListener
-
- browseButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- String result = showDialog(parent.getShell(), text.getText().trim());
- if (result != null) {
- text.setText(result);
- }
- }
- });
- }
-
- /**
- * Shows a dialog letting the user choose a set of enum, and returns a
- * string containing the result.
- *
- * @param shell the parent shell
- * @param currentValue an initial value, if any
- * @return the chosen string, or null
- */
- @Nullable
- public String showDialog(@NonNull Shell shell, @Nullable String currentValue) {
- // we need to get the project of the file being edited.
- UiElementNode uiNode = getUiParent();
- AndroidXmlEditor editor = uiNode.getEditor();
- IProject project = editor.getProject();
- if (project != null) {
- // get the resource repository for this project and the system resources.
- ResourceRepository projectRepository =
- ResourceManager.getInstance().getProjectResources(project);
-
- if (mType != null) {
- // get the Target Data to get the system resources
- AndroidTargetData data = editor.getTargetData();
- ResourceChooser dlg = ResourceChooser.create(project, mType, data, shell)
- .setCurrentResource(currentValue);
- if (dlg.open() == Window.OK) {
- return dlg.getCurrentResource();
- }
- } else {
- ReferenceChooserDialog dlg = new ReferenceChooserDialog(
- project,
- projectRepository,
- shell);
-
- dlg.setCurrentResource(currentValue);
-
- if (dlg.open() == Window.OK) {
- return dlg.getCurrentResource();
- }
- }
- }
-
- return null;
- }
-
- /**
- * Gets all the values one could use to auto-complete a "resource" value in an XML
- * content assist.
- * <p/>
- * Typically the user is editing the value of an attribute in a resource XML, e.g.
- * <pre> "&lt;Button android:test="@string/my_[caret]_string..." </pre>
- * <p/>
- *
- * "prefix" is the value that the user has typed so far (or more exactly whatever is on the
- * left side of the insertion point). In the example above it would be "@style/my_".
- * <p/>
- *
- * To avoid a huge long list of values, the completion works on two levels:
- * <ul>
- * <li> If a resource type as been typed so far (e.g. "@style/"), then limit the values to
- * the possible completions that match this type.
- * <li> If no resource type as been typed so far, then return the various types that could be
- * completed. So if the project has only strings and layouts resources, for example,
- * the returned list will only include "@string/" and "@layout/".
- * </ul>
- *
- * Finally if anywhere in the string we find the special token "android:", we use the
- * current framework system resources rather than the project resources.
- * This works for both "@android:style/foo" and "@style/android:foo" conventions even though
- * the reconstructed name will always be of the former form.
- *
- * Note that "android:" here is a keyword specific to Android resources and should not be
- * mixed with an XML namespace for an XML attribute name.
- */
- @Override
- public String[] getPossibleValues(String prefix) {
- return computeResourceStringMatches(getUiParent().getEditor(), getDescriptor(), prefix);
- }
-
- /**
- * Computes the set of resource string matches for a given resource prefix in a given editor
- *
- * @param editor the editor context
- * @param descriptor the attribute descriptor, if any
- * @param prefix the prefix, if any
- * @return an array of resource string matches
- */
- @Nullable
- public static String[] computeResourceStringMatches(
- @NonNull AndroidXmlEditor editor,
- @Nullable AttributeDescriptor descriptor,
- @Nullable String prefix) {
-
- if (prefix == null || !prefix.regionMatches(1, ANDROID_PKG, 0, ANDROID_PKG.length())) {
- IProject project = editor.getProject();
- if (project != null) {
- // get the resource repository for this project and the system resources.
- ResourceManager resourceManager = ResourceManager.getInstance();
- ResourceRepository repository = resourceManager.getProjectResources(project);
-
- List<IProject> libraries = null;
- ProjectState projectState = Sdk.getProjectState(project);
- if (projectState != null) {
- libraries = projectState.getFullLibraryProjects();
- }
-
- String[] projectMatches = computeResourceStringMatches(descriptor, prefix,
- repository, false);
-
- if (libraries == null || libraries.isEmpty()) {
- return projectMatches;
- }
-
- // Also compute matches for each of the libraries, and combine them
- Set<String> matches = new HashSet<String>(200);
- for (String s : projectMatches) {
- matches.add(s);
- }
-
- for (IProject library : libraries) {
- repository = resourceManager.getProjectResources(library);
- projectMatches = computeResourceStringMatches(descriptor, prefix,
- repository, false);
- for (String s : projectMatches) {
- matches.add(s);
- }
- }
-
- String[] sorted = matches.toArray(new String[matches.size()]);
- Arrays.sort(sorted);
- return sorted;
- }
- } else {
- // If there's a prefix with "android:" in it, use the system resources
- // Non-public framework resources are filtered out later.
- AndroidTargetData data = editor.getTargetData();
- if (data != null) {
- ResourceRepository repository = data.getFrameworkResources();
- return computeResourceStringMatches(descriptor, prefix, repository, true);
- }
- }
-
- return null;
- }
-
- /**
- * Computes the set of resource string matches for a given prefix and a
- * given resource repository
- *
- * @param attributeDescriptor the attribute descriptor, if any
- * @param prefix the prefix, if any
- * @param repository the repository to seaerch in
- * @param isSystem if true, the repository contains framework repository,
- * otherwise it contains project repositories
- * @return an array of resource string matches
- */
- @NonNull
- public static String[] computeResourceStringMatches(
- @Nullable AttributeDescriptor attributeDescriptor,
- @Nullable String prefix,
- @NonNull ResourceRepository repository,
- boolean isSystem) {
- // Get list of potential resource types, either specific to this project
- // or the generic list.
- Collection<ResourceType> resTypes = (repository != null) ?
- repository.getAvailableResourceTypes() :
- EnumSet.allOf(ResourceType.class);
-
- // Get the type name from the prefix, if any. It's any word before the / if there's one
- String typeName = null;
- if (prefix != null) {
- Matcher m = Pattern.compile(".*?([a-z]+)/.*").matcher(prefix); //$NON-NLS-1$
- if (m.matches()) {
- typeName = m.group(1);
- }
- }
-
- // Now collect results
- List<String> results = new ArrayList<String>();
-
- if (typeName == null) {
- // This prefix does not have a / in it, so the resource string is either empty
- // or does not have the resource type in it. Simply offer the list of potential
- // resource types.
- if (prefix != null && prefix.startsWith(PREFIX_THEME_REF)) {
- results.add(ANDROID_THEME_PREFIX + ResourceType.ATTR.getName() + '/');
- if (resTypes.contains(ResourceType.ATTR)
- || resTypes.contains(ResourceType.STYLE)) {
- results.add(PREFIX_THEME_REF + ResourceType.ATTR.getName() + '/');
- if (prefix != null && prefix.startsWith(ANDROID_THEME_PREFIX)) {
- // including attr isn't required
- for (ResourceItem item : repository.getResourceItemsOfType(
- ResourceType.ATTR)) {
- results.add(ANDROID_THEME_PREFIX + item.getName());
- }
- }
- }
- return results.toArray(new String[results.size()]);
- }
-
- for (ResourceType resType : resTypes) {
- if (isSystem) {
- results.add(ANDROID_PREFIX + resType.getName() + '/');
- } else {
- results.add('@' + resType.getName() + '/');
- }
- if (resType == ResourceType.ID) {
- // Also offer the + version to create an id from scratch
- results.add("@+" + resType.getName() + '/'); //$NON-NLS-1$
- }
- }
-
- // Also add in @android: prefix to completion such that if user has typed
- // "@an" we offer to complete it.
- if (prefix == null ||
- ANDROID_PKG.regionMatches(0, prefix, 1, prefix.length() - 1)) {
- results.add(ANDROID_PREFIX);
- }
- } else if (repository != null) {
- // We have a style name and a repository. Find all resources that match this
- // type and recreate suggestions out of them.
-
- String initial = prefix != null && prefix.startsWith(PREFIX_THEME_REF)
- ? PREFIX_THEME_REF : PREFIX_RESOURCE_REF;
- ResourceType resType = ResourceType.getEnum(typeName);
- if (resType != null) {
- StringBuilder sb = new StringBuilder();
- sb.append(initial);
- if (prefix != null && prefix.indexOf('+') >= 0) {
- sb.append('+');
- }
-
- if (isSystem) {
- sb.append(ANDROID_PKG).append(':');
- }
-
- sb.append(typeName).append('/');
- String base = sb.toString();
-
- for (ResourceItem item : repository.getResourceItemsOfType(resType)) {
- results.add(base + item.getName());
- }
-
- if (!isSystem && resType == ResourceType.ATTR) {
- for (ResourceItem item : repository.getResourceItemsOfType(
- ResourceType.STYLE)) {
- results.add(base + item.getName());
- }
- }
- }
- }
-
- if (attributeDescriptor != null) {
- sortAttributeChoices(attributeDescriptor, results);
- } else {
- Collections.sort(results);
- }
-
- return results.toArray(new String[results.size()]);
- }
-
- /**
- * Attempts to sort the attribute values to bubble up the most likely choices to
- * the top.
- * <p>
- * For example, if you are editing a style attribute, it's likely that among the
- * resource values you would rather see @style or @android than @string.
- * @param descriptor the descriptor that the resource values are being completed for,
- * used to prioritize some of the resource types
- * @param choices the set of string resource values
- */
- public static void sortAttributeChoices(AttributeDescriptor descriptor,
- List<String> choices) {
- final IAttributeInfo attributeInfo = descriptor.getAttributeInfo();
- Collections.sort(choices, new Comparator<String>() {
- @Override
- public int compare(String s1, String s2) {
- int compare = score(attributeInfo, s1) - score(attributeInfo, s2);
- if (compare == 0) {
- // Sort alphabetically as a fallback
- compare = s1.compareToIgnoreCase(s2);
- }
- return compare;
- }
- });
- }
-
- /** Compute a suitable sorting score for the given */
- private static final int score(IAttributeInfo attributeInfo, String value) {
- if (value.equals(ANDROID_PREFIX)) {
- return -1;
- }
-
- for (Format format : attributeInfo.getFormats()) {
- String type = null;
- switch (format) {
- case BOOLEAN:
- type = "bool"; //$NON-NLS-1$
- break;
- case COLOR:
- type = "color"; //$NON-NLS-1$
- break;
- case DIMENSION:
- type = "dimen"; //$NON-NLS-1$
- break;
- case INTEGER:
- type = "integer"; //$NON-NLS-1$
- break;
- case STRING:
- type = "string"; //$NON-NLS-1$
- break;
- // default: REFERENCE, FLAG, ENUM, etc - don't have type info about individual
- // elements to help make a decision
- }
-
- if (type != null) {
- if (value.startsWith(PREFIX_RESOURCE_REF)) {
- if (value.startsWith(PREFIX_RESOURCE_REF + type + '/')) {
- return -2;
- }
-
- if (value.startsWith(ANDROID_PREFIX + type + '/')) {
- return -2;
- }
- }
- if (value.startsWith(PREFIX_THEME_REF)) {
- if (value.startsWith(PREFIX_THEME_REF + type + '/')) {
- return -2;
- }
-
- if (value.startsWith(ANDROID_THEME_PREFIX + type + '/')) {
- return -2;
- }
- }
- }
- }
-
- // Handle a few more cases not covered by the Format metadata check
- String type = null;
-
- String attribute = attributeInfo.getName();
- if (attribute.equals(ATTR_ID)) {
- type = "id"; //$NON-NLS-1$
- } else if (attribute.equals(ATTR_STYLE)) {
- type = "style"; //$NON-NLS-1$
- } else if (attribute.equals(ATTR_LAYOUT)) {
- type = "layout"; //$NON-NLS-1$
- } else if (attribute.equals("drawable")) { //$NON-NLS-1$
- type = "drawable"; //$NON-NLS-1$
- } else if (attribute.equals("entries")) { //$NON-NLS-1$
- // Spinner
- type = "array"; //$NON-NLS-1$
- }
-
- if (type != null) {
- if (value.startsWith(PREFIX_RESOURCE_REF)) {
- if (value.startsWith(PREFIX_RESOURCE_REF + type + '/')) {
- return -2;
- }
-
- if (value.startsWith(ANDROID_PREFIX + type + '/')) {
- return -2;
- }
- }
- if (value.startsWith(PREFIX_THEME_REF)) {
- if (value.startsWith(PREFIX_THEME_REF + type + '/')) {
- return -2;
- }
-
- if (value.startsWith(ANDROID_THEME_PREFIX + type + '/')) {
- return -2;
- }
- }
- }
-
- return 0;
- }
-}