com.intellij.tools.ToolEditorDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.intellij.tools.ToolEditorDialog.java

Source

/*
 * Copyright 2000-2012 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.tools;

import com.intellij.execution.ExecutionBundle;
import com.intellij.ide.DataManager;
import com.intellij.ide.macro.MacroManager;
import com.intellij.ide.macro.MacrosDialog;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.FileChooserFactory;
import com.intellij.openapi.fileChooser.PathChooserDialog;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.FixedSizeButton;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.util.Consumer;
import net.miginfocom.swing.MigLayout;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.text.BadLocationException;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.List;

public class ToolEditorDialog extends DialogWrapper {
    private final JTextField myNameField = new JTextField();
    private final JTextField myDescriptionField = new JTextField();
    private final ComboBox myGroupCombo = new ComboBox(-1);
    private final JCheckBox myShowInMainMenuCheckbox = new JCheckBox(
            ToolsBundle.message("tools.menu.main.checkbox"));
    private final JCheckBox myShowInEditorCheckbox = new JCheckBox(
            ToolsBundle.message("tools.menu.editor.checkbox"));
    private final JCheckBox myShowInProjectTreeCheckbox = new JCheckBox(
            ToolsBundle.message("tools.menu.project.checkbox"));
    private final JCheckBox myShowInSearchResultsPopupCheckbox = new JCheckBox(
            ToolsBundle.message("tools.menu.search.checkbox"));
    private final JCheckBox myUseConsoleCheckbox = new JCheckBox(
            ToolsBundle.message("tools.open.console.checkbox"));
    private final JCheckBox myShowConsoleOnStdOutCheckbox = new JCheckBox(
            ExecutionBundle.message("logs.show.console.on.stdout"));
    private final JCheckBox myShowConsoleOnStdErrCheckbox = new JCheckBox(
            ExecutionBundle.message("logs.show.console.on.stderr"));
    private final JCheckBox mySynchronizedAfterRunCheckbox = new JCheckBox(
            ToolsBundle.message("tools.synchronize.files.checkbox"));
    private boolean myEnabled;

    // command fields
    private final JTextField myTfCommandWorkingDirectory = new JTextField();
    private final JTextField myTfCommand = new JTextField();
    private final JTextField myParametersField = new JTextField();
    private JButton myInsertWorkingDirectoryMacroButton;
    private JButton myInsertCommandMacroButton;
    private JButton myInsertParametersMacroButton;

    private final JButton myOutputFiltersButton;
    // panels
    private final JPanel mySimpleProgramPanel = createCommandPane();
    private FilterInfo[] myOutputFilters;
    private final Project myProject;

    @Override
    @NotNull
    protected JPanel createCenterPanel() {
        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints constr;

        // name and group
        constr = new GridBagConstraints();
        constr.gridx = 0;
        constr.gridy = 0;
        constr.anchor = GridBagConstraints.WEST;
        constr.insets = new Insets(5, 0, 0, 0);
        panel.add(new JLabel(ToolsBundle.message("tools.name.label")), constr);

        constr = new GridBagConstraints();
        constr.gridx = 1;
        constr.gridy = 0;
        constr.weightx = 1;
        constr.insets = new Insets(5, 10, 0, 10);
        constr.fill = GridBagConstraints.HORIZONTAL;
        constr.anchor = GridBagConstraints.WEST;
        panel.add(myNameField, constr);

        constr = new GridBagConstraints();
        constr.gridx = 2;
        constr.gridy = 0;
        constr.anchor = GridBagConstraints.WEST;
        constr.insets = new Insets(5, 10, 0, 0);
        panel.add(new JLabel(ToolsBundle.message("tools.group.label")), constr);

        constr = new GridBagConstraints();
        constr.gridx = 3;
        constr.gridy = 0;
        constr.weightx = 0.7;
        constr.insets = new Insets(5, 10, 0, 0);
        constr.fill = GridBagConstraints.HORIZONTAL;
        constr.anchor = GridBagConstraints.WEST;
        panel.add(myGroupCombo, constr);
        myGroupCombo.setEditable(true);
        myGroupCombo.setFont(myNameField.getFont());
        Dimension comboSize = myNameField.getPreferredSize();
        myGroupCombo.setMinimumSize(comboSize);
        myGroupCombo.setPreferredSize(comboSize);

        // description

        constr = new GridBagConstraints();
        constr.gridx = 0;
        constr.gridy = 1;
        constr.anchor = GridBagConstraints.WEST;
        constr.insets = new Insets(5, 0, 0, 0);
        panel.add(new JLabel(ToolsBundle.message("tools.description.label")), constr);

        constr = new GridBagConstraints();
        constr.gridx = 1;
        constr.gridy = 1;
        constr.weightx = 1;
        constr.gridwidth = 3;
        constr.insets = new Insets(5, 10, 0, 0);
        constr.fill = GridBagConstraints.HORIZONTAL;
        constr.anchor = GridBagConstraints.WEST;
        panel.add(myDescriptionField, constr);

        // check boxes
        JPanel panel0 = new JPanel(new BorderLayout());
        panel0.add(getOptionsPanel(), BorderLayout.NORTH);
        panel0.add(getShowInPanel(), BorderLayout.SOUTH);

        constr = new GridBagConstraints();
        constr.gridy = 4;
        constr.gridwidth = 4;
        constr.fill = GridBagConstraints.HORIZONTAL;
        constr.weightx = 1.0;
        constr.insets = new Insets(5, 0, 0, 0);
        panel.add(panel0, constr);

        // custom panels (put into same place)
        constr = new GridBagConstraints();
        constr.gridx = 0;
        constr.gridy = 7/*8*/;
        constr.gridwidth = 4;
        constr.fill = GridBagConstraints.BOTH;
        constr.weightx = 1.0;
        constr.weighty = 1.0;
        constr.anchor = GridBagConstraints.NORTH;
        panel.add(mySimpleProgramPanel, constr);

        return panel;
    }

    @Override
    @NotNull
    protected Action[] createActions() {
        return new Action[] { getOKAction(), getCancelAction(), getHelpAction() };
    }

    @Override
    protected void doHelpAction() {
        HelpManager.getInstance().invokeHelp(getIdForHelpAction());
    }

    protected String getIdForHelpAction() {
        return "preferences.externalToolsEdit";
    }

    protected ToolEditorDialog(JComponent parent, String title) {
        super(parent, true);

        myOutputFiltersButton = new JButton(ToolsBundle.message("tools.filters.button"));

        DataContext dataContext = DataManager.getInstance().getDataContext(parent);
        myProject = CommonDataKeys.PROJECT.getData(dataContext);
        MacroManager.getInstance().cacheMacrosPreview(dataContext);
        setTitle(title);
        init();
        addListeners();
        myShowConsoleOnStdOutCheckbox.setVisible(false);
        myShowConsoleOnStdErrCheckbox.setVisible(false);
    }

    private JPanel createCommandPane() {
        final JPanel pane = new JPanel(new GridBagLayout());
        pane.setBorder(IdeBorderFactory.createTitledBorder(ToolsBundle.message("tools.tool.group"), true));
        GridBagConstraints constr;

        // program

        constr = new GridBagConstraints();
        constr.gridx = 0;
        constr.gridy = 0;
        constr.insets = new Insets(0, 0, 0, 10);
        constr.anchor = GridBagConstraints.BASELINE_LEADING;
        pane.add(new JLabel(ToolsBundle.message("tools.program.label")), constr);

        FixedSizeButton browseCommandButton = new FixedSizeButton(myTfCommand);

        addCommandBrowseAction(pane, browseCommandButton, myTfCommand);

        JPanel _pane0 = new JPanel(new BorderLayout());
        _pane0.add(myTfCommand, BorderLayout.CENTER);
        _pane0.add(browseCommandButton, BorderLayout.EAST);
        TextFieldWithBrowseButton.MyDoClickAction.addTo(browseCommandButton, myTfCommand);

        constr = new GridBagConstraints();
        constr.gridx = 1;
        constr.gridy = 0;
        constr.insets = new Insets(0, 0, 0, 10);
        constr.fill = GridBagConstraints.HORIZONTAL;
        constr.anchor = GridBagConstraints.BASELINE_LEADING;
        constr.weightx = 1.0;
        pane.add(_pane0, constr);

        constr = new GridBagConstraints();
        constr.gridx = 2;
        constr.gridy = 0;
        constr.insets = new Insets(0, 0, 0, 0);
        constr.fill = GridBagConstraints.HORIZONTAL;
        constr.anchor = GridBagConstraints.BASELINE_LEADING;
        myInsertCommandMacroButton = new JButton(ToolsBundle.message("tools.insert.macro.button"));
        pane.add(myInsertCommandMacroButton, constr);

        // parameters

        constr = new GridBagConstraints();
        constr.gridx = 0;
        constr.gridy = 1;
        constr.insets = new Insets(5, 0, 0, 10);
        constr.anchor = GridBagConstraints.BASELINE_LEADING;
        pane.add(new JLabel(ToolsBundle.message("tools.parameters.label")), constr);

        constr = new GridBagConstraints();
        constr.gridx = 1;
        constr.gridy = 1;
        constr.insets = new Insets(5, 0, 0, 10);
        constr.fill = GridBagConstraints.HORIZONTAL;
        constr.anchor = GridBagConstraints.BASELINE_LEADING;
        constr.weightx = 1.0;
        pane.add(myParametersField, constr);

        constr = new GridBagConstraints();
        constr.gridx = 2;
        constr.gridy = 1;
        constr.insets = new Insets(5, 0, 0, 0);
        constr.fill = GridBagConstraints.HORIZONTAL;
        constr.anchor = GridBagConstraints.BASELINE_LEADING;
        myInsertParametersMacroButton = new JButton(ToolsBundle.message("tools.insert.macro.button.a"));
        pane.add(myInsertParametersMacroButton, constr);

        // working directory

        constr = new GridBagConstraints();
        constr.gridx = 0;
        constr.gridy = 2;
        constr.insets = new Insets(5, 0, 0, 10);
        constr.anchor = GridBagConstraints.BASELINE_LEADING;
        pane.add(new JLabel(ToolsBundle.message("tools.working.directory.label")), constr);

        FixedSizeButton browseDirectoryButton = new FixedSizeButton(myTfCommandWorkingDirectory);
        TextFieldWithBrowseButton.MyDoClickAction.addTo(browseDirectoryButton, myTfCommandWorkingDirectory);
        addWorkingDirectoryBrowseAction(pane, browseDirectoryButton, myTfCommandWorkingDirectory);

        JPanel _pane1 = new JPanel(new BorderLayout());
        _pane1.add(myTfCommandWorkingDirectory, BorderLayout.CENTER);
        _pane1.add(browseDirectoryButton, BorderLayout.EAST);

        constr = new GridBagConstraints();
        constr.gridx = 1;
        constr.gridy = 2;
        constr.gridwidth = 1;
        constr.insets = new Insets(5, 0, 0, 10);
        constr.fill = GridBagConstraints.HORIZONTAL;
        constr.anchor = GridBagConstraints.WEST;
        constr.weightx = 1.0;
        pane.add(_pane1, constr);

        constr = new GridBagConstraints();
        constr.gridx = 2;
        constr.gridy = 2;
        constr.insets = new Insets(5, 0, 0, 0);
        constr.fill = GridBagConstraints.HORIZONTAL;
        constr.anchor = GridBagConstraints.BASELINE_LEADING;
        myInsertWorkingDirectoryMacroButton = new JButton(ToolsBundle.message("tools.insert.macro.button.c"));
        pane.add(myInsertWorkingDirectoryMacroButton, constr);

        // for normal resizing
        constr = new GridBagConstraints();
        constr.gridy = 3;
        constr.fill = GridBagConstraints.BASELINE_LEADING;
        constr.weighty = 1.0;
        pane.add(new JLabel(), constr);

        return pane;
    }

    protected void addWorkingDirectoryBrowseAction(final JPanel pane, FixedSizeButton browseDirectoryButton,
            JTextField tfCommandWorkingDirectory) {
        browseDirectoryButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
                PathChooserDialog chooser = FileChooserFactory.getInstance().createPathChooser(descriptor,
                        myProject, pane);

                chooser.choose(null, new Consumer<List<VirtualFile>>() {
                    @Override
                    public void consume(List<VirtualFile> files) {
                        VirtualFile file = files.size() > 0 ? files.get(0) : null;
                        if (file != null) {
                            myTfCommandWorkingDirectory.setText(file.getPresentableUrl());
                        }
                    }
                });
            }
        });
    }

    protected void addCommandBrowseAction(final JPanel pane, FixedSizeButton browseCommandButton,
            JTextField tfCommand) {
        browseCommandButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                FileChooserDescriptor descriptor = FileChooserDescriptorFactory
                        .createSingleFileOrExecutableAppDescriptor();
                PathChooserDialog chooser = FileChooserFactory.getInstance().createPathChooser(descriptor,
                        myProject, pane);
                chooser.choose(null, new Consumer<List<VirtualFile>>() {
                    @Override
                    public void consume(List<VirtualFile> files) {
                        VirtualFile file = files.size() > 0 ? files.get(0) : null;
                        if (file != null) {
                            myTfCommand.setText(file.getPresentableUrl());
                            String workingDirectory = myTfCommandWorkingDirectory.getText();
                            if (workingDirectory == null || workingDirectory.length() == 0) {
                                VirtualFile parent = file.getParent();
                                if (parent != null && parent.isDirectory()) {
                                    myTfCommandWorkingDirectory.setText(parent.getPresentableUrl());
                                }
                            }
                        }
                    }
                });
            }
        });
    }

    private class InsertMacroActionListener implements ActionListener {
        private final JTextField myTextField;

        public InsertMacroActionListener(JTextField textField) {
            myTextField = textField;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            MacrosDialog dialog = new MacrosDialog(myProject);
            dialog.show();
            if (dialog.isOK() && dialog.getSelectedMacro() != null) {
                String macro = dialog.getSelectedMacro().getName();
                int position = myTextField.getCaretPosition();
                try {
                    myTextField.getDocument().insertString(position, "$" + macro + "$", null);
                    myTextField.setCaretPosition(position + macro.length() + 2);
                } catch (BadLocationException ignored) {
                }
            }
            IdeFocusManager.findInstance().requestFocus(myTextField, true);
        }
    }

    private void addListeners() {
        myOutputFiltersButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                OutputFiltersDialog dialog = new OutputFiltersDialog(myOutputFiltersButton,
                        getData().getOutputFilters());
                dialog.show();
                if (dialog.isOK()) {
                    myOutputFilters = dialog.getData();
                }
            }
        });
        myInsertCommandMacroButton.addActionListener(new InsertMacroActionListener(myTfCommand));
        myInsertParametersMacroButton.addActionListener(new InsertMacroActionListener(myParametersField));
        myInsertWorkingDirectoryMacroButton
                .addActionListener(new InsertMacroActionListener(myTfCommandWorkingDirectory));

        myNameField.getDocument().addDocumentListener(new DocumentAdapter() {
            @Override
            public void textChanged(DocumentEvent event) {
                handleOKButton();
            }
        });

        myUseConsoleCheckbox.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                myShowConsoleOnStdOutCheckbox.setVisible(myUseConsoleCheckbox.isSelected());
                myShowConsoleOnStdErrCheckbox.setVisible(myUseConsoleCheckbox.isSelected());
            }
        });
    }

    private void handleOKButton() {
        setOKActionEnabled(myNameField.getText().trim().length() > 0);
    }

    public Tool getData() {
        Tool tool = createTool();

        tool.setName(convertString(myNameField.getText()));
        tool.setDescription(convertString(myDescriptionField.getText()));
        tool.setGroup(
                myGroupCombo.getSelectedItem() != null ? convertString(myGroupCombo.getSelectedItem().toString())
                        : null);
        tool.setShownInMainMenu(myShowInMainMenuCheckbox.isSelected());
        tool.setShownInEditor(myShowInEditorCheckbox.isSelected());
        tool.setShownInProjectViews(myShowInProjectTreeCheckbox.isSelected());
        tool.setShownInSearchResultsPopup(myShowInSearchResultsPopupCheckbox.isSelected());
        tool.setUseConsole(myUseConsoleCheckbox.isSelected());
        tool.setShowConsoleOnStdOut(myShowConsoleOnStdOutCheckbox.isSelected());
        tool.setShowConsoleOnStdErr(myShowConsoleOnStdErrCheckbox.isSelected());
        tool.setFilesSynchronizedAfterRun(mySynchronizedAfterRunCheckbox.isSelected());
        tool.setEnabled(myEnabled);

        tool.setWorkingDirectory(toSystemIndependentFormat(myTfCommandWorkingDirectory.getText()));
        tool.setProgram(convertString(myTfCommand.getText()));
        tool.setParameters(convertString(myParametersField.getText()));

        tool.setOutputFilters(myOutputFilters);

        return tool;
    }

    protected Tool createTool() {
        return new Tool();
    }

    @Override
    protected String getDimensionServiceKey() {
        return "#com.intellij.tools.ToolEditorDialog";
    }

    /**
     * Initialize controls
     */
    protected void setData(Tool tool, String[] existingGroups) {
        myNameField.setText(tool.getName());
        myDescriptionField.setText(tool.getDescription());
        if (myGroupCombo.getItemCount() > 0) {
            myGroupCombo.removeAllItems();
        }
        for (int i = 0; i < existingGroups.length; i++) {
            if (existingGroups[i] != null) {
                myGroupCombo.addItem(existingGroups[i]);
            }
        }
        myGroupCombo.setSelectedItem(tool.getGroup());
        myShowInMainMenuCheckbox.setSelected(tool.isShownInMainMenu());
        myShowInEditorCheckbox.setSelected(tool.isShownInEditor());
        myShowInProjectTreeCheckbox.setSelected(tool.isShownInProjectViews());
        myShowInSearchResultsPopupCheckbox.setSelected(tool.isShownInSearchResultsPopup());
        myUseConsoleCheckbox.setSelected(tool.isUseConsole());
        myShowConsoleOnStdOutCheckbox.setSelected(tool.isShowConsoleOnStdOut());
        myShowConsoleOnStdErrCheckbox.setSelected(tool.isShowConsoleOnStdErr());
        mySynchronizedAfterRunCheckbox.setSelected(tool.synchronizeAfterExecution());
        myEnabled = tool.isEnabled();
        myTfCommandWorkingDirectory.setText(toCurrentSystemFormat(tool.getWorkingDirectory()));
        myTfCommand.setText(tool.getProgram());
        myParametersField.setText(tool.getParameters());
        myOutputFilters = tool.getOutputFilters();
        mySimpleProgramPanel.setVisible(true);
        handleOKButton();
    }

    @Override
    public JComponent getPreferredFocusedComponent() {
        return myNameField;
    }

    private JPanel getShowInPanel() {
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0));
        panel.setBorder(IdeBorderFactory.createTitledBorder(ToolsBundle.message("tools.menu.group"), true));
        panel.add(myShowInMainMenuCheckbox);
        panel.add(myShowInEditorCheckbox);
        panel.add(myShowInProjectTreeCheckbox);
        panel.add(myShowInSearchResultsPopupCheckbox);
        return panel;
    }

    private JPanel getOptionsPanel() {
        JPanel panel = new JPanel(new MigLayout("fill, gap 10"));
        panel.setBorder(IdeBorderFactory.createTitledBorder(ToolsBundle.message("tools.options.group"), true));
        panel.add(mySynchronizedAfterRunCheckbox);
        panel.add(myUseConsoleCheckbox);
        panel.add(myOutputFiltersButton, "ax right, wrap");
        panel.add(myShowConsoleOnStdOutCheckbox);
        panel.add(myShowConsoleOnStdErrCheckbox, "spanx 2");
        return panel;
    }

    private String convertString(String s) {
        if (s != null && s.trim().length() == 0)
            return null;
        return s;
    }

    private String toSystemIndependentFormat(String s) {
        if (s == null)
            return null;
        s = s.trim();
        if (s.length() == 0)
            return null;
        return s.replace(File.separatorChar, '/');
    }

    private String toCurrentSystemFormat(String s) {
        if (s == null)
            return null;
        s = s.trim();
        if (s.length() == 0)
            return null;
        return s.replace('/', File.separatorChar);
    }

    public Project getProject() {
        return myProject;
    }
}