Remove obsolete registry properties

This commit is contained in:
Sergey Malenkov
2015-12-21 16:13:28 +03:00
parent ba1d0e0ddc
commit f02c735efd
15 changed files with 32 additions and 2908 deletions
@@ -20,7 +20,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.options.ex.SingleConfigurableEditor;
import com.intellij.openapi.options.newEditor.OptionsEditorDialog;
import com.intellij.openapi.options.newEditor.SettingsDialog;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
@@ -40,7 +40,7 @@ public class ShowStructureSettingsAction extends AnAction implements DumbAware {
static void showDialog(Project project) {
if (Registry.is("ide.new.project.settings")) {
new SingleConfigurableEditor(project, ProjectStructureConfigurable.getInstance(project), OptionsEditorDialog.DIMENSION_KEY) {
new SingleConfigurableEditor(project, ProjectStructureConfigurable.getInstance(project), SettingsDialog.DIMENSION_KEY) {
@NotNull
@Override
protected DialogStyle getStyle() {
@@ -50,7 +50,7 @@ public class ShowStructureSettingsAction extends AnAction implements DumbAware {
}
else {
ShowSettingsUtil
.getInstance().editConfigurable(project, OptionsEditorDialog.DIMENSION_KEY, ProjectStructureConfigurable.getInstance(project));
.getInstance().editConfigurable(project, SettingsDialog.DIMENSION_KEY, ProjectStructureConfigurable.getInstance(project));
}
}
}
@@ -23,7 +23,6 @@ import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.codeStyle.CodeStyleScheme;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsProvider;
@@ -55,10 +54,7 @@ public class CodeStyleSchemesConfigurable extends SearchableConfigurable.Parent.
public JComponent createComponent() {
myModel = ensureModel();
if (Registry.is("ide.new.settings.dialog")) {
return myPanels == null || myPanels.isEmpty() ? null : myPanels.get(0).createComponent();
}
return myRootSchemesPanel.getPanel();
return myPanels == null || myPanels.isEmpty() ? null : myPanels.get(0).createComponent();
}
@Override
@@ -235,15 +231,12 @@ public class CodeStyleSchemesConfigurable extends SearchableConfigurable.Parent.
}
}
if (Registry.is("ide.new.settings.dialog")) {
int size = myPanels.size();
Configurable[] result = new Configurable[size > 0 ? size - 1 : 0];
for (int i = 0; i < result.length; i++) {
result[i] = myPanels.get(i + 1);
}
return result;
int size = myPanels.size();
Configurable[] result = new Configurable[size > 0 ? size - 1 : 0];
for (int i = 0; i < result.length; i++) {
result[i] = myPanels.get(i + 1);
}
return myPanels.toArray(new Configurable[myPanels.size()]);
return result;
}
private CodeStyleSchemesModel ensureModel() {
@@ -301,10 +294,8 @@ public class CodeStyleSchemesConfigurable extends SearchableConfigurable.Parent.
@Override
public boolean isModified() {
if (myModel != null) {
if (Registry.is("ide.new.settings.dialog")) {
if (myPanels != null && myPanels.size() > 0 && myPanels.get(0).isModified()) {
return true;
}
if (myPanels != null && myPanels.size() > 0 && myPanels.get(0).isModified()) {
return true;
}
boolean schemeListModified = myModel.isSchemeListModified();
if (schemeListModified) {
@@ -23,11 +23,11 @@ import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.codeStyle.CodeStyleScheme;
import com.intellij.psi.codeStyle.CodeStyleSchemes;
import com.intellij.ui.components.labels.SwingActionLink;
import com.intellij.util.Alarm;
import com.intellij.util.ui.JBUI;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -115,9 +115,7 @@ public class CodeStyleMainPanel extends JPanel implements TabbedLanguageCodeStyl
JPanel top = new JPanel(new BorderLayout());
top.add(BorderLayout.WEST, mySchemesPanel.getPanel());
top.add(BorderLayout.EAST, link);
if (Registry.is("ide.new.settings.view")) {
top.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
}
top.setBorder(JBUI.Borders.empty(10));
add(top, BorderLayout.NORTH);
add(mySettingsPanel, BorderLayout.CENTER);
@@ -21,14 +21,11 @@ import com.intellij.openapi.options.newEditor.SettingsDialog;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.InputValidator;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.search.scope.packageSet.NamedScope;
import com.intellij.psi.search.scope.packageSet.PackageSet;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* User: anna
* Date: 03-Jul-2006
@@ -48,15 +45,6 @@ public class EditScopesDialog extends SettingsDialog {
myCheckShared = checkShared;
}
@Override
protected JComponent createCenterPanel() {
JComponent component = super.createCenterPanel();
if (!Registry.is("ide.new.settings.view")) {
component.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
}
return component;
}
@Override
public void doOKAction() {
Object selectedObject = myConfigurable.getSelectedObject();
@@ -18,12 +18,12 @@ package com.intellij.openapi.ui;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.RelativeFont;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.PlatformColors;
import org.jetbrains.annotations.NotNull;
@@ -47,7 +47,7 @@ class Banner extends NonOpaquePanel implements PropertyChangeListener{
public Banner() {
setLayout(new BorderLayout());
setBorder(new EmptyBorder(2, Registry.is("ide.new.settings.dialog") ? 12 : 6, 2, 4));
setBorder(JBUI.Borders.empty(2, 12, 2, 4));
myProjectIcon.setVisible(false);
myProjectIcon.setBorder(new EmptyBorder(0, 12, 0, 4));
@@ -17,7 +17,6 @@
package com.intellij.openapi.ui;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.util.ArrayUtil;
@@ -30,7 +29,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.geom.GeneralPath;
import java.util.ArrayList;
public class DetailsComponent {
@@ -61,61 +59,7 @@ public class DetailsComponent {
public DetailsComponent(boolean detailsEnabled, boolean paintBorder) {
myDetailsEnabled = detailsEnabled;
myPaintBorder = paintBorder;
myComponent = new JPanel(new BorderLayout()) {
@Override
protected void paintComponent(final Graphics g) {
if (NullableComponent.Check.isNull(myContent) || !myDetailsEnabled) return;
GraphicsConfig c = null;
Insets insets = null;
final int leftX;
final int rightX;
final int rightY;
if (!Registry.is("ide.new.settings.dialog")) {
c = new GraphicsConfig(g);
c.setAntialiasing(true);
insets = getInsets();
if (insets == null) {
insets = new Insets(0, 0, 0, 0);
}
g.setColor(UIUtil.getFocusedFillColor());
final Rectangle banner = myBanner.getBounds();
final GeneralPath header = new GeneralPath();
leftX = insets.left;
final int leftY = insets.top;
rightX = insets.left + getWidth() - 1 - insets.right;
rightY = banner.y + banner.height;
header.moveTo(leftX, rightY);
int arc = 8;
header.lineTo(leftX, leftY + arc);
header.quadTo(leftX, leftY, leftX + arc, leftY);
header.lineTo(rightX - arc, leftY);
header.quadTo(rightX, leftY, rightX, leftY + arc);
header.lineTo(rightX, rightY);
header.closePath();
c.getG().fill(header);
g.setColor(UIUtil.getFocusedBoundsColor());
c.getG().draw(header);
if (myPaintBorder) {
final int down = getHeight() - insets.top - insets.bottom - 1;
g.drawLine(leftX, rightY, leftX, down);
g.drawLine(rightX, rightY, rightX, down);
g.drawLine(leftX, down, rightX, down);
}
c.restore();
}
}
};
myComponent = new JPanel(new BorderLayout());
myComponent.setOpaque(false);
myContentGutter.setOpaque(false);
@@ -16,21 +16,16 @@
package com.intellij.ide.actions;
import com.intellij.ide.ui.search.SearchUtil;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurableGroup;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.options.TabbedConfigurable;
import com.intellij.openapi.options.ex.*;
import com.intellij.openapi.options.newEditor.IdeSettingsDialog;
import com.intellij.openapi.options.newEditor.OptionsEditor;
import com.intellij.openapi.options.newEditor.OptionsEditorDialog;
import com.intellij.openapi.options.newEditor.SettingsDialog;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.navigation.Place;
import com.intellij.util.ui.update.Activatable;
@@ -59,34 +54,15 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
public static DialogWrapper getDialog(@Nullable Project project, @NotNull ConfigurableGroup[] groups, @Nullable Configurable toSelect) {
project = getProject(project);
final ConfigurableGroup[] filteredGroups = filterEmptyGroups(groups);
if (Registry.is("ide.new.settings.dialog")) {
return Registry.is("ide.new.settings.view")
? new SettingsDialog(project, filteredGroups, toSelect, null)
: new IdeSettingsDialog(project, filteredGroups, toSelect);
}
//noinspection deprecation
return Registry.is("ide.perProjectModality")
? new OptionsEditorDialog(project, filteredGroups, toSelect, true)
: new OptionsEditorDialog(project, filteredGroups, toSelect);
return new SettingsDialog(project, filteredGroups, toSelect, null);
}
@NotNull
public static ConfigurableGroup[] getConfigurableGroups(@Nullable Project project, boolean withIdeSettings) {
if (Registry.is("ide.new.settings.dialog")) {
if (!withIdeSettings) {
project = getProject(project);
}
return new ConfigurableGroup[]{ConfigurableExtensionPointUtil.getConfigurableGroup(project, withIdeSettings)};
if (!withIdeSettings) {
project = getProject(project);
}
ConfigurableGroup[] groups = !withIdeSettings
? new ConfigurableGroup[]{new ProjectConfigurablesGroup(getProject(project))}
: (project == null)
? new ConfigurableGroup[]{new IdeConfigurablesGroup()}
: new ConfigurableGroup[]{
new ProjectConfigurablesGroup(project),
new IdeConfigurablesGroup()};
return groups;
return new ConfigurableGroup[]{ConfigurableExtensionPointUtil.getConfigurableGroup(project, withIdeSettings)};
}
@NotNull
@@ -162,21 +138,7 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
group = filterEmptyGroups(group);
final Configurable configurable2Select = id2Select == null ? null : new ConfigurableVisitor.ByID(id2Select).find(group);
if (Registry.is("ide.new.settings.view")) {
new SettingsDialog(getProject(project), group, configurable2Select, filter).show();
return;
}
final DialogWrapper dialog = getDialog(project, group, configurable2Select);
new UiNotifyConnector.Once(dialog.getContentPane(), new Activatable.Adapter() {
@Override
public void showNotify() {
final OptionsEditor editor = (OptionsEditor)((DataProvider)dialog).getData(OptionsEditor.KEY.getName());
LOG.assertTrue(editor != null);
editor.select(configurable2Select, filter);
}
});
dialog.show();
new SettingsDialog(getProject(project), group, configurable2Select, filter).show();
}
@Override
@@ -250,14 +212,10 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
boolean showApplyButton) {
final DialogWrapper editor;
if (parent == null) {
editor = Registry.is("ide.new.settings.view")
? new SettingsDialog(project, dimensionKey, configurable, showApplyButton, false)
: new SingleConfigurableEditor(project, configurable, dimensionKey, showApplyButton);
editor = new SettingsDialog(project, dimensionKey, configurable, showApplyButton, false);
}
else {
editor = Registry.is("ide.new.settings.view")
? new SettingsDialog(parent, dimensionKey, configurable, showApplyButton, false)
: new SingleConfigurableEditor(parent, configurable, dimensionKey, showApplyButton);
editor = new SettingsDialog(parent, dimensionKey, configurable, showApplyButton, false);
}
if (advancedInitialization != null) {
new UiNotifyConnector.Once(editor.getContentPane(), new Activatable.Adapter() {
@@ -1,305 +0,0 @@
/*
* Copyright 2000-2015 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.newEditor;
import com.intellij.CommonBundle;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurableGroup;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.ex.ConfigurableVisitor;
import com.intellij.openapi.project.DumbModePermission;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.Gray;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.JBColor;
import com.intellij.ui.border.CustomLineBorder;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Collection;
import java.util.Map;
/**
* @author Konstantin Bulenkov
*/
public class IdeSettingsDialog extends DialogWrapper implements DataProvider {
private Project myProject;
private ConfigurableGroup[] myGroups;
private Configurable myPreselected;
private OptionsEditor myEditor;
private ApplyAction myApplyAction;
public static final String DIMENSION_KEY = "OptionsEditor";
@NonNls static final String LAST_SELECTED_CONFIGURABLE = "options.lastSelected";
/**
* This constructor should be eliminated after the new modality approach
* will have been checked. See a {@code Registry} key ide.perProjectModality
*
* @deprecated
*/
public IdeSettingsDialog(Project project, ConfigurableGroup[] groups,
@Nullable Configurable preselectedConfigurable, boolean applicationModalIfPossible) {
super(project, true, applicationModalIfPossible);
init(project, groups, preselectedConfigurable != null ? preselectedConfigurable : findLastSavedConfigurable(groups, project));
}
/**
* This constructor should be eliminated after the new modality approach
* will have been checked. See a {@code Registry} key ide.perProjectModality
*
* @deprecated
*/
public IdeSettingsDialog(Project project, ConfigurableGroup[] groups,
@NotNull String preselectedConfigurableDisplayName, boolean applicationModalIfPossible) {
super(project, true, applicationModalIfPossible);
init(project, groups, getPreselectedByDisplayName(groups, preselectedConfigurableDisplayName, project));
}
public IdeSettingsDialog(Project project, ConfigurableGroup[] groups, @Nullable Configurable preselectedConfigurable) {
super(project, true);
init(project, groups, preselectedConfigurable != null ? preselectedConfigurable : findLastSavedConfigurable(groups, project));
}
public IdeSettingsDialog(Project project, ConfigurableGroup[] groups, @NotNull String preselectedConfigurableDisplayName) {
super(project, true);
init(project, groups, getPreselectedByDisplayName(groups, preselectedConfigurableDisplayName, project));
}
@Override
public void show() {
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
@Override
public void run() {
IdeSettingsDialog.super.show();
}
});
}
@Nullable
@Override
protected Border createContentPaneBorder() {
return IdeBorderFactory.createEmptyBorder(0);
}
private void init(final Project project, final ConfigurableGroup[] groups, @Nullable final Configurable preselected) {
myProject = project;
myGroups = groups;
myPreselected = preselected;
setTitle(CommonBundle.settingsTitle());
init();
}
@Nullable
private static Configurable getPreselectedByDisplayName(final ConfigurableGroup[] groups, final String preselectedConfigurableDisplayName,
final Project project) {
Configurable result = new ConfigurableVisitor.ByName(preselectedConfigurableDisplayName).find(groups);
return result == null ? findLastSavedConfigurable(groups, project) : result;
}
@Override
public boolean isTypeAheadEnabled() {
return true;
}
@Nullable
@Override
protected JComponent createSouthPanel() {
final JComponent panel = super.createSouthPanel();
CustomLineBorder line = new CustomLineBorder(new JBColor(Gray._153.withAlpha(128), Gray._100.withAlpha(128)), 1, 0, 0, 0);
panel.setBorder(new CompoundBorder(line, new EmptyBorder(8, 12, 8, 12)));
return panel;
}
protected JComponent createCenterPanel() {
myEditor = new OptionsEditor(myProject, myGroups, myPreselected);
myEditor.getContext().addColleague(new OptionsEditorColleague.Adapter() {
@Override
public ActionCallback onModifiedAdded(final Configurable configurable) {
updateStatus();
return ActionCallback.DONE;
}
@Override
public ActionCallback onModifiedRemoved(final Configurable configurable) {
updateStatus();
return ActionCallback.DONE;
}
@Override
public ActionCallback onErrorsChanged() {
updateStatus();
return ActionCallback.DONE;
}
});
Disposer.register(myDisposable, myEditor);
return myEditor;
}
public boolean updateStatus() {
myApplyAction.setEnabled(myEditor.canApply());
final Map<Configurable, ConfigurationException> errors = myEditor.getContext().getErrors();
if (errors.size() == 0) {
setErrorText(null);
}
else {
String text = "Changes were not applied because of an error";
final String errorMessage = getErrorMessage(errors);
if (errorMessage != null) {
text += "<br>" + errorMessage;
}
setErrorText(text);
}
return errors.size() == 0;
}
@Nullable
private static String getErrorMessage(final Map<Configurable, ConfigurationException> errors) {
final Collection<ConfigurationException> values = errors.values();
final ConfigurationException[] exceptions = values.toArray(new ConfigurationException[values.size()]);
if (exceptions.length > 0) {
return exceptions[0].getMessage();
}
return null;
}
@Override
protected String getDimensionServiceKey() {
return DIMENSION_KEY;
}
@Override
public void doOKAction() {
myEditor.flushModifications();
if (myEditor.canApply()) {
myEditor.apply();
if (!updateStatus()) return;
}
saveCurrentConfigurable();
ApplicationManager.getApplication().saveAll();
super.doOKAction();
}
private void saveCurrentConfigurable() {
final Configurable current = myEditor.getContext().getCurrentConfigurable();
if (current == null) return;
final PropertiesComponent props = PropertiesComponent.getInstance(myProject);
if (current instanceof SearchableConfigurable) {
props.setValue(LAST_SELECTED_CONFIGURABLE, ((SearchableConfigurable)current).getId());
}
else {
props.setValue(LAST_SELECTED_CONFIGURABLE, current.getClass().getName());
}
}
@Nullable
private static Configurable findLastSavedConfigurable(ConfigurableGroup[] groups, final Project project) {
final String id = PropertiesComponent.getInstance(project).getValue(LAST_SELECTED_CONFIGURABLE);
if (id == null) return null;
return new ConfigurableVisitor.ByID(id).find(groups);
}
@Override
public void doCancelAction(final AWTEvent source) {
if (source instanceof KeyEvent || source instanceof ActionEvent) {
if (myEditor.getContext().isHoldingFilter()) {
myEditor.clearFilter();
return;
}
}
super.doCancelAction(source);
}
@Override
public void doCancelAction() {
saveCurrentConfigurable();
super.doCancelAction();
}
@NotNull
@Override
protected Action[] createActions() {
myApplyAction = new ApplyAction();
return new Action[]{getOKAction(), getCancelAction(), myApplyAction, getHelpAction()};
}
@Override
protected void doHelpAction() {
final String topic = myEditor.getHelpTopic();
if (topic != null) {
HelpManager.getInstance().invokeHelp(topic);
}
}
@Override
public JComponent getPreferredFocusedComponent() {
return myEditor.getPreferredFocusedComponent();
}
public Object getData(@NonNls String dataId) {
if (OptionsEditor.KEY.is(dataId)) {
return myEditor;
}
return myEditor == null ? null : myEditor.getData(dataId);
}
private class ApplyAction extends AbstractAction {
public ApplyAction() {
super(CommonBundle.getApplyButtonText());
setEnabled(false);
}
public void actionPerformed(final ActionEvent e) {
myEditor.apply();
myEditor.revalidate();
myEditor.repaint();
updateStatus();
}
}
}
@@ -1,316 +0,0 @@
/*
* Copyright 2000-2015 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.newEditor;
import com.intellij.CommonBundle;
import com.intellij.ide.ui.search.SearchUtil;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurableGroup;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.ex.Settings;
import com.intellij.openapi.project.DumbModePermission;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class OptionsEditorDialog extends DialogWrapper implements DataProvider{
private Project myProject;
private ConfigurableGroup[] myGroups;
private Configurable myPreselected;
private OptionsEditor myEditor;
private ApplyAction myApplyAction;
public static final String DIMENSION_KEY = "OptionsEditor";
@NonNls static final String LAST_SELECTED_CONFIGURABLE = "options.lastSelected";
/** This constructor should be eliminated after the new modality approach
* will have been checked. See a {@code Registry} key ide.perProjectModality
* @deprecated
*/
public OptionsEditorDialog(Project project, ConfigurableGroup[] groups,
@Nullable Configurable preselectedConfigurable, boolean applicationModalIfPossible) {
super(project, true, applicationModalIfPossible);
init(project, groups, preselectedConfigurable != null ? preselectedConfigurable : findLastSavedConfigurable(groups, project));
}
/** This constructor should be eliminated after the new modality approach
* will have been checked. See a {@code Registry} key ide.perProjectModality
* @deprecated
*/
public OptionsEditorDialog(Project project, ConfigurableGroup[] groups,
@NotNull String preselectedConfigurableDisplayName, boolean applicationModalIfPossible) {
super(project, true, applicationModalIfPossible);
init(project, groups, getPreselectedByDisplayName(groups, preselectedConfigurableDisplayName, project));
}
public OptionsEditorDialog(Project project, ConfigurableGroup[] groups, @Nullable Configurable preselectedConfigurable) {
super(project, true);
init(project, groups, preselectedConfigurable != null ? preselectedConfigurable : findLastSavedConfigurable(groups, project));
}
public OptionsEditorDialog(Project project, ConfigurableGroup[] groups, @NotNull String preselectedConfigurableDisplayName) {
super(project, true);
init(project, groups, getPreselectedByDisplayName(groups, preselectedConfigurableDisplayName, project));
}
private void init(final Project project, final ConfigurableGroup[] groups, @Nullable final Configurable preselected) {
myProject = project;
myGroups = groups;
myPreselected = preselected;
setTitle(CommonBundle.settingsTitle());
init();
}
@Override
public void show() {
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
@Override
public void run() {
OptionsEditorDialog.super.show();
}
});
}
@Nullable
private static Configurable getPreselectedByDisplayName(final ConfigurableGroup[] groups, final String preselectedConfigurableDisplayName,
final Project project) {
Configurable result = findPreselectedByDisplayName(preselectedConfigurableDisplayName, groups);
return result == null ? findLastSavedConfigurable(groups, project) : result;
}
@Override
public boolean isTypeAheadEnabled() {
return true;
}
protected JComponent createCenterPanel() {
myEditor = new OptionsEditor(myProject, myGroups, myPreselected);
myEditor.getContext().addColleague(new OptionsEditorColleague.Adapter() {
@Override
public ActionCallback onModifiedAdded(final Configurable configurable) {
updateStatus();
return ActionCallback.DONE;
}
@Override
public ActionCallback onModifiedRemoved(final Configurable configurable) {
updateStatus();
return ActionCallback.DONE;
}
@Override
public ActionCallback onErrorsChanged() {
updateStatus();
return ActionCallback.DONE;
}
});
Disposer.register(myDisposable, myEditor);
return myEditor;
}
public boolean updateStatus() {
myApplyAction.setEnabled(myEditor.canApply());
final Map<Configurable,ConfigurationException> errors = myEditor.getContext().getErrors();
if (errors.size() == 0) {
setErrorText(null);
} else {
String text = "Changes were not applied because of an error";
final String errorMessage = getErrorMessage(errors);
if (errorMessage != null) {
text += "<br>" + errorMessage;
}
setErrorText(text);
}
return errors.size() == 0;
}
@Nullable
private static String getErrorMessage(final Map<Configurable, ConfigurationException> errors) {
final Collection<ConfigurationException> values = errors.values();
final ConfigurationException[] exceptions = values.toArray(new ConfigurationException[values.size()]);
if (exceptions.length > 0) {
return exceptions[0].getMessage();
}
return null;
}
@Override
protected String getDimensionServiceKey() {
return DIMENSION_KEY;
}
@Override
protected void doOKAction() {
myEditor.flushModifications();
if (myEditor.canApply()) {
myEditor.apply();
if (!updateStatus()) return;
}
saveCurrentConfigurable();
ApplicationManager.getApplication().saveAll();
super.doOKAction();
}
private void saveCurrentConfigurable() {
final Configurable current = myEditor.getContext().getCurrentConfigurable();
if (current == null) return;
final PropertiesComponent props = PropertiesComponent.getInstance(myProject);
if (current instanceof SearchableConfigurable) {
props.setValue(LAST_SELECTED_CONFIGURABLE, ((SearchableConfigurable)current).getId());
} else {
props.setValue(LAST_SELECTED_CONFIGURABLE, current.getClass().getName());
}
}
@Nullable
private static Configurable findLastSavedConfigurable(ConfigurableGroup[] groups, final Project project) {
final String id = PropertiesComponent.getInstance(project).getValue(LAST_SELECTED_CONFIGURABLE);
if (id == null) return null;
return findConfigurableInGroups(id, groups);
}
@Nullable
private static Configurable findConfigurableInGroups(String id, Configurable.Composite... groups) {
// avoid unnecessary group expand: check top-level configurables in all groups before looking at children
for (Configurable.Composite group : groups) {
final Configurable[] configurables = group.getConfigurables();
for (Configurable c : configurables) {
if (c instanceof SearchableConfigurable && id.equals(((SearchableConfigurable)c).getId())) {
return c;
} else if (id.equals(c.getClass().getName())) {
return c;
}
}
}
for (Configurable.Composite group : groups) {
final Configurable[] configurables = group.getConfigurables();
for (Configurable c : configurables) {
if (c instanceof Configurable.Composite) {
Configurable result = findConfigurableInGroups(id, (Configurable.Composite)c);
if (result != null) {
return result;
}
}
}
}
return null;
}
@Nullable
private static Configurable findPreselectedByDisplayName(final String preselectedConfigurableDisplayName, ConfigurableGroup[] groups) {
final List<Configurable> all = SearchUtil.expand(groups);
for (Configurable each : all) {
if (preselectedConfigurableDisplayName.equals(each.getDisplayName())) return each;
}
return null;
}
@Override
public void doCancelAction(final AWTEvent source) {
if (source instanceof KeyEvent || source instanceof ActionEvent) {
if (myEditor.getContext().isHoldingFilter()) {
myEditor.clearFilter();
return;
}
}
super.doCancelAction(source);
}
@Override
public void doCancelAction() {
saveCurrentConfigurable();
super.doCancelAction();
}
@NotNull
@Override
protected Action[] createActions() {
myApplyAction = new ApplyAction();
return new Action[] {getOKAction(), getCancelAction(), myApplyAction, getHelpAction()};
}
@Override
protected void doHelpAction() {
final String topic = myEditor.getHelpTopic();
if (topic != null) {
HelpManager.getInstance().invokeHelp(topic);
}
}
@Override
public JComponent getPreferredFocusedComponent() {
return myEditor.getPreferredFocusedComponent();
}
public Object getData(@NonNls String dataId) {
if (Settings.KEY.is(dataId)) {
return myEditor.mySettings;
}
if (OptionsEditor.KEY.is(dataId)) {
return myEditor;
}
return null;
}
private class ApplyAction extends AbstractAction {
public ApplyAction() {
super(CommonBundle.getApplyButtonText());
setEnabled(false);
}
public void actionPerformed(final ActionEvent e) {
myEditor.apply();
myEditor.revalidate();
myEditor.repaint();
}
}
}
@@ -1,981 +0,0 @@
/*
* Copyright 2000-2015 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.newEditor;
import com.intellij.icons.AllIcons;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.Disposable;
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.options.ex.ConfigurableWrapper;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.*;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.treeStructure.*;
import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.TreeUI;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;
public class OptionsTree extends JPanel implements Disposable, OptionsEditorColleague {
private final SettingsFilter myFilter;
final SimpleTree myTree;
List<ConfigurableGroup> myGroups;
FilteringTreeBuilder myBuilder;
Root myRoot;
Map<Configurable, EditorNode> myConfigurable2Node = new HashMap<Configurable, EditorNode>();
MergingUpdateQueue mySelection;
private final OptionsTree.Renderer myRenderer;
public OptionsTree(SettingsFilter filter, ConfigurableGroup... groups) {
myFilter = filter;
myGroups = Arrays.asList(groups);
myRoot = new Root();
final SimpleTreeStructure structure = new SimpleTreeStructure() {
public Object getRootElement() {
return myRoot;
}
};
myTree = new MyTree();
TreeUtil.installActions(myTree);
myTree.setBorder(new EmptyBorder(0, 1, 0, 0));
myTree.setRowHeight(-1);
myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
myRenderer = new Renderer();
myTree.setCellRenderer(myRenderer);
myTree.setRootVisible(false);
myTree.setShowsRootHandles(false);
myBuilder = new MyBuilder(structure);
myBuilder.setFilteringMerge(300, null);
Disposer.register(this, myBuilder);
setLayout(new BorderLayout());
myTree.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(final ComponentEvent e) {
myBuilder.revalidateTree();
}
@Override
public void componentMoved(final ComponentEvent e) {
myBuilder.revalidateTree();
}
@Override
public void componentShown(final ComponentEvent e) {
myBuilder.revalidateTree();
}
});
add(new StickySeparator(myTree), BorderLayout.CENTER);
mySelection = new MergingUpdateQueue("OptionsTree", 150, false, this, this, this).setRestartTimerOnAdd(true);
myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(final TreeSelectionEvent e) {
final TreePath path = e.getNewLeadSelectionPath();
if (path == null) {
queueSelection(null);
}
else {
final Base base = extractNode(path.getLastPathComponent());
queueSelection(base != null ? base.getConfigurable() : null);
}
}
});
}
ActionCallback select(@Nullable Configurable configurable) {
return queueSelection(configurable);
}
public void selectFirst() {
for (ConfigurableGroup eachGroup : myGroups) {
final Configurable[] kids = eachGroup.getConfigurables();
if (kids.length > 0) {
queueSelection(kids[0]);
return;
}
}
}
private Configurable myQueuedConfigurable;
ActionCallback queueSelection(final Configurable configurable) {
if (myBuilder.isSelectionBeingAdjusted()) {
return ActionCallback.REJECTED;
}
final ActionCallback callback = new ActionCallback();
myQueuedConfigurable = configurable;
final Update update = new Update(this) {
public void run() {
if (configurable != myQueuedConfigurable) return;
if (configurable == null) {
myTree.getSelectionModel().clearSelection();
myFilter.myContext.fireSelected(null, OptionsTree.this);
}
else {
myBuilder.getReady(this).doWhenDone(new Runnable() {
@Override
public void run() {
if (configurable != myQueuedConfigurable) return;
final EditorNode editorNode = myConfigurable2Node.get(configurable);
FilteringTreeStructure.FilteringNode editorUiNode = myBuilder.getVisibleNodeFor(editorNode);
if (editorUiNode == null) return;
if (!myBuilder.getSelectedElements().contains(editorUiNode)) {
myBuilder.select(editorUiNode, new Runnable() {
public void run() {
fireSelected(configurable, callback);
}
});
} else {
myBuilder.scrollSelectionToVisible(new Runnable() {
public void run() {
fireSelected(configurable, callback);
}
}, false);
}
}
});
}
}
@Override
public void setRejected() {
super.setRejected();
callback.setRejected();
}
};
mySelection.queue(update);
return callback;
}
private void fireSelected(Configurable configurable, final ActionCallback callback) {
myFilter.myContext.fireSelected(configurable, this).doWhenProcessed(callback.createSetDoneRunnable());
}
public JTree getTree() {
return myTree;
}
public List<Configurable> getPathToRoot(final Configurable configurable) {
final ArrayList<Configurable> path = new ArrayList<Configurable>();
EditorNode eachNode = myConfigurable2Node.get(configurable);
if (eachNode == null) return path;
while (eachNode != null) {
path.add(eachNode.getConfigurable());
final SimpleNode parent = eachNode.getParent();
if (parent instanceof EditorNode) {
eachNode = (EditorNode)parent;
}
else {
break;
}
}
return path;
}
public SimpleNode findNodeFor(final Configurable toSelect) {
return myConfigurable2Node.get(toSelect);
}
@Nullable
public <T extends Configurable> T findConfigurable(Class<T> configurableClass) {
for (Configurable configurable : myConfigurable2Node.keySet()) {
if (configurableClass.isInstance(configurable)) {
return configurableClass.cast(configurable);
}
}
return null;
}
@Nullable
public SearchableConfigurable findConfigurableById(@NotNull String configurableId) {
for (Configurable configurable : myConfigurable2Node.keySet()) {
if (configurable instanceof SearchableConfigurable) {
SearchableConfigurable searchableConfigurable = (SearchableConfigurable) configurable;
if (configurableId.equals(searchableConfigurable.getId())) {
return searchableConfigurable;
}
}
}
return null;
}
class Renderer extends GroupedElementsRenderer.Tree {
private GroupSeparator mySeparator;
private JLabel myProjectIcon;
private JLabel myHandle;
@Override
protected void layout() {
myRendererComponent.setOpaqueActive(false);
mySeparator = new GroupSeparator();
myRendererComponent.add(Registry.is("ide.new.settings.dialog") ? mySeparator : mySeparatorComponent, BorderLayout.NORTH);
final NonOpaquePanel content = new NonOpaquePanel(new BorderLayout());
myHandle = new JLabel("", SwingConstants.CENTER);
if (!SystemInfo.isMac) {
myHandle.setBorder(new EmptyBorder(0, 2, 0, 2));
}
myHandle.setOpaque(false);
content.add(myHandle, BorderLayout.WEST);
content.add(myComponent, BorderLayout.CENTER);
myProjectIcon = new JLabel(" ", SwingConstants.LEFT);
myProjectIcon.setOpaque(true);
content.add(myProjectIcon, BorderLayout.EAST);
myRendererComponent.add(content, BorderLayout.CENTER);
}
public Component getTreeCellRendererComponent(final JTree tree,
final Object value,
final boolean selected,
final boolean expanded,
final boolean leaf,
final int row,
final boolean hasFocus) {
JComponent result;
Color fg = UIUtil.getTreeTextForeground();
mySeparator.configure(null, false);
final Base base = extractNode(value);
if (base instanceof EditorNode) {
final EditorNode editor = (EditorNode)base;
ConfigurableGroup group = null;
if (editor.getParent() == myRoot) {
final DefaultMutableTreeNode prevValue = ((DefaultMutableTreeNode)value).getPreviousSibling();
if (prevValue == null || prevValue instanceof LoadingNode) {
group = editor.getGroup();
mySeparator.configure(group, false);
}
else {
final Base prevBase = extractNode(prevValue);
if (prevBase instanceof EditorNode) {
final EditorNode prevEditor = (EditorNode)prevBase;
if (prevEditor.getGroup() != editor.getGroup()) {
group = editor.getGroup();
mySeparator.configure(group, true);
}
}
}
}
TreePath path = tree.getPathForRow(row);
if (path == null) {
if (value instanceof DefaultMutableTreeNode) {
path = new TreePath(((DefaultMutableTreeNode)value).getPath());
}
}
final boolean toStretch = tree.isVisible() && path != null;
int forcedWidth = 2000;
if (toStretch) {
final Rectangle visibleRect = tree.getVisibleRect();
int nestingLevel = tree.isRootVisible() ? path.getPathCount() - 1 : path.getPathCount() - 2;
final int left = UIUtil.getTreeLeftChildIndent();
final int right = UIUtil.getTreeRightChildIndent();
final Insets treeInsets = tree.getInsets();
int indent = (left + right) * nestingLevel + (treeInsets != null ? treeInsets.left + treeInsets.right : 0);
forcedWidth = visibleRect.width > 0 ? visibleRect.width - indent : forcedWidth;
}
result = configureComponent(base.getText(), base.getText(), null, null, row == -1 || selected, group != null,
group != null ? group.getDisplayName() : null, forcedWidth - 4);
if (base.isError()) {
fg = JBColor.red;
}
else if (base.isModified()) {
fg = JBColor.blue;
}
}
else {
result = configureComponent(value.toString(), null, null, null, selected, false, null, -1);
}
if (value instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
TreePath nodePath = new TreePath(node.getPath());
myHandle.setIcon(((SimpleTree)tree).getHandleIcon(node, nodePath));
} else {
myHandle.setIcon(null);
}
myTextLabel.setForeground(selected ? UIUtil.getTreeSelectionForeground() : fg);
myTextLabel.setOpaque(selected);
if (Registry.is("ide.new.settings.dialog")) {
myTextLabel.setBorder(new EmptyBorder(1,2,1,0));
}
Project project = null;
if (base != null && Registry.is("ide.new.settings.dialog")) {
SimpleNode parent = base.getParent();
if (parent == myRoot) {
project = getConfigurableProject(base); // show icon for top-level nodes
}
}
if (project != null) {
myProjectIcon.setBackground(selected ? getSelectionBackground() : getBackground());
myProjectIcon.setIcon(selected ? AllIcons.General.ProjectConfigurableSelected : AllIcons.General.ProjectConfigurable);
myProjectIcon.setVisible(true);
myProjectIcon.setToolTipText(OptionsBundle.message(project.isDefault()
? "configurable.default.project.tooltip"
: "configurable.current.project.tooltip"));
} else {
myProjectIcon.setVisible(false);
}
if (Registry.is("ide.new.settings.dialog")) {
result.setBackground(selected ? UIUtil.getTreeSelectionBackground() : UIUtil.SIDE_PANEL_BACKGROUND);
}
return result;
}
protected JComponent createItemComponent() {
myTextLabel = new ErrorLabel();
return myTextLabel;
}
public boolean isUnderHandle(final Point point) {
final Point handlePoint = SwingUtilities.convertPoint(myRendererComponent, point, myHandle);
final Rectangle bounds = myHandle.getBounds();
return bounds.x < handlePoint.x && bounds.getMaxX() >= handlePoint.x;
}
}
@Nullable
private Base extractNode(Object object) {
if (object instanceof DefaultMutableTreeNode) {
final DefaultMutableTreeNode uiNode = (DefaultMutableTreeNode)object;
final Object o = uiNode.getUserObject();
if (o instanceof FilteringTreeStructure.FilteringNode) {
return (Base)((FilteringTreeStructure.FilteringNode)o).getDelegate();
}
}
return null;
}
abstract static class Base extends CachingSimpleNode {
protected Base(final SimpleNode aParent) {
super(aParent);
}
String getText() {
return null;
}
boolean isModified() {
return false;
}
boolean isError() {
return false;
}
Configurable getConfigurable() {
return null;
}
}
class Root extends Base {
Root() {
super(null);
}
protected SimpleNode[] buildChildren() {
List<SimpleNode> result = new ArrayList<SimpleNode>();
for (ConfigurableGroup eachGroup : myGroups) {
result.addAll(buildGroup(eachGroup));
}
return result.isEmpty() ? NO_CHILDREN : result.toArray(new SimpleNode[result.size()]);
}
private List<EditorNode> buildGroup(final ConfigurableGroup eachGroup) {
List<EditorNode> result = new ArrayList<EditorNode>();
final Configurable[] kids = eachGroup.getConfigurables();
if (kids.length > 0) {
for (Configurable eachKid : kids) {
if (!isInvisibleNode(eachKid)) {
result.add(new EditorNode(this, eachKid, eachGroup));
}
}
}
return sort(result);
}
}
private static boolean isInvisibleNode(final Configurable child) {
return child instanceof SearchableConfigurable.Parent && !((SearchableConfigurable.Parent)child).isVisible();
}
private static List<EditorNode> sort(List<EditorNode> c) {
List<EditorNode> cc = new ArrayList<EditorNode>(c);
Collections.sort(cc, new Comparator<EditorNode>() {
public int compare(final EditorNode o1, final EditorNode o2) {
return getConfigurableDisplayName(o1.getConfigurable()).compareToIgnoreCase(getConfigurableDisplayName(o2.getConfigurable()));
}
});
return cc;
}
private static String getConfigurableDisplayName(final Configurable c) {
final String name = c.getDisplayName();
return name != null ? name : "{ Unnamed Page:" + c.getClass().getSimpleName() + " }";
}
private List<EditorNode> buildChildren(final Configurable configurable, SimpleNode parent, final ConfigurableGroup group) {
if (configurable instanceof Configurable.Composite) {
final Configurable[] kids = ((Configurable.Composite)configurable).getConfigurables();
final List<EditorNode> result = new ArrayList<EditorNode>(kids.length);
for (Configurable child : kids) {
result.add(new EditorNode(parent, child, group));
myFilter.myContext.registerKid(configurable, child);
}
return result; // TODO: DECIDE IF INNERS SHOULD BE SORTED: sort(result);
}
else {
return Collections.emptyList();
}
}
private static final EditorNode[] EMPTY_EN_ARRAY = new EditorNode[0];
class EditorNode extends Base {
Configurable myConfigurable;
ConfigurableGroup myGroup;
EditorNode(SimpleNode parent, Configurable configurable, @Nullable ConfigurableGroup group) {
super(parent);
myConfigurable = configurable;
myGroup = group;
myConfigurable2Node.put(configurable, this);
addPlainText(getConfigurableDisplayName(configurable));
}
protected EditorNode[] buildChildren() {
List<EditorNode> list = OptionsTree.this.buildChildren(myConfigurable, this, null);
return list.isEmpty() ? EMPTY_EN_ARRAY : list.toArray(new EditorNode[list.size()]);
}
@Override
public boolean isAlwaysLeaf() {
return !(myConfigurable instanceof Configurable.Composite);
}
@Override
public boolean isContentHighlighted() {
return getParent() == myRoot;
}
@Override
Configurable getConfigurable() {
return myConfigurable;
}
@Override
public int getWeight() {
if (getParent() == myRoot) {
return Integer.MAX_VALUE - myGroups.indexOf(myGroup);
}
else {
return WeightBasedComparator.UNDEFINED_WEIGHT;
}
}
public ConfigurableGroup getGroup() {
return myGroup;
}
@Override
String getText() {
return getConfigurableDisplayName(myConfigurable).replace("\n", " ");
}
@Override
boolean isModified() {
return myFilter.myContext.getModified().contains(myConfigurable);
}
@Override
boolean isError() {
return myFilter.myContext.getErrors().containsKey(myConfigurable);
}
}
public void dispose() {
myQueuedConfigurable = null;
}
public ActionCallback onSelected(final Configurable configurable, final Configurable oldConfigurable) {
return queueSelection(configurable);
}
public ActionCallback onModifiedAdded(final Configurable colleague) {
myTree.repaint();
return ActionCallback.DONE;
}
public ActionCallback onModifiedRemoved(final Configurable configurable) {
myTree.repaint();
return ActionCallback.DONE;
}
public ActionCallback onErrorsChanged() {
return ActionCallback.DONE;
}
public void processTextEvent(KeyEvent e) {
myTree.processKeyEvent(e);
}
private class MyTree extends SimpleTree {
private MyTree() {
getInputMap().clear();
setOpaque(true);
}
@Override
public final String getToolTipText(MouseEvent event) {
if (event != null) {
Point point = event.getPoint();
Component component = getDeepestRendererComponentAt(point.x, point.y);
if (component instanceof JLabel) {
JLabel label = (JLabel)component;
if (label.getIcon() != null) {
String text = label.getToolTipText();
if (text != null) {
return text;
}
}
}
}
return super.getToolTipText(event);
}
@Override
protected boolean paintNodes() {
return false;
}
@Override
protected boolean highlightSingleNode() {
return false;
}
@Override
public void setUI(final TreeUI ui) {
TreeUI actualUI = ui;
if (!(ui instanceof MyTreeUi)) {
actualUI = new MyTreeUi();
}
super.setUI(actualUI);
}
@Override
protected boolean isCustomUI() {
return true;
}
@Override
protected void configureUiHelper(final TreeUIHelper helper) {
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
@Override
public void processKeyEvent(final KeyEvent e) {
TreePath path = myTree.getSelectionPath();
if (path != null) {
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
if (isExpanded(path)) {
collapsePath(path);
return;
}
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
if (isCollapsed(path)) {
expandPath(path);
return;
}
}
}
super.processKeyEvent(e);
}
@Override
protected void processMouseEvent(final MouseEvent e) {
final MyTreeUi ui = (MyTreeUi)myTree.getUI();
final boolean toggleNow =
e.getID() == MouseEvent.MOUSE_RELEASED && UIUtil.isActionClick(e, MouseEvent.MOUSE_RELEASED) && !ui.isToggleEvent(e);
final boolean toggleLater =
e.getID() == MouseEvent.MOUSE_PRESSED;
if (toggleNow || toggleLater) {
final TreePath path = getPathForLocation(e.getX(), e.getY());
if (path != null) {
final Rectangle bounds = getPathBounds(path);
if (bounds != null && path.getLastPathComponent() instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
final boolean selected = isPathSelected(path);
final boolean expanded = isExpanded(path);
final Component comp =
myRenderer.getTreeCellRendererComponent(this, node, selected, expanded, node.isLeaf(), getRowForPath(path), isFocusOwner());
comp.setBounds(bounds);
comp.validate();
Point point = new Point(e.getX() - bounds.x, e.getY() - bounds.y);
if (myRenderer.isUnderHandle(point)) {
if (toggleNow) {
ui.toggleExpandState(path);
e.consume();
return;
} else if (toggleLater) {
e.consume();
return;
}
}
}
}
}
super.processMouseEvent(e);
}
private class MyTreeUi extends BasicTreeUI {
@Override
public void toggleExpandState(final TreePath path) {
super.toggleExpandState(path);
}
@Override
public boolean isToggleEvent(final MouseEvent event) {
return super.isToggleEvent(event);
}
@Override
protected boolean shouldPaintExpandControl(final TreePath path,
final int row,
final boolean isExpanded,
final boolean hasBeenExpanded,
final boolean isLeaf) {
return false;
}
@Override
protected void paintHorizontalPartOfLeg(final Graphics g,
final Rectangle clipBounds,
final Insets insets,
final Rectangle bounds,
final TreePath path,
final int row,
final boolean isExpanded,
final boolean hasBeenExpanded,
final boolean isLeaf) {
}
@Override
protected void paintVerticalPartOfLeg(final Graphics g, final Rectangle clipBounds, final Insets insets, final TreePath path) {
}
@Override
public void paint(Graphics g, JComponent c) {
GraphicsUtil.setupAntialiasing(g);
super.paint(g, c);
}
}
}
private class MyBuilder extends FilteringTreeBuilder {
List<Object> myToExpandOnResetFilter;
boolean myRefilteringNow;
boolean myWasHoldingFilter;
public MyBuilder(SimpleTreeStructure structure) {
super(myTree, myFilter, structure, new WeightBasedComparator(false));
myTree.addTreeExpansionListener(new TreeExpansionListener() {
public void treeExpanded(TreeExpansionEvent event) {
invalidateExpansions();
}
public void treeCollapsed(TreeExpansionEvent event) {
invalidateExpansions();
}
});
}
private void invalidateExpansions() {
if (!myRefilteringNow) {
myToExpandOnResetFilter = null;
}
}
@Override
protected boolean isSelectable(final Object nodeObject) {
return nodeObject instanceof EditorNode;
}
@Override
public boolean isAutoExpandNode(final NodeDescriptor nodeDescriptor) {
return myFilter.myContext.isHoldingFilter();
}
@Override
public boolean isToEnsureSelectionOnFocusGained() {
return false;
}
@Override
protected ActionCallback refilterNow(Object preferredSelection, boolean adjustSelection) {
final List<Object> toRestore = new ArrayList<Object>();
if (myFilter.myContext.isHoldingFilter() && !myWasHoldingFilter && myToExpandOnResetFilter == null) {
myToExpandOnResetFilter = myBuilder.getUi().getExpandedElements();
} else if (!myFilter.myContext.isHoldingFilter() && myWasHoldingFilter && myToExpandOnResetFilter != null) {
toRestore.addAll(myToExpandOnResetFilter);
myToExpandOnResetFilter = null;
}
myWasHoldingFilter = myFilter.myContext.isHoldingFilter();
ActionCallback result = super.refilterNow(preferredSelection, adjustSelection);
myRefilteringNow = true;
return result.doWhenDone(new Runnable() {
public void run() {
myRefilteringNow = false;
if (!myFilter.myContext.isHoldingFilter() && getSelectedElements().isEmpty()) {
restoreExpandedState(toRestore);
}
}
});
}
private void restoreExpandedState(List<Object> toRestore) {
TreePath[] selected = myTree.getSelectionPaths();
if (selected == null) {
selected = new TreePath[0];
}
List<TreePath> toCollapse = new ArrayList<TreePath>();
for (int eachRow = 0; eachRow < myTree.getRowCount(); eachRow++) {
if (!myTree.isExpanded(eachRow)) continue;
TreePath eachVisiblePath = myTree.getPathForRow(eachRow);
if (eachVisiblePath == null) continue;
Object eachElement = myBuilder.getElementFor(eachVisiblePath.getLastPathComponent());
if (toRestore.contains(eachElement)) continue;
for (TreePath eachSelected : selected) {
if (!eachVisiblePath.isDescendant(eachSelected)) {
toCollapse.add(eachVisiblePath);
}
}
}
for (TreePath each : toCollapse) {
myTree.collapsePath(each);
}
}
}
Project getConfigurableProject(Configurable configurable) {
if (configurable instanceof ConfigurableWrapper) {
ConfigurableWrapper wrapper = (ConfigurableWrapper)configurable;
return wrapper.getExtensionPoint().getProject();
}
return getConfigurableProject(myConfigurable2Node.get(configurable));
}
private static Project getConfigurableProject(SimpleNode node) {
if (node == null) {
return null;
}
if (node instanceof EditorNode) {
EditorNode editor = (EditorNode)node;
Configurable configurable = editor.getConfigurable();
if (configurable instanceof ConfigurableWrapper) {
ConfigurableWrapper wrapper = (ConfigurableWrapper)configurable;
return wrapper.getExtensionPoint().getProject();
}
}
return getConfigurableProject(node.getParent());
}
private static final class GroupSeparator extends JLabel {
public static final int SPACE = 10;
public GroupSeparator() {
setFont(UIUtil.getLabelFont());
setFont(getFont().deriveFont(Font.BOLD));
}
public void configure(ConfigurableGroup group, boolean isSpaceNeeded) {
if (group == null) {
setVisible(false);
}
else {
setVisible(true);
int bottom = UIUtil.isUnderNativeMacLookAndFeel() ? 1 : 3;
int top = isSpaceNeeded
? bottom + SPACE
: bottom;
setBorder(BorderFactory.createEmptyBorder(top, 3, bottom, 3));
setText(group.getDisplayName());
}
}
}
private static final class StickySeparator extends JComponent {
private final SimpleTree myTree;
private final JScrollPane myScroller;
private final GroupSeparator mySeparator;
public StickySeparator(SimpleTree tree) {
myTree = tree;
myScroller = ScrollPaneFactory.createScrollPane(myTree);
myScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
mySeparator = new GroupSeparator();
add(myScroller);
}
@Override
public void doLayout() {
myScroller.setBounds(0, 0, getWidth(), getHeight());
}
@Override
public void paint(Graphics g) {
super.paint(g);
if (Registry.is("ide.new.settings.dialog")) {
ConfigurableGroup group = getGroup(GroupSeparator.SPACE + mySeparator.getFont().getSize());
if (group != null && group == getGroup(-GroupSeparator.SPACE)) {
mySeparator.configure(group, false);
Rectangle bounds = myScroller.getViewport().getBounds();
int height = mySeparator.getPreferredSize().height;
if (bounds.height > height) {
bounds.height = height;
}
g.setColor(myTree.getBackground());
if (g instanceof Graphics2D) {
int h = bounds.height / 3;
int y = bounds.y + bounds.height - h;
g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height - h);
((Graphics2D)g).setPaint(UIUtil.getGradientPaint(
0, y, g.getColor(),
0, y + h, ColorUtil.toAlpha(g.getColor(), 0)));
g.fillRect(bounds.x, y, bounds.width, h);
}
else {
g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
}
mySeparator.setSize(bounds.width - 1, bounds.height);
mySeparator.paint(g.create(bounds.x + 1, bounds.y, bounds.width - 1, bounds.height));
}
}
}
private ConfigurableGroup getGroup(int offset) {
TreePath path = myTree.getClosestPathForLocation(-myTree.getX(), -myTree.getY() + offset);
SimpleNode node = myTree.getNodeFor(path);
if (node instanceof FilteringTreeStructure.FilteringNode) {
Object delegate = ((FilteringTreeStructure.FilteringNode)node).getDelegate();
while (delegate instanceof EditorNode) {
EditorNode editor = (EditorNode)delegate;
ConfigurableGroup group = editor.getGroup();
if (group != null) {
return group;
}
delegate = editor.getParent();
}
}
return null;
}
}
}
@@ -39,6 +39,8 @@ import java.util.ArrayList;
* @author Sergey.Malenkov
*/
public class SettingsDialog extends DialogWrapper implements DataProvider {
public static final String DIMENSION_KEY = "SettingsEditor";
private final String myDimensionServiceKey;
private final AbstractEditor myEditor;
private boolean myApplyButtonNeeded;
@@ -64,7 +66,7 @@ public class SettingsDialog extends DialogWrapper implements DataProvider {
public SettingsDialog(@NotNull Project project, @NotNull ConfigurableGroup[] groups, Configurable configurable, String filter) {
super(project, true);
myDimensionServiceKey = "SettingsEditor";
myDimensionServiceKey = DIMENSION_KEY;
myEditor = new SettingsEditor(myDisposable, project, groups, configurable, filter);
myApplyButtonNeeded = true;
init(null, project);
@@ -18,7 +18,6 @@ package com.intellij.openapi.options.newEditor;
import com.intellij.ide.ui.laf.darcula.ui.DarculaTextBorder;
import com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.SearchTextField;
import javax.swing.KeyStroke;
@@ -39,14 +38,12 @@ abstract class SettingsSearch extends SearchTextField implements KeyListener {
super(false);
addKeyListener(new KeyAdapter() {
});
if (Registry.is("ide.new.settings.dialog")) {
if (!SystemInfo.isMac) {
JTextField editor = getTextEditor();
editor.putClientProperty("JTextField.variant", "search");
if (!(editor.getUI() instanceof DarculaTextFieldUI)) {
editor.setUI((DarculaTextFieldUI)DarculaTextFieldUI.createUI(editor));
editor.setBorder(new DarculaTextBorder());
}
if (!SystemInfo.isMac) {
JTextField editor = getTextEditor();
editor.putClientProperty("JTextField.variant", "search");
if (!(editor.getUI() instanceof DarculaTextFieldUI)) {
editor.setUI((DarculaTextFieldUI)DarculaTextFieldUI.createUI(editor));
editor.setBorder(new DarculaTextBorder());
}
}
}
@@ -520,15 +520,10 @@ console.too.much.text.buffer.ratio.description=Used for disabling of console pro
when there is too much of text to process.\n\
The ratio is used against the console cycle buffer size (idea.cycle.buffer.size/theRatio=maxTextLength).
ide.settings.appearance.font.family.only=true
ide.settings.keymap.input.method.enabled=false
ide.settings.configurable.loading.threshold=0
ide.settings.replace.group.with.single.configurable=true
ide.settings.old.style=true
ide.new.settings.view=true
ide.new.settings.view.description=New view for the Settings dialog
ide.new.settings.dialog=true
ide.new.settings.dialog.description=New settings dialog
ide.new.project.settings=true
ide.new.project.settings.description=Temporary key for new project settings dialog UI
@@ -56,7 +56,6 @@ import com.intellij.openapi.project.ProjectManagerAdapter;
import com.intellij.openapi.project.ex.ProjectManagerEx;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.wm.*;
import com.intellij.platform.DirectoryProjectConfigurator;
@@ -154,8 +153,6 @@ public class PyCharmEduInitialConfigurator {
codeInsightSettings.REFORMAT_ON_PASTE = CodeInsightSettings.NO_REFORMAT;
Registry.get("ide.new.settings.dialog").setValue(true);
GeneralSettings.getInstance().setShowTipsOnStartup(false);
EditorSettingsExternalizable.getInstance().setVirtualSpace(false);