/* * Copyright 2013 Guidewire Software, Inc. */ package gw.plugin.ij.refactor.intoduceField; import com.intellij.codeInsight.TestFrameworks; import com.intellij.ide.ui.ListCellRendererWrapper; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiLocalVariable; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiParameter; import com.intellij.psi.PsiReference; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.introduce.inplace.KeyboardComboSwitcher; import com.intellij.refactoring.ui.TypeSelectorManager; import gw.plugin.ij.refactor.GosuRefactoringUtil; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemListener; public class GosuIntroduceFieldPopupPanel extends GosuIntroduceFieldCentralPanel { private @Nullable JComboBox myInitializerCombo; private JComboBox myVisibilityCombo; private DefaultComboBoxModel myInitialisersPlaceModel; public GosuIntroduceFieldPopupPanel(PsiClass parentClass, PsiExpression initializerExpression, PsiLocalVariable localVariable, boolean isCurrentMethodConstructor, boolean isInvokedOnDeclaration, boolean willBeDeclaredStatic, PsiExpression[] occurrences, boolean allowInitInMethod, boolean allowInitInMethodIfAll, TypeSelectorManager typeSelectorManager) { super(parentClass, initializerExpression, localVariable, isCurrentMethodConstructor, isInvokedOnDeclaration, willBeDeclaredStatic, occurrences, allowInitInMethod, allowInitInMethodIfAll, typeSelectorManager); } protected void initializeInitializerPlace(PsiExpression initializerExpression, GosuBaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace) { if (initializerExpression != null) { setEnabledInitializationPlaces(initializerExpression, initializerExpression); if (!myAllowInitInMethod) { myInitialisersPlaceModel.removeElement(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD); } } else { myInitialisersPlaceModel.removeAllElements(); } final PsiMethod setUpMethod = TestFrameworks.getInstance().findSetUpMethod(myParentClass); final boolean setupEnabled = myInitialisersPlaceModel.getIndexOf(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD) > -1; if (ourLastInitializerPlace == GosuBaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD && setupEnabled && (myInitializerExpression != null && PsiTreeUtil.isAncestor(setUpMethod, myInitializerExpression, false) || TestFrameworks.getInstance().isTestClass(myParentClass))) { myInitialisersPlaceModel.setSelectedItem(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD); } else if (ourLastInitializerPlace == GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR && myInitialisersPlaceModel.getIndexOf(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR) > -1 && myParentClass.getConstructors().length > 0) { myInitialisersPlaceModel.setSelectedItem(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR); } else if (ourLastInitializerPlace == GosuBaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION && myInitialisersPlaceModel.getIndexOf(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION) > -1) { myInitialisersPlaceModel.setSelectedItem(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION); } else { selectInCurrentMethod(); } } @Override protected void initializeControls(PsiExpression initializerExpression, GosuBaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace) { } @Override public boolean isDeclareFinal() { return allowFinal(); } private void selectInCurrentMethod() { if (myInitialisersPlaceModel.getIndexOf(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD) > -1) { myInitialisersPlaceModel.setSelectedItem(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD); } else if (myInitialisersPlaceModel.getIndexOf(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION) > -1) { myInitialisersPlaceModel.setSelectedItem(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION); } else { myInitialisersPlaceModel.setSelectedItem(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD); } } public GosuBaseExpressionToFieldHandler.InitializationPlace getInitializerPlace() { if (myInitializerCombo != null) { return (GosuBaseExpressionToFieldHandler.InitializationPlace) myInitializerCombo.getSelectedItem(); } return (GosuBaseExpressionToFieldHandler.InitializationPlace) myInitialisersPlaceModel.getElementAt(0); } public String getFieldVisibility() { String visibility = JavaRefactoringSettings.getInstance().INTRODUCE_FIELD_VISIBILITY; if (visibility == null) { visibility = PsiModifier.PRIVATE; } return visibility; } protected JComponent createInitializerPlacePanel(final ItemListener itemListener, final ItemListener finalUpdater) { JPanel groupPanel = new JPanel(new GridBagLayout()); final GridBagConstraints gridBagConstraints = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0); myInitialisersPlaceModel = new DefaultComboBoxModel(); myInitialisersPlaceModel.addElement(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD); myInitialisersPlaceModel.addElement(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION); myInitialisersPlaceModel.addElement(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR); if (TestFrameworks.getInstance().isTestClass(myParentClass)) { myInitialisersPlaceModel.addElement(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD); } initializeInitializerPlace(myInitializerExpression, GosuInplaceIntroduceFieldPopup.ourLastInitializerPlace); if (myInitialisersPlaceModel.getSize() > 1) { final JLabel initLabel = new JLabel(RefactoringBundle.message("initialize.in.border.title") + ":"); initLabel.setDisplayedMnemonic('i'); gridBagConstraints.insets.left = 5; gridBagConstraints.anchor = GridBagConstraints.WEST; groupPanel.add(initLabel, gridBagConstraints); JComboBox initializersCombo = new JComboBox(myInitialisersPlaceModel); KeyboardComboSwitcher.setupActions(initializersCombo, myParentClass.getProject()); initLabel.setLabelFor(initializersCombo); initializersCombo.setRenderer(new ListCellRendererWrapper<GosuBaseExpressionToFieldHandler.InitializationPlace>(initializersCombo) { @Override public void customize(JList list, GosuBaseExpressionToFieldHandler.InitializationPlace value, int index, boolean selected, boolean hasFocus) { setText(getPresentableText(value)); } }); initializersCombo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { itemListener.itemStateChanged(null); finalUpdater.itemStateChanged(null); } }); gridBagConstraints.gridx = 1; gridBagConstraints.insets.top = 0; gridBagConstraints.insets.left = 0; groupPanel.add(initializersCombo, gridBagConstraints); myInitializerCombo = initializersCombo; } return groupPanel; } @Nullable private static String getPresentableText(GosuBaseExpressionToFieldHandler.InitializationPlace value) { if (value == GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD) { return "current method"; } else if (value == GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR) { return "constructor"; } else if (value == GosuBaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION) { return "field declaration"; } else if (value == GosuBaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD) { return "setUp"; } return null; } protected boolean setEnabledInitializationPlaces(PsiElement initializerPart, PsiElement initializer) { if (GosuRefactoringUtil.isPsiReferenceExpression(initializerPart)) { PsiReference refExpr = (PsiReference) initializerPart; // if (refExpr.getQualifierExpression() == null) { PsiElement refElement = refExpr.resolve(); if (refElement == null || (refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter) && !PsiTreeUtil.isAncestor(initializer, refElement, true)) { myInitialisersPlaceModel.removeElement(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION); myInitialisersPlaceModel.removeElement(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR); myInitialisersPlaceModel.removeElement(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD); return false; // } } } PsiElement[] children = initializerPart.getChildren(); for (PsiElement child : children) { if (!setEnabledInitializationPlaces(child, initializer)) { return false; } } return true; } public void setInitializeInFieldDeclaration() { LOG.assertTrue(myInitializerCombo != null); myInitializerCombo.setSelectedItem(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION); } public void setVisibility(String visibility) { myVisibilityCombo.setSelectedItem(visibility); } @Override protected void updateCbFinal() { } @Override protected boolean allowFinal() { final Object selectedItem = getInitializerPlace(); boolean allowFinal = selectedItem == GosuBaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION || (selectedItem == GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR && !myWillBeDeclaredStatic); if (selectedItem == GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD && myIsCurrentMethodConstructor) { final PsiMethod[] constructors = myParentClass.getConstructors(); allowFinal = constructors.length <= 1; } return super.allowFinal() && allowFinal; } @Override protected void updateInitializerSelection() { if (myAllowInitInMethodIfAll || !isReplaceAllOccurrences()) { if (myInitialisersPlaceModel.getIndexOf(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD) == -1) { myInitialisersPlaceModel.insertElementAt(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD, 0); } } else { myInitialisersPlaceModel.removeElement(GosuBaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD); } } @Override protected boolean shouldUpdateTypeSelector() { return false; } @Override protected JPanel appendCheckboxes(ItemListener itemListener) { final JPanel panel = new JPanel(new GridBagLayout()); appendOccurrences(itemListener, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0), panel); return panel; } protected JPanel composeWholePanel(JComponent initializerPlacePanel, JPanel checkboxPanel) { final JPanel panel = new JPanel(new GridBagLayout()); final GridBagConstraints constraints = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); panel.add(initializerPlacePanel, constraints); constraints.gridy++; panel.add(checkboxPanel, constraints); return panel; } }