/* * Copyright 2013 Guidewire Software, Inc. */ package gw.plugin.ij.intentions; import com.intellij.CommonBundle; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.daemon.impl.quickfix.CreateClassKind; import com.intellij.ide.util.PackageUtil; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiDirectory; import com.intellij.refactoring.ui.PackageNameReferenceEditorCombo; import com.intellij.refactoring.util.RefactoringMessageUtil; import com.intellij.ui.DocumentAdapter; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.RecentsManager; import com.intellij.ui.ReferenceEditorComboWithBrowseButton; import com.intellij.util.IncorrectOperationException; import gw.plugin.ij.actions.TypeSystemAwareAction; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.DocumentEvent; import java.awt.*; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; public class GosuCreateClassDialog extends DialogWrapper { private final JLabel myInformationLabel = new JLabel("#"); private final JLabel myPackageLabel = new JLabel(CodeInsightBundle.message("dialog.create.class.destination.package.label")); @NotNull private final ReferenceEditorComboWithBrowseButton myPackageComponent; private final JTextField myTfClassName = new MyTextField(); @NotNull private final Project myProject; @Nullable private PsiDirectory myTargetDirectory; private final String myClassName; private final boolean myClassNameEditable; private final Module myModule; @NonNls private static final String RECENTS_KEY = "CreateClassDialog.RecentsKey"; public GosuCreateClassDialog(@NotNull Project project, @NotNull String title, String targetClassName, @Nullable String targetPackageName, @NotNull GosuCreateClassKind kind, boolean classNameEditable, Module defaultModule) { super(project, true); myClassNameEditable = classNameEditable; myModule = defaultModule; myClassName = targetClassName; myProject = project; myPackageComponent = new PackageNameReferenceEditorCombo( targetPackageName != null ? targetPackageName : "", myProject, RECENTS_KEY, CodeInsightBundle.message("dialog.create.class.package.chooser.title")); myPackageComponent.setTextFieldPreferredWidth(40); init(); if (!myClassNameEditable) { setTitle(CodeInsightBundle.message("dialog.create.class.name", StringUtil.capitalize(kind.getDescription()), targetClassName)); } else { myInformationLabel.setText(CodeInsightBundle.message("dialog.create.class.label", kind.getDescription())); setTitle(title); } myTfClassName.setText(myClassName); } @NotNull protected Action[] createActions() { return new Action[]{getOKAction(), getCancelAction()}; } public JComponent getPreferredFocusedComponent() { return myClassNameEditable ? myTfClassName : myPackageComponent.getChildComponent(); } protected JComponent createCenterPanel() { return new JPanel(new BorderLayout()); } protected JComponent createNorthPanel() { JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints gbConstraints = new GridBagConstraints(); gbConstraints.insets = new Insets(4, 8, 4, 8); gbConstraints.fill = GridBagConstraints.HORIZONTAL; gbConstraints.anchor = GridBagConstraints.WEST; if (myClassNameEditable) { gbConstraints.weightx = 0; gbConstraints.gridwidth = 1; panel.add(myInformationLabel, gbConstraints); panel.setBorder(IdeBorderFactory.createRoundedBorder()); gbConstraints.insets = new Insets(4, 8, 4, 8); gbConstraints.gridx = 1; gbConstraints.weightx = 1; gbConstraints.gridwidth = 1; gbConstraints.fill = GridBagConstraints.HORIZONTAL; gbConstraints.anchor = GridBagConstraints.WEST; panel.add(myTfClassName, gbConstraints); myTfClassName.getDocument().addDocumentListener(new DocumentAdapter() { protected void textChanged(DocumentEvent e) { getOKAction().setEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(myTfClassName.getText())); } }); getOKAction().setEnabled(StringUtil.isNotEmpty(myClassName)); } gbConstraints.gridx = 0; gbConstraints.gridy = 2; gbConstraints.weightx = 0; gbConstraints.gridwidth = 1; panel.add(myPackageLabel, gbConstraints); gbConstraints.gridx = 1; gbConstraints.weightx = 1; new TypeSystemAwareAction() { public void actionPerformed(AnActionEvent e) { myPackageComponent.getButton().doClick(); } }.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_DOWN_MASK)), myPackageComponent.getChildComponent()); JPanel _panel = new JPanel(new BorderLayout()); _panel.add(myPackageComponent, BorderLayout.CENTER); panel.add(_panel, gbConstraints); return panel; } @Nullable public PsiDirectory getTargetDirectory() { return myTargetDirectory; } @NotNull private String getPackageName() { String name = myPackageComponent.getText(); return name != null ? name.trim() : ""; } private static class MyTextField extends JTextField { public Dimension getPreferredSize() { Dimension size = super.getPreferredSize(); FontMetrics fontMetrics = getFontMetrics(getFont()); size.width = fontMetrics.charWidth('a') * 40; return size; } } protected void doOKAction() { RecentsManager.getInstance(myProject).registerRecentEntry(RECENTS_KEY, myPackageComponent.getText()); final String packageName = getPackageName(); final String[] errorString = new String[1]; CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { public void run() { try { myTargetDirectory = myModule == null? PackageUtil.findOrCreateDirectoryForPackage(myProject, packageName, getBaseDir(packageName), true) : PackageUtil.findOrCreateDirectoryForPackage(myModule, packageName, getBaseDir(packageName), true, true); if (myTargetDirectory == null) { errorString[0] = ""; // message already reported by PackageUtil return; } errorString[0] = RefactoringMessageUtil.checkCanCreateClass(myTargetDirectory, getClassName()); } catch (IncorrectOperationException e) { errorString[0] = e.getMessage(); } } }, CodeInsightBundle.message("create.directory.command"), null); if (errorString[0] != null) { if (errorString[0].length() > 0) { Messages.showMessageDialog(myProject, errorString[0], CommonBundle.getErrorTitle(), Messages.getErrorIcon()); } return; } super.doOKAction(); } @Nullable protected PsiDirectory getBaseDir(String packageName) { return myModule == null? null : PackageUtil.findPossiblePackageDirectoryInModule(myModule, packageName); } public String getClassName() { if (myClassNameEditable) { return myTfClassName.getText(); } else { return myClassName; } } }