diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardSwitcher.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardSwitcher.java index aeed202d..1adb4521 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardSwitcher.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardSwitcher.java @@ -16,6 +16,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodSubtype; +import android.widget.HorizontalScrollView; import android.widget.LinearLayout; import androidx.annotation.NonNull; @@ -49,6 +50,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { private EmojiPalettesView mEmojiPalettesView; private View mEmojiTabStripView; private LinearLayout mClipboardStripView; + private HorizontalScrollView mClipboardStripScrollView; private View mSuggestionStripView; private ClipboardHistoryView mClipboardHistoryView; private LatinIME mLatinIME; @@ -280,7 +282,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { mEmojiPalettesView.setVisibility(View.GONE); mEmojiPalettesView.stopEmojiPalettes(); mEmojiTabStripView.setVisibility(View.GONE); - mClipboardStripView.setVisibility(View.GONE); + mClipboardStripScrollView.setVisibility(View.GONE); mSuggestionStripView.setVisibility(View.VISIBLE); mClipboardHistoryView.setVisibility(View.GONE); mClipboardHistoryView.stopClipboardHistory(); @@ -299,7 +301,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { // @see LatinIME#onComputeInset(android.inputmethodservice.InputMethodService.Insets) mKeyboardView.setVisibility(View.GONE); mSuggestionStripView.setVisibility(View.GONE); - mClipboardStripView.setVisibility(View.GONE); + mClipboardStripScrollView.setVisibility(View.GONE); mEmojiTabStripView.setVisibility(View.VISIBLE); mClipboardHistoryView.setVisibility(View.GONE); mEmojiPalettesView.startEmojiPalettes( @@ -322,7 +324,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { mKeyboardView.setVisibility(View.GONE); mEmojiTabStripView.setVisibility(View.GONE); mSuggestionStripView.setVisibility(View.GONE); - mClipboardStripView.setVisibility(View.VISIBLE); + mClipboardStripScrollView.post(() -> mClipboardStripScrollView.fullScroll(HorizontalScrollView.FOCUS_RIGHT)); + mClipboardStripScrollView.setVisibility(View.VISIBLE); mEmojiPalettesView.setVisibility(View.GONE); mClipboardHistoryView.startClipboardHistory( mLatinIME.getClipboardHistoryManager(), @@ -571,6 +574,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { mClipboardHistoryView.setKeyboardActionListener(mLatinIME.mKeyboardActionListener); mEmojiTabStripView = mCurrentInputView.findViewById(R.id.emoji_tab_strip); mClipboardStripView = mCurrentInputView.findViewById(R.id.clipboard_strip); + mClipboardStripScrollView = mCurrentInputView.findViewById(R.id.clipboard_strip_scroll_view); mSuggestionStripView = mCurrentInputView.findViewById(R.id.suggestion_strip_view); return mCurrentInputView; diff --git a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt index 7e8ae9f8..ec89e7a4 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt @@ -28,13 +28,14 @@ import helium314.keyboard.latin.utils.ResourceUtils import helium314.keyboard.latin.utils.ToolbarKey import helium314.keyboard.latin.utils.createToolbarKey import helium314.keyboard.latin.utils.getCodeForToolbarKey +import helium314.keyboard.latin.utils.getCodeForToolbarKeyLongClick class ClipboardHistoryView @JvmOverloads constructor( context: Context, attrs: AttributeSet?, defStyle: Int = R.attr.clipboardHistoryViewStyle ) : LinearLayout(context, attrs, defStyle), View.OnTouchListener, View.OnClickListener, - ClipboardHistoryManager.OnHistoryChangeListener, OnKeyEventListener { + ClipboardHistoryManager.OnHistoryChangeListener, OnKeyEventListener, View.OnLongClickListener { private val clipboardLayoutParams = ClipboardLayoutParams(context.resources) private val pinIconId: Int @@ -69,7 +70,7 @@ class ClipboardHistoryView @JvmOverloads constructor( // even when state is activated, the not activated color is set // in suggestionStripView the same thing works correctly, wtf? // need to properly fix it (and maybe undo the inverted isActivated) when adding a toggle key - listOf(ToolbarKey.LEFT, ToolbarKey.RIGHT, ToolbarKey.COPY, ToolbarKey.CUT, ToolbarKey.CLEAR_CLIPBOARD, ToolbarKey.SELECT_WORD, ToolbarKey.SELECT_ALL, ToolbarKey.CLOSE_HISTORY) + listOf(ToolbarKey.ONE_HANDED, ToolbarKey.UNDO, ToolbarKey.UP, ToolbarKey.DOWN, ToolbarKey.LEFT, ToolbarKey.RIGHT, ToolbarKey.CLEAR_CLIPBOARD, ToolbarKey.COPY, ToolbarKey.CUT, ToolbarKey.SELECT_WORD, ToolbarKey.CLOSE_HISTORY) .forEach { toolbarKeys.add(createToolbarKey(context, keyboardAttr, it)) } keyboardAttr.recycle() } @@ -121,6 +122,7 @@ class ClipboardHistoryView @JvmOverloads constructor( clipboardStrip.addView(it) it.setOnTouchListener(this@ClipboardHistoryView) it.setOnClickListener(this@ClipboardHistoryView) + it.setOnLongClickListener(this@ClipboardHistoryView) colors.setColor(it, ColorType.TOOL_BAR_KEY) colors.setBackground(it, ColorType.STRIP_BACKGROUND) } @@ -240,6 +242,23 @@ class ClipboardHistoryView @JvmOverloads constructor( } } + override fun onLongClick(view: View): Boolean { + val tag = view.tag + if (tag is ToolbarKey) { + val longClickCode = getCodeForToolbarKeyLongClick(tag) + if (longClickCode != KeyCode.UNSPECIFIED) { + keyboardActionListener?.onCodeInput( + longClickCode, + Constants.NOT_A_COORDINATE, + Constants.NOT_A_COORDINATE, + false + ) + } + return true + } + return false + } + override fun onKeyDown(clipId: Long) { keyboardActionListener?.onPressKey(KeyCode.NOT_SPECIFIED, 0, true) } diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyCode.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyCode.kt index e7174da6..bd8015ec 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyCode.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyCode.kt @@ -131,6 +131,9 @@ object KeyCode { const val ACTION_PREVIOUS = -10007 // Code value representing the code is not specified. const val NOT_SPECIFIED = -10008 // todo: not sure if there is need to have the "old" unspecified keyCode different, just test it and maybe merge + const val CLIPBOARD_COPY_ALL = -10009 + const val PAGE_UP = -10010 + const val PAGE_DOWN = -10011 /** to make sure a FlorisBoard code works when reading a JSON layout */ fun Int.checkAndConvertCode(): Int = if (this > 0) this else when (this) { diff --git a/app/src/main/java/helium314/keyboard/latin/LatinIME.java b/app/src/main/java/helium314/keyboard/latin/LatinIME.java index df5f087e..e0a7a154 100644 --- a/app/src/main/java/helium314/keyboard/latin/LatinIME.java +++ b/app/src/main/java/helium314/keyboard/latin/LatinIME.java @@ -1518,6 +1518,7 @@ public class LatinIME extends InputMethodService implements mInputLogic.onTextInput(mSettings.getCurrent(), event, mKeyboardSwitcher.getKeyboardShiftMode(), mHandler); updateStateAfterInputTransaction(completeInputTransaction); + mInputLogic.restartSuggestionsOnWordTouchedByCursor(mSettings.getCurrent(), mKeyboardSwitcher.getCurrentKeyboardScript()); mKeyboardSwitcher.onEvent(event, getCurrentAutoCapsState(), getCurrentRecapitalizeState()); } diff --git a/app/src/main/java/helium314/keyboard/latin/RichInputConnection.java b/app/src/main/java/helium314/keyboard/latin/RichInputConnection.java index 531688d5..1ecb2d95 100644 --- a/app/src/main/java/helium314/keyboard/latin/RichInputConnection.java +++ b/app/src/main/java/helium314/keyboard/latin/RichInputConnection.java @@ -653,9 +653,12 @@ public final class RichInputConnection implements PrivateCommandPerformer { mIC.setSelection(mExpectedSelStart - range.getNumberOfCharsInWordBeforeCursor(), mExpectedSelStart + range.getNumberOfCharsInWordAfterCursor()); } - public void copyText() { - // copy selected text, and if nothing is selected copy the whole text - CharSequence text = getSelectedText(InputConnection.GET_TEXT_WITH_STYLES); + public void copyText(final boolean getSelection) { + CharSequence text = ""; + if (getSelection) { + // copy selected text, and if nothing is selected copy the whole text + text = getSelectedText(InputConnection.GET_TEXT_WITH_STYLES); + } if (text == null || text.length() == 0) { // we have no selection, get the whole text final ExtractedTextRequest etr = new ExtractedTextRequest(); diff --git a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java index d3543c32..df1428c5 100644 --- a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java +++ b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java @@ -636,6 +636,18 @@ public final class InputLogic { } } + /** + * Handles the action of pasting content from the clipboard. + * Retrieves content from the clipboard history manager and commits it to the input connection. + * + */ + private void handleClipboardPaste() { + final String clipboardContent = mLatinIME.getClipboardHistoryManager().retrieveClipboardContent().toString(); + if (!clipboardContent.isEmpty()) { + mLatinIME.onTextInput(clipboardContent); + } + } + /** * Handle a functional key event. *

@@ -685,14 +697,12 @@ public final class InputLogic { // is being handled in {@link KeyboardState#onEvent(Event,int)}. // If disabled, current clipboard content is committed. if (!inputTransaction.getMSettingsValues().mClipboardHistoryEnabled) { - final CharSequence content = mLatinIME.getClipboardHistoryManager() - .retrieveClipboardContent(); - if (!TextUtils.isEmpty(content)) { - mConnection.commitText(content, 1); - inputTransaction.setDidAffectContents(); - } + handleClipboardPaste(); } break; + case KeyCode.CLIPBOARD_PASTE: + handleClipboardPaste(); + break; case KeyCode.SHIFT_ENTER: final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER, event.getMKeyCode(), event.getMX(), event.getMY(), event.isKeyRepeat()); @@ -714,11 +724,14 @@ public final class InputLogic { mConnection.selectWord(inputTransaction.getMSettingsValues().mSpacingAndPunctuations, currentKeyboardScript); break; case KeyCode.CLIPBOARD_COPY: - mConnection.copyText(); + mConnection.copyText(true); + break; + case KeyCode.CLIPBOARD_COPY_ALL: + mConnection.copyText(false); break; case KeyCode.CLIPBOARD_CUT: if (mConnection.hasSelection()) { - mConnection.copyText(); + mConnection.copyText(true); // fake delete keypress to remove the text final Event backspaceEvent = LatinIME.createSoftwareKeypressEvent(KeyCode.DELETE, event.getMX(), event.getMY(), event.isKeyRepeat()); @@ -750,6 +763,12 @@ public final class InputLogic { case KeyCode.MOVE_END_OF_LINE: sendDownUpKeyEvent(KeyEvent.KEYCODE_MOVE_END); break; + case KeyCode.PAGE_UP: + sendDownUpKeyEvent(KeyEvent.KEYCODE_PAGE_UP); + break; + case KeyCode.PAGE_DOWN: + sendDownUpKeyEvent(KeyEvent.KEYCODE_PAGE_DOWN); + break; case KeyCode.VOICE_INPUT: // switching to shortcut IME, shift state, keyboard,... is handled by LatinIME, // {@link KeyboardSwitcher#onEvent(Event)}, or {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. diff --git a/app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.java b/app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.java index 84e1a39c..3994e0a2 100644 --- a/app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.java +++ b/app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.java @@ -10,8 +10,6 @@ import static helium314.keyboard.latin.utils.ToolbarUtilsKt.*; import android.annotation.SuppressLint; import android.app.KeyguardManager; -import android.content.ClipData; -import android.content.ClipboardManager; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Resources; @@ -375,10 +373,13 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick } private void onLongClickToolKey(final View view) { - if (ToolbarKey.CLIPBOARD == view.getTag() && view.getParent() == mPinnedKeys) { - onLongClickClipboardKey(); // long click pinned clipboard key + if (!(view.getTag() instanceof ToolbarKey tag)) return; + if (view.getParent() == mPinnedKeys) { + final int longClickCode = getCodeForToolbarKeyLongClick(tag); + if (longClickCode != KeyCode.UNSPECIFIED) { + mListener.onCodeInput(longClickCode, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false); + } } else if (view.getParent() == mToolbar) { - final ToolbarKey tag = (ToolbarKey) view.getTag(); final View pinnedKeyView = mPinnedKeys.findViewWithTag(tag); if (pinnedKeyView == null) { addKeyToPinnedKeys(tag); @@ -392,22 +393,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick } } - private void onLongClickClipboardKey() { - ClipboardManager clipboardManager = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clipData = clipboardManager.getPrimaryClip(); - Log.d(TAG, "long click clipboard key"); - if (clipData != null && clipData.getItemCount() > 0 && clipData.getItemAt(0) != null) { - String clipString = clipData.getItemAt(0).coerceToText(getContext()).toString(); - if (clipString.length() == 1) { - mListener.onTextInput(clipString); - } else if (clipString.length() > 1) { - //awkward workaround - mListener.onTextInput(clipString.substring(0, clipString.length() - 1)); - mListener.onTextInput(clipString.substring(clipString.length() - 1)); - } - } - } - @SuppressLint("ClickableViewAccessibility") // no need for View#performClick, we return false mostly anyway private boolean onLongClickSuggestion(final TextView wordView) { boolean showIcon = true; diff --git a/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt index 1edb9e6b..44e62729 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt @@ -60,6 +60,19 @@ fun getCodeForToolbarKey(key: ToolbarKey) = when (key) { CLOSE_HISTORY -> KeyCode.ALPHA } +fun getCodeForToolbarKeyLongClick(key: ToolbarKey) = when (key) { + RIGHT -> KeyCode.MOVE_END_OF_LINE + LEFT -> KeyCode.MOVE_START_OF_LINE + UP -> KeyCode.PAGE_UP + DOWN -> KeyCode.PAGE_DOWN + UNDO -> KeyCode.REDO + REDO -> KeyCode.UNDO + COPY -> KeyCode.CLIPBOARD_COPY_ALL + SELECT_WORD -> KeyCode.CLIPBOARD_SELECT_ALL + CLIPBOARD -> KeyCode.CLIPBOARD_PASTE + else -> KeyCode.UNSPECIFIED +} + private fun getStyleableIconId(key: ToolbarKey) = when (key) { VOICE -> R.styleable.Keyboard_iconShortcutKey SETTINGS -> R.styleable.Keyboard_iconSettingsKey diff --git a/app/src/main/res/layout/strip_container.xml b/app/src/main/res/layout/strip_container.xml index 54a20ec3..be843796 100644 --- a/app/src/main/res/layout/strip_container.xml +++ b/app/src/main/res/layout/strip_container.xml @@ -24,16 +24,21 @@ android:layout_width="match_parent" android:layout_height="match_parent" style="?attr/suggestionStripViewStyle" /> - - - - + android:scrollbarThumbHorizontal="@color/toolbar_scrollbar" > + + + + +