/* * Copyright 2000-2016 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.refactoring.extractSuperclass; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComponentWithBrowseButton; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.classMembers.MemberInfoBase; import com.intellij.refactoring.ui.DocCommentPanel; import com.intellij.refactoring.ui.RefactoringDialog; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.ui.RecentsManager; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * @author dsl */ public abstract class ExtractSuperBaseDialog<ClassType extends PsiElement, MemberInfoType extends MemberInfoBase> extends RefactoringDialog { private final String myRefactoringName; protected final ClassType mySourceClass; protected PsiDirectory myTargetDirectory; protected final List<MemberInfoType> myMemberInfos; private JRadioButton myRbExtractSuperclass; private JRadioButton myRbExtractSubclass; private JTextField mySourceClassField; private JLabel myClassNameLabel; private JTextField myExtractedSuperNameField; protected JLabel myPackageNameLabel; protected ComponentWithBrowseButton myPackageNameField; protected DocCommentPanel myDocCommentPanel; private JPanel myDestinationRootPanel; protected abstract ComponentWithBrowseButton createPackageNameField(); protected JPanel createDestinationRootPanel() { return null; } protected abstract JTextField createSourceClassField(); protected abstract String getDocCommentPanelName(); protected abstract String getExtractedSuperNameNotSpecifiedMessage(); protected abstract BaseRefactoringProcessor createProcessor(); protected abstract int getDocCommentPolicySetting(); protected abstract void setDocCommentPolicySetting(int policy); @Override protected abstract String getHelpId(); @Nullable protected abstract String validateName(String name); @Nullable protected String validateQualifiedName(String packageName, String extractedSuperName) { return null; } protected abstract String getTopLabelText(); protected abstract String getClassNameLabelText(); protected abstract String getPackageNameLabelText(); protected abstract String getEntityName(); protected abstract void preparePackage() throws OperationFailedException; protected abstract String getDestinationPackageRecentKey(); public ExtractSuperBaseDialog(Project project, ClassType sourceClass, List<MemberInfoType> members, String refactoringName) { super(project, true); myRefactoringName = refactoringName; mySourceClass = sourceClass; myMemberInfos = members; myTargetDirectory = mySourceClass.getContainingFile().getContainingDirectory(); } @Override protected void init() { setTitle(myRefactoringName); myPackageNameField = createPackageNameField(); myDestinationRootPanel = createDestinationRootPanel(); mySourceClassField = createSourceClassField(); myExtractedSuperNameField = createExtractedSuperNameField(); myDocCommentPanel = new DocCommentPanel(getDocCommentPanelName()); myDocCommentPanel.setPolicy(getDocCommentPolicySetting()); super.init(); updateDialog(); } protected JTextField createExtractedSuperNameField() { return new JTextField(); } protected JComponent createActionComponent() { Box box = Box.createHorizontalBox(); final String s = StringUtil.decapitalize(getEntityName()); myRbExtractSuperclass = new JRadioButton(); myRbExtractSuperclass.setText(RefactoringBundle.message("extractSuper.extract", s)); myRbExtractSubclass = new JRadioButton(); myRbExtractSubclass.setText(RefactoringBundle.message("extractSuper.rename.original.class", s)); myRbExtractSubclass.setEnabled(isPossibleToRenameOriginal()); box.add(myRbExtractSuperclass); box.add(myRbExtractSubclass); box.add(Box.createHorizontalGlue()); final ButtonGroup buttonGroup = new ButtonGroup(); buttonGroup.add(myRbExtractSuperclass); buttonGroup.add(myRbExtractSubclass); customizeRadiobuttons(box, buttonGroup); myRbExtractSuperclass.setSelected(true); ItemListener listener = new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { updateDialog(); } }; myRbExtractSuperclass.addItemListener(listener); myRbExtractSubclass.addItemListener(listener); return box; } protected boolean isPossibleToRenameOriginal() { return true; } protected void customizeRadiobuttons(Box box, ButtonGroup buttonGroup) { } @Override protected JComponent createNorthPanel() { Box box = Box.createVerticalBox(); JPanel _panel = new JPanel(new BorderLayout()); _panel.add(new JLabel(getTopLabelText()), BorderLayout.NORTH); _panel.add(mySourceClassField, BorderLayout.CENTER); box.add(_panel); box.add(Box.createVerticalStrut(10)); box.add(createActionComponent()); box.add(Box.createVerticalStrut(10)); myClassNameLabel = new JLabel(); _panel = new JPanel(new BorderLayout()); _panel.add(myClassNameLabel, BorderLayout.NORTH); _panel.add(myExtractedSuperNameField, BorderLayout.CENTER); box.add(_panel); box.add(Box.createVerticalStrut(5)); _panel = new JPanel(new BorderLayout()); myPackageNameLabel = new JLabel(); _panel.add(myPackageNameLabel, BorderLayout.NORTH); _panel.add(myPackageNameField, BorderLayout.CENTER); if (myDestinationRootPanel != null) { _panel.add(myDestinationRootPanel, BorderLayout.SOUTH); } box.add(_panel); box.add(Box.createVerticalStrut(10)); JPanel panel = new JPanel(new BorderLayout()); panel.add(box, BorderLayout.CENTER); return panel; } @Override public JComponent getPreferredFocusedComponent() { return myExtractedSuperNameField; } protected void updateDialog() { myClassNameLabel.setText(getClassNameLabelText()); myPackageNameLabel.setText(getPackageNameLabelText()); getPreviewAction().setEnabled(!isExtractSuperclass()); } public String getExtractedSuperName() { return myExtractedSuperNameField.getText().trim(); } protected abstract String getTargetPackageName(); public PsiDirectory getTargetDirectory() { return myTargetDirectory; } public int getDocCommentPolicy() { return myDocCommentPanel.getPolicy(); } public boolean isExtractSuperclass() { return myRbExtractSuperclass != null && myRbExtractSuperclass.isSelected(); } @Override protected void doAction() { final String[] errorString = new String[]{null}; final String extractedSuperName = getExtractedSuperName(); final String packageName = getTargetPackageName(); RecentsManager.getInstance(myProject).registerRecentEntry(getDestinationPackageRecentKey(), packageName); if (extractedSuperName != null && extractedSuperName.isEmpty()) { // TODO just disable OK button errorString[0] = getExtractedSuperNameNotSpecifiedMessage(); myExtractedSuperNameField.requestFocusInWindow(); } else { String nameError = validateName(extractedSuperName); if (nameError == null) { nameError = validateQualifiedName(packageName, extractedSuperName); } if (nameError != null) { errorString[0] = nameError; myExtractedSuperNameField.requestFocusInWindow(); } else { CommandProcessor.getInstance().executeCommand(myProject, () -> { try { preparePackage(); } catch (IncorrectOperationException | OperationFailedException e) { errorString[0] = e.getMessage(); myPackageNameField.requestFocusInWindow(); } }, RefactoringBundle.message("create.directory"), null); } } if (errorString[0] != null) { if (errorString[0].length() > 0) { CommonRefactoringUtil.showErrorMessage(myRefactoringName, errorString[0], getHelpId(), myProject); } return; } if (!checkConflicts()) return; executeRefactoring(); setDocCommentPolicySetting(getDocCommentPolicy()); closeOKAction(); } protected void executeRefactoring() { if (!isExtractSuperclass()) { invokeRefactoring(createProcessor()); } } @Override protected void doHelpAction() { HelpManager.getInstance().invokeHelp(getHelpId()); } protected boolean checkConflicts() { return true; } protected static class OperationFailedException extends Exception { public OperationFailedException(String message) { super(message); } } public Collection<MemberInfoType> getSelectedMemberInfos() { ArrayList<MemberInfoType> result = new ArrayList<>(myMemberInfos.size()); for (MemberInfoType info : myMemberInfos) { if (info.isChecked()) { result.add(info); } } return result; } }