blob: f736a02d83bf59f11d9af018bd369586283f877f [file] [log] [blame]
/*
* Copyright 2000-2014 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.codeInsight.generation;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.impl.TemplateEditorUtil;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Splitter;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.treeStructure.SimpleTree;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.util.Collection;
/**
* @author Dmitry Avdeev
*/
public class GenerateByPatternDialog extends DialogWrapper {
private final Project myProject;
private JPanel myPanel;
private Splitter mySplitter;
private Tree myTree = new Tree();
private final Editor myEditor;
private final MultiMap<String,PatternDescriptor> myMap;
public GenerateByPatternDialog(Project project, PatternDescriptor[] descriptors) {
super(project);
myProject = project;
setTitle("Generate by Pattern");
setOKButtonText("Generate");
myMap = new MultiMap<String, PatternDescriptor>();
for (PatternDescriptor descriptor : descriptors) {
myMap.putValue(descriptor.getParentId(), descriptor);
}
DefaultMutableTreeNode root = createNode(null);
myTree = new SimpleTree() {
};
myTree.setRootVisible(false);
myTree.setCellRenderer(new DefaultTreeCellRenderer() {
@NotNull
@Override
public Component getTreeCellRendererComponent(@NotNull JTree tree,
Object value,
boolean sel,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
Component component = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row,
hasFocus);
Object object = ((DefaultMutableTreeNode)value).getUserObject();
if (object instanceof PatternDescriptor) {
setText(((PatternDescriptor)object).getName());
setIcon(((PatternDescriptor)object).getIcon());
}
return component;
}
});
myTree.setModel(new DefaultTreeModel(root));
myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(@NotNull TreeSelectionEvent e) {
update();
}
});
myEditor = TemplateEditorUtil.createEditor(true, "");
mySplitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myTree));
JPanel details = new JPanel(new BorderLayout());
details.add(myEditor.getComponent(), BorderLayout.CENTER);
mySplitter.setSecondComponent(details);
mySplitter.setHonorComponentsMinimumSize(true);
mySplitter.setShowDividerControls(true);
myTree.setSelectionRow(0);
init();
}
private void update() {
DefaultMutableTreeNode node = getSelectedNode();
getOKAction().setEnabled(node != null && node.isLeaf());
PatternDescriptor descriptor = getSelectedDescriptor();
if (descriptor != null) {
updateDetails(descriptor);
}
}
private DefaultMutableTreeNode getSelectedNode() {
TreePath path = myTree.getSelectionModel().getSelectionPath();
return path == null ? null : (DefaultMutableTreeNode)path.getLastPathComponent();
}
PatternDescriptor getSelectedDescriptor() {
DefaultMutableTreeNode selectedNode = getSelectedNode();
if (selectedNode != null) {
Object object = selectedNode.getUserObject();
if (object instanceof PatternDescriptor) {
return (PatternDescriptor)object;
}
}
return null;
}
private void updateDetails(final PatternDescriptor descriptor) {
new WriteCommandAction.Simple(myProject) {
@Override
protected void run() throws Throwable {
final Template template = descriptor.getTemplate();
if (template instanceof TemplateImpl) {
String text = ((TemplateImpl)template).getString();
myEditor.getDocument().replaceString(0, myEditor.getDocument().getTextLength(), text);
TemplateEditorUtil.setHighlighter(myEditor, ((TemplateImpl)template).getTemplateContext());
}
else {
myEditor.getDocument().replaceString(0, myEditor.getDocument().getTextLength(), "");
}
}
}.execute();
}
private DefaultMutableTreeNode createNode(@Nullable PatternDescriptor descriptor) {
DefaultMutableTreeNode root = new DefaultMutableTreeNode(descriptor) {
@NotNull
@Override
public String toString() {
Object object = getUserObject();
return object == null ? "" : ((PatternDescriptor)object).getName();
}
};
String id = descriptor == null ? PatternDescriptor.ROOT : descriptor.getId();
Collection<PatternDescriptor> collection = myMap.get(id);
for (PatternDescriptor childDescriptor : collection) {
root.add(createNode(childDescriptor));
}
return root;
}
@Override
protected JComponent createCenterPanel() {
return myPanel;
}
@Override
public JComponent getPreferredFocusedComponent() {
return myTree;
}
@Override
protected String getDimensionServiceKey() {
return "generate.patterns.dialog";
}
@Override
protected void dispose() {
super.dispose();
EditorFactory.getInstance().releaseEditor(myEditor);
}
private void createUIComponents() {
mySplitter = new Splitter(false, 0.3f);
}
}