mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Properties
This commit is contained in:
@@ -16,9 +16,11 @@
|
||||
package com.intellij.android.designer.model;
|
||||
|
||||
import com.android.ide.common.rendering.api.ViewInfo;
|
||||
import com.android.resources.ResourceType;
|
||||
import com.android.sdklib.IAndroidTarget;
|
||||
import com.intellij.android.designer.propertyTable.AttributeProperty;
|
||||
import com.intellij.android.designer.propertyTable.FlagProperty;
|
||||
import com.intellij.android.designer.propertyTable.editors.ResourceDialog;
|
||||
import com.intellij.designer.model.MetaManager;
|
||||
import com.intellij.designer.model.MetaModel;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
@@ -33,6 +35,7 @@ import org.jetbrains.android.sdk.AndroidPlatform;
|
||||
import org.jetbrains.android.sdk.AndroidTargetData;
|
||||
import org.jetbrains.android.uipreview.ProjectClassLoader;
|
||||
import org.jetbrains.android.uipreview.RenderServiceFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -43,12 +46,14 @@ import java.util.*;
|
||||
public class PropertyParser {
|
||||
public static final String KEY = "PROPERTY_PARSER";
|
||||
|
||||
private final Module myModule;
|
||||
private MetaManager myMetaManager;
|
||||
private AttributeDefinitions myDefinitions;
|
||||
private ProjectClassLoader myClassLoader;
|
||||
private Map<String, List<Property>> myCachedProperties;
|
||||
|
||||
public PropertyParser(Module module, IAndroidTarget target) throws Exception {
|
||||
myModule = module;
|
||||
myMetaManager = ViewsMetaManager.getInstance(module.getProject());
|
||||
myCachedProperties = myMetaManager.getCache(target.hashString());
|
||||
if (myCachedProperties == null) {
|
||||
@@ -166,4 +171,9 @@ public class PropertyParser {
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ResourceDialog createResourceDialog(ResourceType... types) {
|
||||
return new ResourceDialog(myModule, types);
|
||||
}
|
||||
}
|
||||
+17
-2
@@ -15,8 +15,11 @@
|
||||
*/
|
||||
package com.intellij.android.designer.propertyTable;
|
||||
|
||||
import com.android.resources.ResourceType;
|
||||
import com.intellij.android.designer.model.PropertyParser;
|
||||
import com.intellij.android.designer.model.RadViewComponent;
|
||||
import com.intellij.android.designer.propertyTable.editors.BooleanEditor;
|
||||
import com.intellij.android.designer.propertyTable.editors.ResourceDialog;
|
||||
import com.intellij.android.designer.propertyTable.editors.StringsComboEditor;
|
||||
import com.intellij.android.designer.propertyTable.renderers.BooleanRenderer;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
@@ -26,6 +29,7 @@ import com.intellij.designer.propertyTable.PropertyRenderer;
|
||||
import com.intellij.designer.propertyTable.editors.AbstractTextFieldEditor;
|
||||
import com.intellij.designer.propertyTable.renderers.LabelPropertyRenderer;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
@@ -141,12 +145,22 @@ public class AttributeProperty extends Property<RadViewComponent> {
|
||||
|
||||
private static class TextDialogEditor extends PropertyEditor {
|
||||
private TextFieldWithBrowseButton myTextField;
|
||||
private RadComponent myRootComponent;
|
||||
|
||||
public TextDialogEditor() {
|
||||
myTextField = new TextFieldWithBrowseButton(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// TODO: Auto-generated method stub
|
||||
PropertyParser parser = myRootComponent.getClientProperty(PropertyParser.KEY);
|
||||
ResourceDialog dialog = parser
|
||||
.createResourceDialog(ResourceType.BOOL, ResourceType.COLOR, ResourceType.DIMEN, ResourceType.DRAWABLE, ResourceType.INTEGER,
|
||||
ResourceType.STRING, ResourceType.ID);
|
||||
dialog.show();
|
||||
|
||||
if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
|
||||
myTextField.setText(dialog.getResourceName());
|
||||
fireValueCommitted(true, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
myTextField.getTextField().setBorder(null);
|
||||
@@ -154,7 +168,8 @@ public class AttributeProperty extends Property<RadViewComponent> {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JComponent getComponent(@Nullable RadComponent component, Object value) {
|
||||
public JComponent getComponent(@NotNull RadComponent rootComponent, @Nullable RadComponent component, Object value) {
|
||||
myRootComponent = rootComponent;
|
||||
myTextField.setText(value == null ? "" : value.toString());
|
||||
myTextField.getTextField().setBorder(null);
|
||||
return myTextField;
|
||||
|
||||
+308
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* 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.editors;
|
||||
|
||||
import com.android.resources.ResourceType;
|
||||
import com.intellij.designer.componentTree.TreeNodeDescriptor;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeStructure;
|
||||
import com.intellij.ide.util.treeView.NodeDescriptor;
|
||||
import com.intellij.ide.util.treeView.NodeRenderer;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.ui.TreeSpeedSearch;
|
||||
import com.intellij.ui.components.JBTabbedPane;
|
||||
import com.intellij.ui.speedSearch.SpeedSearchUtil;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.resourceManagers.ResourceManager;
|
||||
import org.jetbrains.android.util.AndroidUtils;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public class ResourceDialog extends DialogWrapper implements TreeSelectionListener {
|
||||
private final JBTabbedPane myContentPanel;
|
||||
private final ResourcePanel myProjectPanel;
|
||||
private final ResourcePanel mySystemPanel;
|
||||
private final Action myNewResourceAction = new AbstractAction("New Resource...") {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// TODO: Auto-generated method stub
|
||||
}
|
||||
};
|
||||
private String myResultResourceName;
|
||||
|
||||
public ResourceDialog(Module module, ResourceType[] types) {
|
||||
super(module.getProject());
|
||||
|
||||
setTitle("Resource Dialog");
|
||||
getOKAction().setEnabled(false);
|
||||
|
||||
AndroidFacet facet = AndroidFacet.getInstance(module);
|
||||
myProjectPanel = new ResourcePanel(facet, types, false);
|
||||
mySystemPanel = new ResourcePanel(facet, types, true);
|
||||
|
||||
myContentPanel = new JBTabbedPane();
|
||||
myContentPanel.setPreferredSize(new Dimension(500, 400));
|
||||
myContentPanel.addTab("Project", myProjectPanel.myComponent);
|
||||
myContentPanel.addTab("System", mySystemPanel.myComponent);
|
||||
|
||||
myContentPanel.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
myNewResourceAction.setEnabled(myContentPanel.getSelectedComponent() == myProjectPanel.myComponent);
|
||||
valueChanged(null);
|
||||
}
|
||||
});
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myProjectPanel.myTree;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return myContentPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Action[] createLeftSideActions() {
|
||||
return new Action[]{myNewResourceAction};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
super.dispose();
|
||||
Disposer.dispose(myProjectPanel.myTreeBuilder);
|
||||
Disposer.dispose(mySystemPanel.myTreeBuilder);
|
||||
}
|
||||
|
||||
public String getResourceName() {
|
||||
return myResultResourceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
ResourcePanel panel = myContentPanel.getSelectedComponent() == myProjectPanel.myComponent ? myProjectPanel : mySystemPanel;
|
||||
Set<ResourceItem> elements = panel.myTreeBuilder.getSelectedElements(ResourceItem.class);
|
||||
getOKAction().setEnabled(!elements.isEmpty());
|
||||
|
||||
if (elements.isEmpty()) {
|
||||
myResultResourceName = null;
|
||||
}
|
||||
else {
|
||||
String prefix = panel == myProjectPanel ? "@" : "@android:";
|
||||
myResultResourceName = prefix + elements.iterator().next().getName();
|
||||
}
|
||||
}
|
||||
|
||||
private class ResourcePanel {
|
||||
public final Tree myTree;
|
||||
public final AbstractTreeBuilder myTreeBuilder;
|
||||
public final JScrollPane myComponent;
|
||||
|
||||
public ResourcePanel(AndroidFacet facet, ResourceType[] types, boolean system) {
|
||||
myTree = new Tree();
|
||||
myTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
|
||||
myTree.setScrollsOnExpand(true);
|
||||
myTree.setRootVisible(false);
|
||||
myTree.setShowsRootHandles(true);
|
||||
ToolTipManager.sharedInstance().registerComponent(myTree);
|
||||
TreeUtil.installActions(myTree);
|
||||
|
||||
ResourceManager manager = facet.getResourceManager(system ? AndroidUtils.SYSTEM_RESOURCE_PACKAGE : null);
|
||||
ResourceGroup[] groups = new ResourceGroup[types.length];
|
||||
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
groups[i] = new ResourceGroup(types[i], manager);
|
||||
}
|
||||
|
||||
myTreeBuilder =
|
||||
new AbstractTreeBuilder(myTree, (DefaultTreeModel)myTree.getModel(), new TreeContentProvider(groups), null);
|
||||
myTreeBuilder.initRootNode();
|
||||
|
||||
TreeSelectionModel selectionModel = myTree.getSelectionModel();
|
||||
selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
selectionModel.addTreeSelectionListener(ResourceDialog.this);
|
||||
|
||||
myTree.setCellRenderer(new NodeRenderer() {
|
||||
@Override
|
||||
protected void doAppend(@NotNull @Nls String fragment,
|
||||
@NotNull SimpleTextAttributes attributes,
|
||||
boolean isMainText,
|
||||
boolean selected) {
|
||||
SpeedSearchUtil.appendFragmentsForSpeedSearch(myTree, fragment, attributes, selected, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAppend(@NotNull String fragment, @NotNull SimpleTextAttributes attributes, boolean selected) {
|
||||
SpeedSearchUtil.appendFragmentsForSpeedSearch(myTree, fragment, attributes, selected, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAppend(String fragment, boolean selected) {
|
||||
SpeedSearchUtil.appendFragmentsForSpeedSearch(myTree, fragment, SimpleTextAttributes.REGULAR_ATTRIBUTES, selected, this);
|
||||
}
|
||||
});
|
||||
new TreeSpeedSearch(myTree, TreeSpeedSearch.NODE_DESCRIPTOR_TOSTRING, true);
|
||||
|
||||
myComponent = ScrollPaneFactory.createScrollPane(myTree);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ResourceGroup {
|
||||
private List<ResourceItem> myItems = new ArrayList<ResourceItem>();
|
||||
private final ResourceType myType;
|
||||
|
||||
public ResourceGroup(ResourceType type, ResourceManager manager) {
|
||||
myType = type;
|
||||
|
||||
Collection<String> resourceNames = manager.getValueResourceNames(type.getName());
|
||||
for (String resourceName : resourceNames) {
|
||||
myItems.add(new ResourceItem(this, resourceName));
|
||||
}
|
||||
|
||||
for (String file : manager.getFileResourcesNames(type.getName())) {
|
||||
myItems.add(new ResourceItem(this, file));
|
||||
}
|
||||
|
||||
if (type == ResourceType.ID) {
|
||||
for (String id : manager.getIds()) {
|
||||
if (!resourceNames.contains(id)) {
|
||||
myItems.add(new ResourceItem(this, id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(myItems, new Comparator<ResourceItem>() {
|
||||
@Override
|
||||
public int compare(ResourceItem resource1, ResourceItem resource2) {
|
||||
return resource1.toString().compareTo(resource2.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myType.getName();
|
||||
}
|
||||
|
||||
public List<ResourceItem> getItems() {
|
||||
return myItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myType.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ResourceItem {
|
||||
private final ResourceGroup myGroup;
|
||||
private final String myName;
|
||||
|
||||
public ResourceItem(@NotNull ResourceGroup group, @NotNull String name) {
|
||||
myGroup = group;
|
||||
myName = name;
|
||||
}
|
||||
|
||||
public ResourceGroup getGroup() {
|
||||
return myGroup;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myGroup.getName() + "/" + myName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myName;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TreeContentProvider extends AbstractTreeStructure {
|
||||
private final Object myTreeRoot = new Object();
|
||||
private final ResourceGroup[] myGroups;
|
||||
|
||||
public TreeContentProvider(ResourceGroup[] groups) {
|
||||
myGroups = groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRootElement() {
|
||||
return myTreeRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getChildElements(Object element) {
|
||||
if (element == myTreeRoot) {
|
||||
return myGroups;
|
||||
}
|
||||
if (element instanceof ResourceGroup) {
|
||||
ResourceGroup group = (ResourceGroup)element;
|
||||
return group.getItems().toArray();
|
||||
}
|
||||
return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getParentElement(Object element) {
|
||||
if (element instanceof ResourceItem) {
|
||||
ResourceItem resource = (ResourceItem)element;
|
||||
return resource.getGroup();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public NodeDescriptor createDescriptor(Object element, NodeDescriptor parentDescriptor) {
|
||||
return new TreeNodeDescriptor(parentDescriptor, element, element == null ? null : element.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSomethingToCommit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() {
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -32,7 +32,7 @@ public class StringsComboEditor extends ComboEditor {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JComponent getComponent(@Nullable RadComponent component, Object value) {
|
||||
public JComponent getComponent(@NotNull RadComponent rootComponent, @Nullable RadComponent component, Object value) {
|
||||
myCombo.setSelectedItem(value);
|
||||
return myCombo;
|
||||
}
|
||||
|
||||
+5
@@ -30,6 +30,11 @@ public final class TreeNodeDescriptor extends NodeDescriptor {
|
||||
myElement = element;
|
||||
}
|
||||
|
||||
public TreeNodeDescriptor(@Nullable NodeDescriptor parentDescriptor, Object element, String name) {
|
||||
this(parentDescriptor, element);
|
||||
myName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update() {
|
||||
return false;
|
||||
|
||||
+4
@@ -359,6 +359,10 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
|
||||
return myDesignerCard.isVisible() ? myGlassLayer : myErrorLabel;
|
||||
}
|
||||
|
||||
public RadComponent getRootComponent() {
|
||||
return myRootComponent;
|
||||
}
|
||||
|
||||
public Object[] getTreeRoots() {
|
||||
return myRootComponent == null ? ArrayUtil.EMPTY_OBJECT_ARRAY : new Object[]{myRootComponent};
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ public abstract class PropertyEditor {
|
||||
private final EventListenerList myListenerList = new EventListenerList();
|
||||
|
||||
@NotNull
|
||||
public abstract JComponent getComponent(@Nullable RadComponent component, Object value);
|
||||
public abstract JComponent getComponent(@NotNull RadComponent rootComponent, @Nullable RadComponent component, Object value);
|
||||
|
||||
@Nullable
|
||||
public JComponent getPreferredFocusedComponent(@NotNull JComponent component) {
|
||||
|
||||
+1
-1
@@ -821,7 +821,7 @@ public final class PropertyTable extends JBTable implements ComponentSelectionLi
|
||||
@Override
|
||||
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
|
||||
try {
|
||||
JComponent component = myEditor.getComponent(getCurrentComponent(), getValue((Property)value));
|
||||
JComponent component = myEditor.getComponent(myDesigner.getRootComponent(), getCurrentComponent(), getValue((Property)value));
|
||||
|
||||
if (component instanceof JComboBox) {
|
||||
component.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ public abstract class AbstractTextFieldEditor extends PropertyEditor {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JComponent getComponent(@Nullable RadComponent component, Object value) {
|
||||
public JComponent getComponent(@NotNull RadComponent rootComponent, @Nullable RadComponent component, Object value) {
|
||||
setEditorValue(component, value);
|
||||
myTextField.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
|
||||
return myTextField;
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public class BooleanEditor extends PropertyEditor {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JComponent getComponent(@Nullable RadComponent component, Object value) {
|
||||
public JComponent getComponent(@NotNull RadComponent rootComponent, @Nullable RadComponent component, Object value) {
|
||||
try {
|
||||
myInsideChange = true;
|
||||
myCheckBox.setBackground(UIUtil.getTableBackground());
|
||||
|
||||
Reference in New Issue
Block a user