blob: de48eb7b0c64dbbce9841249bf74fcafdc5b0540 [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.intellij.android.designer.propertyTable.renderers;
import com.android.tools.idea.rendering.ResourceHelper;
import com.intellij.android.designer.model.RadModelBuilder;
import com.intellij.designer.model.PropertiesContainer;
import com.intellij.designer.model.PropertyContext;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.propertyTable.renderers.AbstractResourceRenderer;
import com.intellij.designer.propertyTable.renderers.BooleanRenderer;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ArrayUtil;
import org.jetbrains.android.dom.attrs.AttributeFormat;
import org.jetbrains.android.dom.resources.ResourceElement;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.resourceManagers.ResourceManager;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.List;
import java.util.Set;
/**
* @author Alexander Lobas
*/
public class ResourceRenderer extends AbstractResourceRenderer<String> {
public static final String[] DIMENSIONS = {"dp", "sp", "pt", "px", "mm", "in"};
private static final String ANDROID_PREFIX = "@android:";
private BooleanRenderer myBooleanRenderer;
private final Set<AttributeFormat> myFormats;
public ResourceRenderer(Set<AttributeFormat> formats) {
if (formats.contains(AttributeFormat.Boolean)) {
myBooleanRenderer = new BooleanRenderer();
}
myFormats = formats;
}
@NotNull
@Override
public JComponent getComponent(@Nullable PropertiesContainer container,
PropertyContext context,
@Nullable Object object,
boolean selected,
boolean hasFocus) {
String value = (String)object;
if (myBooleanRenderer != null && (StringUtil.isEmpty(value) || "false".equals(value) || "true".equals(value))) {
return myBooleanRenderer.getComponent(container, context, "true".equals(value), selected, hasFocus);
}
return super.getComponent(container, context, object, selected, hasFocus);
}
@Override
protected void formatValue(RadComponent component, String value) {
if (!StringUtil.isEmpty(value)) {
StringBuilder colorValue = new StringBuilder();
boolean system = false;
int prefix = -1;
if (value.startsWith("#")) {
prefix = 1;
}
else if (value.startsWith(ANDROID_PREFIX)) {
prefix = ANDROID_PREFIX.length();
system = true;
}
else if (value.startsWith("@")) {
prefix = 1;
}
if (prefix != -1) {
myColoredComponent.append(value.substring(0, prefix), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
myColoredComponent.append(value.substring(prefix), textStyle(component, value, system, colorValue));
}
else if (myFormats.contains(AttributeFormat.Dimension)) {
if (value.length() > 3 && value.endsWith("dip")) {
myColoredComponent.append(value.substring(0, value.length() - 3));
myColoredComponent.append("dip", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
}
else if (value.length() > 2) {
int index = value.length() - 2;
String dimension = value.substring(index);
if (ArrayUtil.indexOf(DIMENSIONS, dimension) != -1) {
myColoredComponent.append(value.substring(0, index));
myColoredComponent.append(dimension, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
}
else {
myColoredComponent.append(value);
}
}
else {
myColoredComponent.append(value);
}
}
else {
myColoredComponent.append(value);
}
if (colorValue.length() > 0) {
value = colorValue.toString();
}
if (myFormats.contains(AttributeFormat.Color) && value.startsWith("#")) {
try {
Color color = ResourceHelper.parseColor(value);
if (color != null) {
myColorIcon.setColor(color);
myColoredComponent.setIcon(myColorIcon);
}
}
catch (Throwable e) {
}
}
}
}
private static SimpleTextAttributes textStyle(RadComponent component, String value, boolean system, StringBuilder colorValue) {
if (value.startsWith("@") && !value.startsWith("@id/") && !value.startsWith("@+id/") && !value.startsWith("@android:id/")) {
try {
int start = system ? ANDROID_PREFIX.length() : 1;
int index = value.indexOf('/', start + 1);
String type = value.substring(start, index);
String name = value.substring(index + 1);
Module module = RadModelBuilder.getModule(component);
if (module != null) {
AndroidFacet facet = AndroidFacet.getInstance(module);
if (facet != null) {
ResourceManager manager = facet.getResourceManager(system ? AndroidUtils.SYSTEM_RESOURCE_PACKAGE : null);
if (manager != null) {
List<ResourceElement> resources = manager.findValueResources(type, name, false);
if ("color".equalsIgnoreCase(type) && !resources.isEmpty()) {
colorValue.append(resources.get(0).getRawText());
}
if (resources.isEmpty() && manager.findResourceFiles(type, name, false).isEmpty()) {
return SimpleTextAttributes.ERROR_ATTRIBUTES;
}
}
}
}
}
catch (Throwable e) {
}
}
return SimpleTextAttributes.REGULAR_ATTRIBUTES;
}
@Override
public void updateUI() {
if (myBooleanRenderer != null) {
SwingUtilities.updateComponentTreeUI(myBooleanRenderer);
}
super.updateUI();
}
}