aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/pixart/messenger/ui/widget/EditMessage.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/pixart/messenger/ui/widget/EditMessage.java')
-rw-r--r--src/main/java/de/pixart/messenger/ui/widget/EditMessage.java169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/main/java/de/pixart/messenger/ui/widget/EditMessage.java b/src/main/java/de/pixart/messenger/ui/widget/EditMessage.java
new file mode 100644
index 000000000..3b9b50f1c
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/ui/widget/EditMessage.java
@@ -0,0 +1,169 @@
+package de.pixart.messenger.ui.widget;
+
+import android.content.Context;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.annotation.Nullable;
+import android.support.text.emoji.widget.EmojiEditText;
+import android.support.v13.view.inputmethod.EditorInfoCompat;
+import android.support.v13.view.inputmethod.InputConnectionCompat;
+import android.support.v13.view.inputmethod.InputContentInfoCompat;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.Spanned;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+
+import de.pixart.messenger.Config;
+
+public class EditMessage extends EmojiEditText {
+
+ private static final InputFilter SPAN_FILTER = new InputFilter() {
+
+ @Override
+ public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
+ return source instanceof Spanned ? source.toString() : source;
+ }
+ };
+ protected Handler mTypingHandler = new Handler();
+ protected KeyboardListener keyboardListener;
+
+ private OnCommitContentListener mCommitContentListener = null;
+ private String[] mimeTypes = null;
+
+ private boolean isUserTyping = false;
+
+ protected Runnable mTypingTimeout = new Runnable() {
+ @Override
+ public void run() {
+ if (isUserTyping && keyboardListener != null) {
+ keyboardListener.onTypingStopped();
+ isUserTyping = false;
+ }
+ }
+ };
+
+ private boolean lastInputWasTab = false;
+
+ public EditMessage(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public EditMessage(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent e) {
+ if (keyCode == KeyEvent.KEYCODE_ENTER && !e.isShiftPressed()) {
+ lastInputWasTab = false;
+ if (keyboardListener != null && keyboardListener.onEnterPressed()) {
+ return true;
+ }
+ } else if (keyCode == KeyEvent.KEYCODE_TAB && !e.isAltPressed() && !e.isCtrlPressed()) {
+ if (keyboardListener != null && keyboardListener.onTabPressed(this.lastInputWasTab)) {
+ lastInputWasTab = true;
+ return true;
+ }
+ } else {
+ lastInputWasTab = false;
+ }
+ return super.onKeyDown(keyCode, e);
+ }
+
+ @Override
+ public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
+ super.onTextChanged(text, start, lengthBefore, lengthAfter);
+ lastInputWasTab = false;
+ if (this.mTypingHandler != null && this.keyboardListener != null) {
+ this.mTypingHandler.removeCallbacks(mTypingTimeout);
+ this.mTypingHandler.postDelayed(mTypingTimeout, Config.TYPING_TIMEOUT * 1000);
+ final int length = text.length();
+ if (!isUserTyping && length > 0) {
+ this.isUserTyping = true;
+ this.keyboardListener.onTypingStarted();
+ } else if (length == 0) {
+ this.isUserTyping = false;
+ this.keyboardListener.onTextDeleted();
+ }
+ this.keyboardListener.onTextChanged();
+ }
+ }
+
+ public void setKeyboardListener(KeyboardListener listener) {
+ this.keyboardListener = listener;
+ if (listener != null) {
+ this.isUserTyping = false;
+ }
+ }
+
+ @Override
+ public boolean onTextContextMenuItem(int id) {
+ if (id == android.R.id.paste) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ return super.onTextContextMenuItem(android.R.id.pasteAsPlainText);
+ } else {
+ Editable editable = getEditableText();
+ InputFilter[] filters = editable.getFilters();
+ InputFilter[] tempFilters = new InputFilter[filters != null ? filters.length + 1 : 1];
+ if (filters != null) {
+ System.arraycopy(filters, 0, tempFilters, 1, filters.length);
+ }
+ tempFilters[0] = SPAN_FILTER;
+ editable.setFilters(tempFilters);
+ try {
+ return super.onTextContextMenuItem(id);
+ } finally {
+ editable.setFilters(filters);
+ }
+ }
+ } else {
+ return super.onTextContextMenuItem(id);
+ }
+ }
+
+ public void setRichContentListener(String[] mimeTypes, OnCommitContentListener listener) {
+ this.mimeTypes = mimeTypes;
+ this.mCommitContentListener = listener;
+ }
+
+ @Override
+ @Nullable
+ public InputConnection onCreateInputConnection(EditorInfo editorInfo) {
+ final InputConnection ic = super.onCreateInputConnection(editorInfo);
+
+ if (mimeTypes != null && mCommitContentListener != null) {
+ EditorInfoCompat.setContentMimeTypes(editorInfo, mimeTypes);
+ return InputConnectionCompat.createWrapper(ic, editorInfo, new InputConnectionCompat.OnCommitContentListener() {
+
+ @Override
+ public boolean onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts) {
+ return EditMessage.this.mCommitContentListener.onCommitContent(inputContentInfo, flags, opts, mimeTypes);
+ }
+ });
+ } else {
+ return ic;
+ }
+ }
+
+ public interface OnCommitContentListener {
+ boolean onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts, String[] mimeTypes);
+ }
+
+ public interface KeyboardListener {
+ boolean onEnterPressed();
+
+ void onTypingStarted();
+
+ void onTypingStopped();
+
+ void onTextDeleted();
+
+ void onTextChanged();
+
+ boolean onTabPressed(boolean repeated);
+ }
+}