Settings: sort configurables

This commit is contained in:
Sergey Malenkov
2014-09-08 19:26:12 +04:00
parent bb80849ccb
commit 3c9ece667b
12 changed files with 222 additions and 312 deletions
@@ -75,7 +75,7 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
new IdeConfigurablesGroup()};
return Registry.is("ide.new.settings.dialog")
? MixedConfigurableGroup.getGroups(getConfigurables(groups, true))
? new ConfigurableGroup[]{new SortedConfigurableGroup(getConfigurables(groups, true))}
: groups;
}
@@ -60,9 +60,7 @@ public class ConfigurableWrapper implements SearchableConfigurable {
}
return !ep.dynamic && ep.children == null && ep.childrenEPName == null
? (T)new ConfigurableWrapper(ep, configurable)
: "itself".equals(ep.groupId)
? (T)new GroupWrapper(ep, configurable)
: (T)new CompositeWrapper(ep, configurable);
: (T)new CompositeWrapper(ep, configurable);
}
else {
return ep.createConfigurable();
@@ -245,15 +243,4 @@ public class ConfigurableWrapper implements SearchableConfigurable {
return this;
}
}
private static final class GroupWrapper extends CompositeWrapper implements ConfigurableGroup {
private GroupWrapper(@NotNull ConfigurableEP ep, @Nullable UnnamedConfigurable configurable, Configurable... kids) {
super(ep, configurable, kids);
}
@Override
public String getShortName() {
return getDisplayName();
}
}
}
@@ -1,175 +0,0 @@
/*
* Copyright 2000-2014 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.openapi.options.ex;
import com.intellij.openapi.options.*;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.*;
import java.util.Map.Entry;
public final class MixedConfigurableGroup implements SearchableConfigurable, ConfigurableGroup, Configurable.NoScroll {
private final String myGroupId;
private Configurable[] myConfigurables;
private MixedConfigurableGroup(String groupId, ArrayList<Configurable> configurables) {
myGroupId = groupId;
myConfigurables = (configurables != null)
? configurables.toArray(new Configurable[configurables.size()])
: new Configurable[0];
Arrays.sort(myConfigurables, COMPARATOR);
}
private MixedConfigurableGroup(String groupId, HashMap<String, ArrayList<Configurable>> configurables) {
this(groupId, configurables.remove(groupId));
}
@Override
public JComponent createComponent() {
return null;
}
@Override
public boolean isModified() {
return false;
}
@Override
public void apply() throws ConfigurationException {
}
@Override
public void reset() {
}
@Override
public void disposeUIResources() {
myConfigurables = null;
}
@Override
public Runnable enableSearch(String option) {
return null;
}
@NotNull
@Override
public String getId() {
return "configurable.group." + myGroupId;
}
@Override
public String getHelpTopic() {
return "configurable.group." + myGroupId + ".help.topic";
}
@Override
public String getDisplayName() {
return OptionsBundle.message("configurable.group." + myGroupId + ".settings.display.name");
}
@Override
public String getShortName() {
return getDisplayName();
}
@Override
public Configurable[] getConfigurables() {
return myConfigurables;
}
public static ConfigurableGroup[] getGroups(Configurable... configurables) {
ArrayList<ConfigurableGroup> groups = new ArrayList<ConfigurableGroup>();
HashMap<String, ArrayList<Configurable>> map = new HashMap<String, ArrayList<Configurable>>();
for (Configurable configurable : configurables) {
if (configurable instanceof ConfigurableGroup) {
groups.add((ConfigurableGroup)configurable);
}
else {
String groupId = null;
if (configurable instanceof ConfigurableWrapper) {
groupId = ((ConfigurableWrapper)configurable).getExtensionPoint().groupId;
}
ArrayList<Configurable> list = map.get(groupId);
if (list == null) {
map.put(groupId, list = new ArrayList<Configurable>());
}
list.add(configurable);
}
}
ArrayList<Configurable> buildList = map.get("build");
if (buildList != null) {
NodeConfigurable buildTools = new NodeConfigurable("build.tools", 1000);
buildTools.add(find("MavenSettings", buildList.iterator()));
buildTools.add(find("reference.settingsdialog.project.gradle", buildList.iterator()));
buildTools.add(find("reference.settingsdialog.project.gant", buildList.iterator()));
if (buildTools.getConfigurables() != null) {
buildList.add(0, buildTools);
}
}
groups.add(0, new MixedConfigurableGroup("appearance", map));
groups.add(1, new MixedConfigurableGroup("editor", map));
groups.add(new MixedConfigurableGroup("project", map));
groups.add(new MixedConfigurableGroup("build", map));
groups.add(new MixedConfigurableGroup("language", map));
groups.add(new MixedConfigurableGroup("tools", map));
ConfigurableGroup other = new MixedConfigurableGroup(null, map);
for(Entry<String, ArrayList<Configurable>>entry: map.entrySet()){
groups.add(new MixedConfigurableGroup(entry.getKey(), entry.getValue()));
}
groups.add(other);
return groups.toArray(new ConfigurableGroup[groups.size()]);
}
private static Configurable find(String id, Iterator<Configurable> iterator) {
while (iterator.hasNext()) {
Configurable configurable = iterator.next();
if (configurable instanceof SearchableConfigurable) {
SearchableConfigurable sc = (SearchableConfigurable)configurable;
if (id.equals(sc.getId())) {
iterator.remove();
return configurable;
}
}
}
return null;
}
public static int getGroupWeight(Configurable configurable) {
if (configurable instanceof NodeConfigurable) {
return ((NodeConfigurable)configurable).getGroupWeight();
}
if (configurable instanceof ConfigurableWrapper) {
return ((ConfigurableWrapper)configurable).getExtensionPoint().groupWeight;
}
return 0;
}
private static final Comparator<Configurable> COMPARATOR = new Comparator<Configurable>() {
@Override
public int compare(Configurable configurable1, Configurable configurable2) {
if (configurable1 == null || configurable2 == null) {
return configurable2 != null ? -1 : configurable1 != null ? 1 : 0;
}
int weight1 = getGroupWeight(configurable1);
int weight2 = getGroupWeight(configurable2);
return weight1 > weight2 ? -1 : weight1 < weight2 ? 1 : StringUtil.naturalCompare(configurable1.getDisplayName(),
configurable2.getDisplayName());
}
};
}
@@ -1,77 +0,0 @@
/*
* Copyright 2000-2014 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.openapi.options.ex;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.options.SearchableConfigurable;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
public final class NodeConfigurable extends SearchableConfigurable.Parent.Abstract {
private final ArrayList<Configurable> myConfigurables = new ArrayList<Configurable>();
private final String myId;
private final int myWeight;
public NodeConfigurable(@NotNull String id, int weight) {
myId = id;
myWeight = weight;
}
public int getGroupWeight() {
return myWeight;
}
public void add(Configurable configurable) {
if (configurable != null) {
super.disposeUIResources();
myConfigurables.add(configurable);
}
}
@Override
public void disposeUIResources() {
super.disposeUIResources();
myConfigurables.clear();
}
@NotNull
@Override
public String getId() {
return "node.configurable." + myId;
}
@Nullable
@Override
public String getHelpTopic() {
return "node.configurable." + myId + ".help.topic";
}
@Nls
@Override
public String getDisplayName() {
return OptionsBundle.message("node.configurable." + myId + ".display.name");
}
@Override
protected Configurable[] buildConfigurables() {
int size = myConfigurables.size();
return size == 0 ? null : myConfigurables.toArray(new Configurable[size]);
}
}
@@ -0,0 +1,195 @@
/*
* Copyright 2000-2014 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.openapi.options.ex;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurableGroup;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
/**
* @author Sergey.Malenkov
*/
public final class SortedConfigurableGroup
extends SearchableConfigurable.Parent.Abstract
implements SearchableConfigurable, ConfigurableGroup, Configurable.NoScroll {
public static ConfigurableGroup getGroup(Configurable... configurables) {
SortedConfigurableGroup root = new SortedConfigurableGroup("root");
HashMap<String, SortedConfigurableGroup> map = new HashMap<String, SortedConfigurableGroup>();
map.put("root", root);
for (Configurable configurable : configurables) {
int weight = 0;
String groupId = null;
if (configurable instanceof ConfigurableWrapper) {
ConfigurableWrapper wrapper = (ConfigurableWrapper)configurable;
weight = wrapper.getExtensionPoint().groupWeight;
groupId = wrapper.getExtensionPoint().groupId;
}
SortedConfigurableGroup composite = map.get(groupId);
if (composite == null) {
composite = new SortedConfigurableGroup(groupId);
map.put(groupId, composite);
}
composite.add(weight, configurable);
}
// process supported groups
root.add(60, map.remove("appearance"));
root.add(50, map.remove("editor"));
root.add(40, map.remove("project"));
SortedConfigurableGroup build = map.remove("build");
if (build == null) {
build = map.remove("build.tools");
}
else {
build.add(1000, map.remove("build.tools"));
}
root.add(30, build);
root.add(20, map.remove("language"));
root.add(10, map.remove("tools"));
root.add(-10, map.remove(null));
// process unsupported groups
if (1 < map.size()) {
for (SortedConfigurableGroup group : map.values()) {
if (root != group) {
group.myDisplayName = "Category: " + group.myGroupId;
root.add(0, group);
}
}
}
return root;
}
private final ArrayList<WeightConfigurable> myList = new ArrayList<WeightConfigurable>();
private final String myGroupId;
private String myDisplayName;
private SortedConfigurableGroup(String groupId) {
myGroupId = groupId;
}
public SortedConfigurableGroup(Configurable... configurables) {
myGroupId = "root";
// create groups from configurations
HashMap<String, SortedConfigurableGroup> map = new HashMap<String, SortedConfigurableGroup>();
map.put(myGroupId, this);
for (Configurable configurable : configurables) {
int weight = 0;
String groupId = null;
if (configurable instanceof ConfigurableWrapper) {
ConfigurableWrapper wrapper = (ConfigurableWrapper)configurable;
weight = wrapper.getExtensionPoint().groupWeight;
groupId = wrapper.getExtensionPoint().groupId;
}
SortedConfigurableGroup composite = map.get(groupId);
if (composite == null) {
composite = new SortedConfigurableGroup(groupId);
map.put(groupId, composite);
}
composite.add(weight, configurable);
}
// process supported groups
add(60, map.remove("appearance"));
add(50, map.remove("editor"));
add(40, map.remove("project"));
SortedConfigurableGroup build = map.remove("build");
if (build == null) {
build = map.remove("build.tools");
}
else {
build.add(1000, map.remove("build.tools"));
}
add(30, build);
add(20, map.remove("language"));
add(10, map.remove("tools"));
add(-10, map.remove(null));
// process unsupported groups
if (1 < map.size()) {
for (SortedConfigurableGroup group : map.values()) {
if (this != group) {
group.myDisplayName = "Category: " + group.myGroupId;
add(0, group);
}
}
}
}
private void add(int weight, Configurable configurable) {
if (configurable != null) {
myList.add(new WeightConfigurable(configurable, weight));
}
}
@Override
protected Configurable[] buildConfigurables() {
Collections.sort(myList);
int length = myList.size();
Configurable[] result = new Configurable[length];
for (int i = 0; i < result.length; i++) {
result[i] = myList.get(i).myConfigurable;
}
myList.clear();
return result;
}
@NotNull
@Override
public String getId() {
return "configurable.group." + myGroupId;
}
@Nullable
@Override
public String getHelpTopic() {
return "configurable.group." + myGroupId + ".help.topic";
}
@Nls
@Override
public String getDisplayName() {
return myDisplayName != null ? myDisplayName : OptionsBundle.message("configurable.group." + myGroupId + ".settings.display.name");
}
@Override
public String getShortName() {
return getDisplayName();
}
private static final class WeightConfigurable implements Comparable<WeightConfigurable> {
private final Configurable myConfigurable;
private final int myWeight;
private WeightConfigurable(@NotNull Configurable configurable, int weight) {
myConfigurable = configurable;
myWeight = weight;
}
@Override
public int compareTo(@NotNull WeightConfigurable pair) {
return myWeight > pair.myWeight ? -1 :
myWeight < pair.myWeight ? 1 :
StringUtil.naturalCompare(myConfigurable.getDisplayName(), pair.myConfigurable.getDisplayName());
}
}
}
@@ -23,7 +23,6 @@ import com.intellij.openapi.options.ConfigurableGroup;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
import com.intellij.openapi.options.ex.NodeConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
@@ -383,17 +382,6 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
SimpleNode parent = base.getParent();
if (parent == myRoot) {
project = getConfigurableProject(base); // show icon for top-level nodes
if (base.getConfigurable() instanceof NodeConfigurable) { // special case for custom subgroups (build.tools)
Configurable[] configurables = ((NodeConfigurable)base.getConfigurable()).getConfigurables();
if (configurables != null) { // assume that all configurables have the same project
project = getConfigurableProject(configurables[0]);
}
}
}
else if (parent instanceof Base && ((Base)parent).getConfigurable() instanceof NodeConfigurable) {
if (((Base)base.getParent()).getConfigurable() instanceof NodeConfigurable) {
project = getConfigurableProject(base); // special case for custom subgroups
}
}
}
if (project != null) {
@@ -20,7 +20,7 @@ import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.options.*;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
import com.intellij.openapi.options.ex.NodeConfigurable;
import com.intellij.openapi.options.ex.SortedConfigurableGroup;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
@@ -220,15 +220,15 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
}
@Nullable
private ConfigurableGroup findConfigurableGroupAt(int x, int y) {
private String findGroupNameAt(int x, int y) {
TreePath path = myTree.getClosestPathForLocation(x - myTree.getX(), y - myTree.getY());
while (path != null) {
MyNode node = extractNode(path);
if (node == null) {
return null;
}
if (node.myComposite instanceof ConfigurableGroup) {
return (ConfigurableGroup)node.myComposite;
if (myRoot == node.getParent()) {
return node.myDisplayName;
}
path = path.getParentPath();
}
@@ -273,10 +273,10 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
mySeparator.setFont(getFont().deriveFont(Font.BOLD));
}
int height = mySeparator.getPreferredSize().height;
ConfigurableGroup group = findConfigurableGroupAt(0, height);
if (group != null && group == findConfigurableGroupAt(0, 0)) {
String group = findGroupNameAt(0, height);
if (group != null && group.equals(findGroupNameAt(0, 0))) {
mySeparator.setBorder(BorderFactory.createEmptyBorder(0, 18, 0, 0));
mySeparator.setText(group.getDisplayName());
mySeparator.setText(group);
Rectangle bounds = myScroller.getViewport().getBounds();
if (bounds.height > height) {
@@ -403,11 +403,13 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
if (myGroups == null || myGroups.length == 0) {
return NO_CHILDREN;
}
SimpleNode[] result = new SimpleNode[myGroups.length];
for (int i = 0; i < myGroups.length; i++) {
result[i] = new MyNode(this, myGroups[i], 0);
ArrayList<MyNode> list = new ArrayList<MyNode>();
for (ConfigurableGroup group : myGroups) {
for (Configurable configurable : group.getConfigurables()) {
list.add(new MyNode(this, configurable, 0));
}
}
return result;
return list.toArray(new SimpleNode[list.size()]);
}
}
@@ -426,15 +428,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
myLevel = level;
}
private MyNode(CachingSimpleNode parent, ConfigurableGroup group, int level) {
super(parent);
myComposite = group;
myConfigurable = group instanceof Configurable ? (Configurable)group : null;
String name = group.getDisplayName();
myDisplayName = name != null ? name.replace("\n", " ") : "{ " + group.getClass().getSimpleName() + " }";
myLevel = level;
}
@Override
protected SimpleNode[] buildChildren() {
if (myConfigurable != null) {
@@ -530,15 +523,15 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
if (parent instanceof MyNode) {
if (myRoot == parent.getParent()) {
project = findConfigurableProject(node); // show icon for top-level nodes
if (node.myConfigurable instanceof NodeConfigurable) { // special case for custom subgroups (build.tools)
Configurable[] configurables = ((NodeConfigurable)node.myConfigurable).getConfigurables();
if (node.myConfigurable instanceof SortedConfigurableGroup) { // special case for custom subgroups (build.tools)
Configurable[] configurables = ((SortedConfigurableGroup)node.myConfigurable).getConfigurables();
if (configurables != null) { // assume that all configurables have the same project
project = findConfigurableProject(configurables[0]);
}
}
}
else if (((MyNode)parent).myConfigurable instanceof NodeConfigurable) {
if (((MyNode)node.getParent()).myConfigurable instanceof NodeConfigurable) {
else if (((MyNode)parent).myConfigurable instanceof SortedConfigurableGroup) {
if (((MyNode)node.getParent()).myConfigurable instanceof SortedConfigurableGroup) {
project = findConfigurableProject(node); // special case for custom subgroups
}
}
@@ -198,10 +198,6 @@ options.xml.display.name=XML
settings.panel.title=Settings
node.configurable.build.tools.display.name=Build Tools
node.configurable.build.tools.settings.description=<html><body>\
Configure your project integration with different build tools: Maven, Gradle or Gant.
configurable.group.appearance.settings.display.name=Appearance and Behavior
configurable.group.appearance.settings.description=<html><body>\
Personalize IntelliJ appearance and behavior: change themes and font size, tune the keymap,\
@@ -218,6 +214,9 @@ configurable.group.build.settings.display.name=Build, Execution, Deployment
configurable.group.build.settings.description=<html><body>\
Configure you project integration with different build tools (Maven, Gradle or Gant),\
modify the default compiler settings, manage server access configurations, customize the Debugger behavior, etc.
configurable.group.build.tools.settings.display.name=Build Tools
configurable.group.build.tools.settings.description=<html><body>\
Configure your project integration with different build tools: Maven, Gradle or Gant.
configurable.group.language.settings.display.name=Languages and Frameworks
configurable.group.language.settings.description=<html><body>\
Configure the settings related to specific frameworks and technologies used in your project.
@@ -227,7 +226,7 @@ configurable.group.tools.settings.description=<html><body>\
manage server certificates and tasks, configure diagrams layout, etc.
configurable.group.null.settings.display.name=Other Settings
configurable.group.null.settings.description=<html><body>\
Other settings that must be sorted out to another groups.
Settings that are related to non-bundled custom plugins and are not assigned to any other category.
configurable.default.project.tooltip=For default project
configurable.current.project.tooltip=For current project
@@ -25,7 +25,7 @@
<selectInTarget implementation="com.intellij.openapi.vcs.changes.SelectInChangesViewTarget"/>
<projectConfigurable groupId="itself" groupWeight="110" dynamic="true" key="version.control.main.configurable.name" bundle="messages.VcsBundle"
<projectConfigurable groupId="root" groupWeight="45" dynamic="true" key="version.control.main.configurable.name" bundle="messages.VcsBundle"
provider="com.intellij.openapi.vcs.configurable.VcsManagerConfigurableProvider" id="vcs"/>
<changesViewContent tabName="Repository" className="com.intellij.openapi.vcs.changes.committed.CommittedChangesViewManager"
+1 -1
View File
@@ -88,7 +88,7 @@
<moduleBuilder builderClass="org.jetbrains.plugins.gradle.service.project.wizard.GradleModuleBuilder"/>
<internalFileTemplate name="Gradle Build Script"/>
<internalFileTemplate name="Gradle Build Script with wrapper"/>
<projectConfigurable groupId="build" id="reference.settingsdialog.project.gradle"
<projectConfigurable groupId="build.tools" groupWeight="110" id="reference.settingsdialog.project.gradle"
instance="org.jetbrains.plugins.gradle.service.settings.GradleConfigurable"
key="gradle.name" bundle="i18n.GradleBundle"/>
<library.presentationProvider implementation="org.jetbrains.plugins.gradle.config.GradleLibraryPresentationProvider" order="last"/>
+1 -1
View File
@@ -273,7 +273,7 @@
<fileTypeFactory implementation="org.jetbrains.plugins.groovy.GroovyFileTypeLoader"/>
<fileTypeFactory implementation="org.jetbrains.plugins.groovy.dgm.DGMFileTypeFactory"/>
<projectConfigurable groupId="build" instance="org.jetbrains.plugins.groovy.gant.GantConfigurable" id="reference.settingsdialog.project.gant"
<projectConfigurable groupId="build.tools" groupWeight="100" instance="org.jetbrains.plugins.groovy.gant.GantConfigurable" id="reference.settingsdialog.project.gant"
displayName="Gant"/>
<library.presentationProvider implementation="org.jetbrains.plugins.groovy.config.GroovyLibraryPresentationProvider"/>
@@ -46,7 +46,7 @@
<applicationService serviceImplementation="org.jetbrains.idea.maven.indices.MavenIndicesManager"/>
<applicationService serviceImplementation="org.jetbrains.idea.maven.services.MavenRepositoryServicesManager"/>
<projectConfigurable groupId="build" instance="org.jetbrains.idea.maven.utils.MavenSettings" id="MavenSettings" displayName="Maven" order="last">
<projectConfigurable groupId="build.tools" groupWeight="120" instance="org.jetbrains.idea.maven.utils.MavenSettings" id="MavenSettings" displayName="Maven" order="last">
<configurable instance="org.jetbrains.idea.maven.project.MavenImportingConfigurable" id="reference.settings.project.maven.importing"
key="maven.tab.importing" bundle="ProjectBundle"/>
<configurable instance="org.jetbrains.idea.maven.project.MavenIgnoredFilesConfigurable"