blob: 9d434bdbe0212be63c96566a38730f50285a86f8 [file] [log] [blame]
/*
* Copyright 2000-2013 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.keymap.impl.ui;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.actionSystem.ex.QuickList;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.keymap.KeyMapBundle;
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.JBColor;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
public class KeyboardShortcutDialog extends DialogWrapper {
private StrokePanel myFirstStrokePanel;
private StrokePanel mySecondStrokePanel;
private final JCheckBox myEnableSecondKeystroke;
private final JLabel myKeystrokePreview;
private final JTextArea myConflictInfoArea;
private Keymap myKeymap;
private final String myActionId;
private final Group myMainGroup;
public KeyboardShortcutDialog(Component component, String actionId, final QuickList[] quickLists) {
super(component, true);
setTitle(KeyMapBundle.message("keyboard.shortcut.dialog.title"));
myActionId = actionId;
final Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(component));
myMainGroup = ActionsTreeUtil.createMainGroup(project, myKeymap, quickLists, null, false, null); //without current filter
myEnableSecondKeystroke = new JCheckBox();
UIUtil.applyStyle(UIUtil.ComponentStyle.SMALL, myEnableSecondKeystroke);
myEnableSecondKeystroke.setBorder(new EmptyBorder(4, 0, 0, 2));
myEnableSecondKeystroke.setFocusable(false);
myKeystrokePreview = new JLabel(" ");
myConflictInfoArea = new JTextArea("");
myConflictInfoArea.setFocusable(false);
init();
}
@NotNull
protected Action[] createActions(){
return new Action[]{getOKAction(),getCancelAction(),getHelpAction()};
}
protected JComponent createCenterPanel() {
JPanel panel = new JPanel(new GridBagLayout());
// First stroke
myFirstStrokePanel = new StrokePanel(KeyMapBundle.message("first.stroke.panel.title"));
panel.add(
myFirstStrokePanel,
new GridBagConstraints(0,0,2,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(0,0,0,0),0,0)
);
// Second stroke panel
panel.add(
myEnableSecondKeystroke,
new GridBagConstraints(0,1,1,1,0,0,GridBagConstraints.NORTHWEST,GridBagConstraints.NONE,new Insets(0,0,0,0),0,0)
);
mySecondStrokePanel = new StrokePanel(KeyMapBundle.message("second.stroke.panel.title"));
panel.add(
mySecondStrokePanel,
new GridBagConstraints(1,1,1,1,1,0,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL,new Insets(0,0,0,0),0,0)
);
// Shortcut preview
JPanel previewPanel = new JPanel(new BorderLayout());
previewPanel.setBorder(IdeBorderFactory.createTitledBorder(KeyMapBundle.message("shortcut.preview.ide.border.factory.title"), true));
previewPanel.add(myKeystrokePreview);
panel.add(
previewPanel,
new GridBagConstraints(0,2,2,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(0,0,0,0),0,0)
);
// Conflicts
JPanel conflictsPanel = new JPanel(new BorderLayout());
conflictsPanel.setBorder(IdeBorderFactory.createTitledBorder(KeyMapBundle.message("conflicts.ide.border.factory.title"),
true));
myConflictInfoArea.setEditable(false);
myConflictInfoArea.setBackground(panel.getBackground());
myConflictInfoArea.setLineWrap(true);
myConflictInfoArea.setWrapStyleWord(true);
final JScrollPane conflictInfoScroll = ScrollPaneFactory.createScrollPane(myConflictInfoArea);
conflictInfoScroll.setPreferredSize(new Dimension(260, 60));
conflictInfoScroll.setBorder(null);
conflictsPanel.add(conflictInfoScroll);
panel.add(
conflictsPanel,
new GridBagConstraints(0,3,2,1,1,1,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0)
);
myEnableSecondKeystroke.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleSecondKey();
updateCurrentKeyStrokeInfo();
/** TODO[anton]???? */
if (myEnableSecondKeystroke.isSelected()) {
mySecondStrokePanel.getShortcutTextField().requestFocus();
}
else {
myFirstStrokePanel.getShortcutTextField().requestFocus();
}
}
});
return panel;
}
public JComponent getPreferredFocusedComponent(){
return IdeFocusTraversalPolicy.getPreferredFocusedComponent(myFirstStrokePanel);
}
public void setData(Keymap keymap, KeyboardShortcut shortcut) {
myKeymap = keymap;
myEnableSecondKeystroke.setSelected(false);
if (shortcut != null) {
myFirstStrokePanel.getShortcutTextField().setKeyStroke(shortcut.getFirstKeyStroke());
if (shortcut.getSecondKeyStroke() != null) {
myEnableSecondKeystroke.setSelected(true);
mySecondStrokePanel.getShortcutTextField().setKeyStroke(shortcut.getSecondKeyStroke());
}
}
handleSecondKey();
updateCurrentKeyStrokeInfo();
}
private void updateCurrentKeyStrokeInfo() {
if (myConflictInfoArea == null || myKeystrokePreview == null){
return;
}
myConflictInfoArea.setText(null);
myKeystrokePreview.setText(" ");
if (myKeymap == null){
return;
}
KeyboardShortcut keyboardShortcut = getKeyboardShortcut();
if (keyboardShortcut == null){
return;
}
String strokeText = getTextByKeyStroke(keyboardShortcut.getFirstKeyStroke());
String suffixText = getTextByKeyStroke(keyboardShortcut.getSecondKeyStroke());
if(suffixText != null && suffixText.length() > 0) {
strokeText += ',' + suffixText;
}
myKeystrokePreview.setText(strokeText);
StringBuffer buffer = new StringBuffer();
Map<String, ArrayList<KeyboardShortcut>> conflicts = myKeymap.getConflicts(myActionId, keyboardShortcut);
Set<String> keys = conflicts.keySet();
String[] actionIds = ArrayUtil.toStringArray(keys);
boolean loaded = true;
for (String actionId : actionIds) {
String actionPath = myMainGroup.getActionQualifiedPath(actionId);
if (actionPath == null) {
loaded = false;
}
if (buffer.length() > 1) {
buffer.append('\n');
}
buffer.append('[');
buffer.append(actionPath != null ? actionPath : actionId);
buffer.append(']');
}
if (buffer.length() == 0) {
myConflictInfoArea.setForeground(UIUtil.getTextAreaForeground());
myConflictInfoArea.setText(KeyMapBundle.message("no.conflict.info.message"));
}
else {
myConflictInfoArea.setForeground(JBColor.RED);
if (loaded) {
myConflictInfoArea.setText(KeyMapBundle.message("assigned.to.info.message", buffer.toString()));
} else {
myConflictInfoArea.setText("Assigned to " + buffer.toString() + " which is now not loaded but may be loaded later");
}
}
}
private void handleSecondKey() {
mySecondStrokePanel.setEnabled(myEnableSecondKeystroke.isSelected());
}
public KeyboardShortcut getKeyboardShortcut() {
KeyStroke firstStroke = myFirstStrokePanel.getKeyStroke();
if (firstStroke == null) {
return null;
}
KeyStroke secondStroke = myEnableSecondKeystroke.isSelected() ? mySecondStrokePanel.getKeyStroke() : null;
return new KeyboardShortcut(firstStroke, secondStroke);
}
static String getTextByKeyStroke(KeyStroke keyStroke) {
if(keyStroke == null) {
return "";
}
return KeymapUtil.getKeystrokeText(keyStroke);
}
protected void doHelpAction() {
HelpManager.getInstance().invokeHelp("preferences.keymap.shortcut");
}
private class StrokePanel extends JPanel {
private final ShortcutTextField myShortcutTextField;
public StrokePanel(String borderText) {
setLayout(new BorderLayout());
setBorder(IdeBorderFactory.createTitledBorder(borderText, false));
myShortcutTextField = new ShortcutTextField(){
protected void updateCurrentKeyStrokeInfo() {
KeyboardShortcutDialog.this.updateCurrentKeyStrokeInfo();
}
};
add(myShortcutTextField);
}
public ShortcutTextField getShortcutTextField() {
return myShortcutTextField;
}
public void setEnabled(boolean state) {
myShortcutTextField.setEnabled(state);
repaint();
}
public KeyStroke getKeyStroke() {
return myShortcutTextField.getKeyStroke();
}
}
}