blob: 9796918fbddec33b8f942495b056f9126e5082ac [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.model;
import com.intellij.android.designer.propertyTable.CustomViewProperty;
import com.intellij.designer.ModuleProvider;
import com.intellij.designer.componentTree.AttributeWrapper;
import com.intellij.designer.model.*;
import com.intellij.designer.propertyTable.PropertyTable;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiClass;
import com.intellij.psi.xml.XmlTag;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import org.jetbrains.android.uipreview.ChooseClassDialog;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Alexander Lobas
*/
public class RadCustomViewComponent extends RadViewComponent implements IConfigurableComponent, IComponentDecorator {
private static final String NAME_KEY = "view.name";
public static final String MODEL_KEY = "view.model";
private static final Property CLASS_PROPERTY = new CustomViewProperty();
@Override
public String getCreationXml() {
return "<" + getClientProperty(NAME_KEY) + "\n" +
"android:layout_width=\"wrap_content\"\n" +
"android:layout_height=\"wrap_content\"/>";
}
@Override
public void configure(RadComponent rootComponent) throws Exception {
String view = chooseView(rootComponent);
if (view != null) {
setClientProperty(NAME_KEY, view);
}
else {
throw new Exception();
}
}
@Nullable
public static String chooseView(RadComponent rootComponent) {
ModuleProvider moduleProvider = RadModelBuilder.getModuleProvider(rootComponent);
if (moduleProvider == null) {
return null;
}
ChooseClassDialog dialog = new ChooseClassDialog(moduleProvider.getModule(), "Views", false) {
@Override
protected void findClasses(Module module, boolean includeAll, DefaultListModel model, String[] classes) {
Set<String> names = new HashSet<String>();
for (PsiClass psiClass : findInheritors(module, "android.view.View", false)) {
model.addElement(psiClass);
names.add(psiClass.getQualifiedName());
}
for (PsiClass psiClass : findInheritors(module, "android.view.View", true)) {
String name = psiClass.getQualifiedName();
if (!names.contains(name) && name != null && (!name.startsWith("android.") || name.startsWith("android.support"))) {
model.addElement(psiClass);
}
}
}
};
if (dialog.showAndGet()) {
return dialog.getClassName();
}
return null;
}
@Nullable
public String getViewClass() {
XmlTag tag = getTag();
String tagName = tag.getName();
if (!StringUtil.isEmpty(tagName) && !tagName.equals("view")) {
return tagName;
}
String classAttribute = tag.getAttributeValue("class");
if (!StringUtil.isEmpty(classAttribute)) {
return classAttribute;
}
return null;
}
@Override
public void decorateTree(SimpleColoredComponent renderer, AttributeWrapper wrapper) {
String viewClass = getViewClass();
if (viewClass != null) {
renderer.append(" - " + viewClass, wrapper.getAttribute(SimpleTextAttributes.REGULAR_ATTRIBUTES));
}
}
@Override
public MetaModel getMetaModelForProperties() throws Exception {
MetaModel metaModel = getClientProperty(MODEL_KEY);
if (metaModel == null) {
ModuleProvider moduleProvider = RadModelBuilder.getModuleProvider(getRoot());
assert moduleProvider != null;
MetaManager metaManager = ViewsMetaManager.getInstance(moduleProvider.getProject());
PsiClass viewClass = ChooseClassDialog.findClass(moduleProvider.getModule(), getViewClass());
while (viewClass != null) {
metaModel = metaManager.getModelByTarget(viewClass.getQualifiedName());
if (metaModel != null) {
break;
}
viewClass = viewClass.getSuperClass();
}
if (metaModel == null) {
metaModel = myMetaModel;
}
setClientProperty(MODEL_KEY, metaModel);
}
return metaModel;
}
@Override
public List<Property> getInplaceProperties() throws Exception {
List<Property> properties = new ArrayList<Property>();
MetaModel metaModel = getMetaModelForProperties();
List<Property> allProperties = getProperties();
properties.add(CLASS_PROPERTY);
for (String name : metaModel.getInplaceProperties()) {
Property property = PropertyTable.findProperty(allProperties, name);
if (property != null) {
properties.add(property);
}
}
properties.add(PropertyTable.findProperty(allProperties, "id"));
return properties;
}
@Override
public void setProperties(List<Property> properties) {
List<Property> oldProperties = getProperties();
if (!properties.isEmpty() && (oldProperties == null || oldProperties.isEmpty())) {
properties = new ArrayList<Property>(properties);
properties.add(0, CLASS_PROPERTY);
}
super.setProperties(properties);
}
}