/*
* Copyright 2000-2007 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.execution.configurations.coverage;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.execution.ExecutionBundle;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.PackageChooser;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.peer.PeerFactory;
import com.intellij.psi.PsiPackage;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.ui.classFilter.ClassFilterEditor;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.util.Arrays;
import java.util.List;
/**
* Base {@link com.intellij.openapi.options.Configurable} for configuring code coverage
* To obtain a full configurable use
* <code>
* SettingsEditorGroup<YourConfiguration> group = new SettingsEditorGroup<YourConfiguration>();
* group.addEditor(title, yourConfigurable);
* group.addEditor(title, yourCoverageConfigurable);
* </code>
* @author ven
*/
public abstract class CoverageConfigurable<T extends CoverageEnabledConfiguration> extends SettingsEditor<T> {
Project myProject;
private MyClassFilterEditor myClassFilterEditor;
private JCheckBox myCoverageEnabledCheckbox;
private JCheckBox myMergeDataCheckbox;
private JLabel myCoverageNotSupportedLabel;
private static class MyClassFilterEditor extends ClassFilterEditor {
public MyClassFilterEditor(Project project) {
super(project);
}
public String[] getFilterPatterns() {
final ClassFilter[] classFilters = super.getFilters();
String[] result = new String[classFilters.length];
for (int i = 0; i < result.length; i++) {
result[i] = classFilters[i].getPattern();
}
return result;
}
protected void addPatternFilter() {
PackageChooser chooser = PeerFactory.getInstance().getUIHelper().
createPackageChooser(CodeInsightBundle.message("coverage.pattern.filter.editor.choose.package.title"), myProject);
chooser.show();
List<PsiPackage> packages = chooser.getSelectedPackages();
if (!packages.isEmpty()) {
for (final PsiPackage aPackage : packages) {
final String fqName = aPackage.getQualifiedName();
final String pattern = fqName.length() > 0 ? fqName + ".*" : "*";
myTableModel.addRow(createFilter(pattern));
}
int row = myTableModel.getRowCount() - 1;
myTable.getSelectionModel().setSelectionInterval(row, row);
myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
myTable.requestFocus();
}
}
protected String getAddPatternButtonText() {
return CodeInsightBundle.message("coverage.button.add.package");
}
}
public CoverageConfigurable(final Project project) {
myProject = project;
}
/**
* Coverage is supported for running with JRE 5.0 or higher. This methods should return true
* if the user has configured right JRE.
* @param configuration configured run configuration
* @return true iff JRE 5.0 or higher is currently configured
*/
protected abstract boolean isJre50Configured(T configuration);
protected void resetEditorFrom(final T configuration) {
final boolean isJre50 = isJre50Configured(configuration);
myCoverageNotSupportedLabel.setVisible(!isJre50);
myCoverageEnabledCheckbox.setEnabled(isJre50);
myMergeDataCheckbox.setEnabled(isJre50);
myMergeDataCheckbox.setSelected(configuration.isMergeWithPreviousResults());
myClassFilterEditor.setEnabled(isJre50);
myCoverageEnabledCheckbox.setSelected(isJre50 && configuration.isCoverageEnabled());
final String[] filter = configuration.getCoveragePatterns();
if (filter != null) {
final List<String> oldPatterns = Arrays.asList((myClassFilterEditor.getFilterPatterns()));
for (String pattern : filter) {
if (!oldPatterns.contains(pattern)) {
myClassFilterEditor.addPattern(pattern);
}
}
}
}
protected void applyEditorTo(final T configuration) throws ConfigurationException {
configuration.setCoverageEnabled(myCoverageEnabledCheckbox.isSelected());
configuration.setMergeWithPreviousResults(myMergeDataCheckbox.isSelected());
configuration.setCoveragePatterns(myClassFilterEditor.getFilterPatterns());
}
@NotNull
protected JComponent createEditor() {
JPanel result = new JPanel(new VerticalFlowLayout());
myCoverageEnabledCheckbox = new JCheckBox(ExecutionBundle.message("enable.coverage.with.emma"));
result.add(myCoverageEnabledCheckbox);
myMergeDataCheckbox = new JCheckBox(ExecutionBundle.message("merge.coverage.data"));
result.add(myMergeDataCheckbox);
JPanel panel = new JPanel(new VerticalFlowLayout());
panel.setBorder(IdeBorderFactory.createTitledBorder(ExecutionBundle.message("record.coverage.filters.title")));
myClassFilterEditor = new MyClassFilterEditor(myProject);
panel.add(myClassFilterEditor);
result.add(panel);
myCoverageEnabledCheckbox.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
myClassFilterEditor.setEnabled(myCoverageEnabledCheckbox.isSelected());
}
});
myCoverageNotSupportedLabel = new JLabel(CodeInsightBundle.message("code.coverage.is.not.supported"));
myCoverageNotSupportedLabel.setIcon(UIUtil.getOptionPanelWarningIcon());
result.add(myCoverageNotSupportedLabel);
return result;
}
protected void disposeEditor() {}
}