Finally remove two generations of settings editing UI

This commit is contained in:
Maxim Shafirov
2012-05-30 21:45:31 +04:00
parent 470c48ef1c
commit b83dacd894
6 changed files with 5 additions and 1521 deletions
@@ -15,20 +15,21 @@
*/
package com.intellij.ide.actions;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurableGroup;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.options.ex.*;
import com.intellij.openapi.options.ex.ConfigurableExtensionPointUtil;
import com.intellij.openapi.options.ex.IdeConfigurablesGroup;
import com.intellij.openapi.options.ex.ProjectConfigurablesGroup;
import com.intellij.openapi.options.ex.SingleConfigurableEditor;
import com.intellij.openapi.options.newEditor.OptionsEditor;
import com.intellij.openapi.options.newEditor.OptionsEditorDialog;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,8 +42,6 @@ import java.util.List;
*/
public class ShowSettingsUtilImpl extends ShowSettingsUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.ShowSettingsUtilImpl");
@NonNls
private static final String PREFER_CLASSIC_OPTIONS_EDITOR = "PREFER_CLASSIC_OPTIONS_EDITOR";
public void showSettingsDialog(Project project, ConfigurableGroup[] group) {
try {
@@ -56,16 +55,7 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
private static void _showSettingsDialog(final Project project, ConfigurableGroup[] group, Configurable toSelect) {
group = filterEmptyGroups(group);
if ("false".equalsIgnoreCase(System.getProperty("new.options.editor"))) {
if (Boolean.toString(true).equals(PropertiesComponent.getInstance().getValue(PREFER_CLASSIC_OPTIONS_EDITOR))) {
showExplorerOptions(project, group);
}
else {
showControlPanelOptions(project, group, toSelect);
}
} else {
new OptionsEditorDialog(project, group, toSelect).show();
}
new OptionsEditorDialog(project, group, toSelect).show();
}
public void showSettingsDialog(@Nullable final Project project, final Class configurableClass) {
@@ -177,19 +167,6 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
return groups.toArray(new ConfigurableGroup[groups.size()]);
}
public static void showControlPanelOptions(Project project, ConfigurableGroup[] groups, Configurable preselectedConfigurable) {
PropertiesComponent.getInstance().setValue(PREFER_CLASSIC_OPTIONS_EDITOR, Boolean.toString(false));
ControlPanelSettingsEditor editor = new ControlPanelSettingsEditor(project, groups, preselectedConfigurable);
editor.show();
}
public static void showExplorerOptions(Project project, ConfigurableGroup[] group) {
PropertiesComponent.getInstance().setValue(PREFER_CLASSIC_OPTIONS_EDITOR, Boolean.toString(true));
ExplorerSettingsEditor editor = new ExplorerSettingsEditor(project, group);
editor.show();
}
public boolean editConfigurable(Project project, Configurable configurable) {
return editConfigurable(project, createDimensionKey(configurable), configurable);
}
@@ -1,64 +0,0 @@
/*
* Copyright 2000-2009 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.
*/
/**
* @author cdr
*/
package com.intellij.openapi.options.ex;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurableGroup;
import java.awt.event.KeyEvent;
public class ControlPanelMnemonicsUtil {
private ControlPanelMnemonicsUtil() {
}
public static Configurable getConfigurableFromMnemonic(KeyEvent e, ConfigurableGroup[] groups) {
if (e.getModifiers() != 0) return null;
ConfigurableGroup group = getGroupFromKeycode(e.getKeyCode(), groups);
if (group == null) return null;
int idx = getIndexFromKeycode(e.getKeyCode(), group == groups[0]);
if (idx < 0 || idx >= group.getConfigurables().length) return null;
return group.getConfigurables()[idx];
}
public static int getIndexFromKeycode(int keyCode, boolean isNumeric) {
if (isNumeric) {
if (keyCode >= KeyEvent.VK_1 && keyCode <= KeyEvent.VK_9) return keyCode - KeyEvent.VK_1;
if (keyCode >= KeyEvent.VK_NUMPAD1 && keyCode <= KeyEvent.VK_NUMPAD9) return keyCode - KeyEvent.VK_NUMPAD1;
if (keyCode == KeyEvent.VK_NUMPAD0 || keyCode == KeyEvent.VK_0) return 9;
}
else {
if (keyCode >= KeyEvent.VK_A && keyCode <= KeyEvent.VK_Z) return keyCode - KeyEvent.VK_A;
}
return -1;
}
public static ConfigurableGroup getGroupFromKeycode(int keyCode, ConfigurableGroup[] groups) {
if (keyCode >= KeyEvent.VK_0 && keyCode <= KeyEvent.VK_9 ||
keyCode >= KeyEvent.VK_NUMPAD0 && keyCode <= KeyEvent.VK_NUMPAD9) {
return groups[0];
}
if (keyCode >= KeyEvent.VK_A && keyCode <= KeyEvent.VK_Z && groups.length > 1) return groups[1];
return null;
}
}
@@ -1,556 +0,0 @@
/*
* Copyright 2000-2009 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.CommonBundle;
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.actions.ShowSettingsUtilImpl;
import com.intellij.ide.ui.search.DefaultSearchableConfigurable;
import com.intellij.ide.ui.search.SearchUtil;
import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionButtonComponent;
import com.intellij.openapi.actionSystem.ex.ActionButtonLook;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.help.HelpManager;
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.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.LabeledIcon;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.TitledSeparator;
import com.intellij.util.Alarm;
import com.intellij.util.Consumer;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.*;
import java.util.Set;
/**
* Created by IntelliJ IDEA.
* User: max
* Date: Dec 8, 2003
* Time: 9:40:01 PM
* To change this template use Options | File Templates.
*/
public class ControlPanelSettingsEditor extends DialogWrapper {
private static final int ICONS_PER_ROW = 8;
private static final Insets ICON_INSETS = new Insets(2, 2, 2, 2);
protected final Project myProject;
private final ConfigurableGroup[] myGroups;
private JPanel myPanel;
private Configurable myKeypressedConfigurable = null;
private int mySelectedRow = 0;
private int mySelectedColumn = 0;
private int mySelectedGroup = 0;
private Set<Configurable> myOptionContainers = null;
private SearchUtil.ConfigurableSearchTextField mySearchField;
private final Alarm mySearchUpdater = new Alarm();
private final JBPopup[] myPopup = new JBPopup[2];
public ControlPanelSettingsEditor(Project project, ConfigurableGroup[] groups, Configurable preselectedConfigurable) {
super(project, true);
myProject = project;
myGroups = groups;
setTitle(OptionsBundle.message("settings.panel.title"));
setCancelButtonText(CommonBundle.getCloseButtonText());
init();
if (preselectedConfigurable != null) {
selectConfigurable(preselectedConfigurable);
editConfigurable(preselectedConfigurable);
}
}
protected String getDimensionServiceKey() {
return "#com.intellij.openapi.options.ex.ControlPanelSettingsEditor";
}
protected Action[] createActions() {
return new Action[]{getCancelAction()};
}
@NonNls
protected void doHelpAction() {
HelpManager.getInstance().invokeHelp("preferences");
}
protected Action[] createLeftSideActions() {
return new Action[]{new SwitchToClassicViewAction()};
}
protected JComponent createCenterPanel() {
myPanel = new JPanel(new VerticalFlowLayout());
for (int i = 0; i < myGroups.length; i++) {
ConfigurableGroup group = myGroups[i];
myPanel.add(createGroupComponent(group, i));
}
final MyKeyAdapter keyAdapter = new MyKeyAdapter();
myPanel.addKeyListener(keyAdapter);
Disposer.register(myDisposable, new Disposable() {
public void dispose() {
myPanel.removeKeyListener(keyAdapter);
}
});
JPanel panel = new JPanel(new GridBagLayout());
panel.add(myPanel,
new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0));
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(panel);
scrollPane.setBorder(null);
return scrollPane;
}
private void selectConfigurable(Configurable configurable) {
for (int g = 0; g < myGroups.length; g++) {
ConfigurableGroup group = myGroups[g];
Configurable[] allConfigurables = group.getConfigurables();
int count = allConfigurables.length;
int rowCount = getRowCount(count);
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < ICONS_PER_ROW; j++) {
int n = i * ICONS_PER_ROW + j;
if (n < count && configurable == allConfigurables[n]) {
mySelectedGroup = g;
mySelectedRow = i;
mySelectedColumn = j;
return;
}
}
}
}
}
public JComponent getPreferredFocusedComponent() {
return myPanel;
}
private JComponent createGroupComponent(ConfigurableGroup group, int groupIdx) {
JPanel panel = new JPanel(new VerticalFlowLayout());
final TitledSeparator separator = new TitledSeparator();
separator.setText(group.getDisplayName());
separator.setTitleFont(new JLabel().getFont().deriveFont(20.0f));
panel.add(separator);
Configurable[] allConfigurables = group.getConfigurables();
int count = allConfigurables.length;
int rowCount = getRowCount(count);
JPanel toolBar = new JPanel(new GridLayout(0, ICONS_PER_ROW));
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < ICONS_PER_ROW; j++) {
int n = i * ICONS_PER_ROW + j;
if (n < count) {
toolBar.add(createActionButton(allConfigurables[n], getShortcut(n, groupIdx), groupIdx, j, i));
}
}
}
panel.add(toolBar);
panel.add(new JPanel());
return panel;
}
private static int getRowCount(int count) {
return count / ICONS_PER_ROW + (count % ICONS_PER_ROW == 0 ? 0 : 1);
}
private static KeyStroke getShortcut(int actionIdx, int groupIdx) {
int mnemonic = getMnemonicByIndex(actionIdx, groupIdx);
if (mnemonic == 0) return null;
return KeyStroke.getKeyStroke(mnemonic, 0);
}
private static int getMnemonicByIndex(int idx, int groupIdx) {
if (groupIdx == 0) {
if (idx >= 0 && idx < 9) return KeyEvent.VK_1 + idx;
if (idx == 9) return KeyEvent.VK_0;
return 0;
}
if (groupIdx == 1) {
if (idx >= 0 && idx < KeyEvent.VK_Z - KeyEvent.VK_A) return KeyEvent.VK_A + idx;
}
return 0;
}
@Nullable
private Configurable getSelectedConfigurable() {
if (mySelectedColumn == -1 || mySelectedRow == -1 || mySelectedGroup == -1) return null;
final Configurable[] configurables = myGroups[mySelectedGroup].getConfigurables();
final int index = mySelectedColumn + mySelectedRow * ICONS_PER_ROW;
if (index >= configurables.length) return null;
return configurables[index];
}
private JComponent createActionButton(final Configurable configurable,
KeyStroke shortcut,
final int groupIdx,
final int column,
final int row) {
return new MyActionButton(configurable, shortcut, groupIdx, row, column);
}
private void editConfigurable(Configurable configurable) {
Configurable actualConfigurable = configurable;
if (configurable instanceof ProjectComponent) {
actualConfigurable = new ProjectConfigurableWrapper(myProject, configurable);
}
if (actualConfigurable instanceof SearchableConfigurable){
actualConfigurable = new DefaultSearchableConfigurable((SearchableConfigurable)actualConfigurable);
((DefaultSearchableConfigurable)actualConfigurable).clearSearch();
@NonNls final String filter = mySearchField.getText();
if (filter != null && filter.length() > 0 ){
final DefaultSearchableConfigurable finalConfigurable = (DefaultSearchableConfigurable)actualConfigurable;
SwingUtilities.invokeLater(new Runnable (){
public void run() {
finalConfigurable.enableSearch(filter);
}
});
}
}
final SingleConfigurableEditor configurableEditor =
new SingleConfigurableEditor(myProject, actualConfigurable, SingleConfigurableEditor.createDimensionKey(configurable));
configurableEditor.show();
}
public void dispose() {
for (JBPopup popup : myPopup) {
if (popup != null) {
popup.cancel();
}
}
mySearchUpdater.cancelAllRequests();
myOptionContainers = null;
super.dispose();
}
protected JComponent createNorthPanel() {
final Consumer<String> selectConfigurable = new Consumer<String>() {
public void consume(final String configurableId) {
if (myOptionContainers != null) {
for (Configurable configurable : myOptionContainers) {
if (Comparing.strEqual(configurable.getDisplayName(), configurableId)){
editConfigurable(configurable);
return;
}
}
}
}
};
final SearchableOptionsRegistrar optionsRegistrar = SearchableOptionsRegistrar.getInstance();
final JPanel panel = new JPanel(new GridBagLayout());
mySearchField = new SearchUtil.ConfigurableSearchTextField();
final DocumentAdapter docAdapter = new DocumentAdapter() {
protected void textChanged(final DocumentEvent e) {
mySearchUpdater.cancelAllRequests();
mySearchUpdater.addRequest(new Runnable() {
public void run() {
@NonNls final String searchPattern = mySearchField.getText();
if (searchPattern != null && searchPattern.length() > 0) {
myOptionContainers = optionsRegistrar.getConfigurables(myGroups, e.getType(), myOptionContainers, searchPattern,
myProject).getContentHits();
}
else {
myOptionContainers = null;
}
SearchUtil.showHintPopup(mySearchField, myPopup, mySearchUpdater, selectConfigurable, myProject);
myPanel.repaint();
}
}, 300, ModalityState.defaultModalityState());
}
};
mySearchField.addDocumentListener(docAdapter);
Disposer.register(myDisposable, new Disposable() {
public void dispose() {
if (mySearchField != null) {
panel.remove(mySearchField);
mySearchField.removeDocumentListener(docAdapter);
mySearchField = null;
}
}
});
SearchUtil.registerKeyboardNavigation(mySearchField, myPopup, mySearchUpdater, selectConfigurable, myProject);
final GridBagConstraints gc = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0);
panel.add(Box.createHorizontalBox(), gc);
gc.gridx++;
gc.weightx = 0;
gc.fill = GridBagConstraints.NONE;
final JLabel label = new JLabel(IdeBundle.message("search.textfield.title"));
panel.add(label, gc);
label.setLabelFor(mySearchField);
gc.gridx++;
final int height = mySearchField.getPreferredSize().height;
mySearchField.setPreferredSize(new Dimension(100, height));
panel.add(mySearchField, gc);
return panel;
}
private class MyActionButton extends JComponent implements ActionButtonComponent {
private final Configurable myConfigurable;
private final int myGroupIdx;
private final int myRowIdx;
private final int myColumnIdx;
private boolean myIsMouseInside = false;
private final Icon myIcon;
private final KeyStroke myShortcut;
public MyActionButton(Configurable configurable, KeyStroke shortcut, int groupIdx, int rowIdx, int columnIdx) {
myConfigurable = configurable;
myGroupIdx = groupIdx;
myRowIdx = rowIdx;
myColumnIdx = columnIdx;
myShortcut = shortcut;
myIcon = createIcon();
setToolTipText(null);
setupListeners();
}
private Icon createIcon() {
Icon icon = myConfigurable.getIcon();
if (icon == null) {
icon = AllIcons.General.ConfigurableDefault;
}
String displayName = myConfigurable.getDisplayName();
return new LabeledIcon(icon, displayName, myShortcut == null ? null : " (" + KeyEvent.getKeyText(myShortcut.getKeyCode()) + ")");
}
public Dimension getPreferredSize() {
return new Dimension(myIcon.getIconWidth() + ICON_INSETS.left + ICON_INSETS.right,
myIcon.getIconHeight() + ICON_INSETS.top + ICON_INSETS.bottom);
}
protected void paintComponent(Graphics g) {
UIUtil.applyRenderingHints(g);
super.paintComponent(g);
ActionButtonLook look = ActionButtonLook.IDEA_LOOK;
look.paintBackground(g, this);
look.paintIcon(g, this, myIcon);
look.paintBorder(g, this);
}
public int getPopState() {
if (myKeypressedConfigurable == myConfigurable) return myIsMouseInside ? ActionButtonComponent.PUSHED : ActionButtonComponent.POPPED;
if (myKeypressedConfigurable != null) return ActionButtonComponent.NORMAL;
Configurable selectedConfigurable = getSelectedConfigurable();
if (selectedConfigurable == myConfigurable) return ActionButtonComponent.POPPED;
return ActionButtonComponent.NORMAL;
}
private void setupListeners() {
final MouseAdapter mouseAdapter = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
myIsMouseInside = true;
myKeypressedConfigurable = myConfigurable;
myPanel.repaint();
}
public void mouseReleased(MouseEvent e) {
if (myKeypressedConfigurable == myConfigurable && myIsMouseInside) {
myKeypressedConfigurable = null;
editConfigurable(myConfigurable);
}
else {
myKeypressedConfigurable = null;
}
myIsMouseInside = false;
myPanel.repaint();
}
public void mouseEntered(final MouseEvent e) {
myIsMouseInside = true;
myPanel.repaint();
}
public void mouseExited(final MouseEvent e) {
myIsMouseInside = false;
myPanel.repaint();
}
};
addMouseListener(mouseAdapter);
Disposer.register(myDisposable, new Disposable() {
public void dispose() {
removeMouseListener(mouseAdapter);
}
});
final MouseMotionListener motionListener = new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
mySelectedColumn = myColumnIdx;
mySelectedRow = myRowIdx;
mySelectedGroup = myGroupIdx;
myPanel.repaint();
}
};
addMouseMotionListener(motionListener);
Disposer.register(myDisposable, new Disposable() {
public void dispose() {
removeMouseMotionListener(motionListener);
}
});
}
}
private class SwitchToClassicViewAction extends AbstractAction {
public SwitchToClassicViewAction() {
putValue(Action.NAME, OptionsBundle.message("control.panel.classic.view.button"));
}
public void actionPerformed(ActionEvent e) {
close(OK_EXIT_CODE);
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
ShowSettingsUtilImpl.showExplorerOptions(myProject, myGroups);
}
}, ModalityState.NON_MODAL);
}
}
private class MyKeyAdapter extends KeyAdapter {
public void keyPressed(KeyEvent e) {
try {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
myKeypressedConfigurable = getSelectedConfigurable();
return;
}
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP || code == KeyEvent.VK_DOWN || code == KeyEvent.VK_RIGHT ||
code == KeyEvent.VK_LEFT) {
if (getSelectedConfigurable() == null) {
mySelectedColumn = 0;
mySelectedRow = 0;
mySelectedGroup = 0;
return;
}
int xShift = 0;
int yShift = 0;
if (code == KeyEvent.VK_UP) {
yShift = -1;
}
else if (code == KeyEvent.VK_DOWN) {
yShift = 1;
}
else if (code == KeyEvent.VK_LEFT) {
xShift = -1;
}
else /*if (code == KeyEvent.VK_RIGHT)*/ {
xShift = 1;
}
int newColumn = mySelectedColumn + xShift;
int newRow = mySelectedRow + yShift;
int newGroup = mySelectedGroup;
if (newColumn < 0) newColumn = 0;
if (newColumn >= ICONS_PER_ROW) newColumn = ICONS_PER_ROW - 1;
int idx = newColumn + newRow * ICONS_PER_ROW;
if (idx >= myGroups[newGroup].getConfigurables().length) {
if (yShift > 0) {
newRow = 0;
newGroup++;
if (newGroup >= myGroups.length) return;
idx = newColumn + newRow * ICONS_PER_ROW;
if (idx >= myGroups[newGroup].getConfigurables().length) return;
}
else if (xShift > 0) {
return;
}
}
if (yShift < 0 && idx < 0) {
newGroup--;
if (newGroup < 0) return;
int rowCount = getRowCount(myGroups[newGroup].getConfigurables().length);
newRow = rowCount - 1;
idx = newColumn + newRow * ICONS_PER_ROW;
if (idx >= myGroups[newGroup].getConfigurables().length) {
if (newRow <= 0) return;
newRow--;
}
}
mySelectedColumn = newColumn;
mySelectedRow = newRow;
mySelectedGroup = newGroup;
return;
}
myKeypressedConfigurable = ControlPanelMnemonicsUtil.getConfigurableFromMnemonic(e, myGroups);
}
finally {
myPanel.repaint();
}
}
public void keyReleased(KeyEvent e) {
if (myKeypressedConfigurable != null) {
e.consume();
selectConfigurable(myKeypressedConfigurable);
editConfigurable(myKeypressedConfigurable);
myKeypressedConfigurable = null;
myPanel.repaint();
}
}
}
}
@@ -1,722 +0,0 @@
/*
* Copyright 2000-2009 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.CommonBundle;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.actions.ShowSettingsUtilImpl;
import com.intellij.ide.ui.search.DefaultSearchableConfigurable;
import com.intellij.ide.ui.search.SearchUtil;
import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.options.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import gnu.trove.THashMap;
import gnu.trove.TObjectHashingStrategy;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Map;
import java.util.Set;
public class ExplorerSettingsEditor extends DialogWrapper {
/** When you visit the same editor next time you see the same selected configurable. */
private static final TObjectIntHashMap<String> ourGroup2LastConfigurableIndex = new TObjectIntHashMap<String>();
private static String ourLastGroup;
private final Project myProject;
private int myKeySelectedConfigurableIndex;
private final ConfigurableGroup[] myGroups;
/** Configurable which is currently selected. */
private Configurable mySelectedConfigurable;
private ConfigurableGroup mySelectedGroup;
private JPanel myOptionsPanel;
private final Map<Configurable, JComponent> myInitializedConfigurables2Component;
private final Dimension myPreferredSize;
private final Map<Configurable, Dimension> myConfigurable2PrefSize;
private JButton myHelpButton;
private JPanel myComponentPanel;
private SearchUtil.ConfigurableSearchTextField mySearchField;
private Set<Configurable> myOptionContainers = null;
private final Alarm mySearchUpdater = new Alarm();
private JTree myTree;
@NonNls private final DefaultMutableTreeNode myRoot = new DefaultMutableTreeNode("Root");
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.options.ex.ExplorerSettingsEditor");
private final JBPopup [] myPopup = new JBPopup[2];
private static final TObjectHashingStrategy<Configurable> UNWRAPPING_STRATEGY = new TObjectHashingStrategy<Configurable>() {
public int computeHashCode(final Configurable c) {
return unwrap(c).hashCode();
}
public boolean equals(final Configurable c1, final Configurable c2) {
return unwrap(c1) == unwrap(c2);
}
private Configurable unwrap(Configurable c) {
if (c instanceof DefaultSearchableConfigurable) {
return ((DefaultSearchableConfigurable)c).getDelegate();
}
return c;
}
};
public ExplorerSettingsEditor(Project project, ConfigurableGroup[] group) {
super(project, true);
myProject = project;
myPreferredSize = new Dimension(800, 600);
myGroups = group;
if (myGroups.length == 0) {
throw new IllegalStateException("number of configurables must be more then zero");
}
myInitializedConfigurables2Component = new THashMap<Configurable, JComponent>(UNWRAPPING_STRATEGY);
myConfigurable2PrefSize = new THashMap<Configurable, Dimension>(UNWRAPPING_STRATEGY);
init();
}
protected String getDimensionServiceKey() {
return "#com.intellij.openapi.options.ex.ExplorerSettingsEditor";
}
protected final void init() {
super.init();
int lastGroup = 0;
for (int i = 0; i < myGroups.length; i++) {
ConfigurableGroup group = myGroups[i];
if (Comparing.equal(group.getShortName(), ourLastGroup)) {
lastGroup = i;
break;
}
}
selectGroup(lastGroup);
}
private void selectGroup(int groupIdx) {
final String shortName = myGroups[groupIdx].getShortName();
int lastIndex = ourGroup2LastConfigurableIndex.get(shortName);
if (lastIndex == -1) lastIndex = 0;
selectGroup(groupIdx,lastIndex);
}
private void selectGroup(int groupIdx, int indexToSelect) {
rememberLastUsedPage();
mySelectedGroup = myGroups[groupIdx];
ourLastGroup = mySelectedGroup.getShortName();
final DefaultMutableTreeNode groupNode = (DefaultMutableTreeNode)myRoot.getChildAt(groupIdx);
myTree.expandPath(new TreePath(groupNode.getPath()));
TreeUtil.selectNode(myTree, groupNode.getChildAt(indexToSelect));
Configurable[] configurables = mySelectedGroup.getConfigurables();
Configurable toSelect = configurables[indexToSelect];
selectConfigurable(toSelect, indexToSelect);
requestFocusForMainPanel();
}
private void rememberLastUsedPage() {
if (mySelectedGroup != null) {
Configurable[] configurables = mySelectedGroup.getConfigurables();
int index = -1;
for (int i = 0; i < configurables.length; i++) {
Configurable configurable = configurables[i];
if (UNWRAPPING_STRATEGY.equals(configurable, mySelectedConfigurable)) {
index = i;
break;
}
}
ourGroup2LastConfigurableIndex.put(mySelectedGroup.getShortName(), index);
}
}
private void updateTitle() {
if (mySelectedConfigurable == null) {
setTitle(OptionsBundle.message("settings.panel.title"));
}
else {
String displayName = mySelectedConfigurable.getDisplayName();
setTitle(mySelectedGroup.getDisplayName() + " - " + (displayName != null ? displayName.replace('\n', ' ') : ""));
if (myHelpButton != null) {
myHelpButton.setEnabled(mySelectedConfigurable.getHelpTopic() != null);
}
}
}
/**
* @return false if failed
*/
protected boolean apply() {
if (mySelectedConfigurable == null || !mySelectedConfigurable.isModified()) {
return true;
}
try {
mySelectedConfigurable.apply();
return true;
}
catch (ConfigurationException e) {
if (e.getMessage() != null) {
Messages.showMessageDialog(e.getMessage(), e.getTitle(), Messages.getErrorIcon());
}
return false;
}
}
public final void dispose() {
for (JBPopup popup : myPopup) {
if (popup != null) {
popup.cancel();
}
}
mySearchUpdater.cancelAllRequests();
myAlarm.cancelAllRequests();
rememberLastUsedPage();
//do not dispose resources if components weren't initialized
for (Configurable configurable : myInitializedConfigurables2Component.keySet()) {
configurable.disposeUIResources();
}
mySelectedConfigurable = null;
myOptionContainers = null;
myInitializedConfigurables2Component.clear();
super.dispose();
}
public JComponent getPreferredFocusedComponent() {
return myComponentPanel;
}
protected final JComponent createCenterPanel() {
myComponentPanel = new JPanel(new BorderLayout());
// myOptionPanel contains all configurables. When it updates its UI we also need to update
// UIs of all created but not currently visible configurables.
myOptionsPanel = new JPanel(new BorderLayout()) {
public void updateUI() {
super.updateUI();
for (Configurable configurable : myInitializedConfigurables2Component.keySet()) {
if (configurable.equals(mySelectedConfigurable)) { // don't update visible component (optimization)
continue;
}
JComponent component = myInitializedConfigurables2Component.get(configurable);
SwingUtilities.updateComponentTreeUI(component);
}
}
};
initTree();
initToolbar();
final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTree);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
TreeUtil.expandAll(myTree);
final Dimension preferredSize = new Dimension(myTree.getPreferredSize().width + 20,
scrollPane.getPreferredSize().height);
scrollPane.setPreferredSize(preferredSize);
scrollPane.setMinimumSize(preferredSize);
TreeUtil.collapseAll(myTree, 1);
final JPanel leftPane = new JPanel(new BorderLayout());
leftPane.setBorder(BorderFactory.createRaisedBevelBorder());
leftPane.add(scrollPane, BorderLayout.CENTER);
myComponentPanel.add(leftPane, BorderLayout.WEST);
myOptionsPanel.setBorder(BorderFactory.createEmptyBorder(15, 5, 2, 5));
JScrollPane optionsScrollForTinyScreens = ScrollPaneFactory.createScrollPane(myOptionsPanel);
optionsScrollForTinyScreens.setBorder(null);
myComponentPanel.add(optionsScrollForTinyScreens, BorderLayout.CENTER);
optionsScrollForTinyScreens.setPreferredSize(myPreferredSize);
myComponentPanel.setFocusable(true);
final KeyAdapter keyAdapter = new KeyAdapter() {
public void keyPressed(KeyEvent e) {
Configurable[] configurables = mySelectedGroup.getConfigurables();
int index = myKeySelectedConfigurableIndex;
if (index == -1) return;
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP) {
index--;
if (index == -1) {
final int groupIdx = ArrayUtil.find(myGroups, mySelectedGroup);
if (groupIdx > 0) {
selectGroup(groupIdx - 1, myGroups[groupIdx - 1].getConfigurables().length - 1);
return;
}
}
}
else if (keyCode == KeyEvent.VK_DOWN) {
index++;
if (index == configurables.length) {
final int groupIdx = ArrayUtil.find(myGroups, mySelectedGroup);
if (groupIdx < myGroups.length - 1) {
selectGroup(groupIdx + 1, 0);
return;
}
}
}
else {
Configurable configurableFromMnemonic = ControlPanelMnemonicsUtil.getConfigurableFromMnemonic(e, myGroups);
if (configurableFromMnemonic == null) return;
int keyGroupIndex = -1;
ConfigurableGroup keyGroup = null;
int keyIndexInGroup = 0;
for (int i = 0; i < myGroups.length; i++) {
ConfigurableGroup group = myGroups[i];
int ingroupIdx = ArrayUtil.find(group.getConfigurables(), configurableFromMnemonic);
if (ingroupIdx != -1) {
keyGroupIndex = i;
keyGroup = group;
keyIndexInGroup = ingroupIdx;
break;
}
}
if (mySelectedGroup != keyGroup) {
selectGroup(keyGroupIndex, keyIndexInGroup);
return;
}
index = ControlPanelMnemonicsUtil.getIndexFromKeycode(keyCode, mySelectedGroup == myGroups[0]);
}
if (index == -1 || index >= configurables.length) return;
final TreeNode groupNode = myRoot.getChildAt(ArrayUtil.find(myGroups, mySelectedGroup));
TreeUtil.selectPath(myTree, new TreePath(new TreeNode[]{myRoot, groupNode, groupNode.getChildAt(index)}));
}
};
myComponentPanel.addKeyListener(keyAdapter);
Disposer.register(myDisposable, new Disposable() {
public void dispose() {
myComponentPanel.removeKeyListener(keyAdapter);
}
});
return myComponentPanel;
}
private void initTree() {
myTree = new Tree(myRoot){
public Dimension getPreferredScrollableViewportSize() {
Dimension size = super.getPreferredScrollableViewportSize();
size = new Dimension(size.width + 10, size.height);
return size;
}
};
//noinspection NonStaticInitializer
myTree.setCellRenderer(new ColoredTreeCellRenderer() {
{
setFocusBorderAroundIcon(true);
}
public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
if (value instanceof DefaultMutableTreeNode){
Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
if (userObject instanceof Pair){
final Pair configurableWithMnemonics = ((Pair)userObject);
final Configurable configurable = (Configurable)configurableWithMnemonics.first;
setIcon(configurable.getIcon());
append(configurable.getDisplayName().replaceAll("\n", " "), SimpleTextAttributes.REGULAR_ATTRIBUTES);
append(" ( " + configurableWithMnemonics.second + " )", SimpleTextAttributes.GRAYED_ATTRIBUTES);
} else if (userObject instanceof String){
setIcon(null);
append((String)userObject, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
}
}
}
});
myTree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
final Object node = myTree.getLastSelectedPathComponent();
if (node instanceof DefaultMutableTreeNode) {
final DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)node;
final Object userObject = treeNode.getUserObject();
if (userObject instanceof Pair){
final Pair configurableWithMnemonic = (Pair)userObject;
final Configurable configurable = (Configurable)configurableWithMnemonic.first;
final TreeNode[] nodes = treeNode.getPath();
LOG.assertTrue(nodes != null && nodes.length > 0 && nodes[1] != null);
final int groupIdx = myRoot.getIndex(nodes[1]);
selectConfigurableLater(configurable, ArrayUtil.find(myGroups[groupIdx].getConfigurables(), configurable));
rememberLastUsedPage();
mySelectedGroup = myGroups[groupIdx];
ourLastGroup = mySelectedGroup.getShortName();
}
}
}
});
myTree.setRowHeight(32);
TreeUtil.installActions(myTree);
UIUtil.setLineStyleAngled(myTree);
myTree.setShowsRootHandles(true);
myTree.setRootVisible(false);
}
protected JComponent createNorthPanel() {
final Consumer<String> selectConfigurable = new Consumer<String>() {
public void consume(final String configurableId) {
if (myOptionContainers != null) {
for (int groupIdx = 0; groupIdx < myGroups.length; groupIdx++) {
final ConfigurableGroup group = myGroups[groupIdx];
final Configurable[] configurables = group.getConfigurables();
int idx = 0;
for (Configurable configurable : configurables) {
if (myOptionContainers.contains(configurable)) {
if (Comparing.strEqual(configurable.getDisplayName(), configurableId)) {
rememberLastUsedPage();
mySelectedGroup = myGroups[groupIdx];
ourLastGroup = mySelectedGroup.getShortName();
final DefaultMutableTreeNode groupNode = (DefaultMutableTreeNode)myRoot.getChildAt(groupIdx);
myTree.expandPath(new TreePath(groupNode.getPath()));
TreeUtil.selectNode(myTree, groupNode.getChildAt(idx));
selectConfigurable(configurable, idx);
requestFocusForMainPanel();
return;
}
idx++;
}
}
}
}
}
};
final SearchableOptionsRegistrar optionsRegistrar = SearchableOptionsRegistrar.getInstance();
final JPanel panel = new JPanel(new GridBagLayout());
mySearchField = new SearchUtil.ConfigurableSearchTextField();
final DocumentAdapter documentAdapter = new DocumentAdapter() {
protected void textChanged(final DocumentEvent e) {
mySearchUpdater.cancelAllRequests();
mySearchUpdater.addRequest(new Runnable() {
public void run() {
final @NonNls String searchPattern = mySearchField.getText();
if (searchPattern != null && searchPattern.length() > 0) {
myOptionContainers = optionsRegistrar.getConfigurables(myGroups, e.getType(), myOptionContainers, searchPattern, myProject).getContentHits();
}
else {
myOptionContainers = null;
}
SearchUtil.showHintPopup(mySearchField, myPopup, mySearchUpdater, selectConfigurable, myProject);
initToolbar();
TreeUtil.expandAll(myTree);
if (mySelectedConfigurable instanceof SearchableConfigurable) {
selectOption(new DefaultSearchableConfigurable((SearchableConfigurable)mySelectedConfigurable));
}
myComponentPanel.revalidate();
myComponentPanel.repaint();
}
}, 300, ModalityState.defaultModalityState());
}
};
mySearchField.addDocumentListener(documentAdapter);
Disposer.register(myDisposable, new Disposable(){
public void dispose() {
if (mySearchField != null) {
panel.remove(mySearchField);
mySearchField.removeDocumentListener(documentAdapter);
mySearchField = null;
}
}
});
SearchUtil.registerKeyboardNavigation(mySearchField, myPopup, mySearchUpdater, selectConfigurable, myProject);
final GridBagConstraints gc = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0);
panel.add(Box.createHorizontalBox(), gc);
gc.gridx++;
gc.weightx = 0;
gc.fill = GridBagConstraints.NONE;
final JLabel label = new JLabel(IdeBundle.message("search.textfield.title"));
panel.add(label, gc);
label.setLabelFor(mySearchField);
gc.gridx++;
final int height = mySearchField.getPreferredSize().height;
mySearchField.setPreferredSize(new Dimension(100, height));
panel.add(mySearchField, gc);
return panel;
}
private void requestFocusForMainPanel() {
myComponentPanel.requestFocus();
}
private void initToolbar() {
myRoot.removeAllChildren();
char mnemonicStartChar = '1';
for (ConfigurableGroup group : myGroups) {
DefaultMutableTreeNode groupNode = new DefaultMutableTreeNode(group.getDisplayName());
final Configurable[] configurables = group.getConfigurables();
for (int i = 0; i < configurables.length; i++){
Configurable configurable = configurables[i];
if (myOptionContainers == null || myOptionContainers.contains(configurable)) {
groupNode.add(new DefaultMutableTreeNode(Pair.create(configurable, (char)(mnemonicStartChar + i))));
}
}
mnemonicStartChar = 'A';
myRoot.add(groupNode);
}
((DefaultTreeModel)myTree.getModel()).reload();
}
private final Alarm myAlarm = new Alarm();
private void selectConfigurableLater(final Configurable configurable, final int index) {
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
public void run() {
if (isShowing()) {
selectConfigurable(configurable, index);
}
}
}, 400);
myKeySelectedConfigurableIndex = index;
myComponentPanel.repaint();
}
/**
* Selects configurable with specified <code>class</code>. If there is no configurable of <code>class</code>
* then the method does nothing.
*/
private void selectConfigurable(Configurable configurable, int index) {
// If nothing to be selected then clear panel with configurable's options.
if (configurable == null) {
mySelectedConfigurable = null;
myKeySelectedConfigurableIndex = 0;
updateTitle();
myOptionsPanel.removeAll();
validate();
repaint();
return;
}
// Save changes if any
Dimension currentOptionsSize = myOptionsPanel.getSize();
if (mySelectedConfigurable != null && mySelectedConfigurable.isModified()) {
int exitCode = Messages.showYesNoDialog(OptionsBundle.message("options.page.modified.save.message.text"),
OptionsBundle.message("options.save.changes.message.title"),
Messages.getQuestionIcon());
if (exitCode == 0) {
try {
mySelectedConfigurable.apply();
}
catch (ConfigurationException exc) {
if (exc.getMessage() != null) {
Messages.showMessageDialog(exc.getMessage(), exc.getTitle(), Messages.getErrorIcon());
}
return;
}
}
}
if (mySelectedConfigurable != null) {
Dimension savedPrefferedSize = myConfigurable2PrefSize.get(mySelectedConfigurable);
if (savedPrefferedSize != null) {
myConfigurable2PrefSize.put(mySelectedConfigurable, new Dimension(currentOptionsSize));
}
}
// Show new configurable
myComponentPanel.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
myOptionsPanel.removeAll();
mySelectedConfigurable = configurable;
myKeySelectedConfigurableIndex = index;
if (configurable instanceof SearchableConfigurable){
configurable = new DefaultSearchableConfigurable((SearchableConfigurable)configurable);
}
JComponent component = myInitializedConfigurables2Component.get(configurable);
if (component == null) {
component = configurable.createComponent();
myInitializedConfigurables2Component.put(configurable, component);
}
Dimension compPrefSize;
if (myConfigurable2PrefSize.containsKey(configurable)) {
compPrefSize = myConfigurable2PrefSize.get(configurable);
}
else {
compPrefSize = component.getPreferredSize();
myConfigurable2PrefSize.put(configurable, compPrefSize);
}
int widthDelta = Math.max(compPrefSize.width - currentOptionsSize.width, 0);
int heightDelta = Math.max(compPrefSize.height - currentOptionsSize.height, 0);
myOptionsPanel.add(component, BorderLayout.CENTER);
if (widthDelta > 0 || heightDelta > 0) {
setSize(getSize().width + widthDelta, getSize().height + heightDelta);
// centerRelativeToParent();
}
configurable.reset();
updateTitle();
validate();
repaint();
requestFocusForMainPanel();
myComponentPanel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
if (configurable instanceof DefaultSearchableConfigurable){
selectOption((DefaultSearchableConfigurable)configurable);
}
}
private void selectOption(final DefaultSearchableConfigurable searchableConfigurable) {
searchableConfigurable.clearSearch();
if (myOptionContainers == null || myOptionContainers.isEmpty()) return; //do not highlight current editor when nothing can be selected
@NonNls final String filter = mySearchField.getText();
if (filter != null && filter.length() > 0 ){
searchableConfigurable.enableSearch(filter);
}
}
protected final Action[] createActions() {
return new Action[]{getOKAction(), getCancelAction(), new ApplyAction(), getHelpAction()};
}
protected JButton createJButtonForAction(Action action) {
JButton button = super.createJButtonForAction(action);
if (action == getHelpAction()) {
myHelpButton = button;
}
return button;
}
protected Action[] createLeftSideActions() {
return new Action[]{new SwitchToDefaultViewAction()};
}
protected final void doOKAction() {
boolean ok = apply();
if (ok) {
super.doOKAction();
}
}
protected final void doHelpAction() {
if (mySelectedConfigurable != null) {
String helpTopic = mySelectedConfigurable.getHelpTopic();
if (helpTopic != null) {
HelpManager.getInstance().invokeHelp(helpTopic);
}
}
}
private final class ApplyAction extends AbstractAction {
private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
public ApplyAction() {
super(OptionsBundle.message("options.apply.button"));
final Runnable updateRequest = new Runnable() {
public void run() {
if (!isShowing()) return;
setEnabled(mySelectedConfigurable != null && mySelectedConfigurable.isModified());
addUpdateRequest(this);
}
};
addUpdateRequest(updateRequest);
}
private void addUpdateRequest(final Runnable updateRequest) {
myUpdateAlarm.addRequest(updateRequest, 500, ModalityState.stateForComponent(getWindow()));
}
public void actionPerformed(ActionEvent e) {
if (myPerformAction) return;
myPerformAction = true;
try {
if (apply()) {
setCancelButtonText(CommonBundle.getCloseButtonText());
}
}
finally {
myPerformAction = false;
}
}
}
private class SwitchToDefaultViewAction extends AbstractAction {
public SwitchToDefaultViewAction() {
putValue(Action.NAME, OptionsBundle.message("explorer.panel.default.view.button"));
}
public void actionPerformed(ActionEvent e) {
switchToDefaultView(mySelectedConfigurable);
}
}
private void switchToDefaultView(final Configurable preselectedConfigurable) {
if (preselectedConfigurable != null) {
preselectedConfigurable.disposeUIResources();
}
close(OK_EXIT_CODE);
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
ShowSettingsUtilImpl.showControlPanelOptions(myProject, myGroups, null);
}
}, ModalityState.NON_MODAL);
}
}
@@ -1,101 +0,0 @@
/*
* Copyright 2000-2009 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.ConfigurationException;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
/**
* @author max
*/
public class ProjectConfigurableWrapper implements SearchableConfigurable {
private final Project myProject;
private final Configurable myDelegate;
public ProjectConfigurableWrapper(Project project, Configurable delegate) {
myProject = project;
myDelegate = delegate;
}
public String getDisplayName() {
return myDelegate.getDisplayName();
}
public void reset() {
myDelegate.reset();
}
public void apply() throws ConfigurationException {
checkProjectFileWritable();
myDelegate.apply();
}
private void checkProjectFileWritable() {
String path = myProject.getPresentableUrl();
if (path != null) {
File file = new File(path);
if (file.exists() && !file.canWrite()) {
Messages.showMessageDialog(
myProject,
OptionsBundle.message("project.file.read.only.error.message"),
OptionsBundle.message("cannot.save.settings.default.dialog.title"),
Messages.getErrorIcon()
);
}
}
}
public String getHelpTopic() {
return myDelegate.getHelpTopic();
}
public void disposeUIResources() {
myDelegate.disposeUIResources();
}
public boolean isModified() {
return myDelegate.isModified();
}
public JComponent createComponent() {
return myDelegate.createComponent();
}
public Icon getIcon() {
return myDelegate.getIcon();
}
@NotNull
@NonNls
public String getId() {
return myDelegate instanceof SearchableConfigurable ? ((SearchableConfigurable)myDelegate).getId() : "";
}
@Nullable
public Runnable enableSearch(String option) {
return myDelegate instanceof SearchableConfigurable ? ((SearchableConfigurable)myDelegate).enableSearch(option) : null;
}
}
@@ -1,50 +0,0 @@
/*
* Copyright 2000-2009 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.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Toggleable;
import com.intellij.openapi.ui.ShadowAction;
public class ShowSearchFieldAction extends AnAction implements Toggleable {
private final ShadowAction myShadow;
private final OptionsEditor myEditor;
public ShowSearchFieldAction(OptionsEditor editor) {
myEditor = editor;
myShadow = new ShadowAction(this, ActionManager.getInstance().getAction("Find"), editor);
}
@Override
public void update(final AnActionEvent e) {
super.update(e);
e.getPresentation().setIcon(AllIcons.Actions.Find);
e.getPresentation().putClientProperty(SELECTED_PROPERTY, myEditor.isFilterFieldVisible());
}
public void actionPerformed(final AnActionEvent e) {
if (myEditor.getContext().isHoldingFilter()) {
myEditor.setFilterFieldVisible(true, true, true);
} else {
myEditor.setFilterFieldVisible(!myEditor.isFilterFieldVisible(), true, true);
}
}
}