All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sikuli.basics.HotkeyManager Maven / Gradle / Ivy

There is a newer version: 2.0.5
Show newest version
/*
 * Copyright 2010-2014, Sikuli.org, sikulix.com
 * Released under the MIT License.
 *
 * modified RaiMan 2014
 */
package org.sikuli.basics;

import java.awt.event.KeyEvent;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import org.sikuli.basics.Debug;
import org.sikuli.basics.PreferencesUser;
import org.sikuli.basics.Settings;
import org.sikuli.script.Key;
import org.sikuli.script.Key;

/**
 * Singleton class to bind hotkeys to hotkey listeners
 */
public abstract class HotkeyManager {

  private static HotkeyManager _instance = null;
  private static Map hotkeys;
  private static Map hotkeysGlobal = new HashMap();
  private static final String HotkeyTypeCapture = "Capture";
  private static int HotkeyTypeCaptureKey;
  private static int HotkeyTypeCaptureMod;
  private static final String HotkeyTypeAbort = "Abort";
  private static int HotkeyTypeAbortKey;
  private static int HotkeyTypeAbortMod;

  public static HotkeyManager getInstance() {
    if (_instance == null) {
      /* uncomment for debugging puposes
       if (Settings.isWindows()) {
       _instance = new WindowsHotkeyManager();
       } else if (Settings.isMac()) {
       _instance = new MacHotkeyManager();
       } else if (Settings.isLinux()) {
       _instance = new LinuxHotkeyManager();
       }
       return _instance;
       */
      String cls = getOSHotkeyManagerClass();
      if (cls != null) {
        try {
          Class c = Class.forName(cls);
          Constructor constr = c.getConstructor();
          _instance = (HotkeyManager) constr.newInstance();
        } catch (Exception e) {
          Debug.error("HotkeyManager: Can't create " + cls + ": " + e.getMessage());
        }
      }
      hotkeys = new HashMap();
    }
    return _instance;
  }

  /**
   * remove all hotkeys
   */
  public static void reset() {
    if (_instance == null || hotkeys.isEmpty()) {
      return;
    }
    Debug.log(3, "HotkeyManager: reset - removing all defined hotkeys.");
    boolean res;
    int[] hk = new int[hotkeys.size()];
    int i = 0;
    for (Integer k : hotkeys.keySet()) {
      res = _instance._removeHotkey(k, hotkeys.get(k));
      if (!res) {
        Debug.error("HotkeyManager: reset: failed to remove hotkey: %s %s",
                getKeyModifierText(hotkeys.get(k)), getKeyCodeText(k));
        hk[i++] = -1;
      } else {
        hk[i++] = k;
        Debug.log(3, "removed (%d, %d)" , k, hotkeys.get(k));
      }
    }
    for (int k : hk) {
      if (k == -1) {
        continue;
      }
      hotkeys.remove(k);
    }
  }

  private static String getOSHotkeyManagerClass() {
    String pkg = "org.sikuli.basics.";
    int theOS = Settings.getOS();
    switch (theOS) {
      case Settings.ISMAC:
        return pkg + "MacHotkeyManager";
      case Settings.ISWINDOWS:
        return pkg + "WindowsHotkeyManager";
      case Settings.ISLINUX:
        return pkg + "LinuxHotkeyManager";
      default:
        Debug.error("HotkeyManager: Hotkey registration is not supported on your OS.");
    }
    return null;
  }

  private static String getKeyCodeText(int key) {
    return KeyEvent.getKeyText(key).toUpperCase();
  }

  private static String getKeyModifierText(int modifiers) {
    String txtMod = KeyEvent.getKeyModifiersText(modifiers).toUpperCase();
    if (Settings.isMac()) {
      txtMod = txtMod.replace("META", "CMD");
      txtMod = txtMod.replace("WINDOWS", "CMD");
    } else {
      txtMod = txtMod.replace("META", "WIN");
      txtMod = txtMod.replace("WINDOWS", "WIN");
    }
    return txtMod;
  }

  /**
   * install a hotkey listener for a global hotkey (capture, abort, ...)
   * @param hotkeyType a type string
   * @param callback HotkeyListener
   * @return success
   */
  public boolean addHotkey(String hotkeyType, HotkeyListener callback) {
    PreferencesUser pref = PreferencesUser.getInstance();
    if (hotkeyType == HotkeyTypeCapture) {
      HotkeyTypeCaptureKey = pref.getCaptureHotkey();
      HotkeyTypeCaptureMod = pref.getCaptureHotkeyModifiers();
      return installHotkey(HotkeyTypeCaptureKey, HotkeyTypeCaptureMod, callback, hotkeyType);
    } else if (hotkeyType == HotkeyTypeAbort) {
      HotkeyTypeAbortKey = pref.getStopHotkey();
      HotkeyTypeAbortMod = pref.getStopHotkeyModifiers();
      return installHotkey(HotkeyTypeAbortKey, HotkeyTypeAbortMod, callback, hotkeyType);
    } else {
      Debug.error("HotkeyManager: addHotkey: HotkeyType %s not supported", hotkeyType);
      return false;
    }
  }

  public String getHotKeyText(String hotkeyType) {
    PreferencesUser pref = PreferencesUser.getInstance();
    String key = "";
    String mod = "";
    if (hotkeyType == HotkeyTypeCapture) {
      key = getKeyCodeText(pref.getCaptureHotkey());
      mod = getKeyModifierText(pref.getCaptureHotkeyModifiers());
    } else if (hotkeyType == HotkeyTypeAbort) {
      key = getKeyCodeText(pref.getStopHotkey());
      mod = getKeyModifierText(pref.getStopHotkeyModifiers());
    } else {
      Debug.error("HotkeyManager: getHotKeyText: HotkeyType %s not supported", hotkeyType);
    }
    return mod + " " + key;
  }

  /**
   * install a hotkey listener.
   *
   * @param key key character (class Key)
   * @param modifiers modifiers flag
   * @param callback HotkeyListener
   * @return true if success. false otherwise.
   */
  public boolean addHotkey(char key, int modifiers, HotkeyListener callback) {
    return addHotkey("" + key, modifiers, callback);
  }

  /**
   * install a hotkey listener.
   *
   * @param key key character (class Key)
   * @param modifiers modifiers flag
   * @param callback HotkeyListener
   * @return true if success. false otherwise.
   */
  public boolean addHotkey(String key, int modifiers, HotkeyListener callback) {
    int[] keyCodes = Key.toJavaKeyCode(key.toLowerCase());
    int keyCode = keyCodes[0];
    return installHotkey(keyCode, modifiers, callback, "");
  }

  private boolean installHotkey(int key, int mod, HotkeyListener callback, String hotkeyType) {
    boolean res;
    String txtMod = getKeyModifierText(mod);
    String txtCode = getKeyCodeText(key);
    Debug.info("HotkeyManager: add %s Hotkey: %s %s (%d, %d)" , hotkeyType, txtMod, txtCode, key, mod);
    boolean checkGlobal = true;
    for (Integer k : hotkeys.keySet()) {
      if (k == key && mod == hotkeys.get(key)) {
        res = _instance._removeHotkey(key, hotkeys.get(key));
        if (!res) {
          Debug.error("HotkeyManager: addHotkey: failed to remove already defined hotkey");
          return false;
        } else {
          checkGlobal = false;
        }
      }
    }
    if (checkGlobal) {
      for (Integer kg : hotkeysGlobal.keySet()) {
        if (kg == key && mod == hotkeysGlobal.get(key)) {
          Debug.error("HotkeyManager: addHotkey: ignored: trying to redefine a global hotkey");
          return false;
        }
      }
    }
    res = _instance._addHotkey(key, mod, callback);
    if (res) {
      if (hotkeyType.isEmpty()) {
        hotkeys.put(key, mod);
      } else {
        hotkeysGlobal.put(key, mod);
      }
    } else {
      Debug.error("HotkeyManager: addHotkey: failed");
    }
    return res;
  }

	/**
	 * remove a hotkey by type (not supported yet)
	 * @param hotkeyType capture, abort, ...
	 * @return success
	 */
	public boolean removeHotkey(String hotkeyType) {
    if (hotkeyType == HotkeyTypeCapture) {
      return uninstallHotkey(HotkeyTypeCaptureKey, HotkeyTypeCaptureMod, hotkeyType);
    } else if (hotkeyType == HotkeyTypeAbort) {
      return uninstallHotkey(HotkeyTypeAbortKey, HotkeyTypeAbortMod, hotkeyType);
    } else {
      Debug.error("HotkeyManager: removeHotkey: using HotkeyType as %s not supported yet", hotkeyType);
      return false;
    }
  }

  /**
   * remove a hotkey and uninstall a hotkey listener.
   *
   * @param key key character (class Key)
   * @param modifiers modifiers flag
   * @return true if success. false otherwise.
   */
  public boolean removeHotkey(char key, int modifiers) {
    return removeHotkey("" + key, modifiers);
  }

  /**
   * uninstall a hotkey listener.
   *
   * @param key key string (class Key)
   * @param modifiers modifiers flag
   * @return true if success. false otherwise.
   */
  public boolean removeHotkey(String key, int modifiers) {
    int[] keyCodes = Key.toJavaKeyCode(key.toLowerCase());
    int keyCode = keyCodes[0];
    return uninstallHotkey(keyCode, modifiers, "");
  }

  private boolean uninstallHotkey(int key, int mod, String hotkeyType) {
    boolean res;
    String txtMod = getKeyModifierText(mod);
    String txtCode = getKeyCodeText(key);
    Debug.info("HotkeyManager: remove %s Hotkey: %s %s (%d, %d)" , hotkeyType, txtMod, txtCode, key, mod);
    res = _instance._removeHotkey(key, mod);
    if (res) {
      hotkeys.remove(key);
    } else {
      Debug.error("HotkeyManager: removeHotkey: failed");
    }
    return res;
  }

  abstract public boolean _addHotkey(int keyCode, int modifiers, HotkeyListener callback);

  abstract public boolean _removeHotkey(int keyCode, int modifiers);

  abstract public void cleanUp();
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy