forked from extern/Unexpected-Keyboard
7a3312fd01
This replaces the "disable accent keys" checkbox. The default should work for anyone: Accents will be hidden unless the user has the french language installed. The value "show every accents" is useful for versions of android that don't have subtypes.
253 lines
7.8 KiB
Java
253 lines
7.8 KiB
Java
package juloo.keyboard2;
|
|
|
|
import android.content.Context;
|
|
import android.content.res.Configuration;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.graphics.Typeface;
|
|
import android.inputmethodservice.InputMethodService;
|
|
import android.os.Bundle;
|
|
import android.os.IBinder;
|
|
import android.text.InputType;
|
|
import android.preference.PreferenceManager;
|
|
import android.view.inputmethod.EditorInfo;
|
|
import android.view.inputmethod.InputMethodInfo;
|
|
import android.view.inputmethod.InputMethodManager;
|
|
import android.view.inputmethod.InputMethodSubtype;
|
|
import android.view.KeyEvent;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.util.Log;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
|
|
public class Keyboard2 extends InputMethodService
|
|
implements SharedPreferences.OnSharedPreferenceChangeListener
|
|
{
|
|
private Keyboard2View _keyboardView;
|
|
private int _currentTextLayout;
|
|
private ViewGroup _emojiPane = null;
|
|
private Typeface _specialKeyFont = null;
|
|
|
|
private Config _config;
|
|
|
|
private Map<Integer, KeyboardData> _layoutCache = new HashMap<Integer, KeyboardData>();
|
|
|
|
private KeyboardData getLayout(int resId)
|
|
{
|
|
KeyboardData l = _layoutCache.get(resId);
|
|
if (l == null)
|
|
{
|
|
l = KeyboardData.parse(getResources().getXml(resId));
|
|
_layoutCache.put(resId, l);
|
|
}
|
|
return l;
|
|
}
|
|
|
|
@Override
|
|
public void onCreate()
|
|
{
|
|
super.onCreate();
|
|
_specialKeyFont = Typeface.createFromAsset(getAssets(), "fonts/keys.ttf");
|
|
PreferenceManager.setDefaultValues(this, R.xml.settings, false);
|
|
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
|
|
_config = new Config(this);
|
|
_keyboardView = (Keyboard2View)getLayoutInflater().inflate(R.layout.keyboard, null);
|
|
_keyboardView.reset();
|
|
}
|
|
|
|
public Config getConfig()
|
|
{
|
|
return (_config);
|
|
}
|
|
|
|
public Typeface getSpecialKeyFont()
|
|
{
|
|
return (_specialKeyFont);
|
|
}
|
|
|
|
private List<InputMethodSubtype> getEnabledSubtypes(InputMethodManager imm)
|
|
{
|
|
String pkg = getPackageName();
|
|
for (InputMethodInfo imi : imm.getEnabledInputMethodList())
|
|
if (imi.getPackageName().equals(pkg))
|
|
return imm.getEnabledInputMethodSubtypeList(imi, true);
|
|
return null;
|
|
}
|
|
|
|
private void refreshSubtypeLayout(InputMethodSubtype subtype)
|
|
{
|
|
if (_config.layout == -1)
|
|
_currentTextLayout = Config.layoutId_of_string(subtype.getExtraValueOf("default_layout"));
|
|
else
|
|
_currentTextLayout = _config.layout;
|
|
}
|
|
|
|
private int accents_of_subtype(InputMethodSubtype subtype)
|
|
{
|
|
String accents_option = subtype.getExtraValueOf("accents");
|
|
int flags = 0;
|
|
if (accents_option != null)
|
|
for (String acc : accents_option.split("\\|"))
|
|
flags |= Config.accentFlag_of_name(acc);
|
|
return flags;
|
|
}
|
|
|
|
private void refreshAccentsOption(InputMethodManager imm, InputMethodSubtype subtype)
|
|
{
|
|
final int DONT_REMOVE = KeyValue.FLAG_ACCENT_SUPERSCRIPT | KeyValue.FLAG_ACCENT_SUBSCRIPT;
|
|
int to_keep = DONT_REMOVE;
|
|
switch (_config.accents)
|
|
{
|
|
case 1:
|
|
to_keep |= accents_of_subtype(subtype);
|
|
for (InputMethodSubtype s : getEnabledSubtypes(imm))
|
|
to_keep |= accents_of_subtype(s);
|
|
break;
|
|
case 2: to_keep |= accents_of_subtype(subtype); break;
|
|
case 3: to_keep = KeyValue.FLAGS_ACCENTS; break;
|
|
case 4: break;
|
|
default: throw new IllegalArgumentException();
|
|
}
|
|
_config.accent_flags_to_remove = ~to_keep & KeyValue.FLAGS_ACCENTS;
|
|
}
|
|
|
|
private void refreshSubtypeImm()
|
|
{
|
|
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
|
|
_config.shouldOfferSwitchingToNextInputMethod = imm.shouldOfferSwitchingToNextInputMethod(getConnectionToken());
|
|
InputMethodSubtype subtype = imm.getCurrentInputMethodSubtype();
|
|
refreshSubtypeLayout(subtype);
|
|
refreshAccentsOption(imm, subtype);
|
|
}
|
|
|
|
@Override
|
|
public View onCreateInputView()
|
|
{
|
|
ViewGroup parent = (ViewGroup)_keyboardView.getParent();
|
|
|
|
if (parent != null)
|
|
parent.removeView(_keyboardView);
|
|
return (_keyboardView);
|
|
}
|
|
|
|
@Override
|
|
public void onStartInputView(EditorInfo info, boolean restarting)
|
|
{
|
|
refreshSubtypeImm();
|
|
if ((info.inputType & InputType.TYPE_CLASS_NUMBER) != 0)
|
|
_keyboardView.setKeyboard(getLayout(R.xml.numeric));
|
|
else
|
|
_keyboardView.setKeyboard(getLayout(_currentTextLayout));
|
|
_keyboardView.reset(); // Layout might need to change due to rotation
|
|
}
|
|
|
|
@Override
|
|
public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype)
|
|
{
|
|
refreshSubtypeImm();
|
|
_keyboardView.setKeyboard(getLayout(_currentTextLayout));
|
|
}
|
|
|
|
@Override
|
|
public void onFinishInputView(boolean finishingInput)
|
|
{
|
|
super.onFinishInputView(finishingInput);
|
|
_keyboardView.reset();
|
|
}
|
|
|
|
@Override
|
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
|
|
{
|
|
_config.refresh();
|
|
refreshSubtypeImm();
|
|
_keyboardView.refreshConfig(_config, getLayout(_currentTextLayout));
|
|
}
|
|
|
|
@Override
|
|
public void onConfigurationChanged(Configuration newConfig)
|
|
{
|
|
_keyboardView.reset();
|
|
}
|
|
|
|
public void handleKeyUp(KeyValue key, int flags)
|
|
{
|
|
if (getCurrentInputConnection() == null)
|
|
return ;
|
|
key = KeyModifier.handleFlags(key, flags);
|
|
if (key.eventCode == KeyValue.EVENT_CONFIG)
|
|
{
|
|
Intent intent = new Intent(this, SettingsActivity.class);
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
startActivity(intent);
|
|
}
|
|
else if (key.eventCode == KeyValue.EVENT_SWITCH_TEXT)
|
|
_keyboardView.setKeyboard(getLayout(_currentTextLayout));
|
|
else if (key.eventCode == KeyValue.EVENT_SWITCH_NUMERIC)
|
|
_keyboardView.setKeyboard(getLayout(R.xml.numeric));
|
|
else if (key.eventCode == KeyValue.EVENT_SWITCH_EMOJI)
|
|
{
|
|
if (_emojiPane == null)
|
|
_emojiPane = (ViewGroup)getLayoutInflater().inflate(R.layout.emoji_pane, null);
|
|
setInputView(_emojiPane);
|
|
}
|
|
else if (key.eventCode == KeyValue.EVENT_SWITCH_BACK_EMOJI)
|
|
setInputView(_keyboardView);
|
|
else if (key.eventCode == KeyValue.EVENT_CHANGE_METHOD)
|
|
{
|
|
InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
|
|
imm.switchToNextInputMethod(getConnectionToken(), false);
|
|
}
|
|
else if ((flags & (KeyValue.FLAG_CTRL | KeyValue.FLAG_ALT)) != 0)
|
|
handleMetaKeyUp(key, flags);
|
|
// else if (eventCode == KeyEvent.KEYCODE_DEL)
|
|
// handleDelKey(1, 0);
|
|
// else if (eventCode == KeyEvent.KEYCODE_FORWARD_DEL)
|
|
// handleDelKey(0, 1);
|
|
else if (key.char_ == KeyValue.CHAR_NONE)
|
|
{
|
|
if (key.eventCode != KeyValue.EVENT_NONE)
|
|
handleMetaKeyUp(key, flags);
|
|
else
|
|
getCurrentInputConnection().commitText(key.symbol, 1);
|
|
}
|
|
else
|
|
sendKeyChar(key.char_);
|
|
}
|
|
|
|
// private void handleDelKey(int before, int after)
|
|
// {
|
|
// CharSequence selection = getCurrentInputConnection().getSelectedText(0);
|
|
|
|
// if (selection != null && selection.length() > 0)
|
|
// getCurrentInputConnection().commitText("", 1);
|
|
// else
|
|
// getCurrentInputConnection().deleteSurroundingText(before, after);
|
|
// }
|
|
|
|
private void handleMetaKeyUp(KeyValue key, int flags)
|
|
{
|
|
int metaState = 0;
|
|
KeyEvent event;
|
|
|
|
if (key.eventCode == KeyValue.EVENT_NONE)
|
|
return ;
|
|
if ((flags & KeyValue.FLAG_CTRL) != 0)
|
|
metaState |= KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON;
|
|
if ((flags & KeyValue.FLAG_ALT) != 0)
|
|
metaState |= KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_ON;
|
|
if ((flags & KeyValue.FLAG_SHIFT) != 0)
|
|
metaState |= KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON;
|
|
event = new KeyEvent(1, 1, KeyEvent.ACTION_DOWN, key.eventCode, 1, metaState);
|
|
getCurrentInputConnection().sendKeyEvent(event);
|
|
getCurrentInputConnection().sendKeyEvent(KeyEvent.changeAction(event, KeyEvent.ACTION_UP));
|
|
}
|
|
|
|
private IBinder getConnectionToken()
|
|
{
|
|
return getWindow().getWindow().getAttributes().token;
|
|
}
|
|
}
|