public static InputEvent getInputEvent(String actionName) { final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionName); KeyStroke keyStroke = null; for (Shortcut each : shortcuts) { if (each instanceof KeyboardShortcut) { keyStroke = ((KeyboardShortcut) each).getFirstKeyStroke(); if (keyStroke != null) break; } } if (keyStroke != null) { return new KeyEvent( JOptionPane.getRootFrame(), KeyEvent.KEY_PRESSED, System.currentTimeMillis(), keyStroke.getModifiers(), keyStroke.getKeyCode(), keyStroke.getKeyChar(), KeyEvent.KEY_LOCATION_STANDARD); } else { return new MouseEvent( JOptionPane.getRootFrame(), MouseEvent.MOUSE_PRESSED, 0, 0, 0, 0, 1, false, MouseEvent.BUTTON1); } }
/** * Converts a KeyStroke into a string representation for preference storage. * * @param prefsStroke the KeyStroke to convert * @return a string representation of the form "modifiers keyCode" or <code>null</code> * if the prefsStroke is invalid or <code>null</code> */ public static final String strokeToPrefs(KeyStroke prefsStroke) { if (prefsStroke == null) return null; else return String.valueOf(prefsStroke.getModifiers()) + ' ' + String.valueOf(prefsStroke.getKeyCode()); }
/** * This is hack. AWT doesn't allow to create KeyStroke with specified key code and key char * simultaneously. Therefore we are using reflection. */ private static KeyStroke getKeyStrokeWithoutMouseModifiers(KeyStroke originalKeyStroke) { int modifier = originalKeyStroke.getModifiers() & ~InputEvent.BUTTON1_DOWN_MASK & ~InputEvent.BUTTON1_MASK & ~InputEvent.BUTTON2_DOWN_MASK & ~InputEvent.BUTTON2_MASK & ~InputEvent.BUTTON3_DOWN_MASK & ~InputEvent.BUTTON3_MASK; try { Method[] methods = AWTKeyStroke.class.getDeclaredMethods(); Method getCachedStrokeMethod = null; for (Method method : methods) { if (GET_CACHED_STROKE_METHOD_NAME.equals(method.getName())) { getCachedStrokeMethod = method; getCachedStrokeMethod.setAccessible(true); break; } } if (getCachedStrokeMethod == null) { throw new IllegalStateException("not found method with name getCachedStrokeMethod"); } Object[] getCachedStrokeMethodArgs = new Object[] { originalKeyStroke.getKeyChar(), originalKeyStroke.getKeyCode(), modifier, originalKeyStroke.isOnKeyRelease() }; return (KeyStroke) getCachedStrokeMethod.invoke(originalKeyStroke, getCachedStrokeMethodArgs); } catch (Exception exc) { throw new IllegalStateException(exc.getMessage()); } }
public static boolean isDigraphStart(@NotNull KeyStroke key) { if ((key.getModifiers() & KeyEvent.CTRL_MASK) != 0) { if (key.getKeyCode() == KeyEvent.VK_K || key.getKeyCode() == KeyEvent.VK_V || key.getKeyCode() == KeyEvent.VK_Q) { return true; } } return false; }
public static String getKeystrokeText(KeyStroke accelerator) { if (accelerator == null) return ""; if (SystemInfo.isMac) { return MacKeymapUtil.getKeyStrokeText(accelerator); } String acceleratorText = ""; int modifiers = accelerator.getModifiers(); if (modifiers > 0) { acceleratorText = getModifiersText(modifiers); } final int code = accelerator.getKeyCode(); String keyText = SystemInfo.isMac ? MacKeymapUtil.getKeyText(code) : KeyEvent.getKeyText(code); // [vova] this is dirty fix for bug #35092 if (CANCEL_KEY_TEXT.equals(keyText)) { keyText = BREAK_KEY_TEXT; } acceleratorText += keyText; return acceleratorText.trim(); }
private int getMnemonicCharIndex(String text) { final int mnemonicIndex = myPresentation.getDisplayedMnemonicIndex(); if (mnemonicIndex != -1) { return mnemonicIndex; } final ShortcutSet shortcutSet = myAction.getShortcutSet(); final Shortcut[] shortcuts = shortcutSet.getShortcuts(); for (Shortcut shortcut : shortcuts) { if (!(shortcut instanceof KeyboardShortcut)) continue; KeyboardShortcut keyboardShortcut = (KeyboardShortcut) shortcut; if (keyboardShortcut.getSecondKeyStroke() == null) { // we are interested only in "mnemonic-like" shortcuts final KeyStroke keyStroke = keyboardShortcut.getFirstKeyStroke(); final int modifiers = keyStroke.getModifiers(); if (BitUtil.isSet(modifiers, InputEvent.ALT_MASK)) { return (keyStroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) ? text.indexOf(keyStroke.getKeyChar()) : text.indexOf(KeyEvent.getKeyText(keyStroke.getKeyCode())); } } } return -1; }
private static boolean isEnterKeyStroke(KeyStroke keyStroke) { return keyStroke.getKeyCode() == KeyEvent.VK_ENTER && keyStroke.getModifiers() == 0; }
protected ActionCallback _execute(final PlaybackContext context) { final String actionName = getText().substring(PREFIX.length()).trim(); final ActionManager am = ActionManager.getInstance(); final AnAction targetAction = am.getAction(actionName); if (targetAction == null) { dumpError(context, "Unknown action: " + actionName); return new ActionCallback.Rejected(); } if (!context.isUseDirectActionCall()) { final Shortcut[] sc = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionName); KeyStroke stroke = null; for (Shortcut each : sc) { if (each instanceof KeyboardShortcut) { final KeyboardShortcut ks = (KeyboardShortcut) each; final KeyStroke first = ks.getFirstKeyStroke(); final KeyStroke second = ks.getSecondKeyStroke(); if (first != null && second == null) { stroke = KeyStroke.getKeyStroke(first.getKeyCode(), first.getModifiers(), false); break; } } } if (stroke != null) { final ActionCallback result = new TimedOutCallback( Registry.intValue("actionSystem.commandProcessingTimeout"), "Timed out calling action id=" + actionName, new Throwable(), true) { @Override protected void dumpError() { context.error(getMessage(), getLine()); } }; context.message("Invoking action via shortcut: " + stroke.toString(), getLine()); final KeyStroke finalStroke = stroke; IdeFocusManager.getGlobalInstance() .doWhenFocusSettlesDown( new Runnable() { @Override public void run() { final Ref<AnActionListener> listener = new Ref<AnActionListener>(); listener.set( new AnActionListener.Adapter() { @Override public void beforeActionPerformed( final AnAction action, DataContext dataContext, AnActionEvent event) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { if (context.isDisposed()) { am.removeAnActionListener(listener.get()); return; } if (targetAction.equals(action)) { context.message( "Performed action: " + actionName, context.getCurrentLine()); am.removeAnActionListener(listener.get()); result.setDone(); } } }); } }); am.addAnActionListener(listener.get()); context.runPooledThread( new Runnable() { @Override public void run() { type(context.getRobot(), finalStroke); } }); } }); return result; } } final InputEvent input = getInputEvent(actionName); final ActionCallback result = new ActionCallback(); context.getRobot().delay(Registry.intValue("actionSystem.playback.delay")); SwingUtilities.invokeLater( new Runnable() { public void run() { am.tryToExecute(targetAction, input, null, null, false) .doWhenProcessed(result.createSetDoneRunnable()); } }); return result; }
/** * This method is not being used to paint menu item since 6.0 This code left for compatibility * only. Do not use or override it, this will not cause any visible effect. */ public static void paintMenuItem( Graphics g, JComponent c, Icon checkIcon, Icon arrowIcon, Color background, Color foreground, int defaultTextIconGap) { JMenuItem b = (JMenuItem) c; ButtonModel model = b.getModel(); Dimension size = b.getSize(); Insets i = c.getInsets(); Rectangle viewRect = new Rectangle(size); viewRect.x += i.left; viewRect.y += i.top; viewRect.width -= (i.right + viewRect.x); viewRect.height -= (i.bottom + viewRect.y); Rectangle iconRect = new Rectangle(); Rectangle textRect = new Rectangle(); Rectangle acceleratorRect = new Rectangle(); Rectangle checkRect = new Rectangle(); Rectangle arrowRect = new Rectangle(); Font holdf = g.getFont(); Font f = c.getFont(); g.setFont(f); FontMetrics fm = SwingUtilities2.getFontMetrics(c, g, f); FontMetrics fmAccel = SwingUtilities2.getFontMetrics(c, g, UIManager.getFont("MenuItem.acceleratorFont")); if (c.isOpaque()) { if (model.isArmed() || (c instanceof JMenu && model.isSelected())) { g.setColor(background); } else { g.setColor(c.getBackground()); } g.fillRect(0, 0, size.width, size.height); } // get Accelerator text KeyStroke accelerator = b.getAccelerator(); String acceleratorText = ""; if (accelerator != null) { int modifiers = accelerator.getModifiers(); if (modifiers > 0) { acceleratorText = KeyEvent.getKeyModifiersText(modifiers); acceleratorText += "+"; } acceleratorText += KeyEvent.getKeyText(accelerator.getKeyCode()); } // layout the text and icon String text = layoutMenuItem( c, fm, b.getText(), fmAccel, acceleratorText, b.getIcon(), checkIcon, arrowIcon, b.getVerticalAlignment(), b.getHorizontalAlignment(), b.getVerticalTextPosition(), b.getHorizontalTextPosition(), viewRect, iconRect, textRect, acceleratorRect, checkRect, arrowRect, b.getText() == null ? 0 : defaultTextIconGap, defaultTextIconGap); // Paint the Check Color holdc = g.getColor(); if (checkIcon != null) { if (model.isArmed() || (c instanceof JMenu && model.isSelected())) g.setColor(foreground); checkIcon.paintIcon(c, g, checkRect.x, checkRect.y); g.setColor(holdc); } // Paint the Icon if (b.getIcon() != null) { Icon icon; if (!model.isEnabled()) { icon = b.getDisabledIcon(); } else if (model.isPressed() && model.isArmed()) { icon = b.getPressedIcon(); if (icon == null) { // Use default icon icon = b.getIcon(); } } else { icon = b.getIcon(); } if (icon != null) { icon.paintIcon(c, g, iconRect.x, iconRect.y); } } // Draw the Text if (text != null && !text.equals("")) { // Once BasicHTML becomes public, use BasicHTML.propertyKey // instead of the hardcoded string below! View v = (View) c.getClientProperty("html"); if (v != null) { v.paint(g, textRect); } else { int mnemIndex = b.getDisplayedMnemonicIndex(); if (!model.isEnabled()) { // *** paint the text disabled g.setColor(b.getBackground().brighter()); SwingUtilities2.drawStringUnderlineCharAt( b, g, text, mnemIndex, textRect.x, textRect.y + fmAccel.getAscent()); g.setColor(b.getBackground().darker()); SwingUtilities2.drawStringUnderlineCharAt( b, g, text, mnemIndex, textRect.x - 1, textRect.y + fmAccel.getAscent() - 1); } else { // *** paint the text normally if (model.isArmed() || (c instanceof JMenu && model.isSelected())) { g.setColor(foreground); } else { g.setColor(b.getForeground()); } SwingUtilities2.drawStringUnderlineCharAt( b, g, text, mnemIndex, textRect.x, textRect.y + fm.getAscent()); } } } // Draw the Accelerator Text if (acceleratorText != null && !acceleratorText.equals("")) { // Get the maxAccWidth from the parent to calculate the offset. int accOffset = 0; Container parent = b.getParent(); if (parent != null && parent instanceof JComponent) { JComponent p = (JComponent) parent; Integer maxValueInt = (Integer) p.getClientProperty(MotifGraphicsUtils.MAX_ACC_WIDTH); int maxValue = maxValueInt != null ? maxValueInt.intValue() : acceleratorRect.width; // Calculate the offset, with which the accelerator texts will be drawn with. accOffset = maxValue - acceleratorRect.width; } g.setFont(UIManager.getFont("MenuItem.acceleratorFont")); if (!model.isEnabled()) { // *** paint the acceleratorText disabled g.setColor(b.getBackground().brighter()); SwingUtilities2.drawString( c, g, acceleratorText, acceleratorRect.x - accOffset, acceleratorRect.y + fm.getAscent()); g.setColor(b.getBackground().darker()); SwingUtilities2.drawString( c, g, acceleratorText, acceleratorRect.x - accOffset - 1, acceleratorRect.y + fm.getAscent() - 1); } else { // *** paint the acceleratorText normally if (model.isArmed() || (c instanceof JMenu && model.isSelected())) { g.setColor(foreground); } else { g.setColor(b.getForeground()); } SwingUtilities2.drawString( c, g, acceleratorText, acceleratorRect.x - accOffset, acceleratorRect.y + fmAccel.getAscent()); } } // Paint the Arrow if (arrowIcon != null) { if (model.isArmed() || (c instanceof JMenu && model.isSelected())) g.setColor(foreground); if (!(b.getParent() instanceof JMenuBar)) arrowIcon.paintIcon(c, g, arrowRect.x, arrowRect.y); } g.setColor(holdc); g.setFont(holdf); }
public void registerKeyStroke(KeyStroke keyStroke, String description) { String modifiersText = KeyEvent.getKeyModifiersText(keyStroke.getModifiers()); String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode()); keyboardEntries.add( (modifiersText.length() != 0 ? modifiersText + " " : "") + keyText + ": " + description); }
/** * This method fills <code>myActions</code> list. * * @return true if there is a shortcut with second stroke found. */ public KeyProcessorContext updateCurrentContext( Component component, Shortcut sc, boolean isModalContext) { myContext.setFoundComponent(null); myContext.getActions().clear(); if (isControlEnterOnDialog(component, sc)) return myContext; boolean hasSecondStroke = false; // here we try to find "local" shortcuts for (; component != null; component = component.getParent()) { if (!(component instanceof JComponent)) { continue; } ArrayList listOfActions = (ArrayList) ((JComponent) component).getClientProperty(AnAction.ourClientProperty); if (listOfActions == null) { continue; } for (Object listOfAction : listOfActions) { if (!(listOfAction instanceof AnAction)) { continue; } AnAction action = (AnAction) listOfAction; hasSecondStroke |= addAction(action, sc); } // once we've found a proper local shortcut(s), we continue with non-local shortcuts if (!myContext.getActions().isEmpty()) { myContext.setFoundComponent((JComponent) component); break; } } // search in main keymap Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); String[] actionIds = keymap.getActionIds(sc); ActionManager actionManager = ActionManager.getInstance(); for (String actionId : actionIds) { AnAction action = actionManager.getAction(actionId); if (action != null) { if (isModalContext && !action.isEnabledInModalContext()) { continue; } hasSecondStroke |= addAction(action, sc); } } if (!hasSecondStroke && sc instanceof KeyboardShortcut) { // little trick to invoke action which second stroke is a key w/o modifiers, but user still // holds the modifier key(s) of the first stroke final KeyboardShortcut keyboardShortcut = (KeyboardShortcut) sc; final KeyStroke firstKeyStroke = keyboardShortcut.getFirstKeyStroke(); final KeyStroke secondKeyStroke = keyboardShortcut.getSecondKeyStroke(); if (secondKeyStroke != null && secondKeyStroke.getModifiers() != 0 && firstKeyStroke.getModifiers() != 0) { final KeyboardShortcut altShortCut = new KeyboardShortcut( firstKeyStroke, KeyStroke.getKeyStroke(secondKeyStroke.getKeyCode(), 0)); final String[] additionalActions = keymap.getActionIds(altShortCut); for (final String actionId : additionalActions) { AnAction action = actionManager.getAction(actionId); if (action != null) { if (isModalContext && !action.isEnabledInModalContext()) { continue; } hasSecondStroke |= addAction(action, altShortCut); } } } } myContext.setHasSecondStroke(hasSecondStroke); Comparator<? super AnAction> comparator = PlatformDataKeys.ACTIONS_SORTER.getData(myContext.getDataContext()); if (comparator != null) { Collections.sort(myContext.getActions(), comparator); } return myContext; }
@NotNull public DigraphResult processKey(@NotNull KeyStroke key, @NotNull Editor editor) { switch (digraphState) { case DIG_STATE_START: logger.debug("DIG_STATE_START"); if (key.getKeyCode() == KeyEvent.VK_K && (key.getModifiers() & KeyEvent.CTRL_MASK) != 0) { logger.debug("found Ctrl-K"); digraphState = DIG_STATE_DIG_ONE; return DigraphResult.OK; } else if ((key.getKeyCode() == KeyEvent.VK_V || key.getKeyCode() == KeyEvent.VK_Q) && (key.getModifiers() & KeyEvent.CTRL_MASK) != 0) { logger.debug("found Ctrl-V"); digraphState = DIG_STATE_CODE_START; codeChars = new char[8]; codeCnt = 0; return DigraphResult.OK; } else { return new DigraphResult(key); } case DIG_STATE_DIG_ONE: logger.debug("DIG_STATE_DIG_ONE"); if (key.getKeyChar() != KeyEvent.CHAR_UNDEFINED) { digraphChar = key.getKeyChar(); digraphState = DIG_STATE_DIG_TWO; return DigraphResult.OK; } else { digraphState = DIG_STATE_START; return DigraphResult.BAD; } case DIG_STATE_DIG_TWO: logger.debug("DIG_STATE_DIG_TWO"); digraphState = DIG_STATE_START; if (key.getKeyChar() != KeyEvent.CHAR_UNDEFINED) { char ch = VimPlugin.getDigraph().getDigraph(digraphChar, key.getKeyChar()); return new DigraphResult(KeyStroke.getKeyStroke(ch)); } return DigraphResult.BAD; case DIG_STATE_CODE_START: logger.debug("DIG_STATE_CODE_START"); switch (key.getKeyChar()) { case 'o': case 'O': codeMax = 3; digraphState = DIG_STATE_CODE_CHAR; codeType = 8; logger.debug("Octal"); return DigraphResult.OK; case 'x': case 'X': codeMax = 2; digraphState = DIG_STATE_CODE_CHAR; codeType = 16; logger.debug("hex2"); return DigraphResult.OK; case 'u': codeMax = 4; digraphState = DIG_STATE_CODE_CHAR; codeType = 16; logger.debug("hex4"); return DigraphResult.OK; case 'U': codeMax = 8; digraphState = DIG_STATE_CODE_CHAR; codeType = 16; logger.debug("hex8"); return DigraphResult.OK; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': codeMax = 3; digraphState = DIG_STATE_CODE_CHAR; codeType = 10; codeChars[codeCnt++] = key.getKeyChar(); logger.debug("decimal"); return DigraphResult.OK; default: switch (key.getKeyCode()) { case KeyEvent.VK_TAB: KeyStroke code = KeyStroke.getKeyStroke('\t'); digraphState = DIG_STATE_START; return new DigraphResult(code); default: logger.debug("unknown"); digraphState = DIG_STATE_START; return new DigraphResult(key); } } case DIG_STATE_CODE_CHAR: logger.debug("DIG_STATE_CODE_CHAR"); boolean valid = false; switch (codeType) { case 10: if (key.getKeyChar() >= '0' && key.getKeyChar() <= '9') { valid = true; } break; case 8: if (key.getKeyChar() >= '0' && key.getKeyChar() <= '7') { valid = true; } break; case 16: if (key.getKeyChar() >= '0' && key.getKeyChar() <= '9' || key.getKeyChar() >= 'a' && key.getKeyChar() <= 'f' || key.getKeyChar() >= 'A' && key.getKeyChar() <= 'F') { valid = true; } break; } if (valid) { logger.debug("valid"); codeChars[codeCnt++] = key.getKeyChar(); if (codeCnt == codeMax) { String digits = new String(codeChars, 0, codeCnt); int val = Integer.parseInt(digits, codeType); KeyStroke code = KeyStroke.getKeyStroke((char) val); digraphState = DIG_STATE_START; return new DigraphResult(code); } else { return DigraphResult.OK; } } else if (codeCnt > 0) { logger.debug("invalid"); String digits = new String(codeChars, 0, codeCnt); int val = Integer.parseInt(digits, codeType); digraphState = DIG_STATE_START; KeyStroke code = KeyStroke.getKeyStroke((char) val); VimPlugin.getMacro().postKey(key, editor); return new DigraphResult(code); } else { return DigraphResult.BAD; } default: return DigraphResult.BAD; } }