mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Finally remove two generations of settings editing UI
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
-64
@@ -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;
|
||||
}
|
||||
}
|
||||
-556
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-722
@@ -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);
|
||||
}
|
||||
}
|
||||
-101
@@ -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;
|
||||
}
|
||||
}
|
||||
-50
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user