diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/internal/KeyboardIconsSet.java b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/internal/KeyboardIconsSet.java
index ac6c37f55..5e2430a4f 100644
--- a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/internal/KeyboardIconsSet.java
+++ b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/internal/KeyboardIconsSet.java
@@ -52,6 +52,7 @@ public final class KeyboardIconsSet {
public static final String NAME_PREVIOUS_KEY = "previous_key";
public static final String NAME_TAB_KEY = "tab_key";
public static final String NAME_SHORTCUT_KEY = "shortcut_key";
+ public static final String NAME_CLIPBOARD_KEY = "clipboard_key";
public static final String NAME_INCOGNITO_KEY = "incognito_key";
public static final String NAME_SHORTCUT_KEY_DISABLED = "shortcut_key_disabled";
public static final String NAME_LANGUAGE_SWITCH_KEY = "language_switch_key";
@@ -80,6 +81,7 @@ public final class KeyboardIconsSet {
NAME_PREVIOUS_KEY, R.styleable.Keyboard_iconPreviousKey,
NAME_TAB_KEY, R.styleable.Keyboard_iconTabKey,
NAME_SHORTCUT_KEY, R.styleable.Keyboard_iconShortcutKey,
+ NAME_CLIPBOARD_KEY, R.styleable.Keyboard_iconClipboardKey,
NAME_INCOGNITO_KEY, R.styleable.Keyboard_iconIncognitoKey,
NAME_SPACE_KEY_FOR_NUMBER_LAYOUT, R.styleable.Keyboard_iconSpaceKeyForNumberLayout,
NAME_SHIFT_KEY_SHIFTED, R.styleable.Keyboard_iconShiftKeyShifted,
diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/LatinIME.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/LatinIME.java
index 4e2f52edf..1285380d0 100644
--- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/LatinIME.java
+++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/LatinIME.java
@@ -1117,6 +1117,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
+ public CharSequence getSelection() {
+ return mInputLogic.mConnection.getSelectedText(0);
+ }
+
/**
* This is called when the user has clicked on the extracted text view,
* when running in fullscreen mode. The default implementation hides
@@ -1584,10 +1588,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
currentSettingsValues.mInputAttributes.mShouldShowSuggestions
&& currentSettingsValues.isSuggestionsEnabledPerUserSettings();
final boolean shouldShowSuggestionsStripUnlessPassword = currentSettingsValues.mShowsVoiceInputKey
+ || currentSettingsValues.mShowsClipboardKey
|| shouldShowSuggestionCandidates
|| currentSettingsValues.isApplicationSpecifiedCompletionsOn();
final boolean shouldShowSuggestionsStrip = shouldShowSuggestionsStripUnlessPassword
- && !currentSettingsValues.mInputAttributes.mIsPasswordField;
+ && (!currentSettingsValues.mInputAttributes.mIsPasswordField || currentSettingsValues.mShowsClipboardKey);
mSuggestionStripView.updateVisibility(shouldShowSuggestionsStrip, isFullscreenMode());
if (!shouldShowSuggestionsStrip) {
return;
diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java
index 3b1d47b06..6522d5d7e 100644
--- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java
+++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java
@@ -56,6 +56,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
// PREF_VOICE_MODE_OBSOLETE is obsolete. Use PREF_VOICE_INPUT_KEY instead.
public static final String PREF_VOICE_MODE_OBSOLETE = "voice_mode";
public static final String PREF_VOICE_INPUT_KEY = "pref_voice_input_key";
+ public static final String PREF_CLIPBOARD_CLIPBOARD_KEY = "pref_clipboard_clipboard_key";
public static final String PREF_EDIT_PERSONAL_DICTIONARY = "edit_personal_dictionary";
// PREF_AUTO_CORRECTION_THRESHOLD_OBSOLETE is obsolete. Use PREF_AUTO_CORRECTION instead.
public static final String PREF_AUTO_CORRECTION_THRESHOLD_OBSOLETE =
@@ -77,6 +78,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
"pref_show_language_switch_key";
public static final String PREF_SHOW_EMOJI_KEY =
"pref_show_emoji_key";
+ public static final String PREF_SHOW_CLIPBOARD_KEY =
+ "pref_show_clipboard_key";
public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
"pref_include_other_imes_in_language_switch_list";
public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles";
diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java
index db584fb86..3db4e2449 100644
--- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java
+++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java
@@ -73,6 +73,7 @@ public class SettingsValues {
public final boolean mShowsHints;
public final boolean mShowsLanguageSwitchKey;
public final boolean mShowsEmojiKey;
+ public final boolean mShowsClipboardKey;
public final boolean mUsePersonalizedDicts;
public final boolean mUseDoubleSpacePeriod;
public final boolean mBlockPotentiallyOffensive;
@@ -149,6 +150,7 @@ public class SettingsValues {
mShowsHints = prefs.getBoolean(Settings.PREF_SHOW_HINTS, true);
mShowsLanguageSwitchKey = prefs.getBoolean(Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY, false);
mShowsEmojiKey = prefs.getBoolean(Settings.PREF_SHOW_EMOJI_KEY, false);
+ mShowsClipboardKey = prefs.getBoolean(Settings.PREF_SHOW_CLIPBOARD_KEY, false);
mUsePersonalizedDicts = prefs.getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, true);
mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true)
&& inputAttributes.mIsGeneralTextInput;
@@ -188,7 +190,8 @@ public class SettingsValues {
//&& !mInputAttributes.mInputTypeNoAutoCorrect;
mSuggestionsEnabledPerUserSettings = !mInputAttributes.mIsPasswordField &&
readSuggestionsEnabled(prefs);
- mIncognitoModeEnabled = Settings.readAlwaysIncognitoMode(prefs) || mInputAttributes.mNoLearning;
+ mIncognitoModeEnabled = Settings.readAlwaysIncognitoMode(prefs) || mInputAttributes.mNoLearning
+ || mInputAttributes.mIsPasswordField;
mIsInternal = Settings.isInternal(prefs);
mHasCustomKeyPreviewAnimationParams = prefs.getBoolean(
DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS, false);
diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/suggestions/SuggestionStripView.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/suggestions/SuggestionStripView.java
index 2f2400de8..e2c1a2e0c 100644
--- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -16,6 +16,8 @@
package org.dslul.openboard.inputmethod.latin.suggestions;
+import android.content.ClipData;
+import android.content.ClipboardManager;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -59,6 +61,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
public interface Listener {
void pickSuggestionManually(SuggestedWordInfo word);
void onCodeInput(int primaryCode, int x, int y, boolean isKeyRepeat);
+ void onTextInput(final String rawText);
+ CharSequence getSelection();
}
static final boolean DBG = DebugFlags.DEBUG_ENABLED;
@@ -66,6 +70,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private final ViewGroup mSuggestionsStrip;
private final ImageButton mVoiceKey;
+ private final ImageButton mClipboardKey;
private final ImageButton mOtherKey;
MainKeyboardView mMainKeyboardView;
@@ -126,6 +131,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
mSuggestionsStrip = findViewById(R.id.suggestions_strip);
mVoiceKey = findViewById(R.id.suggestions_strip_voice_key);
+ mClipboardKey = findViewById(R.id.suggestions_strip_clipboard_key);
mOtherKey = findViewById(R.id.suggestions_strip_other_key);
mStripVisibilityGroup = new StripVisibilityGroup(this, mSuggestionsStrip);
@@ -161,9 +167,13 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
R.styleable.Keyboard, defStyle, R.style.SuggestionStripView);
final Drawable iconVoice = keyboardAttr.getDrawable(R.styleable.Keyboard_iconShortcutKey);
final Drawable iconIncognito = keyboardAttr.getDrawable(R.styleable.Keyboard_iconIncognitoKey);
+ final Drawable iconClipboard = keyboardAttr.getDrawable(R.styleable.Keyboard_iconClipboardKey);
keyboardAttr.recycle();
mVoiceKey.setImageDrawable(iconVoice);
mVoiceKey.setOnClickListener(this);
+ mClipboardKey.setImageDrawable(iconClipboard);
+ mClipboardKey.setOnClickListener(this);
+ mClipboardKey.setOnLongClickListener(this);
mOtherKey.setImageDrawable(iconIncognito);
}
@@ -181,7 +191,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
final int visibility = shouldBeVisible ? VISIBLE : (isFullscreenMode ? GONE : INVISIBLE);
setVisibility(visibility);
final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent();
- mVoiceKey.setVisibility(currentSettingsValues.mShowsVoiceInputKey ? VISIBLE : INVISIBLE);
+ mVoiceKey.setVisibility(currentSettingsValues.mShowsVoiceInputKey ? VISIBLE : GONE);
+ mClipboardKey.setVisibility(currentSettingsValues.mShowsClipboardKey ? VISIBLE : (mVoiceKey.getVisibility() == GONE ? INVISIBLE : GONE));
mOtherKey.setVisibility(currentSettingsValues.mIncognitoModeEnabled ? VISIBLE : INVISIBLE);
}
@@ -256,6 +267,23 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
@Override
public boolean onLongClick(final View view) {
+ if (view == mClipboardKey) {
+ ClipboardManager clipboardManager = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
+ ClipData clipData = clipboardManager.getPrimaryClip();
+ 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));
+ }
+ }
+ AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(
+ Constants.NOT_A_CODE, this);
+ return true;
+ }
AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(
Constants.NOT_A_CODE, this);
return showMoreSuggestions();
@@ -413,6 +441,15 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
false /* isKeyRepeat */);
return;
}
+ if (view == mClipboardKey) {
+ CharSequence selectionSequence = mListener.getSelection();
+ if (selectionSequence != null && selectionSequence.length() > 0
+ && !Settings.getInstance().getCurrent().mInputAttributes.mIsPasswordField) {
+ ClipboardManager clipboardManager = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
+ clipboardManager.setPrimaryClip(ClipData.newPlainText(selectionSequence, selectionSequence));
+ }
+ return;
+ }
final Object tag = view.getTag();
// {@link Integer} tag is set at
diff --git a/app/src/main/res/drawable/sym_keyboard_clipboard_dark.xml b/app/src/main/res/drawable/sym_keyboard_clipboard_dark.xml
new file mode 100644
index 000000000..c5bd90c58
--- /dev/null
+++ b/app/src/main/res/drawable/sym_keyboard_clipboard_dark.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/sym_keyboard_clipboard_light.xml b/app/src/main/res/drawable/sym_keyboard_clipboard_light.xml
new file mode 100644
index 000000000..29fa0da12
--- /dev/null
+++ b/app/src/main/res/drawable/sym_keyboard_clipboard_light.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/layout/suggestions_strip.xml b/app/src/main/res/layout/suggestions_strip.xml
index c6a412e39..7f98671b5 100644
--- a/app/src/main/res/layout/suggestions_strip.xml
+++ b/app/src/main/res/layout/suggestions_strip.xml
@@ -20,34 +20,45 @@
-
-
-
-
+ android:soundEffectsEnabled="false">
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index 2c6db9f17..7defaf7dc 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -270,6 +270,7 @@
+
diff --git a/app/src/main/res/values/keyboard-icons-holo.xml b/app/src/main/res/values/keyboard-icons-holo.xml
index 5ef52f264..6cec98fc8 100644
--- a/app/src/main/res/values/keyboard-icons-holo.xml
+++ b/app/src/main/res/values/keyboard-icons-holo.xml
@@ -29,6 +29,7 @@
- @drawable/sym_keyboard_search_holo_dark
- @drawable/sym_keyboard_tab_holo_dark
- @drawable/sym_keyboard_voice_holo_dark
+ - @drawable/sym_keyboard_clipboard_dark
- @drawable/sym_keyboard_incognito_dark
- @drawable/sym_keyboard_space_holo_dark
- @drawable/sym_keyboard_shift_locked_holo_dark
diff --git a/app/src/main/res/values/keyboard-icons-lxx-dark-parent.xml b/app/src/main/res/values/keyboard-icons-lxx-dark-parent.xml
index 04f92b99f..2bc53e0eb 100644
--- a/app/src/main/res/values/keyboard-icons-lxx-dark-parent.xml
+++ b/app/src/main/res/values/keyboard-icons-lxx-dark-parent.xml
@@ -36,6 +36,7 @@
- @drawable/sym_keyboard_previous_lxx_dark
- @drawable/sym_keyboard_voice_lxx_dark
- @drawable/sym_keyboard_voice_off_lxx_dark
+ - @drawable/sym_keyboard_clipboard_dark
- @drawable/sym_keyboard_incognito_lxx_dark
- @drawable/sym_keyboard_space_lxx_dark
- @drawable/sym_keyboard_language_switch_lxx_dark
diff --git a/app/src/main/res/values/keyboard-icons-lxx-light-parent.xml b/app/src/main/res/values/keyboard-icons-lxx-light-parent.xml
index 051095ad6..a566d513e 100644
--- a/app/src/main/res/values/keyboard-icons-lxx-light-parent.xml
+++ b/app/src/main/res/values/keyboard-icons-lxx-light-parent.xml
@@ -36,6 +36,7 @@
- @drawable/sym_keyboard_previous_lxx_light
- @drawable/sym_keyboard_voice_lxx_light
- @drawable/sym_keyboard_voice_off_lxx_light
+ - @drawable/sym_keyboard_clipboard_light
- @drawable/sym_keyboard_incognito_lxx_light
- @drawable/sym_keyboard_space_lxx_light
- @drawable/sym_keyboard_language_switch_lxx_light
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d2d0881b4..22285205f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -179,6 +179,10 @@
No voice input methods enabled. Check Languages & input settings.
+
+ Clipboard key
+ Press to copy, long-press to paste.
+
Configure input methods
diff --git a/app/src/main/res/xml/prefs_screen_preferences.xml b/app/src/main/res/xml/prefs_screen_preferences.xml
index aefdcd215..1a3a869bf 100644
--- a/app/src/main/res/xml/prefs_screen_preferences.xml
+++ b/app/src/main/res/xml/prefs_screen_preferences.xml
@@ -71,4 +71,10 @@
android:title="@string/voice_input"
android:defaultValue="true"
android:persistent="true" />
+