| /* |
| * Copyright 2000-2013 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.lang.ant.config.impl.configuration; |
| |
| import com.intellij.lang.ant.AntBundle; |
| import com.intellij.lang.ant.config.AntBuildFileBase; |
| import com.intellij.lang.ant.config.impl.*; |
| import com.intellij.openapi.Disposable; |
| import com.intellij.openapi.application.Application; |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.projectRoots.ProjectJdkTable; |
| import com.intellij.openapi.projectRoots.Sdk; |
| import com.intellij.openapi.projectRoots.ui.ProjectJdksEditor; |
| import com.intellij.openapi.ui.ComponentWithBrowseButton; |
| import com.intellij.openapi.ui.DialogBuilder; |
| import com.intellij.openapi.ui.DialogWrapper; |
| import com.intellij.openapi.util.Disposer; |
| import com.intellij.ui.*; |
| import com.intellij.ui.table.JBTable; |
| import com.intellij.util.config.AbstractProperty; |
| import com.intellij.util.containers.Convertor; |
| import com.intellij.util.ui.ColumnInfo; |
| import com.intellij.util.ui.ListTableModel; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import javax.swing.table.TableCellEditor; |
| import java.awt.*; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.util.*; |
| |
| public class BuildFilePropertiesPanel { |
| @NonNls private static final String DIMENSION_SERVICE_KEY = "antBuildFilePropertiesDialogDimension"; |
| |
| private final Form myForm; |
| private AntBuildFileBase myBuildFile; |
| |
| private BuildFilePropertiesPanel(@NotNull final Project project) { |
| myForm = new Form(project); |
| } |
| |
| private void reset(final AntBuildFileBase buildFile) { |
| myBuildFile = buildFile; |
| buildFile.updateProperties(); |
| myForm.reset(myBuildFile); |
| } |
| |
| private void apply() { |
| myForm.apply(myBuildFile); |
| myBuildFile.updateConfig(); |
| } |
| |
| private boolean showDialog() { |
| DialogBuilder builder = new DialogBuilder(myBuildFile.getProject()); |
| builder.setCenterPanel(myForm.myWholePanel); |
| builder.setDimensionServiceKey(DIMENSION_SERVICE_KEY); |
| builder.setPreferredFocusComponent(myForm.getPreferedFocusComponent()); |
| builder.setTitle(AntBundle.message("build.file.properties.dialog.title")); |
| builder.removeAllActions(); |
| builder.addOkAction(); |
| builder.addCancelAction(); |
| builder.setHelpId("reference.dialogs.buildfileproperties"); |
| |
| boolean isOk = builder.show() == DialogWrapper.OK_EXIT_CODE; |
| if (isOk) { |
| apply(); |
| } |
| beforeClose(); |
| return isOk; |
| } |
| |
| private void beforeClose() { |
| myForm.beforeClose(myBuildFile); |
| Disposer.dispose(myForm); |
| } |
| |
| public static boolean editBuildFile(AntBuildFileBase buildFile, @NotNull final Project project) { |
| BuildFilePropertiesPanel panel = new BuildFilePropertiesPanel(project); |
| panel.reset(buildFile); |
| return panel.showDialog(); |
| } |
| |
| abstract static class Tab { |
| private final UIPropertyBinding.Composite myBinding = new UIPropertyBinding.Composite(); |
| |
| public abstract JComponent getComponent(); |
| |
| public abstract String getDisplayName(); |
| |
| public UIPropertyBinding.Composite getBinding() { |
| return myBinding; |
| } |
| |
| public void reset(AbstractProperty.AbstractPropertyContainer options) { |
| myBinding.loadValues(options); |
| } |
| |
| public void apply(AbstractProperty.AbstractPropertyContainer options) { |
| myBinding.apply(options); |
| } |
| |
| public void beforeClose(AbstractProperty.AbstractPropertyContainer options) { |
| myBinding.beforeClose(options); |
| } |
| |
| public abstract JComponent getPreferedFocusComponent(); |
| } |
| |
| private static class Form implements Disposable { |
| private JLabel myBuildFileName; |
| private JTextField myXmx; |
| private JTextField myXss; |
| private JCheckBox myRunInBackground; |
| private JCheckBox myCloseOnNoError; |
| private JPanel myTabsPlace; |
| private JPanel myWholePanel; |
| private JLabel myHeapSizeLabel; |
| private final Tab[] myTabs; |
| private final UIPropertyBinding.Composite myBinding = new UIPropertyBinding.Composite(); |
| private final TabbedPaneWrapper myWrapper; |
| |
| private Form(@NotNull final Project project) { |
| myTabs = new Tab[]{ |
| new PropertiesTab(), |
| new ExecutionTab(GlobalAntConfiguration.getInstance(), project), |
| new AdditionalClasspathTab(), |
| new FiltersTab() |
| }; |
| |
| myHeapSizeLabel.setLabelFor(myXmx); |
| myWrapper = new TabbedPaneWrapper(this); |
| myTabsPlace.setLayout(new BorderLayout()); |
| myTabsPlace.add(myWrapper.getComponent(), BorderLayout.CENTER); |
| |
| myBinding.bindBoolean(myRunInBackground, AntBuildFileImpl.RUN_IN_BACKGROUND); |
| myBinding.bindBoolean(myCloseOnNoError, AntBuildFileImpl.CLOSE_ON_NO_ERRORS); |
| myBinding.bindInt(myXmx, AntBuildFileImpl.MAX_HEAP_SIZE); |
| myBinding.bindInt(myXss, AntBuildFileImpl.MAX_STACK_SIZE); |
| |
| for (Tab tab : myTabs) { |
| myWrapper.addTab(tab.getDisplayName(), tab.getComponent()); |
| } |
| } |
| |
| public JComponent getComponent() { |
| return myWholePanel; |
| } |
| |
| public JComponent getPreferedFocusComponent() { |
| return myTabs[0].getPreferedFocusComponent(); |
| } |
| |
| public void reset(final AntBuildFileBase buildFile) { |
| myBinding.loadValues(buildFile.getAllOptions()); |
| myBuildFileName.setText(buildFile.getPresentableUrl()); |
| for (Tab tab : myTabs) { |
| tab.reset(buildFile.getAllOptions()); |
| } |
| } |
| |
| public void apply(AntBuildFileBase buildFile) { |
| myBinding.apply(buildFile.getAllOptions()); |
| for (Tab tab : myTabs) { |
| tab.apply(buildFile.getAllOptions()); |
| } |
| } |
| |
| public void beforeClose(AntBuildFileBase buildFile) { |
| myBinding.beforeClose(buildFile.getAllOptions()); |
| for (Tab tab : myTabs) { |
| tab.beforeClose(buildFile.getAllOptions()); |
| } |
| } |
| |
| public void dispose() { |
| } |
| } |
| |
| private static class PropertiesTab extends Tab { |
| private JTable myPropertiesTable; |
| private JPanel myWholePanel; |
| |
| private static final ColumnInfo<BuildFileProperty, String> NAME_COLUMN = new ColumnInfo<BuildFileProperty, String>( |
| AntBundle.message("edit.ant.properties.name.column.name")) { |
| public String valueOf(BuildFileProperty buildFileProperty) { |
| return buildFileProperty.getPropertyName(); |
| } |
| |
| public boolean isCellEditable(BuildFileProperty buildFileProperty) { |
| return true; |
| } |
| |
| public void setValue(BuildFileProperty buildFileProperty, String name) { |
| buildFileProperty.setPropertyName(name); |
| } |
| }; |
| private static final ColumnInfo<BuildFileProperty, String> VALUE_COLUMN = new ColumnInfo<BuildFileProperty, String>( |
| AntBundle.message("edit.ant.properties.value.column.name")) { |
| public boolean isCellEditable(BuildFileProperty buildFileProperty) { |
| return true; |
| } |
| |
| public String valueOf(BuildFileProperty buildFileProperty) { |
| return buildFileProperty.getPropertyValue(); |
| } |
| |
| public void setValue(BuildFileProperty buildFileProperty, String value) { |
| buildFileProperty.setPropertyValue(value); |
| } |
| |
| public TableCellEditor getEditor(BuildFileProperty item) { |
| return new AntUIUtil.PropertyValueCellEditor(); |
| } |
| }; |
| private static final ColumnInfo[] PROPERTY_COLUMNS = new ColumnInfo[]{NAME_COLUMN, VALUE_COLUMN}; |
| |
| public PropertiesTab() { |
| myPropertiesTable = new JBTable(); |
| UIPropertyBinding.TableListBinding<BuildFileProperty> tableListBinding = getBinding().bindList(myPropertiesTable, PROPERTY_COLUMNS, |
| AntBuildFileImpl.ANT_PROPERTIES); |
| tableListBinding.setColumnWidths(GlobalAntConfiguration.PROPERTIES_TABLE_LAYOUT); |
| |
| myWholePanel = ToolbarDecorator.createDecorator(myPropertiesTable) |
| .setAddAction(new AnActionButtonRunnable() { |
| |
| |
| @Override |
| public void run(AnActionButton button) { |
| if (myPropertiesTable.isEditing() && !myPropertiesTable.getCellEditor().stopCellEditing()) { |
| return; |
| } |
| BuildFileProperty item = new BuildFileProperty(); |
| ListTableModel<BuildFileProperty> model = (ListTableModel<BuildFileProperty>)myPropertiesTable.getModel(); |
| ArrayList<BuildFileProperty> items = new ArrayList<BuildFileProperty>(model.getItems()); |
| items.add(item); |
| model.setItems(items); |
| int newIndex = model.indexOf(item); |
| ListSelectionModel selectionModel = myPropertiesTable.getSelectionModel(); |
| selectionModel.clearSelection(); |
| selectionModel.setSelectionInterval(newIndex, newIndex); |
| ColumnInfo[] columns = model.getColumnInfos(); |
| for (int i = 0; i < columns.length; i++) { |
| ColumnInfo column = columns[i]; |
| if (column.isCellEditable(item)) { |
| myPropertiesTable.requestFocusInWindow(); |
| myPropertiesTable.editCellAt(newIndex, i); |
| break; |
| } |
| } |
| } |
| }).disableUpDownActions().createPanel(); |
| myWholePanel.setBorder(null); |
| } |
| |
| public JComponent getComponent() { |
| return myWholePanel; |
| } |
| |
| @Nullable |
| public String getDisplayName() { |
| return AntBundle.message("edit.ant.properties.tab.display.name"); |
| } |
| |
| public JComponent getPreferedFocusComponent() { |
| return myPropertiesTable; |
| } |
| } |
| |
| private static class FiltersTab extends Tab { |
| private JTable myFiltersTable; |
| private JPanel myWholePanel; |
| |
| private static final int PREFERRED_CHECKBOX_COLUMN_WIDTH = new JCheckBox().getPreferredSize().width + 4; |
| private static final ColumnInfo<TargetFilter, Boolean> CHECK_BOX_COLUMN = new ColumnInfo<TargetFilter, Boolean>("") { |
| public Boolean valueOf(TargetFilter targetFilter) { |
| return targetFilter.isVisible(); |
| } |
| |
| public void setValue(TargetFilter targetFilter, Boolean aBoolean) { |
| targetFilter.setVisible(aBoolean.booleanValue()); |
| } |
| |
| public int getWidth(JTable table) { |
| return PREFERRED_CHECKBOX_COLUMN_WIDTH; |
| } |
| |
| public Class getColumnClass() { |
| return Boolean.class; |
| } |
| |
| public boolean isCellEditable(TargetFilter targetFilter) { |
| return true; |
| } |
| }; |
| |
| private static final Comparator<TargetFilter> NAME_COMPARATOR = new Comparator<TargetFilter>() { |
| public int compare(TargetFilter o1, TargetFilter o2) { |
| final String name1 = o1.getTargetName(); |
| if (name1 == null) return -1; |
| final String name2 = o2.getTargetName(); |
| if (name2 == null) return 1; |
| return name1.compareToIgnoreCase(name2); |
| } |
| }; |
| private static final ColumnInfo<TargetFilter, String> NAME_COLUMN = new ColumnInfo<TargetFilter, String>( |
| AntBundle.message("ant.target")) { |
| public String valueOf(TargetFilter targetFilter) { |
| return targetFilter.getTargetName(); |
| } |
| |
| public Comparator<TargetFilter> getComparator() { |
| return NAME_COMPARATOR; |
| } |
| }; |
| |
| private static final Comparator<TargetFilter> DESCRIPTION_COMPARATOR = new Comparator<TargetFilter>() { |
| public int compare(TargetFilter o1, TargetFilter o2) { |
| String description1 = o1.getDescription(); |
| if (description1 == null) { |
| description1 = ""; |
| } |
| String description2 = o2.getDescription(); |
| if (description2 == null) { |
| description2 = ""; |
| } |
| return description1.compareToIgnoreCase(description2); |
| } |
| }; |
| private static final ColumnInfo<TargetFilter, String> DESCRIPTION = new ColumnInfo<TargetFilter, String>( |
| AntBundle.message("edit.ant.properties.description.column.name")) { |
| public String valueOf(TargetFilter targetFilter) { |
| return targetFilter.getDescription(); |
| } |
| |
| public Comparator<TargetFilter> getComparator() { |
| return DESCRIPTION_COMPARATOR; |
| } |
| }; |
| private static final ColumnInfo[] COLUMNS = new ColumnInfo[]{CHECK_BOX_COLUMN, NAME_COLUMN, DESCRIPTION}; |
| |
| public FiltersTab() { |
| myFiltersTable.getTableHeader().setReorderingAllowed(false); |
| |
| UIPropertyBinding.TableListBinding tableListBinding = getBinding().bindList(myFiltersTable, COLUMNS, AntBuildFileImpl.TARGET_FILTERS); |
| tableListBinding.setColumnWidths(GlobalAntConfiguration.FILTERS_TABLE_LAYOUT); |
| tableListBinding.setSortable(true); |
| } |
| |
| public JComponent getComponent() { |
| return myWholePanel; |
| } |
| |
| @Nullable |
| public String getDisplayName() { |
| return AntBundle.message("edit.ant.properties.filters.tab.display.name"); |
| } |
| |
| public JComponent getPreferedFocusComponent() { |
| return myFiltersTable; |
| } |
| |
| public void reset(AbstractProperty.AbstractPropertyContainer options) { |
| super.reset(options); |
| } |
| } |
| |
| static class ExecutionTab extends Tab { |
| private JPanel myWholePanel; |
| private JLabel myAntCmdLineLabel; |
| private JLabel myJDKLabel; |
| private RawCommandLineEditor myAntCommandLine; |
| private ComboboxWithBrowseButton myAnts; |
| private ComboboxWithBrowseButton myJDKs; |
| private final ChooseAndEditComboBoxController<Sdk, String> myJDKsController; |
| private JButton mySetDefaultAnt; |
| private SimpleColoredComponent myDefaultAnt; |
| private JRadioButton myUseCastomAnt; |
| private JRadioButton myUseDefaultAnt; |
| |
| private AntReference myProjectDefaultAnt = null; |
| private final GlobalAntConfiguration myAntGlobalConfiguration; |
| private final Project myProject; |
| |
| public ExecutionTab(final GlobalAntConfiguration antConfiguration, @NotNull final Project project) { |
| myAntGlobalConfiguration = antConfiguration; |
| myProject = project; |
| myAntCommandLine.attachLabel(myAntCmdLineLabel); |
| myAntCommandLine.setDialogCaption(AntBundle.message("run.execution.tab.ant.command.line.dialog.title")); |
| setLabelFor(myJDKLabel, myJDKs); |
| |
| myJDKsController = new ChooseAndEditComboBoxController<Sdk, String>(myJDKs, new Convertor<Sdk, String>() { |
| public String convert(Sdk jdk) { |
| return jdk != null ? jdk.getName() : ""; |
| } |
| }, String.CASE_INSENSITIVE_ORDER) { |
| public Iterator<Sdk> getAllListItems() { |
| Application application = ApplicationManager.getApplication(); |
| if (application == null) { |
| return Collections.singletonList((Sdk)null).iterator(); |
| } |
| ArrayList<Sdk> allJdks = new ArrayList<Sdk>(Arrays.asList(ProjectJdkTable.getInstance().getAllJdks())); |
| allJdks.add(0, null); |
| return allJdks.iterator(); |
| } |
| |
| public Sdk openConfigureDialog(Sdk jdk, JComponent parent) { |
| ProjectJdksEditor editor = new ProjectJdksEditor(jdk, myJDKs.getComboBox()); |
| editor.show(); |
| return editor.getSelectedJdk(); |
| } |
| }; |
| |
| UIPropertyBinding.Composite binding = getBinding(); |
| binding.bindString(myAntCommandLine.getTextField(), AntBuildFileImpl.ANT_COMMAND_LINE_PARAMETERS); |
| binding.bindString(myJDKs.getComboBox(), AntBuildFileImpl.CUSTOM_JDK_NAME); |
| binding.addBinding(new RunWithAntBinding(myUseDefaultAnt, myUseCastomAnt, myAnts, myAntGlobalConfiguration)); |
| |
| mySetDefaultAnt.addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent e) { |
| AntSetPanel antSetPanel = new AntSetPanel(myAntGlobalConfiguration); |
| antSetPanel.reset(); |
| antSetPanel.setSelection(myProjectDefaultAnt.find(myAntGlobalConfiguration)); |
| AntInstallation antInstallation = antSetPanel.showDialog(mySetDefaultAnt); |
| if (antInstallation == null) { |
| return; |
| } |
| myProjectDefaultAnt = antInstallation.getReference(); |
| updateDefaultAnt(); |
| } |
| }); |
| } |
| |
| public JComponent getComponent() { |
| return myWholePanel; |
| } |
| |
| @Nullable |
| public String getDisplayName() { |
| return AntBundle.message("edit.ant.properties.execution.tab.display.name"); |
| } |
| |
| public void reset(AbstractProperty.AbstractPropertyContainer options) { |
| String projectJdkName = AntConfigurationImpl.DEFAULT_JDK_NAME.get(options); |
| myJDKsController.setRenderer(new AntUIUtil.ProjectJdkRenderer(true, projectJdkName)); |
| super.reset(options); |
| myJDKsController.resetList(null); |
| myProjectDefaultAnt = AntConfigurationImpl.DEFAULT_ANT.get(options); |
| updateDefaultAnt(); |
| } |
| |
| private void updateDefaultAnt() { |
| myDefaultAnt.clear(); |
| AntUIUtil.customizeReference(myProjectDefaultAnt, myDefaultAnt, myAntGlobalConfiguration); |
| myDefaultAnt.revalidate(); |
| myDefaultAnt.repaint(); |
| } |
| |
| public void apply(AbstractProperty.AbstractPropertyContainer options) { |
| AntConfigurationImpl.DEFAULT_ANT.set(options, myProjectDefaultAnt); |
| super.apply(options); |
| } |
| |
| public JComponent getPreferedFocusComponent() { |
| return myAntCommandLine.getTextField(); |
| } |
| } |
| |
| private static class AdditionalClasspathTab extends Tab { |
| private JPanel myWholePanel; |
| private AntClasspathEditorPanel myClasspath; |
| |
| public AdditionalClasspathTab() { |
| getBinding().addBinding(myClasspath.setClasspathProperty(AntBuildFileImpl.ADDITIONAL_CLASSPATH)); |
| } |
| |
| public JComponent getComponent() { |
| return myWholePanel; |
| } |
| |
| @Nullable |
| public String getDisplayName() { |
| return AntBundle.message("edit.ant.properties.additional.classpath.tab.display.name"); |
| } |
| |
| public JComponent getPreferedFocusComponent() { |
| return myClasspath.getPreferedFocusComponent(); |
| } |
| } |
| |
| private static void setLabelFor(JLabel label, ComponentWithBrowseButton component) { |
| label.setLabelFor(component.getChildComponent()); |
| } |
| } |