@Nullable public static KeyStroke getKeyStroke(@NotNull final ShortcutSet shortcutSet) { final Shortcut[] shortcuts = shortcutSet.getShortcuts(); if (shortcuts.length == 0 || !(shortcuts[0] instanceof KeyboardShortcut)) return null; final KeyboardShortcut shortcut = (KeyboardShortcut) shortcuts[0]; if (shortcut.getSecondKeyStroke() != null) { return null; } return shortcut.getFirstKeyStroke(); }
private ArrayList<Pair<AnAction, KeyStroke>> getSecondKeystrokeActions() { ArrayList<Pair<AnAction, KeyStroke>> secondKeyStrokes = new ArrayList<Pair<AnAction, KeyStroke>>(); for (AnAction action : myContext.getActions()) { Shortcut[] shortcuts = action.getShortcutSet().getShortcuts(); for (Shortcut shortcut : shortcuts) { if (shortcut instanceof KeyboardShortcut) { KeyboardShortcut keyShortcut = (KeyboardShortcut) shortcut; if (keyShortcut.getFirstKeyStroke().equals(myFirstKeyStroke)) { secondKeyStrokes.add( new Pair<AnAction, KeyStroke>(action, keyShortcut.getSecondKeyStroke())); } } } } return secondKeyStrokes; }
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; }
public static String getShortcutText(@NotNull Shortcut shortcut) { String s = ""; if (shortcut instanceof KeyboardShortcut) { KeyboardShortcut keyboardShortcut = (KeyboardShortcut) shortcut; String acceleratorText = getKeystrokeText(keyboardShortcut.getFirstKeyStroke()); if (!acceleratorText.isEmpty()) { s = acceleratorText; } acceleratorText = getKeystrokeText(keyboardShortcut.getSecondKeyStroke()); if (!acceleratorText.isEmpty()) { s += ", " + acceleratorText; } } else if (shortcut instanceof MouseShortcut) { MouseShortcut mouseShortcut = (MouseShortcut) shortcut; s = getMouseShortcutText( mouseShortcut.getButton(), mouseShortcut.getModifiers(), mouseShortcut.getClickCount()); } else if (shortcut instanceof KeyboardModifierGestureShortcut) { final KeyboardModifierGestureShortcut gestureShortcut = (KeyboardModifierGestureShortcut) shortcut; s = gestureShortcut.getType() == KeyboardGestureAction.ModifierType.dblClick ? "Press, release and hold " : "Hold "; s += getKeystrokeText(gestureShortcut.getStroke()); } else { throw new IllegalArgumentException( "unknown shortcut class: " + shortcut.getClass().getCanonicalName()); } return s; }
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; }
@NotNull private JBPopup createUsagePopup( @NotNull final List<Usage> usages, @NotNull final UsageInfoToUsageConverter.TargetElementsDescriptor descriptor, @NotNull Set<UsageNode> visibleNodes, @NotNull final FindUsagesHandler handler, final Editor editor, @NotNull final RelativePoint popupPosition, final int maxUsages, @NotNull final UsageViewImpl usageView, @NotNull final FindUsagesOptions options, @NotNull final JTable table, @NotNull final UsageViewPresentation presentation, @NotNull final AsyncProcessIcon processIcon, boolean hadMoreSeparator) { table.setRowHeight(PlatformIcons.CLASS_ICON.getIconHeight() + 2); table.setShowGrid(false); table.setShowVerticalLines(false); table.setShowHorizontalLines(false); table.setTableHeader(null); table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); table.setIntercellSpacing(new Dimension(0, 0)); PopupChooserBuilder builder = new PopupChooserBuilder(table); final String title = presentation.getTabText(); if (title != null) { String result = getFullTitle(usages, title, hadMoreSeparator, visibleNodes.size() - 1, true); builder.setTitle(result); builder.setAdText(getSecondInvocationTitle(options, handler)); } builder.setMovable(true).setResizable(true); builder.setItemChoosenCallback( new Runnable() { @Override public void run() { int[] selected = table.getSelectedRows(); for (int i : selected) { Object value = table.getValueAt(i, 0); if (value instanceof UsageNode) { Usage usage = ((UsageNode) value).getUsage(); if (usage == MORE_USAGES_SEPARATOR) { appendMoreUsages(editor, popupPosition, handler, maxUsages); return; } navigateAndHint(usage, null, handler, popupPosition, maxUsages, options); } } } }); final JBPopup[] popup = new JBPopup[1]; KeyboardShortcut shortcut = UsageViewImpl.getShowUsagesWithSettingsShortcut(); if (shortcut != null) { new DumbAwareAction() { @Override public void actionPerformed(AnActionEvent e) { popup[0].cancel(); showDialogAndFindUsages(handler, popupPosition, editor, maxUsages); } }.registerCustomShortcutSet(new CustomShortcutSet(shortcut.getFirstKeyStroke()), table); } shortcut = getShowUsagesShortcut(); if (shortcut != null) { new DumbAwareAction() { @Override public void actionPerformed(AnActionEvent e) { popup[0].cancel(); searchEverywhere(options, handler, editor, popupPosition, maxUsages); } }.registerCustomShortcutSet(new CustomShortcutSet(shortcut.getFirstKeyStroke()), table); } InplaceButton settingsButton = createSettingsButton( handler, popupPosition, editor, maxUsages, new Runnable() { @Override public void run() { popup[0].cancel(); } }); ActiveComponent spinningProgress = new ActiveComponent() { @Override public void setActive(boolean active) {} @Override public JComponent getComponent() { return processIcon; } }; builder.setCommandButton(new CompositeActiveComponent(spinningProgress, settingsButton)); DefaultActionGroup toolbar = new DefaultActionGroup(); usageView.addFilteringActions(toolbar); toolbar.add(UsageGroupingRuleProviderImpl.createGroupByFileStructureAction(usageView)); toolbar.add( new AnAction( "Open Find Usages Toolwindow", "Show all usages in a separate toolwindow", AllIcons.Toolwindows.ToolWindowFind) { { AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_USAGES); setShortcutSet(action.getShortcutSet()); } @Override public void actionPerformed(AnActionEvent e) { hideHints(); popup[0].cancel(); FindUsagesManager findUsagesManager = ((FindManagerImpl) FindManager.getInstance(usageView.getProject())) .getFindUsagesManager(); findUsagesManager.findUsages( handler.getPrimaryElements(), handler.getSecondaryElements(), handler, options, FindSettings.getInstance().isSkipResultsWithOneUsage()); } }); ActionToolbar actionToolbar = ActionManager.getInstance() .createActionToolbar(ActionPlaces.USAGE_VIEW_TOOLBAR, toolbar, true); actionToolbar.setReservePlaceAutoPopupIcon(false); final JComponent toolBar = actionToolbar.getComponent(); toolBar.setOpaque(false); builder.setSettingButton(toolBar); popup[0] = builder.createPopup(); JComponent content = popup[0].getContent(); myWidth = (int) (toolBar.getPreferredSize().getWidth() + new JLabel( getFullTitle( usages, title, hadMoreSeparator, visibleNodes.size() - 1, true)) .getPreferredSize() .getWidth() + settingsButton.getPreferredSize().getWidth()); myWidth = -1; for (AnAction action : toolbar.getChildren(null)) { action.unregisterCustomShortcutSet(usageView.getComponent()); action.registerCustomShortcutSet(action.getShortcutSet(), content); } return popup[0]; }
/** * 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; }