Support imeOptions condition in <case>
Change-Id: Ie5494601efb29cf65363c4aa3bf5a9ab04a0109a
This commit is contained in:
parent
59c9930ca9
commit
6624fd8736
5 changed files with 124 additions and 102 deletions
|
@ -155,6 +155,17 @@
|
||||||
<attr name="hasSettingsKey" format="string" />
|
<attr name="hasSettingsKey" format="string" />
|
||||||
<attr name="voiceKeyEnabled" format="string" />
|
<attr name="voiceKeyEnabled" format="string" />
|
||||||
<attr name="hasVoiceKey" format="string" />
|
<attr name="hasVoiceKey" format="string" />
|
||||||
|
<attr name="imeOptions">
|
||||||
|
<!-- This should be aligned with EditorInfo.IME_ACTION_* -->
|
||||||
|
<flag name="actionUnspecified" value="0" />
|
||||||
|
<flag name="actionNone" value="1" />
|
||||||
|
<flag name="actionGo" value="2" />
|
||||||
|
<flag name="actionSearch" value="3" />
|
||||||
|
<flag name="actionSend" value="4" />
|
||||||
|
<flag name="actionNext" value="5" />
|
||||||
|
<flag name="actionDone" value="6" />
|
||||||
|
<flag name="actionPrevious" value="7" />
|
||||||
|
</attr>
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
<declare-styleable name="BaseKeyboard_KeyStyle">
|
<declare-styleable name="BaseKeyboard_KeyStyle">
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
<merge
|
<merge
|
||||||
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
|
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
|
||||||
>
|
>
|
||||||
|
<!-- Functional key styles -->
|
||||||
<switch>
|
<switch>
|
||||||
<case
|
<case
|
||||||
latin:colorScheme="white"
|
latin:colorScheme="white"
|
||||||
|
@ -83,12 +84,6 @@
|
||||||
latin:keyIcon="@drawable/sym_keyboard_tab"
|
latin:keyIcon="@drawable/sym_keyboard_tab"
|
||||||
latin:iconPreview="@drawable/sym_keyboard_feedback_tab"
|
latin:iconPreview="@drawable/sym_keyboard_feedback_tab"
|
||||||
latin:parentStyle="functionalKeyStyle" />
|
latin:parentStyle="functionalKeyStyle" />
|
||||||
<key-style
|
|
||||||
latin:styleName="returnKeyStyle"
|
|
||||||
latin:codes="@integer/key_return"
|
|
||||||
latin:keyIcon="@drawable/sym_keyboard_return"
|
|
||||||
latin:iconPreview="@drawable/sym_keyboard_feedback_return"
|
|
||||||
latin:parentStyle="functionalKeyStyle" />
|
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="micKeyStyle"
|
latin:styleName="micKeyStyle"
|
||||||
latin:codes="@integer/key_voice"
|
latin:codes="@integer/key_voice"
|
||||||
|
@ -165,12 +160,6 @@
|
||||||
latin:keyIcon="@drawable/sym_bkeyboard_tab"
|
latin:keyIcon="@drawable/sym_bkeyboard_tab"
|
||||||
latin:iconPreview="@drawable/sym_keyboard_feedback_tab"
|
latin:iconPreview="@drawable/sym_keyboard_feedback_tab"
|
||||||
latin:parentStyle="functionalKeyStyle" />
|
latin:parentStyle="functionalKeyStyle" />
|
||||||
<key-style
|
|
||||||
latin:styleName="returnKeyStyle"
|
|
||||||
latin:codes="@integer/key_return"
|
|
||||||
latin:keyIcon="@drawable/sym_bkeyboard_return"
|
|
||||||
latin:iconPreview="@drawable/sym_keyboard_feedback_return"
|
|
||||||
latin:parentStyle="functionalKeyStyle" />
|
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="micKeyStyle"
|
latin:styleName="micKeyStyle"
|
||||||
latin:codes="@integer/key_voice"
|
latin:codes="@integer/key_voice"
|
||||||
|
@ -188,6 +177,95 @@
|
||||||
latin:iconPreview="@drawable/sym_keyboard_feedback_tab" />
|
latin:iconPreview="@drawable/sym_keyboard_feedback_tab" />
|
||||||
</case>
|
</case>
|
||||||
</switch>
|
</switch>
|
||||||
|
<!-- Return key style -->
|
||||||
|
<switch>
|
||||||
|
<case
|
||||||
|
latin:imeOptions="actionGo"
|
||||||
|
>
|
||||||
|
<key-style
|
||||||
|
latin:styleName="returnKeyStyle"
|
||||||
|
latin:codes="@integer/key_return"
|
||||||
|
latin:keyLabel="@string/label_go_key"
|
||||||
|
latin:parentStyle="functionalKeyStyle" />
|
||||||
|
</case>
|
||||||
|
<case
|
||||||
|
latin:imeOptions="actionNext"
|
||||||
|
>
|
||||||
|
<key-style
|
||||||
|
latin:styleName="returnKeyStyle"
|
||||||
|
latin:codes="@integer/key_return"
|
||||||
|
latin:keyLabel="@string/label_next_key"
|
||||||
|
latin:parentStyle="functionalKeyStyle" />
|
||||||
|
</case>
|
||||||
|
<case
|
||||||
|
latin:imeOptions="actionDone"
|
||||||
|
>
|
||||||
|
<key-style
|
||||||
|
latin:styleName="returnKeyStyle"
|
||||||
|
latin:codes="@integer/key_return"
|
||||||
|
latin:keyLabel="@string/label_done_key"
|
||||||
|
latin:parentStyle="functionalKeyStyle" />
|
||||||
|
</case>
|
||||||
|
<case
|
||||||
|
latin:imeOptions="actionSend"
|
||||||
|
>
|
||||||
|
<key-style
|
||||||
|
latin:styleName="returnKeyStyle"
|
||||||
|
latin:codes="@integer/key_return"
|
||||||
|
latin:keyLabel="@string/label_send_key"
|
||||||
|
latin:parentStyle="functionalKeyStyle" />
|
||||||
|
</case>
|
||||||
|
<case
|
||||||
|
latin:imeOptions="actionSearch"
|
||||||
|
>
|
||||||
|
<switch>
|
||||||
|
<case
|
||||||
|
latin:colorScheme="white"
|
||||||
|
>
|
||||||
|
<key-style
|
||||||
|
latin:styleName="returnKeyStyle"
|
||||||
|
latin:codes="@integer/key_return"
|
||||||
|
latin:keyIcon="@drawable/sym_keyboard_search"
|
||||||
|
latin:iconPreview="@drawable/sym_keyboard_feedback_search"
|
||||||
|
latin:parentStyle="functionalKeyStyle" />
|
||||||
|
</case>
|
||||||
|
<case
|
||||||
|
latin:colorScheme="black"
|
||||||
|
>
|
||||||
|
<key-style
|
||||||
|
latin:styleName="returnKeyStyle"
|
||||||
|
latin:codes="@integer/key_return"
|
||||||
|
latin:keyIcon="@drawable/sym_bkeyboard_search"
|
||||||
|
latin:iconPreview="@drawable/sym_keyboard_feedback_search"
|
||||||
|
latin:parentStyle="functionalKeyStyle" />
|
||||||
|
</case>
|
||||||
|
</switch>
|
||||||
|
</case>
|
||||||
|
<default>
|
||||||
|
<switch>
|
||||||
|
<case
|
||||||
|
latin:colorScheme="white"
|
||||||
|
>
|
||||||
|
<key-style
|
||||||
|
latin:styleName="returnKeyStyle"
|
||||||
|
latin:codes="@integer/key_return"
|
||||||
|
latin:keyIcon="@drawable/sym_keyboard_return"
|
||||||
|
latin:iconPreview="@drawable/sym_keyboard_feedback_return"
|
||||||
|
latin:parentStyle="functionalKeyStyle" />
|
||||||
|
</case>
|
||||||
|
<case
|
||||||
|
latin:colorScheme="black"
|
||||||
|
>
|
||||||
|
<key-style
|
||||||
|
latin:styleName="returnKeyStyle"
|
||||||
|
latin:codes="@integer/key_return"
|
||||||
|
latin:keyIcon="@drawable/sym_bkeyboard_return"
|
||||||
|
latin:iconPreview="@drawable/sym_keyboard_feedback_return"
|
||||||
|
latin:parentStyle="functionalKeyStyle" />
|
||||||
|
</case>
|
||||||
|
</switch>
|
||||||
|
</default>
|
||||||
|
</switch>
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="toAlphaKeyStyle"
|
latin:styleName="toAlphaKeyStyle"
|
||||||
latin:codes="@integer/key_switch_alpha_symbol"
|
latin:codes="@integer/key_switch_alpha_symbol"
|
||||||
|
|
|
@ -407,23 +407,27 @@ public class BaseKeyboardParser {
|
||||||
R.styleable.BaseKeyboard_Case_hasVoiceKey, id.mHasVoiceKey);
|
R.styleable.BaseKeyboard_Case_hasVoiceKey, id.mHasVoiceKey);
|
||||||
final boolean colorSchemeMatched = matchInteger(viewAttr,
|
final boolean colorSchemeMatched = matchInteger(viewAttr,
|
||||||
R.styleable.BaseKeyboardView_colorScheme, id.mColorScheme);
|
R.styleable.BaseKeyboardView_colorScheme, id.mColorScheme);
|
||||||
|
// As noted at KeyboardSwitcher.KeyboardId class, we are interested only in
|
||||||
final boolean selected = modeMatched && settingsKeyMatched
|
// enum value masked by IME_MASK_ACTION and IME_FLAG_NO_ENTER_ACTION. So matching
|
||||||
&& voiceEnabledMatched && voiceKeyMatched && colorSchemeMatched;
|
// this attribute with id.mImeOptions as integer value is enough for our purpose.
|
||||||
|
final boolean imeOptionsMatched = matchInteger(a,
|
||||||
|
R.styleable.BaseKeyboard_Case_imeOptions, id.mImeOptions);
|
||||||
|
final boolean selected = modeMatched && settingsKeyMatched && voiceEnabledMatched
|
||||||
|
&& voiceKeyMatched && colorSchemeMatched && imeOptionsMatched;
|
||||||
|
|
||||||
if (DEBUG_TAG) {
|
if (DEBUG_TAG) {
|
||||||
Log.d(TAG, "parseCaseCondition: " + Boolean.toString(selected).toUpperCase()
|
Log.d(TAG, String.format(
|
||||||
+ debugInteger(a,
|
"parseCaseCondition: %s%s%s%s%s%s%s",
|
||||||
R.styleable.BaseKeyboard_Case_mode, "mode")
|
Boolean.toString(selected).toUpperCase(),
|
||||||
+ debugBoolean(a,
|
debugInteger(a, R.styleable.BaseKeyboard_Case_mode, "mode"),
|
||||||
R.styleable.BaseKeyboard_Case_hasSettingsKey, "hasSettingsKey")
|
debugBoolean(a, R.styleable.BaseKeyboard_Case_hasSettingsKey,
|
||||||
+ debugBoolean(a,
|
"hasSettingsKey"),
|
||||||
R.styleable.BaseKeyboard_Case_voiceKeyEnabled, "voiceKeyEnabled")
|
debugBoolean(a, R.styleable.BaseKeyboard_Case_voiceKeyEnabled,
|
||||||
+ debugBoolean(a,
|
"voiceKeyEnabled"),
|
||||||
R.styleable.BaseKeyboard_Case_hasVoiceKey, "hasVoiceKey")
|
debugBoolean(a, R.styleable.BaseKeyboard_Case_hasVoiceKey, "hasVoiceKey"),
|
||||||
+ debugInteger(viewAttr,
|
debugInteger(viewAttr, R.styleable.BaseKeyboardView_colorScheme,
|
||||||
R.styleable.BaseKeyboardView_colorScheme, "colorScheme")
|
"colorScheme"),
|
||||||
);
|
debugInteger(a, R.styleable.BaseKeyboard_Case_imeOptions, "imeOptions")));
|
||||||
}
|
}
|
||||||
|
|
||||||
return selected;
|
return selected;
|
||||||
|
|
|
@ -22,6 +22,7 @@ import android.content.res.Resources;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.InflateException;
|
import android.view.InflateException;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
|
||||||
import java.lang.ref.SoftReference;
|
import java.lang.ref.SoftReference;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -165,7 +166,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
this.mHasSettingsKey = hasSettingsKey;
|
this.mHasSettingsKey = hasSettingsKey;
|
||||||
this.mVoiceKeyEnabled = voiceKeyEnabled;
|
this.mVoiceKeyEnabled = voiceKeyEnabled;
|
||||||
this.mHasVoiceKey = hasVoiceKey;
|
this.mHasVoiceKey = hasVoiceKey;
|
||||||
this.mImeOptions = imeOptions;
|
// We are interested only in IME_MASK_ACTION enum value and IME_FLAG_NO_ENTER_ACTION.
|
||||||
|
this.mImeOptions = imeOptions
|
||||||
|
& (EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION);
|
||||||
this.mEnableShiftLock = enableShiftLock;
|
this.mEnableShiftLock = enableShiftLock;
|
||||||
|
|
||||||
this.mHashCode = Arrays.hashCode(new Object[] {
|
this.mHashCode = Arrays.hashCode(new Object[] {
|
||||||
|
@ -301,7 +304,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
mSubtypeSwitcher.getInputLocale());
|
mSubtypeSwitcher.getInputLocale());
|
||||||
|
|
||||||
keyboard = new LatinKeyboard(mInputMethodService, id);
|
keyboard = new LatinKeyboard(mInputMethodService, id);
|
||||||
keyboard.setImeOptions(res, id.mMode, id.mImeOptions);
|
|
||||||
|
|
||||||
if (id.mEnableShiftLock) {
|
if (id.mEnableShiftLock) {
|
||||||
keyboard.enableShiftLock();
|
keyboard.enableShiftLock();
|
||||||
|
|
|
@ -33,7 +33,6 @@ import android.graphics.drawable.Drawable;
|
||||||
import android.text.TextPaint;
|
import android.text.TextPaint;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ViewConfiguration;
|
import android.view.ViewConfiguration;
|
||||||
import android.view.inputmethod.EditorInfo;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -54,9 +53,7 @@ public class LatinKeyboard extends BaseKeyboard {
|
||||||
private Drawable mSpacePreviewIcon;
|
private Drawable mSpacePreviewIcon;
|
||||||
private final Drawable mButtonArrowLeftIcon;
|
private final Drawable mButtonArrowLeftIcon;
|
||||||
private final Drawable mButtonArrowRightIcon;
|
private final Drawable mButtonArrowRightIcon;
|
||||||
private final Drawable mSearchIcon;
|
|
||||||
private final int mSpaceBarTextShadowColor;
|
private final int mSpaceBarTextShadowColor;
|
||||||
private Key mEnterKey;
|
|
||||||
private Key mSpaceKey;
|
private Key mSpaceKey;
|
||||||
private int mSpaceKeyIndex = -1;
|
private int mSpaceKeyIndex = -1;
|
||||||
private int mSpaceDragStartX;
|
private int mSpaceDragStartX;
|
||||||
|
@ -71,12 +68,6 @@ public class LatinKeyboard extends BaseKeyboard {
|
||||||
private int mPrefLetterY;
|
private int mPrefLetterY;
|
||||||
private int mPrefDistance;
|
private int mPrefDistance;
|
||||||
|
|
||||||
// Default Enter key attributes
|
|
||||||
private final Drawable mDefaultEnterIcon;
|
|
||||||
private final Drawable mDefaultEnterPreview;
|
|
||||||
private final CharSequence mDefaultEnterLabel;
|
|
||||||
private final CharSequence mDefaultEnterText;
|
|
||||||
|
|
||||||
private LatinKeyboardShiftState mShiftState = new LatinKeyboardShiftState();
|
private LatinKeyboardShiftState mShiftState = new LatinKeyboardShiftState();
|
||||||
|
|
||||||
private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f;
|
private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f;
|
||||||
|
@ -98,14 +89,10 @@ public class LatinKeyboard extends BaseKeyboard {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mRes = res;
|
mRes = res;
|
||||||
if (id.mColorScheme == BaseKeyboardView.COLOR_SCHEME_BLACK) {
|
if (id.mColorScheme == BaseKeyboardView.COLOR_SCHEME_BLACK) {
|
||||||
// TODO: use <case imeOptions> and <case colorScheme> in XML to load search icon
|
|
||||||
mSearchIcon = res.getDrawable(R.drawable.sym_bkeyboard_search);
|
|
||||||
mShiftedIcon = res.getDrawable(R.drawable.sym_bkeyboard_shift_locked);
|
mShiftedIcon = res.getDrawable(R.drawable.sym_bkeyboard_shift_locked);
|
||||||
mSpaceBarTextShadowColor = res.getColor(
|
mSpaceBarTextShadowColor = res.getColor(
|
||||||
R.color.latinkeyboard_bar_language_shadow_black);
|
R.color.latinkeyboard_bar_language_shadow_black);
|
||||||
} else { // default color scheme is BaseKeyboardView.COLOR_SCHEME_WHITE
|
} else { // default color scheme is BaseKeyboardView.COLOR_SCHEME_WHITE
|
||||||
// TODO: use <case imeOptions> and <case colorScheme> in XML to load search icon
|
|
||||||
mSearchIcon = res.getDrawable(R.drawable.sym_keyboard_search);
|
|
||||||
mShiftedIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
|
mShiftedIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
|
||||||
mSpaceBarTextShadowColor = res.getColor(
|
mSpaceBarTextShadowColor = res.getColor(
|
||||||
R.color.latinkeyboard_bar_language_shadow_white);
|
R.color.latinkeyboard_bar_language_shadow_white);
|
||||||
|
@ -118,16 +105,6 @@ public class LatinKeyboard extends BaseKeyboard {
|
||||||
sSpacebarVerticalCorrection = res.getDimensionPixelOffset(
|
sSpacebarVerticalCorrection = res.getDimensionPixelOffset(
|
||||||
R.dimen.spacebar_vertical_correction);
|
R.dimen.spacebar_vertical_correction);
|
||||||
mSpaceKeyIndex = indexOf(LatinIME.KEYCODE_SPACE);
|
mSpaceKeyIndex = indexOf(LatinIME.KEYCODE_SPACE);
|
||||||
|
|
||||||
if (mEnterKey != null) {
|
|
||||||
mDefaultEnterIcon = mEnterKey.icon;
|
|
||||||
mDefaultEnterPreview = mEnterKey.iconPreview;
|
|
||||||
mDefaultEnterLabel = mEnterKey.label;
|
|
||||||
mDefaultEnterText = mEnterKey.text;
|
|
||||||
} else {
|
|
||||||
mDefaultEnterIcon = mDefaultEnterPreview = null;
|
|
||||||
mDefaultEnterLabel = mDefaultEnterText = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -135,9 +112,6 @@ public class LatinKeyboard extends BaseKeyboard {
|
||||||
XmlResourceParser parser, KeyStyles keyStyles) {
|
XmlResourceParser parser, KeyStyles keyStyles) {
|
||||||
Key key = new LatinKey(res, parent, x, y, parser, keyStyles);
|
Key key = new LatinKey(res, parent, x, y, parser, keyStyles);
|
||||||
switch (key.codes[0]) {
|
switch (key.codes[0]) {
|
||||||
case LatinIME.KEYCODE_ENTER:
|
|
||||||
mEnterKey = key;
|
|
||||||
break;
|
|
||||||
case LatinIME.KEYCODE_SPACE:
|
case LatinIME.KEYCODE_SPACE:
|
||||||
mSpaceKey = key;
|
mSpaceKey = key;
|
||||||
mSpaceIcon = key.icon;
|
mSpaceIcon = key.icon;
|
||||||
|
@ -148,53 +122,6 @@ public class LatinKeyboard extends BaseKeyboard {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void resetKeyAttributes(Key key, CharSequence label) {
|
|
||||||
key.popupCharacters = null;
|
|
||||||
key.popupResId = 0;
|
|
||||||
key.text = null;
|
|
||||||
key.iconPreview = null;
|
|
||||||
key.icon = null;
|
|
||||||
key.hintIcon = null;
|
|
||||||
key.label = label;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: remove this method and use <case imeOptions> in XML
|
|
||||||
public void setImeOptions(Resources res, int mode, int options) {
|
|
||||||
if (mEnterKey == null)
|
|
||||||
return;
|
|
||||||
final boolean configDynamicKeyTopEnterKey = res.getBoolean(
|
|
||||||
R.bool.config_dynamic_key_top_enter_key);
|
|
||||||
if (configDynamicKeyTopEnterKey) {
|
|
||||||
switch (options & (EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION)) {
|
|
||||||
case EditorInfo.IME_ACTION_GO:
|
|
||||||
resetKeyAttributes(mEnterKey, res.getText(R.string.label_go_key));
|
|
||||||
break;
|
|
||||||
case EditorInfo.IME_ACTION_NEXT:
|
|
||||||
resetKeyAttributes(mEnterKey, res.getText(R.string.label_next_key));
|
|
||||||
break;
|
|
||||||
case EditorInfo.IME_ACTION_DONE:
|
|
||||||
resetKeyAttributes(mEnterKey, res.getText(R.string.label_done_key));
|
|
||||||
break;
|
|
||||||
case EditorInfo.IME_ACTION_SEARCH:
|
|
||||||
resetKeyAttributes(mEnterKey, null);
|
|
||||||
mEnterKey.iconPreview = res.getDrawable(R.drawable.sym_keyboard_feedback_search);
|
|
||||||
mEnterKey.icon = mSearchIcon;
|
|
||||||
break;
|
|
||||||
case EditorInfo.IME_ACTION_SEND:
|
|
||||||
resetKeyAttributes(mEnterKey, res.getText(R.string.label_send_key));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
resetKeyAttributes(mEnterKey, mDefaultEnterLabel);
|
|
||||||
mEnterKey.text = mDefaultEnterText;
|
|
||||||
mEnterKey.icon = mDefaultEnterIcon;
|
|
||||||
mEnterKey.iconPreview = mDefaultEnterPreview;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Set the initial size of the preview icon
|
|
||||||
setDefaultBounds(mEnterKey.iconPreview);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableShiftLock() {
|
public void enableShiftLock() {
|
||||||
for (final Key key : getShiftKeys()) {
|
for (final Key key : getShiftKeys()) {
|
||||||
if (key instanceof LatinKey) {
|
if (key instanceof LatinKey) {
|
||||||
|
|
Loading…
Reference in a new issue