blob: 002c2d62f2aec7e3f07dd808e93e792b4371851e [file] [log] [blame]
/*
* Copyright 2000-2009 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 org.jetbrains.plugins.groovy.annotator.intentions.dynamic;
import com.intellij.ide.DeleteProvider;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.listeners.RefactoringElementListenerProvider;
import com.intellij.refactoring.listeners.RefactoringListenerManager;
import com.intellij.ui.*;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
import com.intellij.ui.treeStructure.treetable.TreeTable;
import com.intellij.ui.treeStructure.treetable.TreeTableModel;
import com.intellij.ui.treeStructure.treetable.TreeTableTree;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.AbstractTableCellEditor;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import icons.JetgroovyIcons;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.annotator.intentions.QuickfixUtil;
import org.jetbrains.plugins.groovy.annotator.intentions.dynamic.elements.*;
import org.jetbrains.plugins.groovy.debugger.fragments.GroovyCodeFragment;
import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.TableCellRenderer;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* User: Dmitry.Krasilschikov
* Date: 09.01.2008
*/
public class DynamicToolWindowWrapper {
private static final Logger LOG = Logger.getInstance(DynamicToolWindowWrapper.class);
private static final int CLASS_OR_ELEMENT_NAME_COLUMN = 0;
private static final int TYPE_COLUMN = 1;
private static final String[] myColumnNames = {"Dynamic Element", "Type"};
private final Project myProject;
private ToolWindow myToolWindow = null;
private JPanel myTreeTablePanel;
private SimpleToolWindowPanel myBigPanel;
private ListTreeTableModelOnColumns myTreeTableModel;
private MyTreeTable myTreeTable;
public DynamicToolWindowWrapper(Project project) {
myProject = project;
}
public static DynamicToolWindowWrapper getInstance(Project project) {
return ServiceManager.getService(project, DynamicToolWindowWrapper.class);
}
public TreeTable getTreeTable() {
getToolWindow();
return myTreeTable;
}
public ToolWindow getToolWindow() {
if (myToolWindow == null) {
myToolWindow = ToolWindowManager.getInstance(myProject).registerToolWindow(GroovyBundle.message("dynamic.tool.window.id"), true, ToolWindowAnchor.RIGHT);
myToolWindow.setIcon(JetgroovyIcons.Groovy.DynamicProperty_13);
myToolWindow.setTitle(GroovyBundle.message("dynamic.window"));
myToolWindow.setToHideOnEmptyContent(true);
final JPanel panel = buildBigPanel();
final ContentManager contentManager = myToolWindow.getContentManager();
final Content content = contentManager.getFactory().createContent(panel, "", false);
content.setPreferredFocusableComponent(myTreeTable);
contentManager.addContent(content);
}
return myToolWindow;
}
private JPanel buildBigPanel() {
myBigPanel = new SimpleToolWindowPanel(true);
final ActionManager actionManager = ActionManager.getInstance();
final ActionGroup actionGroup = (ActionGroup)actionManager.getAction("Groovy.Dynamic.Toolbar");
ActionToolbar actionToolbar = actionManager.createActionToolbar("Groovy.Dynamic.Toolbar", actionGroup, true);
myBigPanel.setToolbar(actionToolbar.getComponent());
myBigPanel.setBackground(UIUtil.getFieldForegroundColor());
final JPanel panel = new JPanel(new BorderLayout());
myBigPanel.add(panel, BorderLayout.CENTER);
myTreeTablePanel = new JPanel(new BorderLayout());
rebuildTreePanel();
panel.add(myTreeTablePanel);
myBigPanel.setPreferredSize(new Dimension(200, myBigPanel.getHeight()));
myBigPanel.revalidate();
return myBigPanel;
}
public void rebuildTreePanel() {
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
buildTree(rootNode);
rebuildTreeView(rootNode, false);
}
private void rebuildTreeView(DefaultMutableTreeNode root, boolean expandAll) {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
myTreeTablePanel.removeAll();
final JScrollPane treeTable = createTable(root);
if (expandAll) {
TreeUtil.expandAll(myTreeTable.getTree());
}
myTreeTablePanel.add(treeTable);
myTreeTablePanel.revalidate();
}
private DefaultMutableTreeNode buildTree(DefaultMutableTreeNode rootNode) {
final Collection<DClassElement> containingClasses = DynamicManager.getInstance(myProject).getAllContainingClasses();
DefaultMutableTreeNode containingClassNode;
for (DClassElement containingClassElement : containingClasses) {
containingClassNode = new DefaultMutableTreeNode(containingClassElement);
final Collection<DPropertyElement> properties =
DynamicManager.getInstance(myProject).findDynamicPropertiesOfClass(containingClassElement.getName());
// if (properties.length == 0) continue;
DefaultMutableTreeNode propertyTreeNode;
for (DPropertyElement property : properties) {
propertyTreeNode = new DefaultMutableTreeNode(property);
containingClassNode.add(propertyTreeNode);
}
DefaultMutableTreeNode methodTreeNode;
final Set<DMethodElement> methods = containingClassElement.getMethods();
for (DMethodElement methodElement : methods) {
final String[] psiTypes = QuickfixUtil.getArgumentsTypes(methodElement.getPairs());
final DMethodElement method = DynamicManager.getInstance(myProject)
.findConcreteDynamicMethod(containingClassElement.getName(), methodElement.getName(), psiTypes);
methodTreeNode = new DefaultMutableTreeNode(method);
containingClassNode.add(methodTreeNode);
}
rootNode.add(containingClassNode);
}
return rootNode;
}
private JScrollPane createTable(final MutableTreeNode myTreeRoot) {
ColumnInfo[] columnInfos =
{new ClassColumnInfo(myColumnNames[CLASS_OR_ELEMENT_NAME_COLUMN]), new PropertyTypeColumnInfo(myColumnNames[TYPE_COLUMN])};
myTreeTableModel = new ListTreeTableModelOnColumns(myTreeRoot, columnInfos);
myTreeTable = new MyTreeTable(myTreeTableModel);
new TreeTableSpeedSearch(myTreeTable, new Convertor<TreePath, String>() {
@Override
public String convert(TreePath o) {
final Object node = o.getLastPathComponent();
if (node instanceof DefaultMutableTreeNode) {
final Object object = ((DefaultMutableTreeNode)node).getUserObject();
if (object instanceof DNamedElement) {
return ((DNamedElement)object).getName();
}
}
return "";
}
});
DefaultActionGroup group = new DefaultActionGroup();
group.add(ActionManager.getInstance().getAction(RemoveDynamicAction.GROOVY_DYNAMIC_REMOVE));
PopupHandler.installUnknownPopupHandler(myTreeTable, group, ActionManager.getInstance());
final MyColoredTreeCellRenderer treeCellRenderer = new MyColoredTreeCellRenderer();
myTreeTable.setDefaultRenderer(String.class, new TableCellRenderer() {
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
if (value instanceof String) {
try {
final PsiType type = JavaPsiFacade.getElementFactory(myProject).createTypeFromText((String)value, null);
String shortName = type.getPresentableText();
return new JLabel(shortName);
}
catch (IncorrectOperationException e) {
LOG.debug("Type cannot be created", e);
}
return new JLabel(QuickfixUtil.shortenType((String)value));
}
return new JLabel();
}
});
myTreeTable.setTreeCellRenderer(treeCellRenderer);
myTreeTable.setRootVisible(false);
myTreeTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
final MyPropertyTypeCellEditor typeCellEditor = new MyPropertyTypeCellEditor();
typeCellEditor.addCellEditorListener(new CellEditorListener() {
public void editingStopped(ChangeEvent e) {
final TreeTableTree tree = getTree();
String newTypeValue = ((MyPropertyTypeCellEditor)e.getSource()).getCellEditorValue();
if (newTypeValue == null || tree == null) {
myTreeTable.editingStopped(e);
return;
}
try {
final PsiType type = JavaPsiFacade.getElementFactory(myProject).createTypeFromText(newTypeValue, null);
String canonical = type.getCanonicalText();
if (canonical != null) newTypeValue = canonical;
}
catch (IncorrectOperationException ex) {
//do nothing in case bad string is entered
}
final TreePath editingTypePath = tree.getSelectionPath();
if (editingTypePath == null) return;
final TreePath editingClassPath = editingTypePath.getParentPath();
Object oldTypeValue = myTreeTable.getValueAt(tree.getRowForPath(editingTypePath), TYPE_COLUMN);
if (!(oldTypeValue instanceof String)) {
myTreeTable.editingStopped(e);
return;
}
final Object editingPropertyObject = myTreeTable.getValueAt(tree.getRowForPath(editingTypePath), CLASS_OR_ELEMENT_NAME_COLUMN);
final Object editingClassObject = myTreeTable.getValueAt(tree.getRowForPath(editingClassPath), CLASS_OR_ELEMENT_NAME_COLUMN);
if (!(editingPropertyObject instanceof DItemElement) || !(editingClassObject instanceof DClassElement)) {
myTreeTable.editingStopped(e);
return;
}
final DItemElement dynamicElement = (DItemElement)editingPropertyObject;
final String name = dynamicElement.getName();
final String className = ((DClassElement)editingClassObject).getName();
if (dynamicElement instanceof DPropertyElement) {
DynamicManager.getInstance(myProject).replaceDynamicPropertyType(className, name, (String)oldTypeValue, newTypeValue);
}
else if (dynamicElement instanceof DMethodElement) {
final List<ParamInfo> myPairList = ((DMethodElement)dynamicElement).getPairs();
DynamicManager.getInstance(myProject).replaceDynamicMethodType(className, name, myPairList, (String)oldTypeValue, newTypeValue);
}
}
public void editingCanceled(ChangeEvent e) {
myTreeTable.editingCanceled(e);
}
});
RefactoringListenerManager.getInstance(myProject).addListenerProvider(new RefactoringElementListenerProvider() {
@Nullable
public RefactoringElementListener getListener(final PsiElement element) {
if (element instanceof PsiClass) {
final String qualifiedName = ((PsiClass)element).getQualifiedName();
return new RefactoringElementListener() {
public void elementMoved(@NotNull PsiElement newElement) {
renameElement(qualifiedName, newElement);
}
public void elementRenamed(@NotNull PsiElement newElement) {
renameElement(qualifiedName, newElement);
}
private void renameElement(String oldClassName, PsiElement newElement) {
if (newElement instanceof PsiClass) {
final String newClassName = ((PsiClass)newElement).getQualifiedName();
final DRootElement rootElement = DynamicManager.getInstance(myProject).getRootElement();
final DClassElement oldClassElement = rootElement.getClassElement(oldClassName);
final TreeNode oldClassNode = TreeUtil.findNodeWithObject((DefaultMutableTreeNode)myTreeRoot, oldClassElement);
DynamicManager.getInstance(myProject).replaceClassName(oldClassElement, newClassName);
myTreeTableModel.nodeChanged(oldClassNode);
}
}
};
}
return null;
}
});
myTreeTable.setDefaultEditor(String.class, typeCellEditor);
myTreeTable.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent event) {
final int selectionRow = myTreeTable.getTree().getLeadSelectionRow();
myTreeTable.editCellAt(selectionRow, CLASS_OR_ELEMENT_NAME_COLUMN, event);
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), JComponent.WHEN_FOCUSED);
myTreeTable.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent event) {
final int selectionRow = myTreeTable.getTree().getLeadSelectionRow();
myTreeTable.editCellAt(selectionRow, TYPE_COLUMN, event);
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_F2, InputEvent.CTRL_MASK), JComponent.WHEN_FOCUSED);
myTreeTable.getTree().setShowsRootHandles(true);
myTreeTable.getTableHeader().setReorderingAllowed(false);
myTreeTable.setPreferredScrollableViewportSize(new Dimension(300, myTreeTable.getRowHeight() * 10));
myTreeTable.getColumn(myColumnNames[CLASS_OR_ELEMENT_NAME_COLUMN]).setPreferredWidth(200);
myTreeTable.getColumn(myColumnNames[TYPE_COLUMN]).setPreferredWidth(160);
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTreeTable);
scrollPane.setPreferredSize(new Dimension(600, 400));
return scrollPane;
}
void deleteRow() {
boolean isShowDialog = true;
final int rowsCount = myTreeTable.getSelectedRows().length;
int i = 0;
final TreePath[] paths = myTreeTable.getTree().getSelectionPaths();
if (paths == null) return;
for (TreePath selectionPath : paths) {
if (rowsCount > 1) isShowDialog = false;
if (i == 0) isShowDialog = true;
i++;
//class
final TreePath parent = selectionPath.getParentPath();
if (parent.getParentPath() == null) {
//selectionPath is class
final Object classRow = selectionPath.getLastPathComponent();
if (!(classRow instanceof DefaultMutableTreeNode)) return;
if (!removeClass(((DefaultMutableTreeNode)classRow), isShowDialog, rowsCount)) return;
} else {
//selectionPath is dynamic item
final Object classRow = parent.getLastPathComponent();
final Object dynamicRow = selectionPath.getLastPathComponent();
if (!(classRow instanceof DefaultMutableTreeNode)) return;
if (!(dynamicRow instanceof DefaultMutableTreeNode)) return;
final DefaultMutableTreeNode dynamicItemNode = (DefaultMutableTreeNode)dynamicRow;
final DefaultMutableTreeNode classNode = (DefaultMutableTreeNode)classRow;
final boolean removeClass = classNode.getChildCount() == 1;
if (!removeDynamicElement(dynamicItemNode, isShowDialog, rowsCount)) return;
if (removeClass) {
removeNamedElement((DNamedElement)classNode.getUserObject());
}
}
}
DynamicManager.getInstance(myProject).fireChange();
}
private boolean removeClass(DefaultMutableTreeNode classNode, boolean isShowDialog, int rowsCount) {
final TreeNode rootObject = classNode.getParent();
return rootObject instanceof DefaultMutableTreeNode && removeDynamicElement(classNode, isShowDialog, rowsCount);
}
private boolean removeDynamicElement(DefaultMutableTreeNode child, boolean isShowDialog, int rowsCount) {
Object namedElement = child.getUserObject();
if (!(namedElement instanceof DNamedElement)) return false;
if (isShowDialog) {
int result;
if (rowsCount > 1) {
result = Messages.showOkCancelDialog(myBigPanel, GroovyBundle.message("are.you.sure.to.delete.elements", String.valueOf(rowsCount)),
GroovyBundle.message("dynamic.element.deletion"), Messages.getQuestionIcon());
} else {
result = Messages.showOkCancelDialog(myBigPanel, GroovyBundle.message("are.you.sure.to.delete.dynamic.property",
((DNamedElement)namedElement).getName()),
GroovyBundle.message("dynamic.property.deletion"), Messages.getQuestionIcon());
}
if (result != DialogWrapper.OK_EXIT_CODE) return false;
}
removeNamedElement(((DNamedElement)namedElement));
return true;
}
private void removeNamedElement(DNamedElement namedElement) {
if (namedElement instanceof DClassElement) {
DynamicManager.getInstance(myProject).removeClassElement((DClassElement)namedElement);
} else if (namedElement instanceof DItemElement) {
DynamicManager.getInstance(myProject).removeItemElement((DItemElement)namedElement);
}
}
public void setSelectedNode(DefaultMutableTreeNode node) {
JTree tree = myTreeTable.getTree();
TreePath path = new TreePath(node.getPath());
tree.expandPath(path.getParentPath());
int row = tree.getRowForPath(path);
myTreeTable.getSelectionModel().setSelectionInterval(row, row);
myTreeTable.scrollRectToVisible(myTreeTable.getCellRect(row, 0, true));
IdeFocusManager.getInstance(myProject).requestFocus(myTreeTable, true);
}
public void removeFromParent(DefaultMutableTreeNode parent, DefaultMutableTreeNode child) {
int idx = myTreeTableModel.getIndexOfChild(parent, child);
child.removeFromParent();
myTreeTableModel.nodesWereRemoved(parent, new int[]{idx}, new TreeNode[]{child});
}
@Nullable
private TreeTableTree getTree() {
return myTreeTable != null ? myTreeTable.getTree() : null;
}
private static class PropertyTypeColumnInfo extends ColumnInfo<DefaultMutableTreeNode, String> {
public PropertyTypeColumnInfo(String name) {
super(name);
}
public boolean isCellEditable(DefaultMutableTreeNode node) {
final Object value = node.getUserObject();
return !(value instanceof DClassElement);
}
public String valueOf(DefaultMutableTreeNode treeNode) {
Object userObject = treeNode.getUserObject();
if (userObject instanceof DItemElement) return ((DItemElement)userObject).getType();
return null;
}
}
private static class ClassColumnInfo extends ColumnInfo<DefaultMutableTreeNode, DNamedElement> {
public ClassColumnInfo(String name) {
super(name);
}
public boolean isCellEditable(DefaultMutableTreeNode treeNode) {
final Object userObject = treeNode.getUserObject();
return userObject instanceof DPropertyElement;
}
public Class getColumnClass() {
return TreeTableModel.class;
}
public DNamedElement valueOf(DefaultMutableTreeNode treeNode) {
Object userObject = treeNode.getUserObject();
if (userObject instanceof DClassElement) return ((DClassElement)userObject);
if (userObject instanceof DPropertyElement) return ((DPropertyElement)userObject);
if (userObject instanceof DMethodElement) return ((DMethodElement)userObject);
return null;
}
}
public ListTreeTableModelOnColumns getTreeTableModel() {
getToolWindow();
return myTreeTableModel;
}
private static class MyColoredTreeCellRenderer extends ColoredTreeCellRenderer {
public void customizeCellRenderer(JTree tree,
Object value,
boolean selected,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
value = ((DefaultMutableTreeNode)value).getUserObject();
setPaintFocusBorder(false);
if (!(value instanceof DNamedElement)) return;
if (value instanceof DClassElement) {
final String containingClassName = ((DClassElement)value).getName();
// append(className, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
final String classShortName = QuickfixUtil.shortenType(containingClassName);
append(classShortName, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
}
if (value instanceof DItemElement) {
final DItemElement itemElement = ((DItemElement)value);
final String substringToHighlight = itemElement.getHighlightedText();
final String name = itemElement.getName();
if (substringToHighlight != null) {
appendHighlightName(substringToHighlight, name);
} else {
appendName(name);
}
if (value instanceof DMethodElement) {
appendMethodParameters((DMethodElement)value);
}
}
}
private void appendHighlightName(String substringToHighlight, String name) {
final int begin = name.indexOf(substringToHighlight);
// if (name.length() <= begin) return;
final String first = name.substring(0, begin);
append(first, SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES);
final TextAttributes textAttributes = new TextAttributes();
textAttributes.setBackgroundColor(UIUtil.getListSelectionBackground());
append(substringToHighlight, SimpleTextAttributes.fromTextAttributes(textAttributes));
append(name.substring(first.length() + substringToHighlight.length()), SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES);
}
private void appendName(String name) {
append(name, SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES);
}
private void appendMethodParameters(DMethodElement value) {
StringBuilder buffer = new StringBuilder();
buffer.append("(");
final String[] types = mapToUnqualified(QuickfixUtil.getArgumentsNames(value.getPairs()));
for (int i = 0; i < types.length; i++) {
if (i != 0) buffer.append(", ");
String type = types[i];
buffer.append(type);
}
buffer.append(")");
append(buffer.toString(), SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES);
}
private static String[] mapToUnqualified(final String[] argumentsNames) {
return ContainerUtil.map2Array(argumentsNames, String.class, new NullableFunction<String, String>() {
@Nullable
public String fun(final String s) {
if (s == null) return null;
int index = s.lastIndexOf(".");
if (index > 0 && index < s.length() - 1) return s.substring(index + 1);
return s;
}
});
}
}
private class MyPropertyTypeCellEditor extends AbstractTableCellEditor {
final EditorTextField field;
public MyPropertyTypeCellEditor() {
final Document document = PsiDocumentManager.getInstance(myProject).getDocument(new GroovyCodeFragment(myProject, ""));
field = new EditorTextField(document, myProject, GroovyFileType.GROOVY_FILE_TYPE);
}
public String getCellEditorValue() {
return field.getText();
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
if (value instanceof String) {
field.setText(((String)value));
}
return field;
}
}
private class MyTreeTable extends TreeTable implements DataProvider {
public MyTreeTable(TreeTableModel treeTableModel) {
super(treeTableModel);
}
@Nullable
public Object getData(@NonNls String dataId) {
if (CommonDataKeys.PSI_ELEMENT.is(dataId)) {
return getSelectedElement();
}
else if (CommonDataKeys.PSI_FILE.is(dataId)) {
final PsiElement element = getSelectedElement();
if (element == null) return null;
return element.getContainingFile();
}
else if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) {
return new DeleteProvider() {
@Override
public void deleteElement(@NotNull DataContext dataContext) {
deleteRow();
}
@Override
public boolean canDeleteElement(@NotNull DataContext dataContext) {
return myTreeTable.getTree().getSelectionPaths() != null;
}
};
}
return null;
}
private PsiElement getSelectedElement() {
final TreePath path = getTree().getSelectionPath();
if (path == null) return null;
final Object selectedObject = path.getLastPathComponent();
if (!(selectedObject instanceof DefaultMutableTreeNode)) return null;
final DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)selectedObject;
final Object userObject = selectedNode.getUserObject();
if (!(userObject instanceof DNamedElement)) return null;
if (userObject instanceof DClassElement) {
final DClassElement classElement = (DClassElement)userObject;
try {
PsiType type = JavaPsiFacade.getElementFactory(myProject).createTypeFromText(classElement.getName(), null);
if (type instanceof PsiPrimitiveType) {
type = ((PsiPrimitiveType)type).getBoxedType(PsiManager.getInstance(myProject), GlobalSearchScope.allScope(myProject));
}
if (!(type instanceof PsiClassType)) return null;
return ((PsiClassType)type).resolve();
}
catch (IncorrectOperationException e) {
return null;
}
} else if (userObject instanceof DItemElement) {
final DItemElement itemElement = (DItemElement)userObject;
final TreeNode parentNode = selectedNode.getParent();
if (!(parentNode instanceof DefaultMutableTreeNode)) return null;
final Object classObject = ((DefaultMutableTreeNode)parentNode).getUserObject();
if (!(classObject instanceof DClassElement)) return null;
final String className = ((DClassElement)classObject).getName();
return itemElement.getPsi(PsiManager.getInstance(myProject), className);
}
return null;
}
}
}