/* * Copyright 2015 Igor Maznitsa. * * 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.igormaznitsa.mindmap.swing.panel.utils; import java.awt.event.KeyEvent; import java.util.Locale; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.swing.KeyStroke; public final class KeyShortcut { private final String id; private final int modifiers; private final int keyCode; public static final int ALL_MODIFIERS_MASK = KeyEvent.SHIFT_MASK | KeyEvent.CTRL_MASK | KeyEvent.ALT_MASK | KeyEvent.META_MASK; public KeyShortcut(@Nonnull final String packed) { final String[] split = packed.split("\\*"); this.id = split[0]; final long code = Long.parseLong(split[1], 16); this.keyCode = (int) (code >>> 32); this.modifiers = (int) code; } public boolean isCtrl() { return (this.modifiers & KeyEvent.CTRL_MASK) != 0; } public boolean isAlt() { return (this.modifiers & KeyEvent.ALT_MASK) != 0; } public boolean isShift() { return (this.modifiers & KeyEvent.SHIFT_MASK) != 0; } public boolean isMeta() { return (this.modifiers & KeyEvent.META_MASK) != 0; } public KeyShortcut(@Nonnull final String id, final int keyCode, final int modifiers) { if (id.contains("*")) { throw new IllegalArgumentException("ID can't contain '*'"); } this.id = id; this.modifiers = modifiers; this.keyCode = keyCode; } /** * Get modifiers used by the shortcut. * * @return the modifier flags * @see KeyEvent#CTRL_MASK * @see KeyEvent#SHIFT_MASK * @see KeyEvent#ALT_MASK * @see KeyEvent#META_MASK */ public int getModifiers() { return this.modifiers; } /** * Get the key code used by the shortcut. * * @return the key code * @see KeyEvent */ public int getKeyCode() { return this.keyCode; } @Nonnull public String getID() { return this.id; } public boolean isEvent(@Nonnull final KeyEvent event){ return this.isEvent(event, ALL_MODIFIERS_MASK); } public boolean isEvent(@Nonnull final KeyEvent event, final int modifiersPlayingRole) { final int code = event.getKeyCode() == 0 ? getKeyCode(event.getKeyChar()) : event.getKeyCode(); return code == this.keyCode && (event.getModifiers() & modifiersPlayingRole) == (this.modifiers & modifiersPlayingRole); } private int getKeyCode(char keyChar) { final int result; switch (keyChar) { // Character '+' is 0x2b but VK_PLUS is 0x0209 case '+': { result = KeyEvent.VK_PLUS; } break; default: { result = keyChar; } } return result; } @Override public int hashCode() { return this.modifiers ^ this.keyCode; } @Override public boolean equals(@Nullable final Object object) { if (object == this) { return true; } if (object instanceof KeyShortcut) { final KeyShortcut that = (KeyShortcut) object; return this.id.equals(that.id) && this.keyCode == that.keyCode && this.modifiers == that.modifiers; } return false; } @Nonnull public String packToString() { final long packed = ((long) this.keyCode << 32) | ((long) this.modifiers & 0xFFFFFFFFL); return this.id + '*' + Long.toHexString(packed).toUpperCase(Locale.ENGLISH); } @Override @Nonnull public String toString() { final String modifierText = KeyEvent.getKeyModifiersText(this.modifiers); final String keyText = KeyEvent.getKeyText(this.keyCode); final StringBuilder builder = new StringBuilder(); builder.append(keyText); if (!modifierText.isEmpty()) { builder.append('+').append(modifierText); } return builder.toString(); } public boolean doesConflictWith(@Nullable final KeyStroke stroke) { boolean result = false; if (stroke != null) { result = stroke.getKeyCode() == this.keyCode && (this.modifiers & stroke.getModifiers())==this.modifiers; } return result; } @Nonnull public String getKeyCodeName() { return KeyEvent.getKeyText(this.keyCode); } }