Merge "Paste window instead of action bar when cursor shown."
This commit is contained in:
@@ -68,6 +68,7 @@ import android.text.InputType;
|
||||
import android.text.Selection;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
@@ -111,6 +112,8 @@ import android.widget.CheckedTextView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.OverScroller;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import junit.framework.Assert;
|
||||
@@ -122,7 +125,6 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -423,6 +425,23 @@ public class WebView extends AbsoluteLayout
|
||||
setSelection(selectionStart, selectionEnd);
|
||||
}
|
||||
|
||||
public void replaceSelection(CharSequence text) {
|
||||
Editable editable = getEditable();
|
||||
int selectionStart = Selection.getSelectionStart(editable);
|
||||
int selectionEnd = Selection.getSelectionEnd(editable);
|
||||
setNewText(selectionStart, selectionEnd, text);
|
||||
editable.replace(selectionStart, selectionEnd, text);
|
||||
InputMethodManager imm = InputMethodManager.peekInstance();
|
||||
if (imm != null) {
|
||||
// Since the text has changed, do not allow the IME to replace the
|
||||
// existing text as though it were a completion.
|
||||
imm.restartInput(WebView.this);
|
||||
}
|
||||
// Move caret to the end of the new text
|
||||
int newCaret = selectionStart + text.length();
|
||||
setSelection(newCaret, newCaret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||
Editable editable = getEditable();
|
||||
@@ -609,6 +628,78 @@ public class WebView extends AbsoluteLayout
|
||||
}
|
||||
}
|
||||
|
||||
private class PastePopupWindow extends PopupWindow implements OnClickListener {
|
||||
private ViewGroup mContentView;
|
||||
private TextView mPasteTextView;
|
||||
|
||||
public PastePopupWindow() {
|
||||
super(WebView.this.mContext, null,
|
||||
com.android.internal.R.attr.textSelectHandleWindowStyle);
|
||||
setClippingEnabled(true);
|
||||
LinearLayout linearLayout = new LinearLayout(WebView.this.getContext());
|
||||
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
mContentView = linearLayout;
|
||||
mContentView.setBackgroundResource(
|
||||
com.android.internal.R.drawable.text_edit_paste_window);
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater)WebView.this.mContext.
|
||||
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
ViewGroup.LayoutParams wrapContent = new ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
|
||||
mPasteTextView = (TextView) inflater.inflate(
|
||||
com.android.internal.R.layout.text_edit_action_popup_text, null);
|
||||
mPasteTextView.setLayoutParams(wrapContent);
|
||||
mContentView.addView(mPasteTextView);
|
||||
mPasteTextView.setText(com.android.internal.R.string.paste);
|
||||
mPasteTextView.setOnClickListener(this);
|
||||
this.setContentView(mContentView);
|
||||
}
|
||||
|
||||
public void show(Rect cursorRect, int windowLeft, int windowTop) {
|
||||
measureContent();
|
||||
|
||||
int width = mContentView.getMeasuredWidth();
|
||||
int height = mContentView.getMeasuredHeight();
|
||||
int y = cursorRect.top - height;
|
||||
if (y < windowTop) {
|
||||
// There's not enough room vertically, move it below the
|
||||
// handle.
|
||||
// The selection handle is vertically offset by 1/4 of the
|
||||
// line height.
|
||||
y = cursorRect.bottom - (cursorRect.height() / 4) +
|
||||
mSelectHandleCenter.getIntrinsicHeight();
|
||||
}
|
||||
int x = cursorRect.centerX() - (width / 2);
|
||||
if (x < windowLeft) {
|
||||
x = windowLeft;
|
||||
}
|
||||
if (!isShowing()) {
|
||||
showAtLocation(WebView.this, Gravity.NO_GRAVITY, x, y);
|
||||
}
|
||||
update(x, y, width, height);
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
pasteFromClipboard();
|
||||
selectionDone();
|
||||
}
|
||||
|
||||
protected void measureContent() {
|
||||
final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
|
||||
mContentView.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels,
|
||||
View.MeasureSpec.AT_MOST),
|
||||
View.MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels,
|
||||
View.MeasureSpec.AT_MOST));
|
||||
}
|
||||
}
|
||||
|
||||
// The listener to capture global layout change event.
|
||||
private InnerGlobalLayoutListener mGlobalLayoutListener = null;
|
||||
@@ -636,6 +727,7 @@ public class WebView extends AbsoluteLayout
|
||||
private boolean mGLViewportEmpty = false;
|
||||
WebViewInputConnection mInputConnection = null;
|
||||
private int mFieldPointer;
|
||||
private PastePopupWindow mPasteWindow;
|
||||
|
||||
/**
|
||||
* Transportation object for returning WebView across thread boundaries.
|
||||
@@ -5910,6 +6002,27 @@ public class WebView extends AbsoluteLayout
|
||||
return true;
|
||||
}
|
||||
|
||||
private void showPasteWindow() {
|
||||
ClipboardManager cm = (ClipboardManager)(mContext
|
||||
.getSystemService(Context.CLIPBOARD_SERVICE));
|
||||
if (cm.hasPrimaryClip()) {
|
||||
Rect cursorRect = contentToViewRect(mSelectCursorBase);
|
||||
int[] location = new int[2];
|
||||
getLocationInWindow(location);
|
||||
cursorRect.offset(location[0] - mScrollX, location[1] - mScrollY);
|
||||
if (mPasteWindow == null) {
|
||||
mPasteWindow = new PastePopupWindow();
|
||||
}
|
||||
mPasteWindow.show(cursorRect, location[0], location[1]);
|
||||
}
|
||||
}
|
||||
|
||||
private void hidePasteButton() {
|
||||
if (mPasteWindow != null) {
|
||||
mPasteWindow.hide();
|
||||
}
|
||||
}
|
||||
|
||||
private void syncSelectionCursors() {
|
||||
mSelectCursorBaseLayerId =
|
||||
nativeGetHandleLayerId(mNativeClass, HANDLE_ID_BASE, mSelectCursorBase);
|
||||
@@ -5919,13 +6032,11 @@ public class WebView extends AbsoluteLayout
|
||||
|
||||
private boolean setupWebkitSelect() {
|
||||
syncSelectionCursors();
|
||||
ClipboardManager cm = (ClipboardManager)(mContext
|
||||
.getSystemService(Context.CLIPBOARD_SERVICE));
|
||||
if (!mIsCaretSelection || cm.hasPrimaryClip()) {
|
||||
if (!startSelectActionMode()) {
|
||||
selectionDone();
|
||||
return false;
|
||||
}
|
||||
if (mIsCaretSelection) {
|
||||
showPasteWindow();
|
||||
} else if (!startSelectActionMode()) {
|
||||
selectionDone();
|
||||
return false;
|
||||
}
|
||||
mSelectingText = true;
|
||||
mTouchMode = TOUCH_DRAG_MODE;
|
||||
@@ -5982,6 +6093,7 @@ public class WebView extends AbsoluteLayout
|
||||
*/
|
||||
void selectionDone() {
|
||||
if (mSelectingText) {
|
||||
hidePasteButton();
|
||||
mSelectingText = false;
|
||||
// finish is idempotent, so this is fine even if selectionDone was
|
||||
// called by mSelectCallback.onDestroyActionMode
|
||||
@@ -6051,12 +6163,8 @@ public class WebView extends AbsoluteLayout
|
||||
if (clipData != null) {
|
||||
ClipData.Item clipItem = clipData.getItemAt(0);
|
||||
CharSequence pasteText = clipItem.getText();
|
||||
if (pasteText != null) {
|
||||
int[] handles = new int[4];
|
||||
getSelectionHandles(handles);
|
||||
mWebViewCore.sendMessage(EventHub.DELETE_TEXT, handles);
|
||||
mWebViewCore.sendMessage(EventHub.INSERT_TEXT,
|
||||
pasteText.toString());
|
||||
if (mInputConnection != null) {
|
||||
mInputConnection.replaceSelection(pasteText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6614,6 +6722,7 @@ public class WebView extends AbsoluteLayout
|
||||
mSelectionStarted = true;
|
||||
mSelectDraggingCursor = mSelectCursorBase;
|
||||
mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
|
||||
hidePasteButton();
|
||||
} else if (mSelectHandleLeft != null
|
||||
&& mSelectHandleLeft.getBounds()
|
||||
.contains(shiftedX, shiftedY)) {
|
||||
@@ -7276,10 +7385,11 @@ public class WebView extends AbsoluteLayout
|
||||
|
||||
if (mSelectingText) {
|
||||
mSelectionStarted = false;
|
||||
syncSelectionCursors();
|
||||
if (mIsCaretSelection) {
|
||||
resetCaretTimer();
|
||||
showPasteWindow();
|
||||
}
|
||||
syncSelectionCursors();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user