update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / inheritanceToDelegation / InheritanceToDelegationDialog.java
blob09a791c07986b408b41749c6c72f7460f0079fb2
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.refactoring.inheritanceToDelegation;
18 import com.intellij.openapi.help.HelpManager;
19 import com.intellij.openapi.options.ConfigurationException;
20 import com.intellij.openapi.project.Project;
21 import com.intellij.openapi.util.text.StringUtil;
22 import com.intellij.psi.*;
23 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
24 import com.intellij.psi.codeStyle.SuggestedNameInfo;
25 import com.intellij.psi.codeStyle.VariableKind;
26 import com.intellij.refactoring.HelpID;
27 import com.intellij.refactoring.JavaRefactoringSettings;
28 import com.intellij.refactoring.RefactoringBundle;
29 import com.intellij.refactoring.classMembers.MemberInfoChange;
30 import com.intellij.refactoring.classMembers.MemberInfoModel;
31 import com.intellij.refactoring.ui.ClassCellRenderer;
32 import com.intellij.refactoring.ui.MemberSelectionPanel;
33 import com.intellij.refactoring.ui.NameSuggestionsField;
34 import com.intellij.refactoring.ui.RefactoringDialog;
35 import com.intellij.refactoring.util.classMembers.InterfaceMemberDependencyGraph;
36 import com.intellij.refactoring.util.classMembers.MemberInfo;
37 import com.intellij.util.containers.HashMap;
38 import org.jetbrains.annotations.NonNls;
39 import org.jetbrains.annotations.NotNull;
41 import javax.swing.*;
42 import java.awt.*;
43 import java.awt.event.ItemEvent;
44 import java.awt.event.ItemListener;
45 import java.util.ArrayList;
46 import java.util.Collection;
47 import java.util.Collections;
49 public class InheritanceToDelegationDialog extends RefactoringDialog {
50 private final PsiClass[] mySuperClasses;
52 private final PsiClass myClass;
53 private final HashMap<PsiClass, Collection<MemberInfo>> myBasesToMemberInfos;
55 private NameSuggestionsField myFieldNameField;
56 private NameSuggestionsField myInnerClassNameField;
57 private JCheckBox myCbGenerateGetter;
58 private MemberSelectionPanel myMemberSelectionPanel;
59 private JComboBox myClassCombo;
60 private final Project myProject;
61 private MyClassComboItemListener myClassComboItemListener;
62 private NameSuggestionsField.DataChanged myDataChangedListener;
64 public InheritanceToDelegationDialog(Project project,
65 PsiClass aClass,
66 PsiClass[] superClasses,
67 HashMap<PsiClass,Collection<MemberInfo>> basesToMemberInfos) {
68 super(project, true);
69 myProject = project;
70 myClass = aClass;
71 mySuperClasses = superClasses;
72 myBasesToMemberInfos = basesToMemberInfos;
74 setTitle(InheritanceToDelegationHandler.REFACTORING_NAME);
75 init();
78 @Override
79 public JComponent getPreferredFocusedComponent() {
80 return myFieldNameField;
83 protected void dispose() {
84 myInnerClassNameField.removeDataChangedListener(myDataChangedListener);
85 myFieldNameField.removeDataChangedListener(myDataChangedListener);
86 myClassCombo.removeItemListener(myClassComboItemListener);
87 super.dispose();
90 @NotNull
91 public String getFieldName() {
92 return myFieldNameField.getEnteredName();
95 public String getInnerClassName() {
96 if (myInnerClassNameField != null) {
97 return myInnerClassNameField.getEnteredName();
99 else {
100 return null;
104 public boolean isGenerateGetter() {
105 return myCbGenerateGetter.isSelected();
108 @Override
109 protected void canRun() throws ConfigurationException {
110 final String fieldName = getFieldName();
111 final PsiNameHelper helper = JavaPsiFacade.getInstance(myProject).getNameHelper();
112 if (!helper.isIdentifier(fieldName)){
113 throw new ConfigurationException("\'" + StringUtil.first(fieldName, 10, true) + "\' is invalid field name for delegation");
115 if (myInnerClassNameField != null) {
116 final String className = myInnerClassNameField.getEnteredName();
117 if (!helper.isIdentifier(className)) {
118 throw new ConfigurationException("\'" + StringUtil.first(className, 10, true) + "\' is invalid inner class name");
123 public Collection<MemberInfo> getSelectedMemberInfos() {
124 return myMemberSelectionPanel.getTable().getSelectedMemberInfos();
127 public PsiClass getSelectedTargetClass() {
128 return (PsiClass)myClassCombo.getSelectedItem();
132 protected void doHelpAction() {
133 HelpManager.getInstance().invokeHelp(HelpID.INHERITANCE_TO_DELEGATION);
136 protected void doAction() {
137 JavaRefactoringSettings.getInstance().INHERITANCE_TO_DELEGATION_DELEGATE_OTHER = myCbGenerateGetter.isSelected();
139 final Collection<MemberInfo> selectedMemberInfos = getSelectedMemberInfos();
140 final ArrayList<PsiClass> implementedInterfaces = new ArrayList<PsiClass>();
141 final ArrayList<PsiMethod> delegatedMethods = new ArrayList<PsiMethod>();
143 for (MemberInfo memberInfo : selectedMemberInfos) {
144 final PsiElement member = memberInfo.getMember();
145 if (member instanceof PsiClass && Boolean.FALSE.equals(memberInfo.getOverrides())) {
146 implementedInterfaces.add((PsiClass)member);
148 else if (member instanceof PsiMethod) {
149 delegatedMethods.add((PsiMethod)member);
152 invokeRefactoring(new InheritanceToDelegationProcessor(myProject, myClass,
153 getSelectedTargetClass(), getFieldName(),
154 getInnerClassName(),
155 implementedInterfaces.toArray(new PsiClass[implementedInterfaces.size()]),
156 delegatedMethods.toArray(new PsiMethod[delegatedMethods.size()]),
157 isGenerateGetter(), isGenerateGetter()));
160 protected JComponent createNorthPanel() {
161 JPanel panel = new JPanel(new GridBagLayout());
162 GridBagConstraints gbc = new GridBagConstraints();
164 gbc.fill = GridBagConstraints.BOTH;
165 gbc.anchor = GridBagConstraints.WEST;
166 gbc.gridy = 0;
167 gbc.gridx = 0;
170 gbc.insets = new Insets(4, 8, 0, 8);
171 myClassCombo = new JComboBox(mySuperClasses);
172 myClassCombo.setRenderer(new ClassCellRenderer());
173 gbc.gridwidth = 2;
174 final JLabel classComboLabel = new JLabel();
175 panel.add(classComboLabel, gbc);
176 gbc.gridy++;
177 panel.add(myClassCombo, gbc);
178 classComboLabel.setText(RefactoringBundle.message("replace.inheritance.from"));
180 myClassComboItemListener = new MyClassComboItemListener();
181 myClassCombo.addItemListener(myClassComboItemListener);
183 gbc.gridy++;
184 gbc.gridwidth = 1;
185 gbc.insets = new Insets(4, 8, 4, 0);
186 final JLabel fieldNameLabel = new JLabel();
187 panel.add(fieldNameLabel, gbc);
189 myFieldNameField = new NameSuggestionsField(myProject);
190 gbc.gridx++;
191 gbc.gridwidth = GridBagConstraints.REMAINDER;
192 gbc.insets = new Insets(4, 4, 4, 8);
193 gbc.weightx = 1.0;
194 panel.add(myFieldNameField.getComponent(), gbc);
195 fieldNameLabel.setText(RefactoringBundle.message("field.name"));
197 // if(InheritanceToDelegationUtil.isInnerClassNeeded(myClass, mySuperClass)) {
198 gbc.gridx = 0;
199 gbc.gridy++;
200 gbc.gridwidth = 1;
201 gbc.insets = new Insets(4, 8, 4, 0);
202 gbc.weightx = 0.0;
203 final JLabel innerClassNameLabel = new JLabel();
204 panel.add(innerClassNameLabel, gbc);
206 /*String[] suggestions = new String[mySuperClasses.length];
207 for (int i = 0; i < suggestions.length; i++) {
208 suggestions[i] = "My" + mySuperClasses[i].getName();
210 myInnerClassNameField = new NameSuggestionsField(myProject);
211 gbc.gridx++;
212 gbc.gridwidth = GridBagConstraints.REMAINDER;
213 gbc.insets = new Insets(4, 4, 4, 8);
214 gbc.weightx = 1.0;
215 panel.add(myInnerClassNameField.getComponent(), gbc);
216 innerClassNameLabel.setText(RefactoringBundle.message("inner.class.name"));
218 return panel;
222 protected JComponent createCenterPanel() {
223 JPanel panel = new JPanel(new GridBagLayout());
224 GridBagConstraints gbc = new GridBagConstraints();
226 gbc.fill = GridBagConstraints.BOTH;
227 gbc.anchor = GridBagConstraints.WEST;
228 gbc.gridy = 0;
229 gbc.gridx = 0;
230 gbc.weightx = 1.0;
232 gbc.weighty = 1.0;
233 gbc.gridwidth = 1;
234 gbc.insets = new Insets(4, 8, 4, 4);
236 myMemberSelectionPanel = new MemberSelectionPanel(RefactoringBundle.message("delegate.members"), Collections.<MemberInfo>emptyList(), null);
237 panel.add(myMemberSelectionPanel, gbc);
238 MyMemberInfoModel memberInfoModel = new InheritanceToDelegationDialog.MyMemberInfoModel();
239 myMemberSelectionPanel.getTable().setMemberInfoModel(memberInfoModel);
240 myMemberSelectionPanel.getTable().addMemberInfoChangeListener(memberInfoModel);
243 gbc.gridy++;
244 gbc.insets = new Insets(4, 8, 0, 8);
245 gbc.weighty = 0.0;
246 myCbGenerateGetter = new JCheckBox(RefactoringBundle.message("generate.getter.for.delegated.component"));
247 myCbGenerateGetter.setFocusable(false);
248 panel.add(myCbGenerateGetter, gbc);
249 myCbGenerateGetter.setSelected(JavaRefactoringSettings.getInstance().INHERITANCE_TO_DELEGATION_DELEGATE_OTHER);
250 updateTargetClass();
252 return panel;
255 private void updateTargetClass() {
256 final PsiClass targetClass = getSelectedTargetClass();
257 PsiManager psiManager = myClass.getManager();
258 PsiType superType = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory().createType(targetClass);
259 SuggestedNameInfo suggestedNameInfo =
260 JavaCodeStyleManager.getInstance(psiManager.getProject()).suggestVariableName(VariableKind.FIELD, null, null, superType);
261 myFieldNameField.setSuggestions(suggestedNameInfo.names);
262 myInnerClassNameField.getComponent().setEnabled(InheritanceToDelegationUtil.isInnerClassNeeded(myClass, targetClass));
263 @NonNls final String suggestion = "My" + targetClass.getName();
264 myInnerClassNameField.setSuggestions(new String[]{suggestion});
266 myDataChangedListener = new NameSuggestionsField.DataChanged() {
267 public void dataChanged() {
268 validateButtons();
271 myInnerClassNameField.addDataChangedListener(myDataChangedListener);
272 myFieldNameField.addDataChangedListener(myDataChangedListener);
274 myMemberSelectionPanel.getTable().setMemberInfos(myBasesToMemberInfos.get(targetClass));
275 myMemberSelectionPanel.getTable().fireExternalDataChange();
278 private class MyMemberInfoModel implements MemberInfoModel<PsiMember, MemberInfo> {
279 final HashMap<PsiClass,InterfaceMemberDependencyGraph> myGraphs;
281 public MyMemberInfoModel() {
282 myGraphs = new HashMap<PsiClass, InterfaceMemberDependencyGraph>();
283 for (PsiClass superClass : mySuperClasses) {
284 myGraphs.put(superClass, new InterfaceMemberDependencyGraph(superClass));
288 public boolean isMemberEnabled(MemberInfo memberInfo) {
289 if (getGraph().getDependent().contains(memberInfo.getMember())) {
290 return false;
292 else {
293 return true;
297 public boolean isCheckedWhenDisabled(MemberInfo member) {
298 return true;
301 public boolean isAbstractEnabled(MemberInfo member) {
302 return false;
305 public boolean isAbstractWhenDisabled(MemberInfo member) {
306 return false;
309 public Boolean isFixedAbstract(MemberInfo member) {
310 return null;
313 public int checkForProblems(@NotNull MemberInfo member) {
314 return OK;
317 public String getTooltipText(MemberInfo member) {
318 return null;
321 public void memberInfoChanged(MemberInfoChange<PsiMember, MemberInfo> event) {
322 final Collection<MemberInfo> changedMembers = event.getChangedMembers();
324 for (MemberInfo changedMember : changedMembers) {
325 getGraph().memberChanged(changedMember);
329 private InterfaceMemberDependencyGraph getGraph() {
330 return myGraphs.get(getSelectedTargetClass());
334 private class MyClassComboItemListener implements ItemListener {
335 public void itemStateChanged(ItemEvent e) {
336 if (e.getStateChange() == ItemEvent.SELECTED) {
337 updateTargetClass();