package com.intellij.lang.javascript.linter.tslint.ui; import com.intellij.javascript.nodejs.util.NodePackage; import com.intellij.lang.javascript.linter.JSLinterBaseView; import com.intellij.lang.javascript.linter.NodeModuleConfigurationView; import com.intellij.lang.javascript.linter.tslint.config.TsLintConfiguration; import com.intellij.lang.javascript.linter.tslint.config.TsLintState; import com.intellij.lang.javascript.linter.tslint.ide.TsLintConfigFileType; import com.intellij.lang.javascript.linter.ui.JSLinterConfigFileTexts; import com.intellij.lang.javascript.linter.ui.JSLinterConfigFileView; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.components.JBCheckBox; import com.intellij.util.ui.FormBuilder; import com.intellij.util.ui.SwingHelper; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.File; import java.util.Collections; /** * @author Irina.Chernushina on 6/3/2015. */ public final class TsLintView extends JSLinterBaseView<TsLintState> { private static final JSLinterConfigFileTexts CONFIG_TEXTS = getConfigTexts(); private final Project myProject; private final boolean myDialog; private final NodeModuleConfigurationView myNodeModuleConfigurationView; private final JSLinterConfigFileView myConfigFileView; private TextFieldWithBrowseButton myRules; private JBCheckBox myAllowJs; public TsLintView(@NotNull Project project, boolean fullModeDialog) { super(fullModeDialog); myProject = project; myDialog = fullModeDialog; myConfigFileView = new JSLinterConfigFileView(project, CONFIG_TEXTS, TsLintConfigFileType.INSTANCE); myConfigFileView.setAdditionalConfigFilesProducer(() -> { final String home = System.getProperty("user.home"); final LocalFileSystem lfs = LocalFileSystem.getInstance(); final File homeFile = new File(home); VirtualFile homeVf = lfs.findFileByIoFile(homeFile); if (homeVf == null) { homeVf = lfs.refreshAndFindFileByIoFile(homeFile); } if (homeVf == null) return Collections.emptyList(); VirtualFile config = homeVf.findChild(TsLintConfiguration.TSLINT_JSON); if (config == null) { config = lfs.refreshAndFindFileByIoFile(new File(homeFile, TsLintConfiguration.TSLINT_JSON)); } if (config == null) return Collections.emptyList(); return Collections.singletonList(config); }); myNodeModuleConfigurationView = new NodeModuleConfigurationView(project, "tslint", "TSLint", null); } @Nullable @Override protected Component createTopRightComponent() { return null; } @NotNull @Override protected Component createCenterComponent() { myRules = new TextFieldWithBrowseButton(); myAllowJs = new JBCheckBox(); SwingHelper.installFileCompletionAndBrowseDialog(myProject, myRules, "Select additional rules directory", FileChooserDescriptorFactory.createSingleFolderDescriptor()); final FormBuilder nodeFieldsWrapperBuilder = FormBuilder.createFormBuilder() .setAlignLabelOnRight(true) .setHorizontalGap(UIUtil.DEFAULT_HGAP) .setVerticalGap(UIUtil.DEFAULT_VGAP) .setFormLeftIndent(UIUtil.DEFAULT_HGAP) .addLabeledComponent("&Node interpreter:", myNodeModuleConfigurationView.getNodeInterpreterField()) .addLabeledComponent("TSLint package:", myNodeModuleConfigurationView.getPackageField()); JPanel panel = FormBuilder.createFormBuilder() .setAlignLabelOnRight(true) .setHorizontalGap(UIUtil.DEFAULT_HGAP) .setVerticalGap(UIUtil.DEFAULT_VGAP) .setFormLeftIndent(UIUtil.DEFAULT_HGAP) .addComponent(nodeFieldsWrapperBuilder.getPanel()) .addComponent(myConfigFileView.getComponent()) .addSeparator(4) .addVerticalGap(4) .addLabeledComponent("Additional rules directory:", myRules) .addLabeledComponent("Lint JavaScript files:", myAllowJs) .getPanel(); final JPanel centerPanel = SwingHelper.wrapWithHorizontalStretch(panel); centerPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); return centerPanel; } @Override protected void handleEnableStatusChanged(boolean enabled) { enableCustomConfigPath(enabled); } @NotNull @Override protected TsLintState getState() { final TsLintState.Builder builder = new TsLintState.Builder() .setNodePath(myNodeModuleConfigurationView.getNodeInterpreterField().getInterpreterRef()) .setPackagePath(myNodeModuleConfigurationView.getPackageField().getSelected().getSystemDependentPath()) .setCustomConfigFileUsed(myConfigFileView.isCustomConfigFileUsed()) .setCustomConfigFilePath(myConfigFileView.getCustomConfigFilePath()) .setAllowJs(myAllowJs.isSelected()); if (!StringUtil.isEmptyOrSpaces(myRules.getText())) { builder.setRulesDirectory(myRules.getText().trim()); } return builder.build(); } @Override protected void setState(@NotNull TsLintState state) { myNodeModuleConfigurationView.getNodeInterpreterField().setInterpreterRef(state.getInterpreterRef()); myNodeModuleConfigurationView.getPackageField().setSelected(new NodePackage(state.getPackagePath())); myConfigFileView.setCustomConfigFileUsed(state.isCustomConfigFileUsed()); myConfigFileView.setCustomConfigFilePath(StringUtil.notNullize(state.getCustomConfigFilePath())); if (! StringUtil.isEmptyOrSpaces(state.getRulesDirectory())) { myRules.setText(state.getRulesDirectory()); } myAllowJs.setSelected(state.isAllowJs()); resizeOnSeparateDialog(); } private void resizeOnSeparateDialog() { if (isFullModeDialog()) { myNodeModuleConfigurationView.setPreferredWidthToComponents(); myConfigFileView.setPreferredWidthToComponents(); } } private void enableCustomConfigPath(boolean enabled) { myConfigFileView.onEnabledStateChanged(enabled); } private static JSLinterConfigFileTexts getConfigTexts() { return new JSLinterConfigFileTexts("Search for tslint.json", "When linting a TypeScript file, TSLint looks for tslint.json starting from the file's folder and then moving up to the filesystem root" + " or in the user's home directory.", "Select TSLint configuration file (*.json)"); } }