| /* |
| * 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; |
| |
| import com.intellij.android.designer.model.RadViewComponent; |
| import com.intellij.designer.model.MetaModel; |
| import com.intellij.designer.model.Property; |
| import com.intellij.designer.propertyTable.IPropertyDecorator; |
| import com.intellij.designer.propertyTable.PropertyEditor; |
| import com.intellij.designer.propertyTable.PropertyRenderer; |
| import com.intellij.designer.propertyTable.editors.BooleanEditor; |
| import com.intellij.designer.propertyTable.renderers.BooleanRenderer; |
| import com.intellij.designer.propertyTable.renderers.LabelPropertyRenderer; |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.psi.xml.XmlAttribute; |
| import org.jetbrains.android.dom.attrs.AttributeDefinition; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.util.*; |
| |
| /** |
| * @author Alexander Lobas |
| */ |
| public class FlagProperty extends PropertyWithNamespace implements IPropertyDecorator, IXmlAttributeLocator { |
| private final PropertyRenderer myRenderer = new LabelPropertyRenderer(null); |
| protected final AttributeDefinition myDefinition; |
| protected final List<Property<RadViewComponent>> myOptions = new ArrayList<Property<RadViewComponent>>(); |
| private String myJavadocText; |
| |
| public FlagProperty(@NotNull String name, @NotNull AttributeDefinition definition) { |
| super(null, name); |
| myDefinition = definition; |
| |
| for (String option : definition.getValues()) { |
| myOptions.add(new OptionProperty(this, option, option)); |
| } |
| } |
| |
| @Override |
| protected String getAttributeName() { |
| return myDefinition.getName(); |
| } |
| |
| @Override |
| public Property<RadViewComponent> createForNewPresentation(@Nullable Property parent, @NotNull String name) { |
| return new FlagProperty(name, myDefinition); |
| } |
| |
| @Override |
| public void decorate(@NotNull MetaModel model) { |
| String name = getName(); |
| for (Property option : myOptions) { |
| model.decorate(option, name + "." + option.getName()); |
| } |
| } |
| |
| @NotNull |
| @Override |
| public List<Property<RadViewComponent>> getChildren(@Nullable RadViewComponent component) { |
| return myOptions; |
| } |
| |
| @Override |
| public Object getValue(@NotNull RadViewComponent component) throws Exception { |
| StringBuilder value = new StringBuilder("["); |
| Set<String> options = getOptions(component); |
| int index = 0; |
| for (Property option : myOptions) { |
| if (options.contains(((OptionProperty)option).getValueName())) { |
| if (index++ > 0) { |
| value.append(", "); |
| } |
| value.append(option.getName()); |
| } |
| } |
| return value.append("]").toString(); |
| } |
| |
| @Override |
| public boolean isDefaultValue(@NotNull RadViewComponent component) throws Exception { |
| return getAttribute(component) == null; |
| } |
| |
| @Override |
| public void setDefaultValue(@NotNull RadViewComponent component) throws Exception { |
| final XmlAttribute attribute = getAttribute(component); |
| if (attribute != null) { |
| ApplicationManager.getApplication().runWriteAction(new Runnable() { |
| @Override |
| public void run() { |
| attribute.delete(); |
| } |
| }); |
| } |
| } |
| |
| @NotNull |
| @Override |
| public PropertyRenderer getRenderer() { |
| return myRenderer; |
| } |
| |
| @Override |
| public PropertyEditor getEditor() { |
| return null; |
| } |
| |
| @Nullable |
| protected XmlAttribute getAttribute(RadViewComponent component) { |
| return component.getTag().getAttribute(myDefinition.getName(), getNamespace(component, false)); |
| } |
| |
| @Override |
| public boolean checkAttribute(RadViewComponent component, XmlAttribute attribute) { |
| return getAttribute(component) == attribute; |
| } |
| |
| protected Set<String> getOptions(RadViewComponent component) throws Exception { |
| String value = component.getTag().getAttributeValue(myDefinition.getName(), getNamespace(component, false)); |
| if (value == null) { |
| return Collections.emptySet(); |
| } |
| Set<String> options = new HashSet<String>(); |
| for (String option : StringUtil.split(value, "|")) { |
| options.add(option.trim()); |
| } |
| return options; |
| } |
| |
| private boolean isOption(RadViewComponent component, String name) throws Exception { |
| return getOptions(component).contains(name); |
| } |
| |
| private void setOption(final RadViewComponent component, String name, boolean set) throws Exception { |
| final Set<String> options = new HashSet<String>(getOptions(component)); |
| if (set) { |
| if (!options.add(name)) { |
| return; |
| } |
| } |
| else if (!options.remove(name)) { |
| return; |
| } |
| |
| ApplicationManager.getApplication().runWriteAction(new Runnable() { |
| @Override |
| public void run() { |
| if (options.isEmpty()) { |
| XmlAttribute attribute = getAttribute(component); |
| if (attribute != null) { |
| attribute.delete(); |
| } |
| } |
| else { |
| component.getTag().setAttribute(myDefinition.getName(), getNamespace(component, true), StringUtil.join(options, "|")); |
| } |
| } |
| }); |
| } |
| |
| @Override |
| public String getJavadocText() { |
| if (myJavadocText == null) { |
| String javadocText = myDefinition.getDocValue(null); |
| if (javadocText != null) { |
| myJavadocText = JavadocParser.build(getName(), javadocText); |
| } |
| } |
| return myJavadocText; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////////////// |
| // |
| // Option |
| // |
| ////////////////////////////////////////////////////////////////////////////////////////// |
| |
| protected class OptionProperty extends Property<RadViewComponent> { |
| private final PropertyRenderer myRenderer = new BooleanRenderer(); |
| private final PropertyEditor myEditor = new BooleanEditor(); |
| private final String myValueName; |
| |
| public OptionProperty(@Nullable Property parent, @NotNull String name, @NotNull String valueName) { |
| super(parent, name); |
| myValueName = valueName; |
| } |
| |
| public String getValueName() { |
| return myValueName; |
| } |
| |
| @Override |
| public Property<RadViewComponent> createForNewPresentation(@Nullable Property parent, @NotNull String name) { |
| return null; |
| } |
| |
| @Override |
| public Object getValue(@NotNull RadViewComponent component) throws Exception { |
| return isOption(component, myValueName); |
| } |
| |
| @Override |
| public void setValue(@NotNull RadViewComponent component, Object value) throws Exception { |
| setOption(component, myValueName, (Boolean)value); |
| } |
| |
| @Override |
| public boolean isDefaultValue(@NotNull RadViewComponent component) throws Exception { |
| return !isOption(component, myValueName); |
| } |
| |
| @Override |
| public void setDefaultValue(@NotNull RadViewComponent component) throws Exception { |
| setValue(component, Boolean.FALSE); |
| } |
| |
| @NotNull |
| @Override |
| public PropertyRenderer getRenderer() { |
| return myRenderer; |
| } |
| |
| @Override |
| public PropertyEditor getEditor() { |
| return myEditor; |
| } |
| |
| @Override |
| public boolean needRefreshPropertyList() { |
| return true; |
| } |
| } |
| } |