mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
(no message)
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
package com.intellij.refactoring.changeSignature.inCallers;
|
||||
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Splitter;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ui.Tree;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.tree.*;
|
||||
import java.awt.*;
|
||||
import java.util.Enumeration;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
*/
|
||||
public class CallerChooser extends DialogWrapper {
|
||||
PsiMethod myMethod;
|
||||
private EditorTextField myEditorField;
|
||||
private Alarm myAlarm = new Alarm();
|
||||
private MethodNode myRoot;
|
||||
private Project myProject;
|
||||
|
||||
public CallerChooser(final PsiMethod method, String title) {
|
||||
super(true);
|
||||
myMethod = method;
|
||||
myProject = myMethod.getProject();
|
||||
setTitle(title);
|
||||
init();
|
||||
}
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
Splitter splitter = new Splitter(false, ((float)0.6));
|
||||
JPanel result = new JPanel(new BorderLayout());
|
||||
final Tree tree = createTree();
|
||||
JScrollPane scrollPane = new JScrollPane(tree);
|
||||
splitter.setFirstComponent(scrollPane);
|
||||
myEditorField = createCallSitesViewer();
|
||||
myEditorField.setText(getText(myMethod));
|
||||
myEditorField.setBorder(IdeBorderFactory.createBorder());
|
||||
splitter.setSecondComponent(myEditorField);
|
||||
result.add(splitter);
|
||||
|
||||
tree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
final TreePath path = e.getPath();
|
||||
if (path != null) {
|
||||
MethodNode node = (MethodNode)path.getLastPathComponent();
|
||||
final PsiMethod method = node.getMethod();
|
||||
myAlarm.cancelAllRequests();
|
||||
myAlarm.addRequest(new Runnable() {
|
||||
public void run() {
|
||||
myEditorField.setText(getText(method));
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getText(final PsiMethod method) {
|
||||
final PsiFile file = method.getContainingFile();
|
||||
Document document = PsiDocumentManager.getInstance(myProject).getDocument(file);
|
||||
final int start = document.getLineStartOffset(document.getLineNumber(method.getTextRange().getStartOffset()));
|
||||
final int end = document.getLineEndOffset(document.getLineNumber(method.getTextRange().getEndOffset()));
|
||||
return document.getText().substring(start, end);
|
||||
}
|
||||
|
||||
private EditorTextField createCallSitesViewer() {
|
||||
return new EditorTextField("", myProject, StdFileTypes.JAVA) {
|
||||
protected EditorEx createEditor() {
|
||||
final EditorEx editor = super.createEditor();
|
||||
editor.setOneLineMode(false);
|
||||
return editor;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Tree createTree() {
|
||||
final CheckedTreeNode root = new CheckedTreeNode(null);
|
||||
myRoot = new MethodNode(myMethod);
|
||||
root.add(myRoot);
|
||||
final CheckboxTree.CheckboxTreeCellRenderer cellRenderer = new CheckboxTree.CheckboxTreeCellRenderer() {
|
||||
public void customizeCellRenderer(JTree tree,
|
||||
Object value,
|
||||
boolean selected,
|
||||
boolean expanded,
|
||||
boolean leaf,
|
||||
int row,
|
||||
boolean hasFocus) {
|
||||
if (value instanceof MethodNode) {
|
||||
((MethodNode)value).customizeRenderer(getTextRenderer());
|
||||
}
|
||||
}
|
||||
};
|
||||
Tree tree = new CheckboxTree(cellRenderer, root) {
|
||||
protected void checkNode(CheckedTreeNode node, boolean checked) {
|
||||
super.checkNode(node, checked);
|
||||
updateChildren(node, !checked);
|
||||
}
|
||||
};
|
||||
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
tree.getSelectionModel().setSelectionPath(new TreePath(myRoot.getPath()));
|
||||
return tree;
|
||||
}
|
||||
|
||||
private void updateChildren(final CheckedTreeNode node, boolean toEnable) {
|
||||
final Enumeration children = node.children();
|
||||
while (children.hasMoreElements()) {
|
||||
MethodNode child = (MethodNode)children.nextElement();
|
||||
child.setEnabled(toEnable);
|
||||
updateChildren(child, toEnable);
|
||||
}
|
||||
}
|
||||
|
||||
public PsiMethod[] getSelectedMethods () {
|
||||
MethodNode node = myRoot;
|
||||
ArrayList<PsiMethod> result = new ArrayList<PsiMethod>();
|
||||
getSelectedMethodsInner(node, result);
|
||||
return result.toArray(new PsiMethod[result.size()]);
|
||||
}
|
||||
|
||||
private void getSelectedMethodsInner(final MethodNode node, final ArrayList<PsiMethod> methods) {
|
||||
if (node.isChecked()) {
|
||||
methods.add(node.getMethod());
|
||||
} else {
|
||||
final Enumeration children = node.children();
|
||||
while (children.hasMoreElements()) {
|
||||
getSelectedMethodsInner((MethodNode)children.nextElement(), methods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void doOKAction() {
|
||||
if (!verifyPaths(myRoot)) {
|
||||
Messages.showErrorDialog(myProject, "Not all paths to refactored method are selected", "Change Signature");
|
||||
return;
|
||||
}
|
||||
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
private boolean verifyPaths(final MethodNode node) {
|
||||
if (node.isChecked()) return true;
|
||||
final Enumeration children = node.children();
|
||||
if (!children.hasMoreElements()) return false;
|
||||
|
||||
while (children.hasMoreElements()) {
|
||||
if (!verifyPaths((MethodNode)children.nextElement())) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.intellij.refactoring.changeSignature.inCallers;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.presentation.java.ClassPresentationUtil;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiSearchHelper;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.ui.CheckedTreeNode;
|
||||
import com.intellij.ui.ColoredTreeCellRenderer;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.util.ui.IdeaUIManager;
|
||||
|
||||
import javax.swing.tree.TreeNode;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
*/
|
||||
public class MethodNode extends CheckedTreeNode {
|
||||
private PsiMethod myMethod;
|
||||
private boolean myOldChecked;
|
||||
|
||||
public MethodNode(final PsiMethod method) {
|
||||
super(method);
|
||||
myMethod = method;
|
||||
isChecked = false;
|
||||
}
|
||||
|
||||
public PsiMethod getMethod() {
|
||||
return myMethod;
|
||||
}
|
||||
|
||||
//IMPORTANT: do not build children in children()
|
||||
private void buildChildren () {
|
||||
if (children == null) {
|
||||
final PsiMethod[] callers = findCallers();
|
||||
if (callers.length > 0) {
|
||||
children = new Vector(callers.length);
|
||||
for (int i = 0; i < callers.length; i++) {
|
||||
PsiMethod caller = callers[i];
|
||||
children.add(new MethodNode(caller));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TreeNode getChildAt(int index) {
|
||||
buildChildren();
|
||||
return super.getChildAt(index);
|
||||
}
|
||||
|
||||
public int getChildCount() {
|
||||
buildChildren();
|
||||
return super.getChildCount();
|
||||
}
|
||||
|
||||
public int getIndex(TreeNode aChild) {
|
||||
buildChildren();
|
||||
return super.getIndex(aChild);
|
||||
}
|
||||
|
||||
private PsiMethod[] findCallers() {
|
||||
final Project project = myMethod.getProject();
|
||||
final PsiSearchHelper searchHelper = PsiManager.getInstance(project).getSearchHelper();
|
||||
final PsiReference[] refs = searchHelper.findReferencesIncludingOverriding(myMethod, GlobalSearchScope.allScope(project), true);
|
||||
List<PsiMethod> callers = new ArrayList<PsiMethod>();
|
||||
for (int i = 0; i < refs.length; i++) {
|
||||
final PsiElement element = refs[i].getElement();
|
||||
if (element instanceof PsiReferenceExpression && element.getParent() instanceof PsiMethodCallExpression) {
|
||||
final PsiElement enclosingContext = PsiTreeUtil.getParentOfType(element, new Class[]{PsiMethod.class, PsiClass.class});
|
||||
if (enclosingContext instanceof PsiMethod) callers.add((PsiMethod)enclosingContext);
|
||||
}
|
||||
}
|
||||
return callers.toArray(new PsiMethod[callers.size()]);
|
||||
}
|
||||
|
||||
public void customizeRenderer (ColoredTreeCellRenderer renderer) {
|
||||
int flags = Iconable.ICON_FLAG_VISIBILITY | Iconable.ICON_FLAG_READ_STATUS;
|
||||
renderer.setIcon(myMethod.getIcon(flags));
|
||||
|
||||
final StringBuffer buffer = new StringBuffer(128);
|
||||
final PsiClass containingClass = myMethod.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
buffer.append(ClassPresentationUtil.getNameForClass(containingClass, false));
|
||||
buffer.append('.');
|
||||
}
|
||||
final String methodText = PsiFormatUtil.formatMethod(
|
||||
myMethod,
|
||||
PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS,
|
||||
PsiFormatUtil.SHOW_TYPE
|
||||
);
|
||||
buffer.append(methodText);
|
||||
|
||||
final int style = isEnabled() ? SimpleTextAttributes.STYLE_PLAIN : SimpleTextAttributes.STYLE_STRIKEOUT;
|
||||
renderer.append(buffer.toString(), new SimpleTextAttributes(style, IdeaUIManager.getTreeForegroung()));
|
||||
|
||||
final String packageName = getPackageName(myMethod.getContainingClass());
|
||||
renderer.append(" (" + packageName + ")", new SimpleTextAttributes(SimpleTextAttributes.STYLE_ITALIC, Color.GRAY));
|
||||
}
|
||||
|
||||
private String getPackageName(final PsiClass aClass) {
|
||||
final PsiFile file = aClass.getContainingFile();
|
||||
if (file instanceof PsiJavaFile) {
|
||||
return ((PsiJavaFile)file).getPackageName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setEnabled(final boolean enabled) {
|
||||
super.setEnabled(enabled);
|
||||
if (!enabled) {
|
||||
myOldChecked = isChecked();
|
||||
setChecked(false);
|
||||
}
|
||||
else {
|
||||
setChecked(myOldChecked);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,9 +39,11 @@ public class CheckboxTree extends Tree {
|
||||
|
||||
if (checkBounds.contains(e.getPoint())) {
|
||||
CheckedTreeNode node = (CheckedTreeNode) getPathForRow(row).getLastPathComponent();
|
||||
toggleNode(node);
|
||||
e.consume();
|
||||
setSelectionRow(row);
|
||||
if (node.isEnabled()) {
|
||||
toggleNode(node);
|
||||
e.consume();
|
||||
setSelectionRow(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,6 +116,7 @@ public class CheckboxTree extends Tree {
|
||||
invalidate();
|
||||
if (value instanceof CheckedTreeNode) {
|
||||
CheckedTreeNode node = (CheckedTreeNode)value;
|
||||
myCheckbox.setEnabled(node.isEnabled());
|
||||
myCheckbox.setSelected(node.isChecked());
|
||||
|
||||
myCheckbox.setBackground(null);
|
||||
@@ -139,8 +142,8 @@ public class CheckboxTree extends Tree {
|
||||
boolean hasFocus
|
||||
);
|
||||
|
||||
public SimpleColoredComponent getTextRenderer () { return myTextRenderer; }
|
||||
public JCheckBox getCheckbox() { return myCheckbox; }
|
||||
public ColoredTreeCellRenderer getTextRenderer () { return myTextRenderer; }
|
||||
public JCheckBox getCheckbox() { return myCheckbox; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ import javax.swing.tree.DefaultMutableTreeNode;
|
||||
* Time: 5:14:07 PM
|
||||
*/
|
||||
public class CheckedTreeNode extends DefaultMutableTreeNode {
|
||||
private boolean isChecked = true;
|
||||
protected boolean isChecked = true;
|
||||
private boolean isEnabled = true;
|
||||
public CheckedTreeNode(Object userObject) {
|
||||
super(userObject);
|
||||
}
|
||||
@@ -21,4 +22,12 @@ public class CheckedTreeNode extends DefaultMutableTreeNode {
|
||||
public void setChecked(boolean checked) {
|
||||
isChecked = checked;
|
||||
}
|
||||
|
||||
public void setEnabled(final boolean enabled) {
|
||||
isEnabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return isEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user