1d8e057e067696d5e75999fcec1736b8963f3bf92satok/*
2d8e057e067696d5e75999fcec1736b8963f3bf92satok * Copyright (C) 2010 The Android Open Source Project
3d8e057e067696d5e75999fcec1736b8963f3bf92satok *
4d8e057e067696d5e75999fcec1736b8963f3bf92satok * Licensed under the Apache License, Version 2.0 (the "License");
5d8e057e067696d5e75999fcec1736b8963f3bf92satok * you may not use this file except in compliance with the License.
6d8e057e067696d5e75999fcec1736b8963f3bf92satok * You may obtain a copy of the License at
7d8e057e067696d5e75999fcec1736b8963f3bf92satok *
8d8e057e067696d5e75999fcec1736b8963f3bf92satok *      http://www.apache.org/licenses/LICENSE-2.0
9d8e057e067696d5e75999fcec1736b8963f3bf92satok *
10d8e057e067696d5e75999fcec1736b8963f3bf92satok * Unless required by applicable law or agreed to in writing, software
11d8e057e067696d5e75999fcec1736b8963f3bf92satok * distributed under the License is distributed on an "AS IS" BASIS,
12d8e057e067696d5e75999fcec1736b8963f3bf92satok * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d8e057e067696d5e75999fcec1736b8963f3bf92satok * See the License for the specific language governing permissions and
14d8e057e067696d5e75999fcec1736b8963f3bf92satok * limitations under the License.
15d8e057e067696d5e75999fcec1736b8963f3bf92satok */
16d8e057e067696d5e75999fcec1736b8963f3bf92satok
17d8e057e067696d5e75999fcec1736b8963f3bf92satokpackage com.android.ex.editstyledtext;
18d8e057e067696d5e75999fcec1736b8963f3bf92satok
19d8e057e067696d5e75999fcec1736b8963f3bf92satokimport java.io.InputStream;
20d8e057e067696d5e75999fcec1736b8963f3bf92satokimport java.util.ArrayList;
21d8e057e067696d5e75999fcec1736b8963f3bf92satokimport java.util.HashMap;
22d8e057e067696d5e75999fcec1736b8963f3bf92satok
23d8e057e067696d5e75999fcec1736b8963f3bf92satokimport com.android.ex.editstyledtext.EditStyledText.EditModeActions.EditModeActionBase;
24d8e057e067696d5e75999fcec1736b8963f3bf92satokimport com.android.ex.editstyledtext.EditStyledText.EditStyledTextSpans.HorizontalLineSpan;
25d8e057e067696d5e75999fcec1736b8963f3bf92satokimport com.android.ex.editstyledtext.EditStyledText.EditStyledTextSpans.MarqueeSpan;
26d8e057e067696d5e75999fcec1736b8963f3bf92satokimport com.android.ex.editstyledtext.EditStyledText.EditStyledTextSpans.RescalableImageSpan;
27d8e057e067696d5e75999fcec1736b8963f3bf92satok
28d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.R;
29d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.app.AlertDialog;
30d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.app.AlertDialog.Builder;
31d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.content.Context;
32d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.content.DialogInterface;
33d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.content.DialogInterface.OnCancelListener;
34d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.graphics.Bitmap;
35d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.graphics.BitmapFactory;
36d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.graphics.Canvas;
37d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.graphics.Color;
38d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.graphics.Rect;
39d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.graphics.drawable.BitmapDrawable;
40d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.graphics.drawable.Drawable;
41d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.graphics.drawable.ShapeDrawable;
42d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.graphics.drawable.shapes.RectShape;
43d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.net.Uri;
44d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.os.Bundle;
45d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.os.Parcel;
46d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.os.Parcelable;
47d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.os.ResultReceiver;
48d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.ClipboardManager;
49d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.Editable;
50d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.Html;
51d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.Layout;
52d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.NoCopySpan;
53d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.NoCopySpan.Concrete;
54d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.Selection;
55d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.Spannable;
56d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.SpannableStringBuilder;
57d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.Spanned;
58d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.TextPaint;
59d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.Html.ImageGetter;
60d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.Html.TagHandler;
61d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.method.ArrowKeyMovementMethod;
62d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.style.AbsoluteSizeSpan;
63d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.style.AlignmentSpan;
64d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.style.BackgroundColorSpan;
65d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.style.CharacterStyle;
66d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.style.DynamicDrawableSpan;
67d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.style.ForegroundColorSpan;
68d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.style.ImageSpan;
69d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.style.ParagraphStyle;
70d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.style.QuoteSpan;
71d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.text.style.UnderlineSpan;
72d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.util.AttributeSet;
73d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.util.Log;
74d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.view.ContextMenu;
75d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.view.Gravity;
76d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.view.KeyEvent;
77d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.view.MenuItem;
78d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.view.MotionEvent;
79d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.view.View;
80d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.view.inputmethod.EditorInfo;
81d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.view.inputmethod.InputConnection;
82d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.view.inputmethod.InputConnectionWrapper;
83d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.view.inputmethod.InputMethodManager;
84d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.widget.Button;
85d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.widget.EditText;
86d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.widget.LinearLayout;
87d8e057e067696d5e75999fcec1736b8963f3bf92satokimport android.widget.TextView;
88d8e057e067696d5e75999fcec1736b8963f3bf92satok
89d8e057e067696d5e75999fcec1736b8963f3bf92satok/**
90d8e057e067696d5e75999fcec1736b8963f3bf92satok * EditStyledText extends EditText for managing the flow and status to edit the styled text. This
91d8e057e067696d5e75999fcec1736b8963f3bf92satok * manages the states and flows of editing, supports inserting image, import/export HTML.
92d8e057e067696d5e75999fcec1736b8963f3bf92satok */
93d8e057e067696d5e75999fcec1736b8963f3bf92satokpublic class EditStyledText extends EditText {
94d8e057e067696d5e75999fcec1736b8963f3bf92satok
95d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final String TAG = "EditStyledText";
96d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
97d8e057e067696d5e75999fcec1736b8963f3bf92satok     * DBG should be false at checking in.
98d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
99d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final boolean DBG = true;
100d8e057e067696d5e75999fcec1736b8963f3bf92satok
101d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
102d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Modes of editing actions.
103d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
104d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** The mode that no editing action is done. */
105d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_NOTHING = 0;
106d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** The mode of copy. */
107d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_COPY = 1;
108d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** The mode of paste. */
109d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_PASTE = 2;
110d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** The mode of changing size. */
111d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_SIZE = 3;
112d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** The mode of changing color. */
113d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_COLOR = 4;
114d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** The mode of selection. */
115d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_SELECT = 5;
116d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** The mode of changing alignment. */
117d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_ALIGN = 6;
118d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** The mode of changing cut. */
119d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_CUT = 7;
120d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_TELOP = 8;
121d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_SWING = 9;
122d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_MARQUEE = 10;
123d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_SELECTALL = 11;
124d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_HORIZONTALLINE = 12;
125d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_STOP_SELECT = 13;
126d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_CLEARSTYLES = 14;
127d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_IMAGE = 15;
128d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_BGCOLOR = 16;
129d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_PREVIEW = 17;
130d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_CANCEL = 18;
131d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_TEXTVIEWFUNCTION = 19;
132d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_START_EDIT = 20;
133d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_END_EDIT = 21;
134d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_RESET = 22;
135d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int MODE_SHOW_MENU = 23;
136d8e057e067696d5e75999fcec1736b8963f3bf92satok
137d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
138d8e057e067696d5e75999fcec1736b8963f3bf92satok     * States of selection.
139d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
140d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** The state that selection isn't started. */
141d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int STATE_SELECT_OFF = 0;
142d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** The state that selection is started. */
143d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int STATE_SELECT_ON = 1;
144d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** The state that selection is done, but not fixed. */
145d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int STATE_SELECTED = 2;
146d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** The state that selection is done and not fixed. */
147d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int STATE_SELECT_FIX = 3;
148d8e057e067696d5e75999fcec1736b8963f3bf92satok
149d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
150d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Help message strings.
151d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
152d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int HINT_MSG_NULL = 0;
153d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int HINT_MSG_COPY_BUF_BLANK = 1;
154d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int HINT_MSG_SELECT_START = 2;
155d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int HINT_MSG_SELECT_END = 3;
156d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int HINT_MSG_PUSH_COMPETE = 4;
157d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int HINT_MSG_BIG_SIZE_ERROR = 5;
158d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int HINT_MSG_END_PREVIEW = 6;
159d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int HINT_MSG_END_COMPOSE = 7;
160d8e057e067696d5e75999fcec1736b8963f3bf92satok
161d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
162d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Fixed Values.
163d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
164d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int DEFAULT_TRANSPARENT_COLOR = 0x00FFFFFF;
165d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final int DEFAULT_FOREGROUND_COLOR = 0xFF000000;
166d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final char ZEROWIDTHCHAR = '\u2060';
167d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static final char IMAGECHAR = '\uFFFC';
168d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final int ID_SELECT_ALL = android.R.id.selectAll;
169d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final int ID_START_SELECTING_TEXT = android.R.id.startSelectingText;
170d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final int ID_STOP_SELECTING_TEXT = android.R.id.stopSelectingText;
171d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final int ID_PASTE = android.R.id.paste;
172d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final int ID_COPY = android.R.id.copy;
173d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final int ID_CUT = android.R.id.cut;
174d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final int ID_HORIZONTALLINE = 0x00FFFF01;
175d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final int ID_CLEARSTYLES = 0x00FFFF02;
176d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final int ID_SHOWEDIT = 0x00FFFF03;
177d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final int ID_HIDEEDIT = 0x00FFFF04;
178d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final int MAXIMAGEWIDTHDIP = 300;
179d8e057e067696d5e75999fcec1736b8963f3bf92satok
180d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
181d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Strings for context menu. TODO: Extract the strings to strings.xml.
182d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
183d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static CharSequence STR_HORIZONTALLINE;
184d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static CharSequence STR_CLEARSTYLES;
185d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static CharSequence STR_PASTE;
186d8e057e067696d5e75999fcec1736b8963f3bf92satok
187d8e057e067696d5e75999fcec1736b8963f3bf92satok    private float mPaddingScale = 0;
188d8e057e067696d5e75999fcec1736b8963f3bf92satok    private ArrayList<EditStyledTextNotifier> mESTNotifiers;
189d8e057e067696d5e75999fcec1736b8963f3bf92satok    private Drawable mDefaultBackground;
190d8e057e067696d5e75999fcec1736b8963f3bf92satok    // EditStyledTextEditorManager manages the flow and status of each function of StyledText.
191d8e057e067696d5e75999fcec1736b8963f3bf92satok    private EditorManager mManager;
192d8e057e067696d5e75999fcec1736b8963f3bf92satok    private InputConnection mInputConnection;
193d8e057e067696d5e75999fcec1736b8963f3bf92satok    private StyledTextConverter mConverter;
194d8e057e067696d5e75999fcec1736b8963f3bf92satok    private StyledTextDialog mDialog;
195d8e057e067696d5e75999fcec1736b8963f3bf92satok
196d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final Concrete SELECTING = new NoCopySpan.Concrete();
197d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static final int PRESSED = Spannable.SPAN_MARK_MARK | (1 << Spannable.SPAN_USER_SHIFT);
198d8e057e067696d5e75999fcec1736b8963f3bf92satok
199d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
200d8e057e067696d5e75999fcec1736b8963f3bf92satok     * EditStyledText extends EditText for managing flow of each editing action.
201d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
202d8e057e067696d5e75999fcec1736b8963f3bf92satok    public EditStyledText(Context context, AttributeSet attrs, int defStyle) {
203d8e057e067696d5e75999fcec1736b8963f3bf92satok        super(context, attrs, defStyle);
204d8e057e067696d5e75999fcec1736b8963f3bf92satok        init();
205d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
206d8e057e067696d5e75999fcec1736b8963f3bf92satok
207d8e057e067696d5e75999fcec1736b8963f3bf92satok    public EditStyledText(Context context, AttributeSet attrs) {
208d8e057e067696d5e75999fcec1736b8963f3bf92satok        super(context, attrs);
209d8e057e067696d5e75999fcec1736b8963f3bf92satok        init();
210d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
211d8e057e067696d5e75999fcec1736b8963f3bf92satok
212d8e057e067696d5e75999fcec1736b8963f3bf92satok    public EditStyledText(Context context) {
213d8e057e067696d5e75999fcec1736b8963f3bf92satok        super(context);
214d8e057e067696d5e75999fcec1736b8963f3bf92satok        init();
215d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
216d8e057e067696d5e75999fcec1736b8963f3bf92satok
217d8e057e067696d5e75999fcec1736b8963f3bf92satok    @Override
218d8e057e067696d5e75999fcec1736b8963f3bf92satok    public boolean onTouchEvent(MotionEvent event) {
219d8e057e067696d5e75999fcec1736b8963f3bf92satok        boolean superResult;
220d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (event.getAction() == MotionEvent.ACTION_UP) {
221d8e057e067696d5e75999fcec1736b8963f3bf92satok            cancelLongPress();
222d8e057e067696d5e75999fcec1736b8963f3bf92satok            boolean editting = isEditting();
223d8e057e067696d5e75999fcec1736b8963f3bf92satok            // If View is touched but not in Edit Mode, starts Edit Mode.
224d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (!editting) {
225d8e057e067696d5e75999fcec1736b8963f3bf92satok                onStartEdit();
226d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
227d8e057e067696d5e75999fcec1736b8963f3bf92satok            int oldSelStart = Selection.getSelectionStart(getText());
228d8e057e067696d5e75999fcec1736b8963f3bf92satok            int oldSelEnd = Selection.getSelectionEnd(getText());
229d8e057e067696d5e75999fcec1736b8963f3bf92satok            superResult = super.onTouchEvent(event);
230d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (isFocused()) {
231d8e057e067696d5e75999fcec1736b8963f3bf92satok                // If selection is started, don't open soft key by
232d8e057e067696d5e75999fcec1736b8963f3bf92satok                // touching.
233d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (getSelectState() == STATE_SELECT_OFF) {
234d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (editting) {
235d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mManager.showSoftKey(Selection.getSelectionStart(getText()),
236d8e057e067696d5e75999fcec1736b8963f3bf92satok                                Selection.getSelectionEnd(getText()));
237d8e057e067696d5e75999fcec1736b8963f3bf92satok                    } else {
238d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mManager.showSoftKey(oldSelStart, oldSelEnd);
239d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
240d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
241d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
242d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager.onCursorMoved();
243d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager.unsetTextComposingMask();
244d8e057e067696d5e75999fcec1736b8963f3bf92satok        } else {
245d8e057e067696d5e75999fcec1736b8963f3bf92satok            superResult = super.onTouchEvent(event);
246d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
247d8e057e067696d5e75999fcec1736b8963f3bf92satok        sendOnTouchEvent(event);
248d8e057e067696d5e75999fcec1736b8963f3bf92satok        return superResult;
249d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
250d8e057e067696d5e75999fcec1736b8963f3bf92satok
251d8e057e067696d5e75999fcec1736b8963f3bf92satok    @Override
252d8e057e067696d5e75999fcec1736b8963f3bf92satok    public Parcelable onSaveInstanceState() {
253d8e057e067696d5e75999fcec1736b8963f3bf92satok        Parcelable superState = super.onSaveInstanceState();
254d8e057e067696d5e75999fcec1736b8963f3bf92satok        SavedStyledTextState ss = new SavedStyledTextState(superState);
255d8e057e067696d5e75999fcec1736b8963f3bf92satok        ss.mBackgroundColor = mManager.getBackgroundColor();
256d8e057e067696d5e75999fcec1736b8963f3bf92satok        return ss;
257d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
258d8e057e067696d5e75999fcec1736b8963f3bf92satok
259d8e057e067696d5e75999fcec1736b8963f3bf92satok    @Override
260d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onRestoreInstanceState(Parcelable state) {
261d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (!(state instanceof SavedStyledTextState)) {
262d8e057e067696d5e75999fcec1736b8963f3bf92satok            super.onRestoreInstanceState(state);
263d8e057e067696d5e75999fcec1736b8963f3bf92satok            return;
264d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
265d8e057e067696d5e75999fcec1736b8963f3bf92satok        SavedStyledTextState ss = (SavedStyledTextState) state;
266d8e057e067696d5e75999fcec1736b8963f3bf92satok        super.onRestoreInstanceState(ss.getSuperState());
267d8e057e067696d5e75999fcec1736b8963f3bf92satok        setBackgroundColor(ss.mBackgroundColor);
268d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
269d8e057e067696d5e75999fcec1736b8963f3bf92satok
270d8e057e067696d5e75999fcec1736b8963f3bf92satok    @Override
271d8e057e067696d5e75999fcec1736b8963f3bf92satok    protected void drawableStateChanged() {
272d8e057e067696d5e75999fcec1736b8963f3bf92satok        super.drawableStateChanged();
273d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mManager != null) {
274d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager.onRefreshStyles();
275d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
276d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
277d8e057e067696d5e75999fcec1736b8963f3bf92satok
278d8e057e067696d5e75999fcec1736b8963f3bf92satok    @Override
279d8e057e067696d5e75999fcec1736b8963f3bf92satok    public boolean onTextContextMenuItem(int id) {
280d8e057e067696d5e75999fcec1736b8963f3bf92satok        boolean selection = getSelectionStart() != getSelectionEnd();
281d8e057e067696d5e75999fcec1736b8963f3bf92satok        switch (id) {
282d8e057e067696d5e75999fcec1736b8963f3bf92satok            case ID_SELECT_ALL:
283d8e057e067696d5e75999fcec1736b8963f3bf92satok                onStartSelectAll();
284d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
285d8e057e067696d5e75999fcec1736b8963f3bf92satok            case ID_START_SELECTING_TEXT:
286d8e057e067696d5e75999fcec1736b8963f3bf92satok                onStartSelect();
287d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.blockSoftKey();
288d8e057e067696d5e75999fcec1736b8963f3bf92satok                break;
289d8e057e067696d5e75999fcec1736b8963f3bf92satok            case ID_STOP_SELECTING_TEXT:
290d8e057e067696d5e75999fcec1736b8963f3bf92satok                onFixSelectedItem();
291d8e057e067696d5e75999fcec1736b8963f3bf92satok                break;
292d8e057e067696d5e75999fcec1736b8963f3bf92satok            case ID_PASTE:
293d8e057e067696d5e75999fcec1736b8963f3bf92satok                onStartPaste();
294d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
295d8e057e067696d5e75999fcec1736b8963f3bf92satok            case ID_COPY:
296d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (selection) {
297d8e057e067696d5e75999fcec1736b8963f3bf92satok                    onStartCopy();
298d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else {
299d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.onStartSelectAll(false);
300d8e057e067696d5e75999fcec1736b8963f3bf92satok                    onStartCopy();
301d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
302d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
303d8e057e067696d5e75999fcec1736b8963f3bf92satok            case ID_CUT:
304d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (selection) {
305d8e057e067696d5e75999fcec1736b8963f3bf92satok                    onStartCut();
306d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else {
307d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.onStartSelectAll(false);
308d8e057e067696d5e75999fcec1736b8963f3bf92satok                    onStartCut();
309d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
310d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
311d8e057e067696d5e75999fcec1736b8963f3bf92satok            case ID_HORIZONTALLINE:
312d8e057e067696d5e75999fcec1736b8963f3bf92satok                onInsertHorizontalLine();
313d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
314d8e057e067696d5e75999fcec1736b8963f3bf92satok            case ID_CLEARSTYLES:
315d8e057e067696d5e75999fcec1736b8963f3bf92satok                onClearStyles();
316d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
317d8e057e067696d5e75999fcec1736b8963f3bf92satok            case ID_SHOWEDIT:
318d8e057e067696d5e75999fcec1736b8963f3bf92satok                onStartEdit();
319d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
320d8e057e067696d5e75999fcec1736b8963f3bf92satok            case ID_HIDEEDIT:
321d8e057e067696d5e75999fcec1736b8963f3bf92satok                onEndEdit();
322d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
323d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
324d8e057e067696d5e75999fcec1736b8963f3bf92satok        return super.onTextContextMenuItem(id);
325d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
326d8e057e067696d5e75999fcec1736b8963f3bf92satok
327d8e057e067696d5e75999fcec1736b8963f3bf92satok    @Override
328d8e057e067696d5e75999fcec1736b8963f3bf92satok    protected void onCreateContextMenu(ContextMenu menu) {
329d8e057e067696d5e75999fcec1736b8963f3bf92satok        super.onCreateContextMenu(menu);
330d8e057e067696d5e75999fcec1736b8963f3bf92satok        MenuHandler handler = new MenuHandler();
331d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (STR_HORIZONTALLINE != null) {
332d8e057e067696d5e75999fcec1736b8963f3bf92satok            menu.add(0, ID_HORIZONTALLINE, 0, STR_HORIZONTALLINE).setOnMenuItemClickListener(
333d8e057e067696d5e75999fcec1736b8963f3bf92satok                    handler);
334d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
335d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (isStyledText() && STR_CLEARSTYLES != null) {
336d8e057e067696d5e75999fcec1736b8963f3bf92satok            menu.add(0, ID_CLEARSTYLES, 0, STR_CLEARSTYLES)
337d8e057e067696d5e75999fcec1736b8963f3bf92satok                    .setOnMenuItemClickListener(handler);
338d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
339d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mManager.canPaste()) {
340d8e057e067696d5e75999fcec1736b8963f3bf92satok            menu.add(0, ID_PASTE, 0, STR_PASTE)
341d8e057e067696d5e75999fcec1736b8963f3bf92satok                    .setOnMenuItemClickListener(handler).setAlphabeticShortcut('v');
342d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
343d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
344d8e057e067696d5e75999fcec1736b8963f3bf92satok
345d8e057e067696d5e75999fcec1736b8963f3bf92satok    @Override
346d8e057e067696d5e75999fcec1736b8963f3bf92satok    protected void onTextChanged(CharSequence text, int start, int before, int after) {
347d8e057e067696d5e75999fcec1736b8963f3bf92satok        // onTextChanged will be called super's constructor.
348d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mManager != null) {
349d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager.updateSpanNextToCursor(getText(), start, before, after);
350d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager.updateSpanPreviousFromCursor(getText(), start, before, after);
351d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (after > before) {
352d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.setTextComposingMask(start, start + after);
353d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else if (before < after) {
354d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.unsetTextComposingMask();
355d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
356d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mManager.isWaitInput()) {
357d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (after > before) {
358d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.onCursorMoved();
359d8e057e067696d5e75999fcec1736b8963f3bf92satok                    onFixSelectedItem();
360d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else if (after < before) {
361d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.onAction(MODE_RESET);
362d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
363d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
364d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
365d8e057e067696d5e75999fcec1736b8963f3bf92satok        super.onTextChanged(text, start, before, after);
366d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
367d8e057e067696d5e75999fcec1736b8963f3bf92satok
368d8e057e067696d5e75999fcec1736b8963f3bf92satok    @Override
369d8e057e067696d5e75999fcec1736b8963f3bf92satok    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
370d8e057e067696d5e75999fcec1736b8963f3bf92satok        mInputConnection =
371d8e057e067696d5e75999fcec1736b8963f3bf92satok                new StyledTextInputConnection(super.onCreateInputConnection(outAttrs), this);
372d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mInputConnection;
373d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
374d8e057e067696d5e75999fcec1736b8963f3bf92satok
375d8e057e067696d5e75999fcec1736b8963f3bf92satok    @Override
376d8e057e067696d5e75999fcec1736b8963f3bf92satok    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
377d8e057e067696d5e75999fcec1736b8963f3bf92satok        super.onFocusChanged(focused, direction, previouslyFocusedRect);
378d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (focused) {
379d8e057e067696d5e75999fcec1736b8963f3bf92satok            onStartEdit();
380d8e057e067696d5e75999fcec1736b8963f3bf92satok        } else if (!isButtonsFocused()) {
381d8e057e067696d5e75999fcec1736b8963f3bf92satok            onEndEdit();
382d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
383d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
384d8e057e067696d5e75999fcec1736b8963f3bf92satok
385d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
386d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Initialize members.
387d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
388d8e057e067696d5e75999fcec1736b8963f3bf92satok    private void init() {
389d8e057e067696d5e75999fcec1736b8963f3bf92satok        mConverter = new StyledTextConverter(this, new StyledTextHtmlStandard());
390d8e057e067696d5e75999fcec1736b8963f3bf92satok        mDialog = new StyledTextDialog(this);
391d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager = new EditorManager(this, mDialog);
392d8e057e067696d5e75999fcec1736b8963f3bf92satok        setMovementMethod(new StyledTextArrowKeyMethod(mManager));
393d8e057e067696d5e75999fcec1736b8963f3bf92satok        mDefaultBackground = getBackground();
394d8e057e067696d5e75999fcec1736b8963f3bf92satok        requestFocus();
395d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
396d8e057e067696d5e75999fcec1736b8963f3bf92satok
397d8e057e067696d5e75999fcec1736b8963f3bf92satok    public interface StyledTextHtmlConverter {
398d8e057e067696d5e75999fcec1736b8963f3bf92satok        public String toHtml(Spanned text);
399d8e057e067696d5e75999fcec1736b8963f3bf92satok
400d8e057e067696d5e75999fcec1736b8963f3bf92satok        public String toHtml(Spanned text, boolean escapeNonAsciiChar);
401d8e057e067696d5e75999fcec1736b8963f3bf92satok
402d8e057e067696d5e75999fcec1736b8963f3bf92satok        public String toHtml(Spanned text, boolean escapeNonAsciiChar, int width, float scale);
403d8e057e067696d5e75999fcec1736b8963f3bf92satok
404d8e057e067696d5e75999fcec1736b8963f3bf92satok        public Spanned fromHtml(String string);
405d8e057e067696d5e75999fcec1736b8963f3bf92satok
406d8e057e067696d5e75999fcec1736b8963f3bf92satok        public Spanned fromHtml(String source, ImageGetter imageGetter, TagHandler tagHandler);
407d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
408d8e057e067696d5e75999fcec1736b8963f3bf92satok
409d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setStyledTextHtmlConverter(StyledTextHtmlConverter html) {
410d8e057e067696d5e75999fcec1736b8963f3bf92satok        mConverter.setStyledTextHtmlConverter(html);
411d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
412d8e057e067696d5e75999fcec1736b8963f3bf92satok
413d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
414d8e057e067696d5e75999fcec1736b8963f3bf92satok     * EditStyledTextInterface provides functions for notifying messages to calling class.
415d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
416d8e057e067696d5e75999fcec1736b8963f3bf92satok    public interface EditStyledTextNotifier {
417d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void sendHintMsg(int msgId);
418d8e057e067696d5e75999fcec1736b8963f3bf92satok
419d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onStateChanged(int mode, int state);
420d8e057e067696d5e75999fcec1736b8963f3bf92satok
421d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean sendOnTouchEvent(MotionEvent event);
422d8e057e067696d5e75999fcec1736b8963f3bf92satok
423d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean isButtonsFocused();
424d8e057e067696d5e75999fcec1736b8963f3bf92satok
425d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean showPreview();
426d8e057e067696d5e75999fcec1736b8963f3bf92satok
427d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void cancelViewManager();
428d8e057e067696d5e75999fcec1736b8963f3bf92satok
429d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean showInsertImageSelectAlertDialog();
430d8e057e067696d5e75999fcec1736b8963f3bf92satok
431d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean showMenuAlertDialog();
432d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
433d8e057e067696d5e75999fcec1736b8963f3bf92satok
434d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
435d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Add Notifier.
436d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
437d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void addEditStyledTextListener(EditStyledTextNotifier estInterface) {
438d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mESTNotifiers == null) {
439d8e057e067696d5e75999fcec1736b8963f3bf92satok            mESTNotifiers = new ArrayList<EditStyledTextNotifier>();
440d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
441d8e057e067696d5e75999fcec1736b8963f3bf92satok        mESTNotifiers.add(estInterface);
442d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
443d8e057e067696d5e75999fcec1736b8963f3bf92satok
444d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
445d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Remove Notifier.
446d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
447d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void removeEditStyledTextListener(EditStyledTextNotifier estInterface) {
448d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mESTNotifiers != null) {
449d8e057e067696d5e75999fcec1736b8963f3bf92satok            int i = mESTNotifiers.indexOf(estInterface);
450d8e057e067696d5e75999fcec1736b8963f3bf92satok
451d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (i > 0) {
452d8e057e067696d5e75999fcec1736b8963f3bf92satok                mESTNotifiers.remove(i);
453d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
454d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
455d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
456d8e057e067696d5e75999fcec1736b8963f3bf92satok
457d8e057e067696d5e75999fcec1736b8963f3bf92satok    private void sendOnTouchEvent(MotionEvent event) {
458d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mESTNotifiers != null) {
459d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (EditStyledTextNotifier notifier : mESTNotifiers) {
460d8e057e067696d5e75999fcec1736b8963f3bf92satok                notifier.sendOnTouchEvent(event);
461d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
462d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
463d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
464d8e057e067696d5e75999fcec1736b8963f3bf92satok
465d8e057e067696d5e75999fcec1736b8963f3bf92satok    public boolean isButtonsFocused() {
466d8e057e067696d5e75999fcec1736b8963f3bf92satok        boolean retval = false;
467d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mESTNotifiers != null) {
468d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (EditStyledTextNotifier notifier : mESTNotifiers) {
469d8e057e067696d5e75999fcec1736b8963f3bf92satok                retval |= notifier.isButtonsFocused();
470d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
471d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
472d8e057e067696d5e75999fcec1736b8963f3bf92satok        return retval;
473d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
474d8e057e067696d5e75999fcec1736b8963f3bf92satok
475d8e057e067696d5e75999fcec1736b8963f3bf92satok    private void showPreview() {
476d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mESTNotifiers != null) {
477d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (EditStyledTextNotifier notifier : mESTNotifiers) {
478d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (notifier.showPreview()) {
479d8e057e067696d5e75999fcec1736b8963f3bf92satok                    break;
480d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
481d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
482d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
483d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
484d8e057e067696d5e75999fcec1736b8963f3bf92satok
485d8e057e067696d5e75999fcec1736b8963f3bf92satok    private void cancelViewManagers() {
486d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mESTNotifiers != null) {
487d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (EditStyledTextNotifier notifier : mESTNotifiers) {
488d8e057e067696d5e75999fcec1736b8963f3bf92satok                notifier.cancelViewManager();
489d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
490d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
491d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
492d8e057e067696d5e75999fcec1736b8963f3bf92satok
493d8e057e067696d5e75999fcec1736b8963f3bf92satok    private void showInsertImageSelectAlertDialog() {
494d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mESTNotifiers != null) {
495d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (EditStyledTextNotifier notifier : mESTNotifiers) {
496d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (notifier.showInsertImageSelectAlertDialog()) {
497d8e057e067696d5e75999fcec1736b8963f3bf92satok                    break;
498d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
499d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
500d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
501d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
502d8e057e067696d5e75999fcec1736b8963f3bf92satok
503d8e057e067696d5e75999fcec1736b8963f3bf92satok    private void showMenuAlertDialog() {
504d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mESTNotifiers != null) {
505d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (EditStyledTextNotifier notifier : mESTNotifiers) {
506d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (notifier.showMenuAlertDialog()) {
507d8e057e067696d5e75999fcec1736b8963f3bf92satok                    break;
508d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
509d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
510d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
511d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
512d8e057e067696d5e75999fcec1736b8963f3bf92satok
513d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
514d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Notify hint messages what action is expected to calling class.
515d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
516d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param msgId Id of the hint message.
517d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
518d8e057e067696d5e75999fcec1736b8963f3bf92satok    private void sendHintMessage(int msgId) {
519d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mESTNotifiers != null) {
520d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (EditStyledTextNotifier notifier : mESTNotifiers) {
521d8e057e067696d5e75999fcec1736b8963f3bf92satok                notifier.sendHintMsg(msgId);
522d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
523d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
524d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
525d8e057e067696d5e75999fcec1736b8963f3bf92satok
526d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
527d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Notify the event that the mode and state are changed.
528d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
529d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param mode Mode of the editing action.
530d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param state Mode of the selection state.
531d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
532d8e057e067696d5e75999fcec1736b8963f3bf92satok    private void notifyStateChanged(int mode, int state) {
533d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mESTNotifiers != null) {
534d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (EditStyledTextNotifier notifier : mESTNotifiers) {
535d8e057e067696d5e75999fcec1736b8963f3bf92satok                notifier.onStateChanged(mode, state);
536d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
537d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
538d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
539d8e057e067696d5e75999fcec1736b8963f3bf92satok
540d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** Start to edit styled text */
541d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartEdit() {
542d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_START_EDIT);
543d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
544d8e057e067696d5e75999fcec1736b8963f3bf92satok
545d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** End of editing styled text */
546d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onEndEdit() {
547d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_END_EDIT);
548d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
549d8e057e067696d5e75999fcec1736b8963f3bf92satok
550d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onResetEdit() {
551d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_RESET);
552d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
553d8e057e067696d5e75999fcec1736b8963f3bf92satok
554d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** Start to copy styled text */
555d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartCopy() {
556d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_COPY);
557d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
558d8e057e067696d5e75999fcec1736b8963f3bf92satok
559d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** Start to cut styled text */
560d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartCut() {
561d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_CUT);
562d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
563d8e057e067696d5e75999fcec1736b8963f3bf92satok
564d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** Start to paste styled text */
565d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartPaste() {
566d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_PASTE);
567d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
568d8e057e067696d5e75999fcec1736b8963f3bf92satok
569d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** Start to change size */
570d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartSize() {
571d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_SIZE);
572d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
573d8e057e067696d5e75999fcec1736b8963f3bf92satok
574d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** Start to change color */
575d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartColor() {
576d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_COLOR);
577d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
578d8e057e067696d5e75999fcec1736b8963f3bf92satok
579d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** Start to change background color */
580d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartBackgroundColor() {
581d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_BGCOLOR);
582d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
583d8e057e067696d5e75999fcec1736b8963f3bf92satok
584d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** Start to change Alignment */
585d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartAlign() {
586d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_ALIGN);
587d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
588d8e057e067696d5e75999fcec1736b8963f3bf92satok
589d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartTelop() {
590d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_TELOP);
591d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
592d8e057e067696d5e75999fcec1736b8963f3bf92satok
593d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartSwing() {
594d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_SWING);
595d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
596d8e057e067696d5e75999fcec1736b8963f3bf92satok
597d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartMarquee() {
598d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_MARQUEE);
599d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
600d8e057e067696d5e75999fcec1736b8963f3bf92satok
601d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** Start to select a text */
602d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartSelect() {
603d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onStartSelect(true);
604d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
605d8e057e067696d5e75999fcec1736b8963f3bf92satok
606d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** Start to select all characters */
607d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartSelectAll() {
608d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onStartSelectAll(true);
609d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
610d8e057e067696d5e75999fcec1736b8963f3bf92satok
611d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartShowPreview() {
612d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_PREVIEW);
613d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
614d8e057e067696d5e75999fcec1736b8963f3bf92satok
615d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartShowMenuAlertDialog() {
616d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onStartShowMenuAlertDialog();
617d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
618d8e057e067696d5e75999fcec1736b8963f3bf92satok
619d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onStartAction(int mode, boolean notifyStateChanged) {
620d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(mode, notifyStateChanged);
621d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
622d8e057e067696d5e75999fcec1736b8963f3bf92satok
623d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** Fix selection */
624d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onFixSelectedItem() {
625d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onFixSelectedItem();
626d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
627d8e057e067696d5e75999fcec1736b8963f3bf92satok
628d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onInsertImage() {
629d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_IMAGE);
630d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
631d8e057e067696d5e75999fcec1736b8963f3bf92satok
632d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
633d8e057e067696d5e75999fcec1736b8963f3bf92satok     * InsertImage to TextView by using URI
634d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
635d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param uri URI of the iamge inserted to TextView.
636d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
637d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onInsertImage(Uri uri) {
638d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onInsertImage(uri);
639d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
640d8e057e067696d5e75999fcec1736b8963f3bf92satok
641d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
642d8e057e067696d5e75999fcec1736b8963f3bf92satok     * InsertImage to TextView by using resource ID
643d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
644d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param resId Resource ID of the iamge inserted to TextView.
645d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
646d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onInsertImage(int resId) {
647d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onInsertImage(resId);
648d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
649d8e057e067696d5e75999fcec1736b8963f3bf92satok
650d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onInsertHorizontalLine() {
651d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onAction(MODE_HORIZONTALLINE);
652d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
653d8e057e067696d5e75999fcec1736b8963f3bf92satok
654d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onClearStyles() {
655d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onClearStyles();
656d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
657d8e057e067696d5e75999fcec1736b8963f3bf92satok
658d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onBlockSoftKey() {
659d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.blockSoftKey();
660d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
661d8e057e067696d5e75999fcec1736b8963f3bf92satok
662d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onUnblockSoftKey() {
663d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.unblockSoftKey();
664d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
665d8e057e067696d5e75999fcec1736b8963f3bf92satok
666d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void onCancelViewManagers() {
667d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onCancelViewManagers();
668d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
669d8e057e067696d5e75999fcec1736b8963f3bf92satok
670d8e057e067696d5e75999fcec1736b8963f3bf92satok    private void onRefreshStyles() {
671d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onRefreshStyles();
672d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
673d8e057e067696d5e75999fcec1736b8963f3bf92satok
674d8e057e067696d5e75999fcec1736b8963f3bf92satok    private void onRefreshZeoWidthChar() {
675d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.onRefreshZeoWidthChar();
676d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
677d8e057e067696d5e75999fcec1736b8963f3bf92satok
678d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
679d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Set Size of the Item.
680d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
681d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param size The size of the Item.
682d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
683d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setItemSize(int size) {
684d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.setItemSize(size, true);
685d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
686d8e057e067696d5e75999fcec1736b8963f3bf92satok
687d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
688d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Set Color of the Item.
689d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
690d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param color The color of the Item.
691d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
692d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setItemColor(int color) {
693d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.setItemColor(color, true);
694d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
695d8e057e067696d5e75999fcec1736b8963f3bf92satok
696d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
697d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Set Alignment of the Item.
698d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
699d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param align The color of the Item.
700d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
701d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setAlignment(Layout.Alignment align) {
702d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.setAlignment(align);
703d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
704d8e057e067696d5e75999fcec1736b8963f3bf92satok
705d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
706d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Set Background color of View.
707d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
708d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param color The background color of view.
709d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
710d8e057e067696d5e75999fcec1736b8963f3bf92satok    @Override
711d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setBackgroundColor(int color) {
712d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (color != DEFAULT_TRANSPARENT_COLOR) {
713d8e057e067696d5e75999fcec1736b8963f3bf92satok            super.setBackgroundColor(color);
714d8e057e067696d5e75999fcec1736b8963f3bf92satok        } else {
715d8e057e067696d5e75999fcec1736b8963f3bf92satok            setBackgroundDrawable(mDefaultBackground);
716d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
717d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.setBackgroundColor(color);
718d8e057e067696d5e75999fcec1736b8963f3bf92satok        onRefreshStyles();
719d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
720d8e057e067696d5e75999fcec1736b8963f3bf92satok
721d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setMarquee(int marquee) {
722d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.setMarquee(marquee);
723d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
724d8e057e067696d5e75999fcec1736b8963f3bf92satok
725d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
726d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Set html to EditStyledText.
727d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
728d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param html The html to be set.
729d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
730d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setHtml(String html) {
731d8e057e067696d5e75999fcec1736b8963f3bf92satok        mConverter.SetHtml(html);
732d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
733d8e057e067696d5e75999fcec1736b8963f3bf92satok
734d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
735d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Set Builder for AlertDialog.
736d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
737d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param builder Builder for opening Alert Dialog.
738d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
739d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setBuilder(Builder builder) {
740d8e057e067696d5e75999fcec1736b8963f3bf92satok        mDialog.setBuilder(builder);
741d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
742d8e057e067696d5e75999fcec1736b8963f3bf92satok
743d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
744d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Set Parameters for ColorAlertDialog.
745d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
746d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param colortitle Title for Alert Dialog.
747d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param colornames List of name of selecting color.
748d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param colorints List of int of color.
749d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
750d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setColorAlertParams(CharSequence colortitle, CharSequence[] colornames,
751d8e057e067696d5e75999fcec1736b8963f3bf92satok            CharSequence[] colorints, CharSequence transparent) {
752d8e057e067696d5e75999fcec1736b8963f3bf92satok        mDialog.setColorAlertParams(colortitle, colornames, colorints, transparent);
753d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
754d8e057e067696d5e75999fcec1736b8963f3bf92satok
755d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
756d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Set Parameters for SizeAlertDialog.
757d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
758d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param sizetitle Title for Alert Dialog.
759d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param sizenames List of name of selecting size.
760d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param sizedisplayints List of int of size displayed in TextView.
761d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param sizesendints List of int of size exported to HTML.
762d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
763d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setSizeAlertParams(CharSequence sizetitle, CharSequence[] sizenames,
764d8e057e067696d5e75999fcec1736b8963f3bf92satok            CharSequence[] sizedisplayints, CharSequence[] sizesendints) {
765d8e057e067696d5e75999fcec1736b8963f3bf92satok        mDialog.setSizeAlertParams(sizetitle, sizenames, sizedisplayints, sizesendints);
766d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
767d8e057e067696d5e75999fcec1736b8963f3bf92satok
768d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setAlignAlertParams(CharSequence aligntitle, CharSequence[] alignnames) {
769d8e057e067696d5e75999fcec1736b8963f3bf92satok        mDialog.setAlignAlertParams(aligntitle, alignnames);
770d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
771d8e057e067696d5e75999fcec1736b8963f3bf92satok
772d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setMarqueeAlertParams(CharSequence marqueetitle, CharSequence[] marqueenames) {
773d8e057e067696d5e75999fcec1736b8963f3bf92satok        mDialog.setMarqueeAlertParams(marqueetitle, marqueenames);
774d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
775d8e057e067696d5e75999fcec1736b8963f3bf92satok
776d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void setContextMenuStrings(CharSequence horizontalline, CharSequence clearstyles,
777d8e057e067696d5e75999fcec1736b8963f3bf92satok            CharSequence paste) {
778d8e057e067696d5e75999fcec1736b8963f3bf92satok        STR_HORIZONTALLINE = horizontalline;
779d8e057e067696d5e75999fcec1736b8963f3bf92satok        STR_CLEARSTYLES = clearstyles;
780d8e057e067696d5e75999fcec1736b8963f3bf92satok        STR_PASTE = paste;
781d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
782d8e057e067696d5e75999fcec1736b8963f3bf92satok
783d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
784d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Check whether editing is started or not.
785d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
786d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @return Whether editing is started or not.
787d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
788d8e057e067696d5e75999fcec1736b8963f3bf92satok    public boolean isEditting() {
789d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mManager.isEditting();
790d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
791d8e057e067696d5e75999fcec1736b8963f3bf92satok
792d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
793d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Check whether styled text or not.
794d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
795d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @return Whether styled text or not.
796d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
797d8e057e067696d5e75999fcec1736b8963f3bf92satok    public boolean isStyledText() {
798d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mManager.isStyledText();
799d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
800d8e057e067696d5e75999fcec1736b8963f3bf92satok
801d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
802d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Check whether SoftKey is Blocked or not.
803d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
804d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @return whether SoftKey is Blocked or not.
805d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
806d8e057e067696d5e75999fcec1736b8963f3bf92satok    public boolean isSoftKeyBlocked() {
807d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mManager.isSoftKeyBlocked();
808d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
809d8e057e067696d5e75999fcec1736b8963f3bf92satok
810d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
811d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Get the mode of the action.
812d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
813d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @return The mode of the action.
814d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
815d8e057e067696d5e75999fcec1736b8963f3bf92satok    public int getEditMode() {
816d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mManager.getEditMode();
817d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
818d8e057e067696d5e75999fcec1736b8963f3bf92satok
819d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
820d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Get the state of the selection.
821d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
822d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @return The state of the selection.
823d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
824d8e057e067696d5e75999fcec1736b8963f3bf92satok    public int getSelectState() {
825d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mManager.getSelectState();
826d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
827d8e057e067696d5e75999fcec1736b8963f3bf92satok
828d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
829d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Get the state of the selection.
830d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
831d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @return The state of the selection.
832d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
833d8e057e067696d5e75999fcec1736b8963f3bf92satok    public String getHtml() {
834d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mConverter.getHtml(true);
835d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
836d8e057e067696d5e75999fcec1736b8963f3bf92satok
837d8e057e067696d5e75999fcec1736b8963f3bf92satok    public String getHtml(boolean escapeFlag) {
838d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mConverter.getHtml(escapeFlag);
839d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
840d8e057e067696d5e75999fcec1736b8963f3bf92satok
841d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
842d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Get the state of the selection.
843d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
844d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @param uris The array of used uris.
845d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @return The state of the selection.
846d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
847d8e057e067696d5e75999fcec1736b8963f3bf92satok    public String getHtml(ArrayList<Uri> uris, boolean escapeFlag) {
848d8e057e067696d5e75999fcec1736b8963f3bf92satok        mConverter.getUriArray(uris, getText());
849d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mConverter.getHtml(escapeFlag);
850d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
851d8e057e067696d5e75999fcec1736b8963f3bf92satok
852d8e057e067696d5e75999fcec1736b8963f3bf92satok    public String getPreviewHtml() {
853d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mConverter.getPreviewHtml();
854d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
855d8e057e067696d5e75999fcec1736b8963f3bf92satok
856d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
857d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Get Background color of View.
858d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
859d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @return The background color of View.
860d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
861d8e057e067696d5e75999fcec1736b8963f3bf92satok    public int getBackgroundColor() {
862d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mManager.getBackgroundColor();
863d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
864d8e057e067696d5e75999fcec1736b8963f3bf92satok
865d8e057e067696d5e75999fcec1736b8963f3bf92satok    public EditorManager getEditStyledTextManager() {
866d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mManager;
867d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
868d8e057e067696d5e75999fcec1736b8963f3bf92satok
869d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
870d8e057e067696d5e75999fcec1736b8963f3bf92satok     * Get Foreground color of View.
871d8e057e067696d5e75999fcec1736b8963f3bf92satok     *
872d8e057e067696d5e75999fcec1736b8963f3bf92satok     * @return The background color of View.
873d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
874d8e057e067696d5e75999fcec1736b8963f3bf92satok    public int getForegroundColor(int pos) {
875d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (pos < 0 || pos > getText().length()) {
876d8e057e067696d5e75999fcec1736b8963f3bf92satok            return DEFAULT_FOREGROUND_COLOR;
877d8e057e067696d5e75999fcec1736b8963f3bf92satok        } else {
878d8e057e067696d5e75999fcec1736b8963f3bf92satok            ForegroundColorSpan[] spans =
879d8e057e067696d5e75999fcec1736b8963f3bf92satok                    getText().getSpans(pos, pos, ForegroundColorSpan.class);
880d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (spans.length > 0) {
881d8e057e067696d5e75999fcec1736b8963f3bf92satok                return spans[0].getForegroundColor();
882d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
883d8e057e067696d5e75999fcec1736b8963f3bf92satok                return DEFAULT_FOREGROUND_COLOR;
884d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
885d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
886d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
887d8e057e067696d5e75999fcec1736b8963f3bf92satok
888d8e057e067696d5e75999fcec1736b8963f3bf92satok    private void finishComposingText() {
889d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mInputConnection != null && !mManager.mTextIsFinishedFlag) {
890d8e057e067696d5e75999fcec1736b8963f3bf92satok            mInputConnection.finishComposingText();
891d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager.mTextIsFinishedFlag = true;
892d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
893d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
894d8e057e067696d5e75999fcec1736b8963f3bf92satok
895d8e057e067696d5e75999fcec1736b8963f3bf92satok    private float getPaddingScale() {
896d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mPaddingScale <= 0) {
897d8e057e067696d5e75999fcec1736b8963f3bf92satok            mPaddingScale = getContext().getResources().getDisplayMetrics().density;
898d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
899d8e057e067696d5e75999fcec1736b8963f3bf92satok        return mPaddingScale;
900d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
901d8e057e067696d5e75999fcec1736b8963f3bf92satok
902d8e057e067696d5e75999fcec1736b8963f3bf92satok    /** Convert pixcel to DIP */
903d8e057e067696d5e75999fcec1736b8963f3bf92satok    private int dipToPx(int dip) {
904d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (mPaddingScale <= 0) {
905d8e057e067696d5e75999fcec1736b8963f3bf92satok            mPaddingScale = getContext().getResources().getDisplayMetrics().density;
906d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
907d8e057e067696d5e75999fcec1736b8963f3bf92satok        return (int) ((float) dip * getPaddingScale() + 0.5);
908d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
909d8e057e067696d5e75999fcec1736b8963f3bf92satok
910d8e057e067696d5e75999fcec1736b8963f3bf92satok    private int getMaxImageWidthDip() {
911d8e057e067696d5e75999fcec1736b8963f3bf92satok        return MAXIMAGEWIDTHDIP;
912d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
913d8e057e067696d5e75999fcec1736b8963f3bf92satok
914d8e057e067696d5e75999fcec1736b8963f3bf92satok    private int getMaxImageWidthPx() {
915d8e057e067696d5e75999fcec1736b8963f3bf92satok        return dipToPx(MAXIMAGEWIDTHDIP);
916d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
917d8e057e067696d5e75999fcec1736b8963f3bf92satok
918d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void addAction(int mode, EditModeActionBase action) {
919d8e057e067696d5e75999fcec1736b8963f3bf92satok        mManager.addAction(mode, action);
920d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
921d8e057e067696d5e75999fcec1736b8963f3bf92satok
922d8e057e067696d5e75999fcec1736b8963f3bf92satok    public void addInputExtra(boolean create, String extra) {
923d8e057e067696d5e75999fcec1736b8963f3bf92satok        Bundle bundle = super.getInputExtras(create);
924d8e057e067696d5e75999fcec1736b8963f3bf92satok        if (bundle != null) {
925d8e057e067696d5e75999fcec1736b8963f3bf92satok            bundle.putBoolean(extra, true);
926d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
927d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
928d8e057e067696d5e75999fcec1736b8963f3bf92satok
929d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static void startSelecting(View view, Spannable content) {
930d8e057e067696d5e75999fcec1736b8963f3bf92satok        content.setSpan(SELECTING, 0, 0, PRESSED);
931d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
932d8e057e067696d5e75999fcec1736b8963f3bf92satok
933d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static void stopSelecting(View view, Spannable content) {
934d8e057e067696d5e75999fcec1736b8963f3bf92satok        content.removeSpan(SELECTING);
935d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
936d8e057e067696d5e75999fcec1736b8963f3bf92satok
937d8e057e067696d5e75999fcec1736b8963f3bf92satok    /**
938d8e057e067696d5e75999fcec1736b8963f3bf92satok     * EditorManager manages the flow and status of editing actions.
939d8e057e067696d5e75999fcec1736b8963f3bf92satok     */
940d8e057e067696d5e75999fcec1736b8963f3bf92satok    private class EditorManager {
941d8e057e067696d5e75999fcec1736b8963f3bf92satok
942d8e057e067696d5e75999fcec1736b8963f3bf92satok        static final private String LOG_TAG = "EditStyledText.EditorManager";
943d8e057e067696d5e75999fcec1736b8963f3bf92satok
944d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean mEditFlag = false;
945d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean mSoftKeyBlockFlag = false;
946d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean mKeepNonLineSpan = false;
947d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean mWaitInputFlag = false;
948d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean mTextIsFinishedFlag = false;
949d8e057e067696d5e75999fcec1736b8963f3bf92satok        private int mMode = MODE_NOTHING;
950d8e057e067696d5e75999fcec1736b8963f3bf92satok        private int mState = STATE_SELECT_OFF;
951d8e057e067696d5e75999fcec1736b8963f3bf92satok        private int mCurStart = 0;
952d8e057e067696d5e75999fcec1736b8963f3bf92satok        private int mCurEnd = 0;
953d8e057e067696d5e75999fcec1736b8963f3bf92satok        private int mColorWaitInput = DEFAULT_TRANSPARENT_COLOR;
954d8e057e067696d5e75999fcec1736b8963f3bf92satok        private int mSizeWaitInput = 0;
955d8e057e067696d5e75999fcec1736b8963f3bf92satok        private int mBackgroundColor = DEFAULT_TRANSPARENT_COLOR;
956d8e057e067696d5e75999fcec1736b8963f3bf92satok
957d8e057e067696d5e75999fcec1736b8963f3bf92satok        private BackgroundColorSpan mComposingTextMask;
958d8e057e067696d5e75999fcec1736b8963f3bf92satok        private EditStyledText mEST;
959d8e057e067696d5e75999fcec1736b8963f3bf92satok        private EditModeActions mActions;
960d8e057e067696d5e75999fcec1736b8963f3bf92satok        private SoftKeyReceiver mSkr;
961d8e057e067696d5e75999fcec1736b8963f3bf92satok        private SpannableStringBuilder mCopyBuffer;
962d8e057e067696d5e75999fcec1736b8963f3bf92satok
963d8e057e067696d5e75999fcec1736b8963f3bf92satok        EditorManager(EditStyledText est, StyledTextDialog dialog) {
964d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST = est;
965d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActions = new EditModeActions(mEST, this, dialog);
966d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSkr = new SoftKeyReceiver(mEST);
967d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
968d8e057e067696d5e75999fcec1736b8963f3bf92satok
969d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void addAction(int mode, EditModeActionBase action) {
970d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActions.addAction(mode, action);
971d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
972d8e057e067696d5e75999fcec1736b8963f3bf92satok
973d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onAction(int mode) {
974d8e057e067696d5e75999fcec1736b8963f3bf92satok            onAction(mode, true);
975d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
976d8e057e067696d5e75999fcec1736b8963f3bf92satok
977d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onAction(int mode, boolean notifyStateChanged) {
978d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActions.onAction(mode);
979d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (notifyStateChanged) {
980d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.notifyStateChanged(mMode, mState);
981d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
982d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
983d8e057e067696d5e75999fcec1736b8963f3bf92satok
984d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void startEdit() {
985d8e057e067696d5e75999fcec1736b8963f3bf92satok            resetEdit();
986d8e057e067696d5e75999fcec1736b8963f3bf92satok            showSoftKey();
987d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
988d8e057e067696d5e75999fcec1736b8963f3bf92satok
989d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onStartSelect(boolean notifyStateChanged) {
990d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
991d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- onClickSelect");
992d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
993d8e057e067696d5e75999fcec1736b8963f3bf92satok            mMode = MODE_SELECT;
994d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mState == STATE_SELECT_OFF) {
995d8e057e067696d5e75999fcec1736b8963f3bf92satok                mActions.onSelectAction();
996d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
997d8e057e067696d5e75999fcec1736b8963f3bf92satok                unsetSelect();
998d8e057e067696d5e75999fcec1736b8963f3bf92satok                mActions.onSelectAction();
999d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1000d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (notifyStateChanged) {
1001d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.notifyStateChanged(mMode, mState);
1002d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1003d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1004d8e057e067696d5e75999fcec1736b8963f3bf92satok
1005d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onCursorMoved() {
1006d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1007d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- onClickView");
1008d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1009d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mState == STATE_SELECT_ON || mState == STATE_SELECTED) {
1010d8e057e067696d5e75999fcec1736b8963f3bf92satok                mActions.onSelectAction();
1011d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.notifyStateChanged(mMode, mState);
1012d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1013d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1014d8e057e067696d5e75999fcec1736b8963f3bf92satok
1015d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onStartSelectAll(boolean notifyStateChanged) {
1016d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1017d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- onClickSelectAll");
1018d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1019d8e057e067696d5e75999fcec1736b8963f3bf92satok            handleSelectAll();
1020d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (notifyStateChanged) {
1021d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.notifyStateChanged(mMode, mState);
1022d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1023d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1024d8e057e067696d5e75999fcec1736b8963f3bf92satok
1025d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onStartShowMenuAlertDialog() {
1026d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActions.onAction(MODE_SHOW_MENU);
1027d8e057e067696d5e75999fcec1736b8963f3bf92satok            // don't call notify state changed because it have to continue
1028d8e057e067696d5e75999fcec1736b8963f3bf92satok            // to the next action.
1029d8e057e067696d5e75999fcec1736b8963f3bf92satok            // mEST.notifyStateChanged(mMode, mState);
1030d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1031d8e057e067696d5e75999fcec1736b8963f3bf92satok
1032d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onFixSelectedItem() {
1033d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1034d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- onFixSelectedItem");
1035d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1036d8e057e067696d5e75999fcec1736b8963f3bf92satok            fixSelectionAndDoNextAction();
1037d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.notifyStateChanged(mMode, mState);
1038d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1039d8e057e067696d5e75999fcec1736b8963f3bf92satok
1040d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onInsertImage(Uri uri) {
1041d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActions.onAction(MODE_IMAGE, uri);
1042d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.notifyStateChanged(mMode, mState);
1043d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1044d8e057e067696d5e75999fcec1736b8963f3bf92satok
1045d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onInsertImage(int resId) {
1046d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActions.onAction(MODE_IMAGE, resId);
1047d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.notifyStateChanged(mMode, mState);
1048d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1049d8e057e067696d5e75999fcec1736b8963f3bf92satok
1050d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void insertImageFromUri(Uri uri) {
1051d8e057e067696d5e75999fcec1736b8963f3bf92satok            insertImageSpan(new EditStyledTextSpans.RescalableImageSpan(mEST.getContext(),
1052d8e057e067696d5e75999fcec1736b8963f3bf92satok                    uri, mEST.getMaxImageWidthPx()), mEST.getSelectionStart());
1053d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1054d8e057e067696d5e75999fcec1736b8963f3bf92satok
1055d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void insertImageFromResId(int resId) {
1056d8e057e067696d5e75999fcec1736b8963f3bf92satok            insertImageSpan(new EditStyledTextSpans.RescalableImageSpan(mEST.getContext(),
1057d8e057e067696d5e75999fcec1736b8963f3bf92satok                    resId, mEST.getMaxImageWidthDip()), mEST.getSelectionStart());
1058d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1059d8e057e067696d5e75999fcec1736b8963f3bf92satok
1060d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void insertHorizontalLine() {
1061d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1062d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- onInsertHorizontalLine:");
1063d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1064d8e057e067696d5e75999fcec1736b8963f3bf92satok            int curpos = mEST.getSelectionStart();
1065d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (curpos > 0 && mEST.getText().charAt(curpos - 1) != '\n') {
1066d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.getText().insert(curpos++, "\n");
1067d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1068d8e057e067696d5e75999fcec1736b8963f3bf92satok            insertImageSpan(
1069d8e057e067696d5e75999fcec1736b8963f3bf92satok                    new HorizontalLineSpan(0xFF000000, mEST.getWidth(), mEST.getText()),
1070d8e057e067696d5e75999fcec1736b8963f3bf92satok                    curpos++);
1071d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.getText().insert(curpos++, "\n");
1072d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.setSelection(curpos);
1073d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.notifyStateChanged(mMode, mState);
1074d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1075d8e057e067696d5e75999fcec1736b8963f3bf92satok
1076d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void clearStyles(CharSequence txt) {
1077d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1078d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d("EditStyledText", "--- onClearStyles");
1079d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1080d8e057e067696d5e75999fcec1736b8963f3bf92satok            int len = txt.length();
1081d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (txt instanceof Editable) {
1082d8e057e067696d5e75999fcec1736b8963f3bf92satok                Editable editable = (Editable) txt;
1083d8e057e067696d5e75999fcec1736b8963f3bf92satok                Object[] styles = editable.getSpans(0, len, Object.class);
1084d8e057e067696d5e75999fcec1736b8963f3bf92satok                for (Object style : styles) {
1085d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (style instanceof ParagraphStyle || style instanceof QuoteSpan
1086d8e057e067696d5e75999fcec1736b8963f3bf92satok                            || style instanceof CharacterStyle
1087d8e057e067696d5e75999fcec1736b8963f3bf92satok                            && !(style instanceof UnderlineSpan)) {
1088d8e057e067696d5e75999fcec1736b8963f3bf92satok                        if (style instanceof ImageSpan || style instanceof HorizontalLineSpan) {
1089d8e057e067696d5e75999fcec1736b8963f3bf92satok                            int start = editable.getSpanStart(style);
1090d8e057e067696d5e75999fcec1736b8963f3bf92satok                            int end = editable.getSpanEnd(style);
1091d8e057e067696d5e75999fcec1736b8963f3bf92satok                            editable.replace(start, end, "");
1092d8e057e067696d5e75999fcec1736b8963f3bf92satok                        }
1093d8e057e067696d5e75999fcec1736b8963f3bf92satok                        editable.removeSpan(style);
1094d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1095d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1096d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1097d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1098d8e057e067696d5e75999fcec1736b8963f3bf92satok
1099d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onClearStyles() {
1100d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActions.onAction(MODE_CLEARSTYLES);
1101d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1102d8e057e067696d5e75999fcec1736b8963f3bf92satok
1103d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onCancelViewManagers() {
1104d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActions.onAction(MODE_CANCEL);
1105d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1106d8e057e067696d5e75999fcec1736b8963f3bf92satok
1107d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void clearStyles() {
1108d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1109d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- onClearStyles");
1110d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1111d8e057e067696d5e75999fcec1736b8963f3bf92satok            clearStyles(mEST.getText());
1112d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.setBackgroundDrawable(mEST.mDefaultBackground);
1113d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBackgroundColor = DEFAULT_TRANSPARENT_COLOR;
1114d8e057e067696d5e75999fcec1736b8963f3bf92satok            onRefreshZeoWidthChar();
1115d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1116d8e057e067696d5e75999fcec1736b8963f3bf92satok
1117d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onRefreshZeoWidthChar() {
1118d8e057e067696d5e75999fcec1736b8963f3bf92satok            Editable txt = mEST.getText();
1119d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (int i = 0; i < txt.length(); i++) {
1120d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (txt.charAt(i) == ZEROWIDTHCHAR) {
1121d8e057e067696d5e75999fcec1736b8963f3bf92satok                    txt.replace(i, i + 1, "");
1122d8e057e067696d5e75999fcec1736b8963f3bf92satok                    i--;
1123d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1124d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1125d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1126d8e057e067696d5e75999fcec1736b8963f3bf92satok
1127d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onRefreshStyles() {
1128d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1129d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- onRefreshStyles");
1130d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1131d8e057e067696d5e75999fcec1736b8963f3bf92satok            Editable txt = mEST.getText();
1132d8e057e067696d5e75999fcec1736b8963f3bf92satok            int len = txt.length();
1133d8e057e067696d5e75999fcec1736b8963f3bf92satok            int width = mEST.getWidth();
1134d8e057e067696d5e75999fcec1736b8963f3bf92satok            HorizontalLineSpan[] lines = txt.getSpans(0, len, HorizontalLineSpan.class);
1135d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (HorizontalLineSpan line : lines) {
1136d8e057e067696d5e75999fcec1736b8963f3bf92satok                line.resetWidth(width);
1137d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1138d8e057e067696d5e75999fcec1736b8963f3bf92satok            MarqueeSpan[] marquees = txt.getSpans(0, len, MarqueeSpan.class);
1139d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (MarqueeSpan marquee : marquees) {
1140d8e057e067696d5e75999fcec1736b8963f3bf92satok                marquee.resetColor(mEST.getBackgroundColor());
1141d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1142d8e057e067696d5e75999fcec1736b8963f3bf92satok
1143d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (lines.length > 0) {
1144d8e057e067696d5e75999fcec1736b8963f3bf92satok                // This is hack, bad needed for renewing View
1145d8e057e067696d5e75999fcec1736b8963f3bf92satok                // by inserting new line.
1146d8e057e067696d5e75999fcec1736b8963f3bf92satok                txt.replace(0, 1, "" + txt.charAt(0));
1147d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1148d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1149d8e057e067696d5e75999fcec1736b8963f3bf92satok
1150d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setBackgroundColor(int color) {
1151d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBackgroundColor = color;
1152d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1153d8e057e067696d5e75999fcec1736b8963f3bf92satok
1154d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setItemSize(int size, boolean reset) {
1155d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1156d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- setItemSize");
1157d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1158d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (isWaitingNextAction()) {
1159d8e057e067696d5e75999fcec1736b8963f3bf92satok                mSizeWaitInput = size;
1160d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else if (mState == STATE_SELECTED || mState == STATE_SELECT_FIX) {
1161d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (size > 0) {
1162d8e057e067696d5e75999fcec1736b8963f3bf92satok                    changeSizeSelectedText(size);
1163d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1164d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (reset) {
1165d8e057e067696d5e75999fcec1736b8963f3bf92satok                    resetEdit();
1166d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1167d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1168d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1169d8e057e067696d5e75999fcec1736b8963f3bf92satok
1170d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setItemColor(int color, boolean reset) {
1171d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1172d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- setItemColor");
1173d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1174d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (isWaitingNextAction()) {
1175d8e057e067696d5e75999fcec1736b8963f3bf92satok                mColorWaitInput = color;
1176d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else if (mState == STATE_SELECTED || mState == STATE_SELECT_FIX) {
1177d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (color != DEFAULT_TRANSPARENT_COLOR) {
1178d8e057e067696d5e75999fcec1736b8963f3bf92satok                    changeColorSelectedText(color);
1179d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1180d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (reset) {
1181d8e057e067696d5e75999fcec1736b8963f3bf92satok                    resetEdit();
1182d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1183d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1184d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1185d8e057e067696d5e75999fcec1736b8963f3bf92satok
1186d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setAlignment(Layout.Alignment align) {
1187d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mState == STATE_SELECTED || mState == STATE_SELECT_FIX) {
1188d8e057e067696d5e75999fcec1736b8963f3bf92satok                changeAlign(align);
1189d8e057e067696d5e75999fcec1736b8963f3bf92satok                resetEdit();
1190d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1191d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1192d8e057e067696d5e75999fcec1736b8963f3bf92satok
1193d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setTelop() {
1194d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mState == STATE_SELECTED || mState == STATE_SELECT_FIX) {
1195d8e057e067696d5e75999fcec1736b8963f3bf92satok                addTelop();
1196d8e057e067696d5e75999fcec1736b8963f3bf92satok                resetEdit();
1197d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1198d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1199d8e057e067696d5e75999fcec1736b8963f3bf92satok
1200d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setSwing() {
1201d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mState == STATE_SELECTED || mState == STATE_SELECT_FIX) {
1202d8e057e067696d5e75999fcec1736b8963f3bf92satok                addSwing();
1203d8e057e067696d5e75999fcec1736b8963f3bf92satok                resetEdit();
1204d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1205d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1206d8e057e067696d5e75999fcec1736b8963f3bf92satok
1207d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setMarquee(int marquee) {
1208d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mState == STATE_SELECTED || mState == STATE_SELECT_FIX) {
1209d8e057e067696d5e75999fcec1736b8963f3bf92satok                addMarquee(marquee);
1210d8e057e067696d5e75999fcec1736b8963f3bf92satok                resetEdit();
1211d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1212d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1213d8e057e067696d5e75999fcec1736b8963f3bf92satok
1214d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setTextComposingMask(int start, int end) {
1215d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1216d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- setTextComposingMask:" + start + "," + end);
1217d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1218d8e057e067696d5e75999fcec1736b8963f3bf92satok            int min = Math.min(start, end);
1219d8e057e067696d5e75999fcec1736b8963f3bf92satok            int max = Math.max(start, end);
1220d8e057e067696d5e75999fcec1736b8963f3bf92satok            int foregroundColor;
1221d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (isWaitInput() && mColorWaitInput != DEFAULT_TRANSPARENT_COLOR) {
1222d8e057e067696d5e75999fcec1736b8963f3bf92satok                foregroundColor = mColorWaitInput;
1223d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
1224d8e057e067696d5e75999fcec1736b8963f3bf92satok                foregroundColor = mEST.getForegroundColor(min);
1225d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1226d8e057e067696d5e75999fcec1736b8963f3bf92satok            int backgroundColor = mEST.getBackgroundColor();
1227d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1228d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG,
1229d8e057e067696d5e75999fcec1736b8963f3bf92satok                        "--- fg:" + Integer.toHexString(foregroundColor) + ",bg:"
1230d8e057e067696d5e75999fcec1736b8963f3bf92satok                                + Integer.toHexString(backgroundColor) + "," + isWaitInput()
1231d8e057e067696d5e75999fcec1736b8963f3bf92satok                                + "," + "," + mMode);
1232d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1233d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (foregroundColor == backgroundColor) {
1234d8e057e067696d5e75999fcec1736b8963f3bf92satok                int maskColor = 0x80000000 | ~(backgroundColor | 0xFF000000);
1235d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (mComposingTextMask == null
1236d8e057e067696d5e75999fcec1736b8963f3bf92satok                        || mComposingTextMask.getBackgroundColor() != maskColor) {
1237d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mComposingTextMask = new BackgroundColorSpan(maskColor);
1238d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1239d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.getText().setSpan(mComposingTextMask, min, max,
1240d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
1241d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1242d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1243d8e057e067696d5e75999fcec1736b8963f3bf92satok
1244d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void setEditMode(int mode) {
1245d8e057e067696d5e75999fcec1736b8963f3bf92satok            mMode = mode;
1246d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1247d8e057e067696d5e75999fcec1736b8963f3bf92satok
1248d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void setSelectState(int state) {
1249d8e057e067696d5e75999fcec1736b8963f3bf92satok            mState = state;
1250d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1251d8e057e067696d5e75999fcec1736b8963f3bf92satok
1252d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void unsetTextComposingMask() {
1253d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1254d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- unsetTextComposingMask");
1255d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1256d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mComposingTextMask != null) {
1257d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.getText().removeSpan(mComposingTextMask);
1258d8e057e067696d5e75999fcec1736b8963f3bf92satok                mComposingTextMask = null;
1259d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1260d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1261d8e057e067696d5e75999fcec1736b8963f3bf92satok
1262d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean isEditting() {
1263d8e057e067696d5e75999fcec1736b8963f3bf92satok            return mEditFlag;
1264d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1265d8e057e067696d5e75999fcec1736b8963f3bf92satok
1266d8e057e067696d5e75999fcec1736b8963f3bf92satok        /* If the style of the span is added, add check case for that style */
1267d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean isStyledText() {
1268d8e057e067696d5e75999fcec1736b8963f3bf92satok            Editable txt = mEST.getText();
1269d8e057e067696d5e75999fcec1736b8963f3bf92satok            int len = txt.length();
1270d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (txt.getSpans(0, len, ParagraphStyle.class).length > 0
1271d8e057e067696d5e75999fcec1736b8963f3bf92satok                    || txt.getSpans(0, len, QuoteSpan.class).length > 0
1272d8e057e067696d5e75999fcec1736b8963f3bf92satok                    || txt.getSpans(0, len, CharacterStyle.class).length > 0
1273d8e057e067696d5e75999fcec1736b8963f3bf92satok                    || mBackgroundColor != DEFAULT_TRANSPARENT_COLOR) {
1274d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
1275d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1276d8e057e067696d5e75999fcec1736b8963f3bf92satok            return false;
1277d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1278d8e057e067696d5e75999fcec1736b8963f3bf92satok
1279d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean isSoftKeyBlocked() {
1280d8e057e067696d5e75999fcec1736b8963f3bf92satok            return mSoftKeyBlockFlag;
1281d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1282d8e057e067696d5e75999fcec1736b8963f3bf92satok
1283d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean isWaitInput() {
1284d8e057e067696d5e75999fcec1736b8963f3bf92satok            return mWaitInputFlag;
1285d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1286d8e057e067696d5e75999fcec1736b8963f3bf92satok
1287d8e057e067696d5e75999fcec1736b8963f3bf92satok        public int getBackgroundColor() {
1288d8e057e067696d5e75999fcec1736b8963f3bf92satok            return mBackgroundColor;
1289d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1290d8e057e067696d5e75999fcec1736b8963f3bf92satok
1291d8e057e067696d5e75999fcec1736b8963f3bf92satok        public int getEditMode() {
1292d8e057e067696d5e75999fcec1736b8963f3bf92satok            return mMode;
1293d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1294d8e057e067696d5e75999fcec1736b8963f3bf92satok
1295d8e057e067696d5e75999fcec1736b8963f3bf92satok        public int getSelectState() {
1296d8e057e067696d5e75999fcec1736b8963f3bf92satok            return mState;
1297d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1298d8e057e067696d5e75999fcec1736b8963f3bf92satok
1299d8e057e067696d5e75999fcec1736b8963f3bf92satok        public int getSelectionStart() {
1300d8e057e067696d5e75999fcec1736b8963f3bf92satok            return mCurStart;
1301d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1302d8e057e067696d5e75999fcec1736b8963f3bf92satok
1303d8e057e067696d5e75999fcec1736b8963f3bf92satok        public int getSelectionEnd() {
1304d8e057e067696d5e75999fcec1736b8963f3bf92satok            return mCurEnd;
1305d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1306d8e057e067696d5e75999fcec1736b8963f3bf92satok
1307d8e057e067696d5e75999fcec1736b8963f3bf92satok        public int getSizeWaitInput() {
1308d8e057e067696d5e75999fcec1736b8963f3bf92satok            return mSizeWaitInput;
1309d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1310d8e057e067696d5e75999fcec1736b8963f3bf92satok
1311d8e057e067696d5e75999fcec1736b8963f3bf92satok        public int getColorWaitInput() {
1312d8e057e067696d5e75999fcec1736b8963f3bf92satok            return mColorWaitInput;
1313d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1314d8e057e067696d5e75999fcec1736b8963f3bf92satok
1315d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void setInternalSelection(int curStart, int curEnd) {
1316d8e057e067696d5e75999fcec1736b8963f3bf92satok            mCurStart = curStart;
1317d8e057e067696d5e75999fcec1736b8963f3bf92satok            mCurEnd = curEnd;
1318d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1319d8e057e067696d5e75999fcec1736b8963f3bf92satok
1320d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void
1321d8e057e067696d5e75999fcec1736b8963f3bf92satok                updateSpanPreviousFromCursor(Editable txt, int start, int before, int after) {
1322d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1323d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "updateSpanPrevious:" + start + "," + before + "," + after);
1324d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1325d8e057e067696d5e75999fcec1736b8963f3bf92satok            int end = start + after;
1326d8e057e067696d5e75999fcec1736b8963f3bf92satok            int min = Math.min(start, end);
1327d8e057e067696d5e75999fcec1736b8963f3bf92satok            int max = Math.max(start, end);
1328d8e057e067696d5e75999fcec1736b8963f3bf92satok            Object[] spansBefore = txt.getSpans(min, min, Object.class);
1329d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (Object span : spansBefore) {
1330d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (span instanceof ForegroundColorSpan || span instanceof AbsoluteSizeSpan
1331d8e057e067696d5e75999fcec1736b8963f3bf92satok                        || span instanceof MarqueeSpan || span instanceof AlignmentSpan) {
1332d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int spanstart = txt.getSpanStart(span);
1333d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int spanend = txt.getSpanEnd(span);
1334d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (DBG) {
1335d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Log.d(LOG_TAG, "spantype:" + span.getClass() + "," + spanstart);
1336d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1337d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int tempmax = max;
1338d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (span instanceof MarqueeSpan || span instanceof AlignmentSpan) {
1339d8e057e067696d5e75999fcec1736b8963f3bf92satok                        // Line Span
1340d8e057e067696d5e75999fcec1736b8963f3bf92satok                        tempmax = findLineEnd(mEST.getText(), max);
1341d8e057e067696d5e75999fcec1736b8963f3bf92satok                    } else {
1342d8e057e067696d5e75999fcec1736b8963f3bf92satok                        if (mKeepNonLineSpan) {
1343d8e057e067696d5e75999fcec1736b8963f3bf92satok                            tempmax = spanend;
1344d8e057e067696d5e75999fcec1736b8963f3bf92satok                        }
1345d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1346d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (spanend < tempmax) {
1347d8e057e067696d5e75999fcec1736b8963f3bf92satok                        if (DBG) {
1348d8e057e067696d5e75999fcec1736b8963f3bf92satok                            Log.d(LOG_TAG, "updateSpanPrevious: extend span");
1349d8e057e067696d5e75999fcec1736b8963f3bf92satok                        }
1350d8e057e067696d5e75999fcec1736b8963f3bf92satok                        txt.setSpan(span, spanstart, tempmax,
1351d8e057e067696d5e75999fcec1736b8963f3bf92satok                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
1352d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1353d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else if (span instanceof HorizontalLineSpan) {
1354d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int spanstart = txt.getSpanStart(span);
1355d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int spanend = txt.getSpanEnd(span);
1356d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (before > after) {
1357d8e057e067696d5e75999fcec1736b8963f3bf92satok                        // When text is deleted just after horizontalLineSpan, horizontalLineSpan
1358d8e057e067696d5e75999fcec1736b8963f3bf92satok                        // has to be deleted, because the charactor just after horizontalLineSpan
1359d8e057e067696d5e75999fcec1736b8963f3bf92satok                        // is '\n'.
1360d8e057e067696d5e75999fcec1736b8963f3bf92satok                        txt.replace(spanstart, spanend, "");
1361d8e057e067696d5e75999fcec1736b8963f3bf92satok                        txt.removeSpan(span);
1362d8e057e067696d5e75999fcec1736b8963f3bf92satok                    } else {
1363d8e057e067696d5e75999fcec1736b8963f3bf92satok                        // When text is added just after horizontalLineSpan add '\n' just after
1364d8e057e067696d5e75999fcec1736b8963f3bf92satok                        // horizontalLineSpan.
1365d8e057e067696d5e75999fcec1736b8963f3bf92satok                        if (spanend == end && end < txt.length()
1366d8e057e067696d5e75999fcec1736b8963f3bf92satok                                && mEST.getText().charAt(end) != '\n') {
1367d8e057e067696d5e75999fcec1736b8963f3bf92satok                            mEST.getText().insert(end, "\n");
1368d8e057e067696d5e75999fcec1736b8963f3bf92satok                        }
1369d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1370d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1371d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1372d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1373d8e057e067696d5e75999fcec1736b8963f3bf92satok
1374d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void updateSpanNextToCursor(Editable txt, int start, int before, int after) {
1375d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1376d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "updateSpanNext:" + start + "," + before + "," + after);
1377d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1378d8e057e067696d5e75999fcec1736b8963f3bf92satok            int end = start + after;
1379d8e057e067696d5e75999fcec1736b8963f3bf92satok            int min = Math.min(start, end);
1380d8e057e067696d5e75999fcec1736b8963f3bf92satok            int max = Math.max(start, end);
1381d8e057e067696d5e75999fcec1736b8963f3bf92satok            Object[] spansAfter = txt.getSpans(max, max, Object.class);
1382d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (Object span : spansAfter) {
1383d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (span instanceof MarqueeSpan || span instanceof AlignmentSpan) {
1384d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int spanstart = txt.getSpanStart(span);
1385d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int spanend = txt.getSpanEnd(span);
1386d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (DBG) {
1387d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Log.d(LOG_TAG, "spantype:" + span.getClass() + "," + spanend);
1388d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1389d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int tempmin = min;
1390d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (span instanceof MarqueeSpan || span instanceof AlignmentSpan) {
1391d8e057e067696d5e75999fcec1736b8963f3bf92satok                        tempmin = findLineStart(mEST.getText(), min);
1392d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1393d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (tempmin < spanstart && before > after) {
1394d8e057e067696d5e75999fcec1736b8963f3bf92satok                        txt.removeSpan(span);
1395d8e057e067696d5e75999fcec1736b8963f3bf92satok                    } else if (spanstart > min) {
1396d8e057e067696d5e75999fcec1736b8963f3bf92satok                        txt.setSpan(span, min, spanend, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
1397d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1398d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else if (span instanceof HorizontalLineSpan) {
1399d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int spanstart = txt.getSpanStart(span);
1400d8e057e067696d5e75999fcec1736b8963f3bf92satok                    // Whene text is changed just before horizontalLineSpan and there is no '\n'
1401d8e057e067696d5e75999fcec1736b8963f3bf92satok                    // just before horizontalLineSpan add '\n'
1402d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (spanstart == end && end > 0 && mEST.getText().charAt(end - 1) != '\n') {
1403d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mEST.getText().insert(end, "\n");
1404d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mEST.setSelection(end);
1405d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1406d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1407d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1408d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1409d8e057e067696d5e75999fcec1736b8963f3bf92satok
1410d8e057e067696d5e75999fcec1736b8963f3bf92satok        /** canPaste returns true only if ClipboardManager doen't contain text. */
1411d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean canPaste() {
1412d8e057e067696d5e75999fcec1736b8963f3bf92satok            return (mCopyBuffer != null && mCopyBuffer.length() > 0 && removeImageChar(
1413d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mCopyBuffer).length() == 0);
1414d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1415d8e057e067696d5e75999fcec1736b8963f3bf92satok
1416d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void endEdit() {
1417d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1418d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- handleCancel");
1419d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1420d8e057e067696d5e75999fcec1736b8963f3bf92satok            mMode = MODE_NOTHING;
1421d8e057e067696d5e75999fcec1736b8963f3bf92satok            mState = STATE_SELECT_OFF;
1422d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEditFlag = false;
1423d8e057e067696d5e75999fcec1736b8963f3bf92satok            mColorWaitInput = DEFAULT_TRANSPARENT_COLOR;
1424d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSizeWaitInput = 0;
1425d8e057e067696d5e75999fcec1736b8963f3bf92satok            mWaitInputFlag = false;
1426d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSoftKeyBlockFlag = false;
1427d8e057e067696d5e75999fcec1736b8963f3bf92satok            mKeepNonLineSpan = false;
1428d8e057e067696d5e75999fcec1736b8963f3bf92satok            mTextIsFinishedFlag = false;
1429d8e057e067696d5e75999fcec1736b8963f3bf92satok            unsetSelect();
1430d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.setOnClickListener(null);
1431d8e057e067696d5e75999fcec1736b8963f3bf92satok            unblockSoftKey();
1432d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1433d8e057e067696d5e75999fcec1736b8963f3bf92satok
1434d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void fixSelectionAndDoNextAction() {
1435d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1436d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- handleComplete:" + mCurStart + "," + mCurEnd);
1437d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1438d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (!mEditFlag) {
1439d8e057e067696d5e75999fcec1736b8963f3bf92satok                return;
1440d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1441d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mCurStart == mCurEnd) {
1442d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (DBG) {
1443d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.d(LOG_TAG, "--- cancel handle complete:" + mCurStart);
1444d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1445d8e057e067696d5e75999fcec1736b8963f3bf92satok                resetEdit();
1446d8e057e067696d5e75999fcec1736b8963f3bf92satok                return;
1447d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1448d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mState == STATE_SELECTED) {
1449d8e057e067696d5e75999fcec1736b8963f3bf92satok                mState = STATE_SELECT_FIX;
1450d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1451d8e057e067696d5e75999fcec1736b8963f3bf92satok            // When the complete button is clicked, this should do action.
1452d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActions.doNext(mMode);
1453d8e057e067696d5e75999fcec1736b8963f3bf92satok            //MetaKeyKeyListener.stopSelecting(mEST, mEST.getText());
1454d8e057e067696d5e75999fcec1736b8963f3bf92satok            stopSelecting(mEST, mEST.getText());
1455d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1456d8e057e067696d5e75999fcec1736b8963f3bf92satok
1457d8e057e067696d5e75999fcec1736b8963f3bf92satok        // Remove obj character for DynamicDrawableSpan from clipboard.
1458d8e057e067696d5e75999fcec1736b8963f3bf92satok        private SpannableStringBuilder removeImageChar(SpannableStringBuilder text) {
1459d8e057e067696d5e75999fcec1736b8963f3bf92satok            SpannableStringBuilder buf = new SpannableStringBuilder(text);
1460d8e057e067696d5e75999fcec1736b8963f3bf92satok            DynamicDrawableSpan[] styles =
1461d8e057e067696d5e75999fcec1736b8963f3bf92satok                    buf.getSpans(0, buf.length(), DynamicDrawableSpan.class);
1462d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (DynamicDrawableSpan style : styles) {
1463d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (style instanceof HorizontalLineSpan
1464d8e057e067696d5e75999fcec1736b8963f3bf92satok                        || style instanceof RescalableImageSpan) {
1465d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int start = buf.getSpanStart(style);
1466d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int end = buf.getSpanEnd(style);
1467d8e057e067696d5e75999fcec1736b8963f3bf92satok                    buf.replace(start, end, "");
1468d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1469d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1470d8e057e067696d5e75999fcec1736b8963f3bf92satok            return buf;
1471d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1472d8e057e067696d5e75999fcec1736b8963f3bf92satok
1473d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void copyToClipBoard() {
1474d8e057e067696d5e75999fcec1736b8963f3bf92satok            int min = Math.min(getSelectionStart(), getSelectionEnd());
1475d8e057e067696d5e75999fcec1736b8963f3bf92satok            int max = Math.max(getSelectionStart(), getSelectionEnd());
1476d8e057e067696d5e75999fcec1736b8963f3bf92satok            mCopyBuffer = (SpannableStringBuilder) mEST.getText().subSequence(min, max);
1477d8e057e067696d5e75999fcec1736b8963f3bf92satok            SpannableStringBuilder clipboardtxt = removeImageChar(mCopyBuffer);
1478d8e057e067696d5e75999fcec1736b8963f3bf92satok            ClipboardManager clip =
1479d8e057e067696d5e75999fcec1736b8963f3bf92satok                    (ClipboardManager) getContext()
1480d8e057e067696d5e75999fcec1736b8963f3bf92satok                            .getSystemService(Context.CLIPBOARD_SERVICE);
1481d8e057e067696d5e75999fcec1736b8963f3bf92satok            clip.setText(clipboardtxt);
1482d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1483d8e057e067696d5e75999fcec1736b8963f3bf92satok                dumpSpannableString(clipboardtxt);
1484d8e057e067696d5e75999fcec1736b8963f3bf92satok                dumpSpannableString(mCopyBuffer);
1485d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1486d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1487d8e057e067696d5e75999fcec1736b8963f3bf92satok
1488d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void cutToClipBoard() {
1489d8e057e067696d5e75999fcec1736b8963f3bf92satok            copyToClipBoard();
1490d8e057e067696d5e75999fcec1736b8963f3bf92satok            int min = Math.min(getSelectionStart(), getSelectionEnd());
1491d8e057e067696d5e75999fcec1736b8963f3bf92satok            int max = Math.max(getSelectionStart(), getSelectionEnd());
1492d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.getText().delete(min, max);
1493d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1494d8e057e067696d5e75999fcec1736b8963f3bf92satok
1495d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean isClipBoardChanged(CharSequence clipboardText) {
1496d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1497d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- isClipBoardChanged:" + clipboardText);
1498d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1499d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mCopyBuffer == null) {
1500d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
1501d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1502d8e057e067696d5e75999fcec1736b8963f3bf92satok            int len = clipboardText.length();
1503d8e057e067696d5e75999fcec1736b8963f3bf92satok            CharSequence removedClipBoard = removeImageChar(mCopyBuffer);
1504d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1505d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- clipBoard:" + len + "," + removedClipBoard + clipboardText);
1506d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1507d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (len != removedClipBoard.length()) {
1508d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
1509d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1510d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (int i = 0; i < len; ++i) {
1511d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (clipboardText.charAt(i) != removedClipBoard.charAt(i)) {
1512d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
1513d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1514d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1515d8e057e067696d5e75999fcec1736b8963f3bf92satok            return false;
1516d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1517d8e057e067696d5e75999fcec1736b8963f3bf92satok
1518d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void pasteFromClipboard() {
1519d8e057e067696d5e75999fcec1736b8963f3bf92satok            int min = Math.min(mEST.getSelectionStart(), mEST.getSelectionEnd());
1520d8e057e067696d5e75999fcec1736b8963f3bf92satok            int max = Math.max(mEST.getSelectionStart(), mEST.getSelectionEnd());
1521d8e057e067696d5e75999fcec1736b8963f3bf92satok            // TODO: Find more smart way to set Span to Clipboard.
1522d8e057e067696d5e75999fcec1736b8963f3bf92satok            Selection.setSelection(mEST.getText(), max);
1523d8e057e067696d5e75999fcec1736b8963f3bf92satok            ClipboardManager clip =
1524d8e057e067696d5e75999fcec1736b8963f3bf92satok                    (ClipboardManager) getContext()
1525d8e057e067696d5e75999fcec1736b8963f3bf92satok                            .getSystemService(Context.CLIPBOARD_SERVICE);
1526d8e057e067696d5e75999fcec1736b8963f3bf92satok            mKeepNonLineSpan = true;
1527d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.getText().replace(min, max, clip.getText());
1528d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (!isClipBoardChanged(clip.getText())) {
1529d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (DBG) {
1530d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.d(TAG, "--- handlePaste: startPasteImage");
1531d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1532d8e057e067696d5e75999fcec1736b8963f3bf92satok                DynamicDrawableSpan[] styles =
1533d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mCopyBuffer.getSpans(0, mCopyBuffer.length(),
1534d8e057e067696d5e75999fcec1736b8963f3bf92satok                                DynamicDrawableSpan.class);
1535d8e057e067696d5e75999fcec1736b8963f3bf92satok                for (DynamicDrawableSpan style : styles) {
1536d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int start = mCopyBuffer.getSpanStart(style);
1537d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (style instanceof HorizontalLineSpan) {
1538d8e057e067696d5e75999fcec1736b8963f3bf92satok                        insertImageSpan(new HorizontalLineSpan(0xFF000000, mEST.getWidth(),
1539d8e057e067696d5e75999fcec1736b8963f3bf92satok                                mEST.getText()), min + start);
1540d8e057e067696d5e75999fcec1736b8963f3bf92satok                    } else if (style instanceof RescalableImageSpan) {
1541d8e057e067696d5e75999fcec1736b8963f3bf92satok                        insertImageSpan(
1542d8e057e067696d5e75999fcec1736b8963f3bf92satok                                new RescalableImageSpan(mEST.getContext(),
1543d8e057e067696d5e75999fcec1736b8963f3bf92satok                                        ((RescalableImageSpan) style).getContentUri(),
1544d8e057e067696d5e75999fcec1736b8963f3bf92satok                                        mEST.getMaxImageWidthPx()), min + start);
1545d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1546d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1547d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1548d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1549d8e057e067696d5e75999fcec1736b8963f3bf92satok
1550d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void handleSelectAll() {
1551d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (!mEditFlag) {
1552d8e057e067696d5e75999fcec1736b8963f3bf92satok                return;
1553d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1554d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActions.onAction(MODE_SELECTALL);
1555d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1556d8e057e067696d5e75999fcec1736b8963f3bf92satok
1557d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void selectAll() {
1558d8e057e067696d5e75999fcec1736b8963f3bf92satok            Selection.selectAll(mEST.getText());
1559d8e057e067696d5e75999fcec1736b8963f3bf92satok            mCurStart = mEST.getSelectionStart();
1560d8e057e067696d5e75999fcec1736b8963f3bf92satok            mCurEnd = mEST.getSelectionEnd();
1561d8e057e067696d5e75999fcec1736b8963f3bf92satok            mMode = MODE_SELECT;
1562d8e057e067696d5e75999fcec1736b8963f3bf92satok            mState = STATE_SELECT_FIX;
1563d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1564d8e057e067696d5e75999fcec1736b8963f3bf92satok
1565d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void resetEdit() {
1566d8e057e067696d5e75999fcec1736b8963f3bf92satok            endEdit();
1567d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEditFlag = true;
1568d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.notifyStateChanged(mMode, mState);
1569d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1570d8e057e067696d5e75999fcec1736b8963f3bf92satok
1571d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void setSelection() {
1572d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1573d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- onSelect:" + mCurStart + "," + mCurEnd);
1574d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1575d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mCurStart >= 0 && mCurStart <= mEST.getText().length() && mCurEnd >= 0
1576d8e057e067696d5e75999fcec1736b8963f3bf92satok                    && mCurEnd <= mEST.getText().length()) {
1577d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (mCurStart < mCurEnd) {
1578d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mEST.setSelection(mCurStart, mCurEnd);
1579d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mState = STATE_SELECTED;
1580d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else if (mCurStart > mCurEnd) {
1581d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mEST.setSelection(mCurEnd, mCurStart);
1582d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mState = STATE_SELECTED;
1583d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else {
1584d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mState = STATE_SELECT_ON;
1585d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1586d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
1587d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(LOG_TAG, "Select is on, but cursor positions are illigal.:"
1588d8e057e067696d5e75999fcec1736b8963f3bf92satok                        + mEST.getText().length() + "," + mCurStart + "," + mCurEnd);
1589d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1590d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1591d8e057e067696d5e75999fcec1736b8963f3bf92satok
1592d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void unsetSelect() {
1593d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1594d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- offSelect");
1595d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1596d8e057e067696d5e75999fcec1736b8963f3bf92satok            //MetaKeyKeyListener.stopSelecting(mEST, mEST.getText());
1597d8e057e067696d5e75999fcec1736b8963f3bf92satok            stopSelecting(mEST, mEST.getText());
1598d8e057e067696d5e75999fcec1736b8963f3bf92satok            int currpos = mEST.getSelectionStart();
1599d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.setSelection(currpos, currpos);
1600d8e057e067696d5e75999fcec1736b8963f3bf92satok            mState = STATE_SELECT_OFF;
1601d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1602d8e057e067696d5e75999fcec1736b8963f3bf92satok
1603d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void setSelectStartPos() {
1604d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1605d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- setSelectStartPos");
1606d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1607d8e057e067696d5e75999fcec1736b8963f3bf92satok            mCurStart = mEST.getSelectionStart();
1608d8e057e067696d5e75999fcec1736b8963f3bf92satok            mState = STATE_SELECT_ON;
1609d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1610d8e057e067696d5e75999fcec1736b8963f3bf92satok
1611d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void setSelectEndPos() {
1612d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mEST.getSelectionEnd() == mCurStart) {
1613d8e057e067696d5e75999fcec1736b8963f3bf92satok                setEndPos(mEST.getSelectionStart());
1614d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
1615d8e057e067696d5e75999fcec1736b8963f3bf92satok                setEndPos(mEST.getSelectionEnd());
1616d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1617d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1618d8e057e067696d5e75999fcec1736b8963f3bf92satok
1619d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setEndPos(int pos) {
1620d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1621d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- setSelectedEndPos:" + pos);
1622d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1623d8e057e067696d5e75999fcec1736b8963f3bf92satok            mCurEnd = pos;
1624d8e057e067696d5e75999fcec1736b8963f3bf92satok            setSelection();
1625d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1626d8e057e067696d5e75999fcec1736b8963f3bf92satok
1627d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean isWaitingNextAction() {
1628d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1629d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- waitingNext:" + mCurStart + "," + mCurEnd + "," + mState);
1630d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1631d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mCurStart == mCurEnd && mState == STATE_SELECT_FIX) {
1632d8e057e067696d5e75999fcec1736b8963f3bf92satok                waitSelection();
1633d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
1634d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
1635d8e057e067696d5e75999fcec1736b8963f3bf92satok                resumeSelection();
1636d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
1637d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1638d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1639d8e057e067696d5e75999fcec1736b8963f3bf92satok
1640d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void waitSelection() {
1641d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1642d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- waitSelection");
1643d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1644d8e057e067696d5e75999fcec1736b8963f3bf92satok            mWaitInputFlag = true;
1645d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mCurStart == mCurEnd) {
1646d8e057e067696d5e75999fcec1736b8963f3bf92satok                mState = STATE_SELECT_ON;
1647d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
1648d8e057e067696d5e75999fcec1736b8963f3bf92satok                mState = STATE_SELECTED;
1649d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1650d8e057e067696d5e75999fcec1736b8963f3bf92satok            //MetaKeyKeyListener.startSelecting(mEST, mEST.getText());
1651d8e057e067696d5e75999fcec1736b8963f3bf92satok            startSelecting(mEST, mEST.getText());
1652d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1653d8e057e067696d5e75999fcec1736b8963f3bf92satok
1654d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void resumeSelection() {
1655d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1656d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- resumeSelection");
1657d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1658d8e057e067696d5e75999fcec1736b8963f3bf92satok            mWaitInputFlag = false;
1659d8e057e067696d5e75999fcec1736b8963f3bf92satok            mState = STATE_SELECT_FIX;
1660d8e057e067696d5e75999fcec1736b8963f3bf92satok            //MetaKeyKeyListener.stopSelecting(mEST, mEST.getText());
1661d8e057e067696d5e75999fcec1736b8963f3bf92satok            stopSelecting(mEST, mEST.getText());
1662d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1663d8e057e067696d5e75999fcec1736b8963f3bf92satok
1664d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean isTextSelected() {
1665d8e057e067696d5e75999fcec1736b8963f3bf92satok            return (mState == STATE_SELECTED || mState == STATE_SELECT_FIX);
1666d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1667d8e057e067696d5e75999fcec1736b8963f3bf92satok
1668d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void setStyledTextSpan(Object span, int start, int end) {
1669d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1670d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- setStyledTextSpan:" + mMode + "," + start + "," + end);
1671d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1672d8e057e067696d5e75999fcec1736b8963f3bf92satok            int min = Math.min(start, end);
1673d8e057e067696d5e75999fcec1736b8963f3bf92satok            int max = Math.max(start, end);
1674d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.getText().setSpan(span, min, max, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
1675d8e057e067696d5e75999fcec1736b8963f3bf92satok            Selection.setSelection(mEST.getText(), max);
1676d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1677d8e057e067696d5e75999fcec1736b8963f3bf92satok
1678d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void setLineStyledTextSpan(Object span) {
1679d8e057e067696d5e75999fcec1736b8963f3bf92satok            int min = Math.min(mCurStart, mCurEnd);
1680d8e057e067696d5e75999fcec1736b8963f3bf92satok            int max = Math.max(mCurStart, mCurEnd);
1681d8e057e067696d5e75999fcec1736b8963f3bf92satok            int current = mEST.getSelectionStart();
1682d8e057e067696d5e75999fcec1736b8963f3bf92satok            int start = findLineStart(mEST.getText(), min);
1683d8e057e067696d5e75999fcec1736b8963f3bf92satok            int end = findLineEnd(mEST.getText(), max);
1684d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (start == end) {
1685d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.getText().insert(end, "\n");
1686d8e057e067696d5e75999fcec1736b8963f3bf92satok                setStyledTextSpan(span, start, end + 1);
1687d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
1688d8e057e067696d5e75999fcec1736b8963f3bf92satok                setStyledTextSpan(span, start, end);
1689d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1690d8e057e067696d5e75999fcec1736b8963f3bf92satok            Selection.setSelection(mEST.getText(), current);
1691d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1692d8e057e067696d5e75999fcec1736b8963f3bf92satok
1693d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void changeSizeSelectedText(int size) {
1694d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mCurStart != mCurEnd) {
1695d8e057e067696d5e75999fcec1736b8963f3bf92satok                setStyledTextSpan(new AbsoluteSizeSpan(size), mCurStart, mCurEnd);
1696d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
1697d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(LOG_TAG, "---changeSize: Size of the span is zero");
1698d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1699d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1700d8e057e067696d5e75999fcec1736b8963f3bf92satok
1701d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void changeColorSelectedText(int color) {
1702d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mCurStart != mCurEnd) {
1703d8e057e067696d5e75999fcec1736b8963f3bf92satok                setStyledTextSpan(new ForegroundColorSpan(color), mCurStart, mCurEnd);
1704d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
1705d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(LOG_TAG, "---changeColor: Size of the span is zero");
1706d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1707d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1708d8e057e067696d5e75999fcec1736b8963f3bf92satok
1709d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void changeAlign(Layout.Alignment align) {
1710d8e057e067696d5e75999fcec1736b8963f3bf92satok            setLineStyledTextSpan(new AlignmentSpan.Standard(align));
1711d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1712d8e057e067696d5e75999fcec1736b8963f3bf92satok
1713d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void addTelop() {
1714d8e057e067696d5e75999fcec1736b8963f3bf92satok            addMarquee(MarqueeSpan.ALTERNATE);
1715d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1716d8e057e067696d5e75999fcec1736b8963f3bf92satok
1717d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void addSwing() {
1718d8e057e067696d5e75999fcec1736b8963f3bf92satok            addMarquee(MarqueeSpan.SCROLL);
1719d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1720d8e057e067696d5e75999fcec1736b8963f3bf92satok
1721d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void addMarquee(int marquee) {
1722d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1723d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- addMarquee:" + marquee);
1724d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1725d8e057e067696d5e75999fcec1736b8963f3bf92satok            setLineStyledTextSpan(new MarqueeSpan(marquee, mEST.getBackgroundColor()));
1726d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1727d8e057e067696d5e75999fcec1736b8963f3bf92satok
1728d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void insertImageSpan(DynamicDrawableSpan span, int curpos) {
1729d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1730d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- insertImageSpan:");
1731d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1732d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (span != null && span.getDrawable() != null) {
1733d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.getText().insert(curpos, "" + IMAGECHAR);
1734d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.getText().setSpan(span, curpos, curpos + 1,
1735d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
1736d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.notifyStateChanged(mMode, mState);
1737d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
1738d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(LOG_TAG, "--- insertImageSpan: null span was inserted");
1739d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.sendHintMessage(HINT_MSG_BIG_SIZE_ERROR);
1740d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1741d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1742d8e057e067696d5e75999fcec1736b8963f3bf92satok
1743d8e057e067696d5e75999fcec1736b8963f3bf92satok        private int findLineStart(Editable text, int current) {
1744d8e057e067696d5e75999fcec1736b8963f3bf92satok            int pos = current;
1745d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (; pos > 0; pos--) {
1746d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (text.charAt(pos - 1) == '\n') {
1747d8e057e067696d5e75999fcec1736b8963f3bf92satok                    break;
1748d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1749d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1750d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1751d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- findLineStart:" + current + "," + text.length() + ","
1752d8e057e067696d5e75999fcec1736b8963f3bf92satok                        + pos);
1753d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1754d8e057e067696d5e75999fcec1736b8963f3bf92satok            return pos;
1755d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1756d8e057e067696d5e75999fcec1736b8963f3bf92satok
1757d8e057e067696d5e75999fcec1736b8963f3bf92satok        private int findLineEnd(Editable text, int current) {
1758d8e057e067696d5e75999fcec1736b8963f3bf92satok            int pos = current;
1759d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (; pos < text.length(); pos++) {
1760d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (text.charAt(pos) == '\n') {
1761d8e057e067696d5e75999fcec1736b8963f3bf92satok                    pos++;
1762d8e057e067696d5e75999fcec1736b8963f3bf92satok                    break;
1763d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1764d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1765d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1766d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- findLineEnd:" + current + "," + text.length() + "," + pos);
1767d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1768d8e057e067696d5e75999fcec1736b8963f3bf92satok            return pos;
1769d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1770d8e057e067696d5e75999fcec1736b8963f3bf92satok
1771d8e057e067696d5e75999fcec1736b8963f3bf92satok        // Only for debug.
1772d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void dumpSpannableString(CharSequence txt) {
1773d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (txt instanceof Spannable) {
1774d8e057e067696d5e75999fcec1736b8963f3bf92satok                Spannable spannable = (Spannable) txt;
1775d8e057e067696d5e75999fcec1736b8963f3bf92satok                int len = spannable.length();
1776d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (DBG) {
1777d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.d(TAG, "--- dumpSpannableString, txt:" + spannable + ", len:" + len);
1778d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1779d8e057e067696d5e75999fcec1736b8963f3bf92satok                Object[] styles = spannable.getSpans(0, len, Object.class);
1780d8e057e067696d5e75999fcec1736b8963f3bf92satok                for (Object style : styles) {
1781d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (DBG) {
1782d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Log.d(TAG,
1783d8e057e067696d5e75999fcec1736b8963f3bf92satok                                "--- dumpSpannableString, class:" + style + ","
1784d8e057e067696d5e75999fcec1736b8963f3bf92satok                                        + spannable.getSpanStart(style) + ","
1785d8e057e067696d5e75999fcec1736b8963f3bf92satok                                        + spannable.getSpanEnd(style) + ","
1786d8e057e067696d5e75999fcec1736b8963f3bf92satok                                        + spannable.getSpanFlags(style));
1787d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1788d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1789d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1790d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1791d8e057e067696d5e75999fcec1736b8963f3bf92satok
1792d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void showSoftKey() {
1793d8e057e067696d5e75999fcec1736b8963f3bf92satok            showSoftKey(mEST.getSelectionStart(), mEST.getSelectionEnd());
1794d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1795d8e057e067696d5e75999fcec1736b8963f3bf92satok
1796d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void showSoftKey(int oldSelStart, int oldSelEnd) {
1797d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1798d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- showsoftkey");
1799d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1800d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (!mEST.isFocused() || isSoftKeyBlocked()) {
1801d8e057e067696d5e75999fcec1736b8963f3bf92satok                return;
1802d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1803d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSkr.mNewStart = Selection.getSelectionStart(mEST.getText());
1804d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSkr.mNewEnd = Selection.getSelectionEnd(mEST.getText());
1805d8e057e067696d5e75999fcec1736b8963f3bf92satok            InputMethodManager imm =
1806d8e057e067696d5e75999fcec1736b8963f3bf92satok                    (InputMethodManager) getContext().getSystemService(
1807d8e057e067696d5e75999fcec1736b8963f3bf92satok                            Context.INPUT_METHOD_SERVICE);
1808d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (imm.showSoftInput(mEST, 0, mSkr) && mSkr != null) {
1809d8e057e067696d5e75999fcec1736b8963f3bf92satok                Selection.setSelection(getText(), oldSelStart, oldSelEnd);
1810d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1811d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1812d8e057e067696d5e75999fcec1736b8963f3bf92satok
1813d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void hideSoftKey() {
1814d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1815d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- hidesoftkey");
1816d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1817d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (!mEST.isFocused()) {
1818d8e057e067696d5e75999fcec1736b8963f3bf92satok                return;
1819d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1820d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSkr.mNewStart = Selection.getSelectionStart(mEST.getText());
1821d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSkr.mNewEnd = Selection.getSelectionEnd(mEST.getText());
1822d8e057e067696d5e75999fcec1736b8963f3bf92satok            InputMethodManager imm =
1823d8e057e067696d5e75999fcec1736b8963f3bf92satok                    (InputMethodManager) mEST.getContext().getSystemService(
1824d8e057e067696d5e75999fcec1736b8963f3bf92satok                            Context.INPUT_METHOD_SERVICE);
1825d8e057e067696d5e75999fcec1736b8963f3bf92satok            imm.hideSoftInputFromWindow(mEST.getWindowToken(), 0, mSkr);
1826d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1827d8e057e067696d5e75999fcec1736b8963f3bf92satok
1828d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void blockSoftKey() {
1829d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1830d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- blockSoftKey:");
1831d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1832d8e057e067696d5e75999fcec1736b8963f3bf92satok            hideSoftKey();
1833d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSoftKeyBlockFlag = true;
1834d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1835d8e057e067696d5e75999fcec1736b8963f3bf92satok
1836d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void unblockSoftKey() {
1837d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1838d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- unblockSoftKey:");
1839d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1840d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSoftKeyBlockFlag = false;
1841d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1842d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
1843d8e057e067696d5e75999fcec1736b8963f3bf92satok
1844d8e057e067696d5e75999fcec1736b8963f3bf92satok    private class StyledTextHtmlStandard implements StyledTextHtmlConverter {
1845d8e057e067696d5e75999fcec1736b8963f3bf92satok        public String toHtml(Spanned text) {
1846d8e057e067696d5e75999fcec1736b8963f3bf92satok            return Html.toHtml(text);
1847d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1848d8e057e067696d5e75999fcec1736b8963f3bf92satok
1849d8e057e067696d5e75999fcec1736b8963f3bf92satok        public String toHtml(Spanned text, boolean escapeNonAsciiChar) {
1850d8e057e067696d5e75999fcec1736b8963f3bf92satok            return Html.toHtml(text);
1851d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1852d8e057e067696d5e75999fcec1736b8963f3bf92satok
1853d8e057e067696d5e75999fcec1736b8963f3bf92satok        public String toHtml(Spanned text, boolean escapeNonAsciiChar, int width, float scale) {
1854d8e057e067696d5e75999fcec1736b8963f3bf92satok            return Html.toHtml(text);
1855d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1856d8e057e067696d5e75999fcec1736b8963f3bf92satok
1857d8e057e067696d5e75999fcec1736b8963f3bf92satok        public Spanned fromHtml(String source) {
1858d8e057e067696d5e75999fcec1736b8963f3bf92satok            return Html.fromHtml(source);
1859d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1860d8e057e067696d5e75999fcec1736b8963f3bf92satok
1861d8e057e067696d5e75999fcec1736b8963f3bf92satok        public Spanned fromHtml(String source, ImageGetter imageGetter, TagHandler tagHandler) {
1862d8e057e067696d5e75999fcec1736b8963f3bf92satok            return Html.fromHtml(source, imageGetter, tagHandler);
1863d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1864d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
1865d8e057e067696d5e75999fcec1736b8963f3bf92satok
1866d8e057e067696d5e75999fcec1736b8963f3bf92satok    private class StyledTextConverter {
1867d8e057e067696d5e75999fcec1736b8963f3bf92satok        private EditStyledText mEST;
1868d8e057e067696d5e75999fcec1736b8963f3bf92satok        private StyledTextHtmlConverter mHtml;
1869d8e057e067696d5e75999fcec1736b8963f3bf92satok
1870d8e057e067696d5e75999fcec1736b8963f3bf92satok        public StyledTextConverter(EditStyledText est, StyledTextHtmlConverter html) {
1871d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST = est;
1872d8e057e067696d5e75999fcec1736b8963f3bf92satok            mHtml = html;
1873d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1874d8e057e067696d5e75999fcec1736b8963f3bf92satok
1875d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setStyledTextHtmlConverter(StyledTextHtmlConverter html) {
1876d8e057e067696d5e75999fcec1736b8963f3bf92satok            mHtml = html;
1877d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1878d8e057e067696d5e75999fcec1736b8963f3bf92satok
1879d8e057e067696d5e75999fcec1736b8963f3bf92satok        public String getHtml(boolean escapeFlag) {
1880d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.clearComposingText();
1881d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.onRefreshZeoWidthChar();
1882d8e057e067696d5e75999fcec1736b8963f3bf92satok            String htmlBody = mHtml.toHtml(mEST.getText(), escapeFlag);
1883d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1884d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- getHtml:" + htmlBody);
1885d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1886d8e057e067696d5e75999fcec1736b8963f3bf92satok            return htmlBody;
1887d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1888d8e057e067696d5e75999fcec1736b8963f3bf92satok
1889d8e057e067696d5e75999fcec1736b8963f3bf92satok        public String getPreviewHtml() {
1890d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.clearComposingText();
1891d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.onRefreshZeoWidthChar();
1892d8e057e067696d5e75999fcec1736b8963f3bf92satok            String html =
1893d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mHtml.toHtml(mEST.getText(), true, getMaxImageWidthDip(),
1894d8e057e067696d5e75999fcec1736b8963f3bf92satok                            getPaddingScale());
1895d8e057e067696d5e75999fcec1736b8963f3bf92satok            int bgColor = mEST.getBackgroundColor();
1896d8e057e067696d5e75999fcec1736b8963f3bf92satok            html =
1897d8e057e067696d5e75999fcec1736b8963f3bf92satok                    String.format("<body bgcolor=\"#%02X%02X%02X\">%s</body>",
1898d8e057e067696d5e75999fcec1736b8963f3bf92satok                            Color.red(bgColor), Color.green(bgColor), Color.blue(bgColor),
1899d8e057e067696d5e75999fcec1736b8963f3bf92satok                            html);
1900d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1901d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- getPreviewHtml:" + html + "," + mEST.getWidth());
1902d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1903d8e057e067696d5e75999fcec1736b8963f3bf92satok            return html;
1904d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1905d8e057e067696d5e75999fcec1736b8963f3bf92satok
1906d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void getUriArray(ArrayList<Uri> uris, Editable text) {
1907d8e057e067696d5e75999fcec1736b8963f3bf92satok            uris.clear();
1908d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
1909d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- getUriArray:");
1910d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1911d8e057e067696d5e75999fcec1736b8963f3bf92satok            int len = text.length();
1912d8e057e067696d5e75999fcec1736b8963f3bf92satok            int next;
1913d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (int i = 0; i < text.length(); i = next) {
1914d8e057e067696d5e75999fcec1736b8963f3bf92satok                next = text.nextSpanTransition(i, len, ImageSpan.class);
1915d8e057e067696d5e75999fcec1736b8963f3bf92satok                ImageSpan[] images = text.getSpans(i, next, ImageSpan.class);
1916d8e057e067696d5e75999fcec1736b8963f3bf92satok                for (int j = 0; j < images.length; j++) {
1917d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (DBG) {
1918d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Log.d(TAG, "--- getUriArray: foundArray" + images[j].getSource());
1919d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1920d8e057e067696d5e75999fcec1736b8963f3bf92satok                    uris.add(Uri.parse(images[j].getSource()));
1921d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1922d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1923d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1924d8e057e067696d5e75999fcec1736b8963f3bf92satok
1925d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void SetHtml(String html) {
1926d8e057e067696d5e75999fcec1736b8963f3bf92satok            final Spanned spanned = mHtml.fromHtml(html, new Html.ImageGetter() {
1927d8e057e067696d5e75999fcec1736b8963f3bf92satok                public Drawable getDrawable(String src) {
1928d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.d(TAG, "--- sethtml: src=" + src);
1929d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (src.startsWith("content://")) {
1930d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Uri uri = Uri.parse(src);
1931d8e057e067696d5e75999fcec1736b8963f3bf92satok                        try {
1932d8e057e067696d5e75999fcec1736b8963f3bf92satok                            Drawable drawable = null;
1933d8e057e067696d5e75999fcec1736b8963f3bf92satok                            Bitmap bitmap = null;
1934d8e057e067696d5e75999fcec1736b8963f3bf92satok                            System.gc();
1935d8e057e067696d5e75999fcec1736b8963f3bf92satok                            InputStream is =
1936d8e057e067696d5e75999fcec1736b8963f3bf92satok                                    mEST.getContext().getContentResolver().openInputStream(uri);
1937d8e057e067696d5e75999fcec1736b8963f3bf92satok                            BitmapFactory.Options opt = new BitmapFactory.Options();
1938d8e057e067696d5e75999fcec1736b8963f3bf92satok                            opt.inJustDecodeBounds = true;
1939d8e057e067696d5e75999fcec1736b8963f3bf92satok                            BitmapFactory.decodeStream(is, null, opt);
1940d8e057e067696d5e75999fcec1736b8963f3bf92satok                            is.close();
1941d8e057e067696d5e75999fcec1736b8963f3bf92satok                            is =  mEST.getContext().getContentResolver().openInputStream(uri);
1942d8e057e067696d5e75999fcec1736b8963f3bf92satok                            int width, height;
1943d8e057e067696d5e75999fcec1736b8963f3bf92satok                            width = opt.outWidth;
1944d8e057e067696d5e75999fcec1736b8963f3bf92satok                            height = opt.outHeight;
1945d8e057e067696d5e75999fcec1736b8963f3bf92satok                            if (opt.outWidth > getMaxImageWidthPx()) {
1946d8e057e067696d5e75999fcec1736b8963f3bf92satok                                width = getMaxImageWidthPx();
1947d8e057e067696d5e75999fcec1736b8963f3bf92satok                                height = height * getMaxImageWidthPx() / opt.outWidth;
1948d8e057e067696d5e75999fcec1736b8963f3bf92satok                                Rect padding = new Rect(0, 0, width, height);
1949d8e057e067696d5e75999fcec1736b8963f3bf92satok                                bitmap = BitmapFactory.decodeStream(is, padding, null);
1950d8e057e067696d5e75999fcec1736b8963f3bf92satok                            } else {
1951d8e057e067696d5e75999fcec1736b8963f3bf92satok                                bitmap = BitmapFactory.decodeStream(is);
1952d8e057e067696d5e75999fcec1736b8963f3bf92satok                            }
1953d8e057e067696d5e75999fcec1736b8963f3bf92satok                            drawable = new BitmapDrawable(
1954d8e057e067696d5e75999fcec1736b8963f3bf92satok                                    mEST.getContext().getResources(), bitmap);
1955d8e057e067696d5e75999fcec1736b8963f3bf92satok                            drawable.setBounds(0, 0, width, height);
1956d8e057e067696d5e75999fcec1736b8963f3bf92satok                            is.close();
1957d8e057e067696d5e75999fcec1736b8963f3bf92satok                            return drawable;
1958d8e057e067696d5e75999fcec1736b8963f3bf92satok                        } catch (Exception e) {
1959d8e057e067696d5e75999fcec1736b8963f3bf92satok                            Log.e(TAG, "--- set html: Failed to loaded content " + uri, e);
1960d8e057e067696d5e75999fcec1736b8963f3bf92satok                            return null;
1961d8e057e067696d5e75999fcec1736b8963f3bf92satok                        } catch (OutOfMemoryError e) {
1962d8e057e067696d5e75999fcec1736b8963f3bf92satok                            Log.e(TAG, "OutOfMemoryError");
1963d8e057e067696d5e75999fcec1736b8963f3bf92satok                            mEST.setHint(HINT_MSG_BIG_SIZE_ERROR);
1964d8e057e067696d5e75999fcec1736b8963f3bf92satok
1965d8e057e067696d5e75999fcec1736b8963f3bf92satok                            return null;
1966d8e057e067696d5e75999fcec1736b8963f3bf92satok                        }
1967d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
1968d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return null;
1969d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
1970d8e057e067696d5e75999fcec1736b8963f3bf92satok            }, null);
1971d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.setText(spanned);
1972d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1973d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
1974d8e057e067696d5e75999fcec1736b8963f3bf92satok
1975d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static class SoftKeyReceiver extends ResultReceiver {
1976d8e057e067696d5e75999fcec1736b8963f3bf92satok        int mNewStart;
1977d8e057e067696d5e75999fcec1736b8963f3bf92satok        int mNewEnd;
1978d8e057e067696d5e75999fcec1736b8963f3bf92satok        EditStyledText mEST;
1979d8e057e067696d5e75999fcec1736b8963f3bf92satok
1980d8e057e067696d5e75999fcec1736b8963f3bf92satok        SoftKeyReceiver(EditStyledText est) {
1981d8e057e067696d5e75999fcec1736b8963f3bf92satok            super(est.getHandler());
1982d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST = est;
1983d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1984d8e057e067696d5e75999fcec1736b8963f3bf92satok
1985d8e057e067696d5e75999fcec1736b8963f3bf92satok        @Override
1986d8e057e067696d5e75999fcec1736b8963f3bf92satok        protected void onReceiveResult(int resultCode, Bundle resultData) {
1987d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (resultCode != InputMethodManager.RESULT_SHOWN) {
1988d8e057e067696d5e75999fcec1736b8963f3bf92satok                Selection.setSelection(mEST.getText(), mNewStart, mNewEnd);
1989d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
1990d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1991d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
1992d8e057e067696d5e75999fcec1736b8963f3bf92satok
1993d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static class SavedStyledTextState extends BaseSavedState {
1994d8e057e067696d5e75999fcec1736b8963f3bf92satok        public int mBackgroundColor;
1995d8e057e067696d5e75999fcec1736b8963f3bf92satok
1996d8e057e067696d5e75999fcec1736b8963f3bf92satok        SavedStyledTextState(Parcelable superState) {
1997d8e057e067696d5e75999fcec1736b8963f3bf92satok            super(superState);
1998d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
1999d8e057e067696d5e75999fcec1736b8963f3bf92satok
2000d8e057e067696d5e75999fcec1736b8963f3bf92satok        @Override
2001d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void writeToParcel(Parcel out, int flags) {
2002d8e057e067696d5e75999fcec1736b8963f3bf92satok            super.writeToParcel(out, flags);
2003d8e057e067696d5e75999fcec1736b8963f3bf92satok            out.writeInt(mBackgroundColor);
2004d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2005d8e057e067696d5e75999fcec1736b8963f3bf92satok
2006d8e057e067696d5e75999fcec1736b8963f3bf92satok        @Override
2007d8e057e067696d5e75999fcec1736b8963f3bf92satok        public String toString() {
2008d8e057e067696d5e75999fcec1736b8963f3bf92satok            return "EditStyledText.SavedState{"
2009d8e057e067696d5e75999fcec1736b8963f3bf92satok                    + Integer.toHexString(System.identityHashCode(this)) + " bgcolor="
2010d8e057e067696d5e75999fcec1736b8963f3bf92satok                    + mBackgroundColor + "}";
2011d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2012d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
2013d8e057e067696d5e75999fcec1736b8963f3bf92satok
2014d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static class StyledTextDialog {
2015d8e057e067696d5e75999fcec1736b8963f3bf92satok        private static final int TYPE_FOREGROUND = 0;
2016d8e057e067696d5e75999fcec1736b8963f3bf92satok        private static final int TYPE_BACKGROUND = 1;
2017d8e057e067696d5e75999fcec1736b8963f3bf92satok        private Builder mBuilder;
2018d8e057e067696d5e75999fcec1736b8963f3bf92satok        private AlertDialog mAlertDialog;
2019d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CharSequence mColorTitle;
2020d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CharSequence mSizeTitle;
2021d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CharSequence mAlignTitle;
2022d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CharSequence mMarqueeTitle;
2023d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CharSequence[] mColorNames;
2024d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CharSequence[] mColorInts;
2025d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CharSequence[] mSizeNames;
2026d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CharSequence[] mSizeDisplayInts;
2027d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CharSequence[] mSizeSendInts;
2028d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CharSequence[] mAlignNames;
2029d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CharSequence[] mMarqueeNames;
2030d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CharSequence mColorDefaultMessage;
2031d8e057e067696d5e75999fcec1736b8963f3bf92satok        private EditStyledText mEST;
2032d8e057e067696d5e75999fcec1736b8963f3bf92satok
2033d8e057e067696d5e75999fcec1736b8963f3bf92satok        public StyledTextDialog(EditStyledText est) {
2034d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST = est;
2035d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2036d8e057e067696d5e75999fcec1736b8963f3bf92satok
2037d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setBuilder(Builder builder) {
2038d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder = builder;
2039d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2040d8e057e067696d5e75999fcec1736b8963f3bf92satok
2041d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setColorAlertParams(CharSequence colortitle, CharSequence[] colornames,
2042d8e057e067696d5e75999fcec1736b8963f3bf92satok                CharSequence[] colorInts, CharSequence defaultColorMessage) {
2043d8e057e067696d5e75999fcec1736b8963f3bf92satok            mColorTitle = colortitle;
2044d8e057e067696d5e75999fcec1736b8963f3bf92satok            mColorNames = colornames;
2045d8e057e067696d5e75999fcec1736b8963f3bf92satok            mColorInts = colorInts;
2046d8e057e067696d5e75999fcec1736b8963f3bf92satok            mColorDefaultMessage = defaultColorMessage;
2047d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2048d8e057e067696d5e75999fcec1736b8963f3bf92satok
2049d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setSizeAlertParams(CharSequence sizetitle, CharSequence[] sizenames,
2050d8e057e067696d5e75999fcec1736b8963f3bf92satok                CharSequence[] sizedisplayints, CharSequence[] sizesendints) {
2051d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSizeTitle = sizetitle;
2052d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSizeNames = sizenames;
2053d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSizeDisplayInts = sizedisplayints;
2054d8e057e067696d5e75999fcec1736b8963f3bf92satok            mSizeSendInts = sizesendints;
2055d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2056d8e057e067696d5e75999fcec1736b8963f3bf92satok
2057d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setAlignAlertParams(CharSequence aligntitle, CharSequence[] alignnames) {
2058d8e057e067696d5e75999fcec1736b8963f3bf92satok            mAlignTitle = aligntitle;
2059d8e057e067696d5e75999fcec1736b8963f3bf92satok            mAlignNames = alignnames;
2060d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2061d8e057e067696d5e75999fcec1736b8963f3bf92satok
2062d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void setMarqueeAlertParams(CharSequence marqueetitle,
2063d8e057e067696d5e75999fcec1736b8963f3bf92satok                CharSequence[] marqueenames) {
2064d8e057e067696d5e75999fcec1736b8963f3bf92satok            mMarqueeTitle = marqueetitle;
2065d8e057e067696d5e75999fcec1736b8963f3bf92satok            mMarqueeNames = marqueenames;
2066d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2067d8e057e067696d5e75999fcec1736b8963f3bf92satok
2068d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean checkColorAlertParams() {
2069d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2070d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- checkParams");
2071d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2072d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mBuilder == null) {
2073d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(TAG, "--- builder is null.");
2074d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2075d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else if (mColorTitle == null || mColorNames == null || mColorInts == null) {
2076d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(TAG, "--- color alert params are null.");
2077d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2078d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else if (mColorNames.length != mColorInts.length) {
2079d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(TAG, "--- the length of color alert params are " + "different.");
2080d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2081d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2082d8e057e067696d5e75999fcec1736b8963f3bf92satok            return true;
2083d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2084d8e057e067696d5e75999fcec1736b8963f3bf92satok
2085d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean checkSizeAlertParams() {
2086d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2087d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- checkParams");
2088d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2089d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mBuilder == null) {
2090d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(TAG, "--- builder is null.");
2091d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2092d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else if (mSizeTitle == null || mSizeNames == null || mSizeDisplayInts == null
2093d8e057e067696d5e75999fcec1736b8963f3bf92satok                    || mSizeSendInts == null) {
2094d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(TAG, "--- size alert params are null.");
2095d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2096d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else if (mSizeNames.length != mSizeDisplayInts.length
2097d8e057e067696d5e75999fcec1736b8963f3bf92satok                    && mSizeSendInts.length != mSizeDisplayInts.length) {
2098d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(TAG, "--- the length of size alert params are " + "different.");
2099d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2100d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2101d8e057e067696d5e75999fcec1736b8963f3bf92satok            return true;
2102d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2103d8e057e067696d5e75999fcec1736b8963f3bf92satok
2104d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean checkAlignAlertParams() {
2105d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2106d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- checkAlignAlertParams");
2107d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2108d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mBuilder == null) {
2109d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(TAG, "--- builder is null.");
2110d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2111d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else if (mAlignTitle == null) {
2112d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(TAG, "--- align alert params are null.");
2113d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2114d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2115d8e057e067696d5e75999fcec1736b8963f3bf92satok            return true;
2116d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2117d8e057e067696d5e75999fcec1736b8963f3bf92satok
2118d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean checkMarqueeAlertParams() {
2119d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2120d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- checkMarqueeAlertParams");
2121d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2122d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mBuilder == null) {
2123d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(TAG, "--- builder is null.");
2124d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2125d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else if (mMarqueeTitle == null) {
2126d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(TAG, "--- Marquee alert params are null.");
2127d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2128d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2129d8e057e067696d5e75999fcec1736b8963f3bf92satok            return true;
2130d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2131d8e057e067696d5e75999fcec1736b8963f3bf92satok
2132d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void buildDialogue(CharSequence title, CharSequence[] names,
2133d8e057e067696d5e75999fcec1736b8963f3bf92satok                DialogInterface.OnClickListener l) {
2134d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setTitle(title);
2135d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setIcon(0);
2136d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setPositiveButton(null, null);
2137d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
2138d8e057e067696d5e75999fcec1736b8963f3bf92satok                public void onClick(DialogInterface dialog, int which) {
2139d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mEST.onStartEdit();
2140d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2141d8e057e067696d5e75999fcec1736b8963f3bf92satok            });
2142d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setItems(names, l);
2143d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setView(null);
2144d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setCancelable(true);
2145d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setOnCancelListener(new OnCancelListener() {
2146d8e057e067696d5e75999fcec1736b8963f3bf92satok                public void onCancel(DialogInterface arg0) {
2147d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (DBG) {
2148d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Log.d(TAG, "--- oncancel");
2149d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
2150d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mEST.onStartEdit();
2151d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2152d8e057e067696d5e75999fcec1736b8963f3bf92satok            });
2153d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.show();
2154d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2155d8e057e067696d5e75999fcec1736b8963f3bf92satok
2156d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void buildAndShowColorDialogue(int type, CharSequence title, int[] colors) {
2157d8e057e067696d5e75999fcec1736b8963f3bf92satok            final int HORIZONTAL_ELEMENT_NUM = 5;
2158d8e057e067696d5e75999fcec1736b8963f3bf92satok            final int BUTTON_SIZE = mEST.dipToPx(50);
2159d8e057e067696d5e75999fcec1736b8963f3bf92satok            final int BUTTON_MERGIN = mEST.dipToPx(2);
2160d8e057e067696d5e75999fcec1736b8963f3bf92satok            final int BUTTON_PADDING = mEST.dipToPx(15);
2161d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setTitle(title);
2162d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setIcon(0);
2163d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setPositiveButton(null, null);
2164d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
2165d8e057e067696d5e75999fcec1736b8963f3bf92satok                public void onClick(DialogInterface dialog, int which) {
2166d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mEST.onStartEdit();
2167d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2168d8e057e067696d5e75999fcec1736b8963f3bf92satok            });
2169d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setItems(null, null);
2170d8e057e067696d5e75999fcec1736b8963f3bf92satok            LinearLayout verticalLayout = new LinearLayout(mEST.getContext());
2171d8e057e067696d5e75999fcec1736b8963f3bf92satok            verticalLayout.setOrientation(LinearLayout.VERTICAL);
2172d8e057e067696d5e75999fcec1736b8963f3bf92satok            verticalLayout.setGravity(Gravity.CENTER_HORIZONTAL);
2173d8e057e067696d5e75999fcec1736b8963f3bf92satok            verticalLayout.setPadding(BUTTON_PADDING, BUTTON_PADDING, BUTTON_PADDING,
2174d8e057e067696d5e75999fcec1736b8963f3bf92satok                    BUTTON_PADDING);
2175d8e057e067696d5e75999fcec1736b8963f3bf92satok            LinearLayout horizontalLayout = null;
2176d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (int i = 0; i < colors.length; i++) {
2177d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (i % HORIZONTAL_ELEMENT_NUM == 0) {
2178d8e057e067696d5e75999fcec1736b8963f3bf92satok                    horizontalLayout = new LinearLayout(mEST.getContext());
2179d8e057e067696d5e75999fcec1736b8963f3bf92satok                    verticalLayout.addView(horizontalLayout);
2180d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2181d8e057e067696d5e75999fcec1736b8963f3bf92satok                Button button = new Button(mEST.getContext());
2182d8e057e067696d5e75999fcec1736b8963f3bf92satok                button.setHeight(BUTTON_SIZE);
2183d8e057e067696d5e75999fcec1736b8963f3bf92satok                button.setWidth(BUTTON_SIZE);
2184d8e057e067696d5e75999fcec1736b8963f3bf92satok                ColorPaletteDrawable cp =
2185d8e057e067696d5e75999fcec1736b8963f3bf92satok                        new ColorPaletteDrawable(colors[i], BUTTON_SIZE, BUTTON_SIZE,
2186d8e057e067696d5e75999fcec1736b8963f3bf92satok                                BUTTON_MERGIN);
2187d8e057e067696d5e75999fcec1736b8963f3bf92satok                button.setBackgroundDrawable(cp);
2188d8e057e067696d5e75999fcec1736b8963f3bf92satok                button.setDrawingCacheBackgroundColor(colors[i]);
2189d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (type == TYPE_FOREGROUND) {
2190d8e057e067696d5e75999fcec1736b8963f3bf92satok                    button.setOnClickListener(new View.OnClickListener() {
2191d8e057e067696d5e75999fcec1736b8963f3bf92satok                        public void onClick(View view) {
2192d8e057e067696d5e75999fcec1736b8963f3bf92satok                            mEST.setItemColor(view.getDrawingCacheBackgroundColor());
2193d8e057e067696d5e75999fcec1736b8963f3bf92satok                            if (mAlertDialog != null) {
2194d8e057e067696d5e75999fcec1736b8963f3bf92satok                                mAlertDialog.setView(null);
2195d8e057e067696d5e75999fcec1736b8963f3bf92satok                                mAlertDialog.dismiss();
2196d8e057e067696d5e75999fcec1736b8963f3bf92satok                                mAlertDialog = null;
2197d8e057e067696d5e75999fcec1736b8963f3bf92satok                            } else {
2198d8e057e067696d5e75999fcec1736b8963f3bf92satok                                Log.e(TAG,
2199d8e057e067696d5e75999fcec1736b8963f3bf92satok                                        "--- buildAndShowColorDialogue: can't find alertDialog");
2200d8e057e067696d5e75999fcec1736b8963f3bf92satok                            }
2201d8e057e067696d5e75999fcec1736b8963f3bf92satok                        }
2202d8e057e067696d5e75999fcec1736b8963f3bf92satok                    });
2203d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else if (type == TYPE_BACKGROUND) {
2204d8e057e067696d5e75999fcec1736b8963f3bf92satok                    button.setOnClickListener(new View.OnClickListener() {
2205d8e057e067696d5e75999fcec1736b8963f3bf92satok                        public void onClick(View view) {
2206d8e057e067696d5e75999fcec1736b8963f3bf92satok                            mEST.setBackgroundColor(view.getDrawingCacheBackgroundColor());
2207d8e057e067696d5e75999fcec1736b8963f3bf92satok                            if (mAlertDialog != null) {
2208d8e057e067696d5e75999fcec1736b8963f3bf92satok                                mAlertDialog.setView(null);
2209d8e057e067696d5e75999fcec1736b8963f3bf92satok                                mAlertDialog.dismiss();
2210d8e057e067696d5e75999fcec1736b8963f3bf92satok                                mAlertDialog = null;
2211d8e057e067696d5e75999fcec1736b8963f3bf92satok                            } else {
2212d8e057e067696d5e75999fcec1736b8963f3bf92satok                                Log.e(TAG,
2213d8e057e067696d5e75999fcec1736b8963f3bf92satok                                        "--- buildAndShowColorDialogue: can't find alertDialog");
2214d8e057e067696d5e75999fcec1736b8963f3bf92satok                            }
2215d8e057e067696d5e75999fcec1736b8963f3bf92satok                        }
2216d8e057e067696d5e75999fcec1736b8963f3bf92satok                    });
2217d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2218d8e057e067696d5e75999fcec1736b8963f3bf92satok                horizontalLayout.addView(button);
2219d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2220d8e057e067696d5e75999fcec1736b8963f3bf92satok
2221d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (type == TYPE_BACKGROUND) {
2222d8e057e067696d5e75999fcec1736b8963f3bf92satok                mBuilder.setPositiveButton(mColorDefaultMessage,
2223d8e057e067696d5e75999fcec1736b8963f3bf92satok                        new DialogInterface.OnClickListener() {
2224d8e057e067696d5e75999fcec1736b8963f3bf92satok                            public void onClick(DialogInterface dialog, int which) {
2225d8e057e067696d5e75999fcec1736b8963f3bf92satok                                mEST.setBackgroundColor(DEFAULT_TRANSPARENT_COLOR);
2226d8e057e067696d5e75999fcec1736b8963f3bf92satok                            }
2227d8e057e067696d5e75999fcec1736b8963f3bf92satok                        });
2228d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else if (type == TYPE_FOREGROUND) {
2229d8e057e067696d5e75999fcec1736b8963f3bf92satok                mBuilder.setPositiveButton(mColorDefaultMessage,
2230d8e057e067696d5e75999fcec1736b8963f3bf92satok                        new DialogInterface.OnClickListener() {
2231d8e057e067696d5e75999fcec1736b8963f3bf92satok                            public void onClick(DialogInterface dialog, int which) {
2232d8e057e067696d5e75999fcec1736b8963f3bf92satok                                mEST.setItemColor(DEFAULT_FOREGROUND_COLOR);
2233d8e057e067696d5e75999fcec1736b8963f3bf92satok                            }
2234d8e057e067696d5e75999fcec1736b8963f3bf92satok                        });
2235d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2236d8e057e067696d5e75999fcec1736b8963f3bf92satok
2237d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setView(verticalLayout);
2238d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setCancelable(true);
2239d8e057e067696d5e75999fcec1736b8963f3bf92satok            mBuilder.setOnCancelListener(new OnCancelListener() {
2240d8e057e067696d5e75999fcec1736b8963f3bf92satok                public void onCancel(DialogInterface arg0) {
2241d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mEST.onStartEdit();
2242d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2243d8e057e067696d5e75999fcec1736b8963f3bf92satok            });
2244d8e057e067696d5e75999fcec1736b8963f3bf92satok            mAlertDialog = mBuilder.show();
2245d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2246d8e057e067696d5e75999fcec1736b8963f3bf92satok
2247d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void onShowForegroundColorAlertDialog() {
2248d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2249d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- onShowForegroundColorAlertDialog");
2250d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2251d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (!checkColorAlertParams()) {
2252d8e057e067696d5e75999fcec1736b8963f3bf92satok                return;
2253d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2254d8e057e067696d5e75999fcec1736b8963f3bf92satok            int[] colorints = new int[mColorInts.length];
2255d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (int i = 0; i < colorints.length; i++) {
2256d8e057e067696d5e75999fcec1736b8963f3bf92satok                colorints[i] = Integer.parseInt((String) mColorInts[i], 16) - 0x01000000;
2257d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2258d8e057e067696d5e75999fcec1736b8963f3bf92satok            buildAndShowColorDialogue(TYPE_FOREGROUND, mColorTitle, colorints);
2259d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2260d8e057e067696d5e75999fcec1736b8963f3bf92satok
2261d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void onShowBackgroundColorAlertDialog() {
2262d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2263d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- onShowBackgroundColorAlertDialog");
2264d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2265d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (!checkColorAlertParams()) {
2266d8e057e067696d5e75999fcec1736b8963f3bf92satok                return;
2267d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2268d8e057e067696d5e75999fcec1736b8963f3bf92satok            int[] colorInts = new int[mColorInts.length];
2269d8e057e067696d5e75999fcec1736b8963f3bf92satok            for (int i = 0; i < colorInts.length; i++) {
2270d8e057e067696d5e75999fcec1736b8963f3bf92satok                colorInts[i] = Integer.parseInt((String) mColorInts[i], 16) - 0x01000000;
2271d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2272d8e057e067696d5e75999fcec1736b8963f3bf92satok            buildAndShowColorDialogue(TYPE_BACKGROUND, mColorTitle, colorInts);
2273d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2274d8e057e067696d5e75999fcec1736b8963f3bf92satok
2275d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void onShowSizeAlertDialog() {
2276d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2277d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- onShowSizeAlertDialog");
2278d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2279d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (!checkSizeAlertParams()) {
2280d8e057e067696d5e75999fcec1736b8963f3bf92satok                return;
2281d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2282d8e057e067696d5e75999fcec1736b8963f3bf92satok            buildDialogue(mSizeTitle, mSizeNames, new DialogInterface.OnClickListener() {
2283d8e057e067696d5e75999fcec1736b8963f3bf92satok                public void onClick(DialogInterface dialog, int which) {
2284d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.d(TAG, "mBuilder.onclick:" + which);
2285d8e057e067696d5e75999fcec1736b8963f3bf92satok                    int size =
2286d8e057e067696d5e75999fcec1736b8963f3bf92satok                            mEST.dipToPx(Integer.parseInt((String) mSizeDisplayInts[which]));
2287d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mEST.setItemSize(size);
2288d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2289d8e057e067696d5e75999fcec1736b8963f3bf92satok            });
2290d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2291d8e057e067696d5e75999fcec1736b8963f3bf92satok
2292d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void onShowAlignAlertDialog() {
2293d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2294d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- onShowAlignAlertDialog");
2295d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2296d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (!checkAlignAlertParams()) {
2297d8e057e067696d5e75999fcec1736b8963f3bf92satok                return;
2298d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2299d8e057e067696d5e75999fcec1736b8963f3bf92satok            buildDialogue(mAlignTitle, mAlignNames, new DialogInterface.OnClickListener() {
2300d8e057e067696d5e75999fcec1736b8963f3bf92satok                public void onClick(DialogInterface dialog, int which) {
2301d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Layout.Alignment align = Layout.Alignment.ALIGN_NORMAL;
2302d8e057e067696d5e75999fcec1736b8963f3bf92satok                    switch (which) {
2303d8e057e067696d5e75999fcec1736b8963f3bf92satok                        case 0:
2304d8e057e067696d5e75999fcec1736b8963f3bf92satok                            align = Layout.Alignment.ALIGN_NORMAL;
2305d8e057e067696d5e75999fcec1736b8963f3bf92satok                            break;
2306d8e057e067696d5e75999fcec1736b8963f3bf92satok                        case 1:
2307d8e057e067696d5e75999fcec1736b8963f3bf92satok                            align = Layout.Alignment.ALIGN_CENTER;
2308d8e057e067696d5e75999fcec1736b8963f3bf92satok                            break;
2309d8e057e067696d5e75999fcec1736b8963f3bf92satok                        case 2:
2310d8e057e067696d5e75999fcec1736b8963f3bf92satok                            align = Layout.Alignment.ALIGN_OPPOSITE;
2311d8e057e067696d5e75999fcec1736b8963f3bf92satok                            break;
2312d8e057e067696d5e75999fcec1736b8963f3bf92satok                        default:
2313d8e057e067696d5e75999fcec1736b8963f3bf92satok                            Log.e(TAG, "--- onShowAlignAlertDialog: got illigal align.");
2314d8e057e067696d5e75999fcec1736b8963f3bf92satok                            break;
2315d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
2316d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mEST.setAlignment(align);
2317d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2318d8e057e067696d5e75999fcec1736b8963f3bf92satok            });
2319d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2320d8e057e067696d5e75999fcec1736b8963f3bf92satok
2321d8e057e067696d5e75999fcec1736b8963f3bf92satok        private void onShowMarqueeAlertDialog() {
2322d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2323d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- onShowMarqueeAlertDialog");
2324d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2325d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (!checkMarqueeAlertParams()) {
2326d8e057e067696d5e75999fcec1736b8963f3bf92satok                return;
2327d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2328d8e057e067696d5e75999fcec1736b8963f3bf92satok            buildDialogue(mMarqueeTitle, mMarqueeNames, new DialogInterface.OnClickListener() {
2329d8e057e067696d5e75999fcec1736b8963f3bf92satok                public void onClick(DialogInterface dialog, int which) {
2330d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (DBG) {
2331d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Log.d(TAG, "mBuilder.onclick:" + which);
2332d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
2333d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mEST.setMarquee(which);
2334d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2335d8e057e067696d5e75999fcec1736b8963f3bf92satok            });
2336d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2337d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
2338d8e057e067696d5e75999fcec1736b8963f3bf92satok
2339d8e057e067696d5e75999fcec1736b8963f3bf92satok    private class MenuHandler implements MenuItem.OnMenuItemClickListener {
2340d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean onMenuItemClick(MenuItem item) {
2341d8e057e067696d5e75999fcec1736b8963f3bf92satok            return onTextContextMenuItem(item.getItemId());
2342d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2343d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
2344d8e057e067696d5e75999fcec1736b8963f3bf92satok
2345d8e057e067696d5e75999fcec1736b8963f3bf92satok    private static class StyledTextArrowKeyMethod extends ArrowKeyMovementMethod {
2346d8e057e067696d5e75999fcec1736b8963f3bf92satok        EditorManager mManager;
2347d8e057e067696d5e75999fcec1736b8963f3bf92satok        String LOG_TAG = "StyledTextArrowKeyMethod";
2348d8e057e067696d5e75999fcec1736b8963f3bf92satok
2349d8e057e067696d5e75999fcec1736b8963f3bf92satok        StyledTextArrowKeyMethod(EditorManager manager) {
2350d8e057e067696d5e75999fcec1736b8963f3bf92satok            super();
2351d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager = manager;
2352d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2353d8e057e067696d5e75999fcec1736b8963f3bf92satok
2354d8e057e067696d5e75999fcec1736b8963f3bf92satok        @Override
2355d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean
2356d8e057e067696d5e75999fcec1736b8963f3bf92satok                onKeyDown(TextView widget, Spannable buffer, int keyCode, KeyEvent event) {
2357d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2358d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "---onkeydown:" + keyCode);
2359d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2360d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager.unsetTextComposingMask();
2361d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mManager.getSelectState() == STATE_SELECT_ON
2362d8e057e067696d5e75999fcec1736b8963f3bf92satok                    || mManager.getSelectState() == STATE_SELECTED) {
2363d8e057e067696d5e75999fcec1736b8963f3bf92satok                return executeDown(widget, buffer, keyCode);
2364d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
2365d8e057e067696d5e75999fcec1736b8963f3bf92satok                return super.onKeyDown(widget, buffer, keyCode, event);
2366d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2367d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2368d8e057e067696d5e75999fcec1736b8963f3bf92satok
2369d8e057e067696d5e75999fcec1736b8963f3bf92satok        private int getEndPos(TextView widget) {
2370d8e057e067696d5e75999fcec1736b8963f3bf92satok            int end;
2371d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (widget.getSelectionStart() == mManager.getSelectionStart()) {
2372d8e057e067696d5e75999fcec1736b8963f3bf92satok                end = widget.getSelectionEnd();
2373d8e057e067696d5e75999fcec1736b8963f3bf92satok            } else {
2374d8e057e067696d5e75999fcec1736b8963f3bf92satok                end = widget.getSelectionStart();
2375d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2376d8e057e067696d5e75999fcec1736b8963f3bf92satok            return end;
2377d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2378d8e057e067696d5e75999fcec1736b8963f3bf92satok
237910c28c7f31687ff57476d0a7381461fef71cc5cbFicus Kirkpatrick        protected boolean up(TextView widget, Spannable buffer) {
2380d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2381d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- up:");
2382d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2383d8e057e067696d5e75999fcec1736b8963f3bf92satok            Layout layout = widget.getLayout();
2384d8e057e067696d5e75999fcec1736b8963f3bf92satok            int end = getEndPos(widget);
2385d8e057e067696d5e75999fcec1736b8963f3bf92satok            int line = layout.getLineForOffset(end);
2386d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (line > 0) {
2387d8e057e067696d5e75999fcec1736b8963f3bf92satok                int to;
2388d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (layout.getParagraphDirection(line) == layout
2389d8e057e067696d5e75999fcec1736b8963f3bf92satok                        .getParagraphDirection(line - 1)) {
2390d8e057e067696d5e75999fcec1736b8963f3bf92satok                    float h = layout.getPrimaryHorizontal(end);
2391d8e057e067696d5e75999fcec1736b8963f3bf92satok                    to = layout.getOffsetForHorizontal(line - 1, h);
2392d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else {
2393d8e057e067696d5e75999fcec1736b8963f3bf92satok                    to = layout.getLineStart(line - 1);
2394d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2395d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.setEndPos(to);
2396d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.onCursorMoved();
2397d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2398d8e057e067696d5e75999fcec1736b8963f3bf92satok            return true;
2399d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2400d8e057e067696d5e75999fcec1736b8963f3bf92satok
240110c28c7f31687ff57476d0a7381461fef71cc5cbFicus Kirkpatrick        protected boolean down(TextView widget, Spannable buffer) {
2402d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2403d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- down:");
2404d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2405d8e057e067696d5e75999fcec1736b8963f3bf92satok            Layout layout = widget.getLayout();
2406d8e057e067696d5e75999fcec1736b8963f3bf92satok            int end = getEndPos(widget);
2407d8e057e067696d5e75999fcec1736b8963f3bf92satok            int line = layout.getLineForOffset(end);
2408d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (line < layout.getLineCount() - 1) {
2409d8e057e067696d5e75999fcec1736b8963f3bf92satok                int to;
2410d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (layout.getParagraphDirection(line) == layout
2411d8e057e067696d5e75999fcec1736b8963f3bf92satok                        .getParagraphDirection(line + 1)) {
2412d8e057e067696d5e75999fcec1736b8963f3bf92satok                    float h = layout.getPrimaryHorizontal(end);
2413d8e057e067696d5e75999fcec1736b8963f3bf92satok                    to = layout.getOffsetForHorizontal(line + 1, h);
2414d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else {
2415d8e057e067696d5e75999fcec1736b8963f3bf92satok                    to = layout.getLineStart(line + 1);
2416d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2417d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.setEndPos(to);
2418d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.onCursorMoved();
2419d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2420d8e057e067696d5e75999fcec1736b8963f3bf92satok            return true;
2421d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2422d8e057e067696d5e75999fcec1736b8963f3bf92satok
242310c28c7f31687ff57476d0a7381461fef71cc5cbFicus Kirkpatrick        protected boolean left(TextView widget, Spannable buffer) {
2424d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2425d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- left:");
2426d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2427d8e057e067696d5e75999fcec1736b8963f3bf92satok            Layout layout = widget.getLayout();
2428d8e057e067696d5e75999fcec1736b8963f3bf92satok            int to = layout.getOffsetToLeftOf(getEndPos(widget));
2429d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager.setEndPos(to);
2430d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager.onCursorMoved();
2431d8e057e067696d5e75999fcec1736b8963f3bf92satok            return true;
2432d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2433d8e057e067696d5e75999fcec1736b8963f3bf92satok
243410c28c7f31687ff57476d0a7381461fef71cc5cbFicus Kirkpatrick        protected boolean right(TextView widget, Spannable buffer) {
2435d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2436d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- right:");
2437d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2438d8e057e067696d5e75999fcec1736b8963f3bf92satok            Layout layout = widget.getLayout();
2439d8e057e067696d5e75999fcec1736b8963f3bf92satok            int to = layout.getOffsetToRightOf(getEndPos(widget));
2440d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager.setEndPos(to);
2441d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager.onCursorMoved();
2442d8e057e067696d5e75999fcec1736b8963f3bf92satok            return true;
2443d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2444d8e057e067696d5e75999fcec1736b8963f3bf92satok
2445d8e057e067696d5e75999fcec1736b8963f3bf92satok        private boolean executeDown(TextView widget, Spannable buffer, int keyCode) {
2446d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2447d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(LOG_TAG, "--- executeDown: " + keyCode);
2448d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2449d8e057e067696d5e75999fcec1736b8963f3bf92satok            boolean handled = false;
2450d8e057e067696d5e75999fcec1736b8963f3bf92satok
2451d8e057e067696d5e75999fcec1736b8963f3bf92satok            switch (keyCode) {
2452d8e057e067696d5e75999fcec1736b8963f3bf92satok                case KeyEvent.KEYCODE_DPAD_UP:
2453d8e057e067696d5e75999fcec1736b8963f3bf92satok                    handled |= up(widget, buffer);
2454d8e057e067696d5e75999fcec1736b8963f3bf92satok                    break;
2455d8e057e067696d5e75999fcec1736b8963f3bf92satok                case KeyEvent.KEYCODE_DPAD_DOWN:
2456d8e057e067696d5e75999fcec1736b8963f3bf92satok                    handled |= down(widget, buffer);
2457d8e057e067696d5e75999fcec1736b8963f3bf92satok                    break;
2458d8e057e067696d5e75999fcec1736b8963f3bf92satok                case KeyEvent.KEYCODE_DPAD_LEFT:
2459d8e057e067696d5e75999fcec1736b8963f3bf92satok                    handled |= left(widget, buffer);
2460d8e057e067696d5e75999fcec1736b8963f3bf92satok                    break;
2461d8e057e067696d5e75999fcec1736b8963f3bf92satok                case KeyEvent.KEYCODE_DPAD_RIGHT:
2462d8e057e067696d5e75999fcec1736b8963f3bf92satok                    handled |= right(widget, buffer);
2463d8e057e067696d5e75999fcec1736b8963f3bf92satok                    break;
2464d8e057e067696d5e75999fcec1736b8963f3bf92satok                case KeyEvent.KEYCODE_DPAD_CENTER:
2465d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.onFixSelectedItem();
2466d8e057e067696d5e75999fcec1736b8963f3bf92satok                    handled = true;
2467d8e057e067696d5e75999fcec1736b8963f3bf92satok                    break;
2468d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2469d8e057e067696d5e75999fcec1736b8963f3bf92satok            return handled;
2470d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2471d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
2472d8e057e067696d5e75999fcec1736b8963f3bf92satok
2473d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static class StyledTextInputConnection extends InputConnectionWrapper {
2474d8e057e067696d5e75999fcec1736b8963f3bf92satok        EditStyledText mEST;
2475d8e057e067696d5e75999fcec1736b8963f3bf92satok
2476d8e057e067696d5e75999fcec1736b8963f3bf92satok        public StyledTextInputConnection(InputConnection target, EditStyledText est) {
2477d8e057e067696d5e75999fcec1736b8963f3bf92satok            super(target, true);
2478d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST = est;
2479d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2480d8e057e067696d5e75999fcec1736b8963f3bf92satok
2481d8e057e067696d5e75999fcec1736b8963f3bf92satok        @Override
2482d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean commitText(CharSequence text, int newCursorPosition) {
2483d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2484d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- commitText:");
2485d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2486d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST.mManager.unsetTextComposingMask();
2487d8e057e067696d5e75999fcec1736b8963f3bf92satok            return super.commitText(text, newCursorPosition);
2488d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2489d8e057e067696d5e75999fcec1736b8963f3bf92satok
2490d8e057e067696d5e75999fcec1736b8963f3bf92satok        @Override
2491d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean finishComposingText() {
2492d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2493d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- finishcomposing:");
2494d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2495d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (!mEST.isSoftKeyBlocked() && !mEST.isButtonsFocused() && !mEST.isEditting()) {
2496d8e057e067696d5e75999fcec1736b8963f3bf92satok                // TODO onEndEdit isn't called temporally .
2497d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.onEndEdit();
2498d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2499d8e057e067696d5e75999fcec1736b8963f3bf92satok            return super.finishComposingText();
2500d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2501d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
2502d8e057e067696d5e75999fcec1736b8963f3bf92satok
2503d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static class EditStyledTextSpans {
2504d8e057e067696d5e75999fcec1736b8963f3bf92satok        private static final String LOG_TAG = "EditStyledTextSpan";
2505d8e057e067696d5e75999fcec1736b8963f3bf92satok
2506d8e057e067696d5e75999fcec1736b8963f3bf92satok        public static class HorizontalLineSpan extends DynamicDrawableSpan {
2507d8e057e067696d5e75999fcec1736b8963f3bf92satok            HorizontalLineDrawable mDrawable;
2508d8e057e067696d5e75999fcec1736b8963f3bf92satok
2509d8e057e067696d5e75999fcec1736b8963f3bf92satok            public HorizontalLineSpan(int color, int width, Spannable spannable) {
2510d8e057e067696d5e75999fcec1736b8963f3bf92satok                super(ALIGN_BOTTOM);
2511d8e057e067696d5e75999fcec1736b8963f3bf92satok                mDrawable = new HorizontalLineDrawable(color, width, spannable);
2512d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2513d8e057e067696d5e75999fcec1736b8963f3bf92satok
2514d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
2515d8e057e067696d5e75999fcec1736b8963f3bf92satok            public Drawable getDrawable() {
2516d8e057e067696d5e75999fcec1736b8963f3bf92satok                return mDrawable;
2517d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2518d8e057e067696d5e75999fcec1736b8963f3bf92satok
2519d8e057e067696d5e75999fcec1736b8963f3bf92satok            public void resetWidth(int width) {
2520d8e057e067696d5e75999fcec1736b8963f3bf92satok                mDrawable.renewBounds(width);
2521d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2522d8e057e067696d5e75999fcec1736b8963f3bf92satok
2523d8e057e067696d5e75999fcec1736b8963f3bf92satok            public int getColor() {
2524d8e057e067696d5e75999fcec1736b8963f3bf92satok                return mDrawable.getPaint().getColor();
2525d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2526d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2527d8e057e067696d5e75999fcec1736b8963f3bf92satok
2528d8e057e067696d5e75999fcec1736b8963f3bf92satok        public static class MarqueeSpan extends CharacterStyle {
2529d8e057e067696d5e75999fcec1736b8963f3bf92satok            public static final int SCROLL = 0;
2530d8e057e067696d5e75999fcec1736b8963f3bf92satok            public static final int ALTERNATE = 1;
2531d8e057e067696d5e75999fcec1736b8963f3bf92satok            public static final int NOTHING = 2;
2532d8e057e067696d5e75999fcec1736b8963f3bf92satok            private int mType;
2533d8e057e067696d5e75999fcec1736b8963f3bf92satok            private int mMarqueeColor;
2534d8e057e067696d5e75999fcec1736b8963f3bf92satok
2535d8e057e067696d5e75999fcec1736b8963f3bf92satok            public MarqueeSpan(int type, int bgc) {
2536d8e057e067696d5e75999fcec1736b8963f3bf92satok                mType = type;
2537d8e057e067696d5e75999fcec1736b8963f3bf92satok                checkType(type);
2538d8e057e067696d5e75999fcec1736b8963f3bf92satok                mMarqueeColor = getMarqueeColor(type, bgc);
2539d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2540d8e057e067696d5e75999fcec1736b8963f3bf92satok
2541d8e057e067696d5e75999fcec1736b8963f3bf92satok            public MarqueeSpan(int type) {
2542d8e057e067696d5e75999fcec1736b8963f3bf92satok                this(type, EditStyledText.DEFAULT_TRANSPARENT_COLOR);
2543d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2544d8e057e067696d5e75999fcec1736b8963f3bf92satok
2545d8e057e067696d5e75999fcec1736b8963f3bf92satok            public int getType() {
2546d8e057e067696d5e75999fcec1736b8963f3bf92satok                return mType;
2547d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2548d8e057e067696d5e75999fcec1736b8963f3bf92satok
2549d8e057e067696d5e75999fcec1736b8963f3bf92satok            public void resetColor(int bgc) {
2550d8e057e067696d5e75999fcec1736b8963f3bf92satok                mMarqueeColor = getMarqueeColor(mType, bgc);
2551d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2552d8e057e067696d5e75999fcec1736b8963f3bf92satok
2553d8e057e067696d5e75999fcec1736b8963f3bf92satok            private int getMarqueeColor(int type, int bgc) {
2554d8e057e067696d5e75999fcec1736b8963f3bf92satok                int THRESHOLD = 128;
2555d8e057e067696d5e75999fcec1736b8963f3bf92satok                int a = Color.alpha(bgc);
2556d8e057e067696d5e75999fcec1736b8963f3bf92satok                int r = Color.red(bgc);
2557d8e057e067696d5e75999fcec1736b8963f3bf92satok                int g = Color.green(bgc);
2558d8e057e067696d5e75999fcec1736b8963f3bf92satok                int b = Color.blue(bgc);
2559d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (a == 0) {
2560d8e057e067696d5e75999fcec1736b8963f3bf92satok                    a = 0x80;
2561d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2562d8e057e067696d5e75999fcec1736b8963f3bf92satok                switch (type) {
2563d8e057e067696d5e75999fcec1736b8963f3bf92satok                    case SCROLL:
2564d8e057e067696d5e75999fcec1736b8963f3bf92satok                        if (r > THRESHOLD) {
2565d8e057e067696d5e75999fcec1736b8963f3bf92satok                            r = r / 2;
2566d8e057e067696d5e75999fcec1736b8963f3bf92satok                        } else {
2567d8e057e067696d5e75999fcec1736b8963f3bf92satok                            r = (0XFF - r) / 2;
2568d8e057e067696d5e75999fcec1736b8963f3bf92satok                        }
2569d8e057e067696d5e75999fcec1736b8963f3bf92satok                        break;
2570d8e057e067696d5e75999fcec1736b8963f3bf92satok                    case ALTERNATE:
2571d8e057e067696d5e75999fcec1736b8963f3bf92satok                        if (g > THRESHOLD) {
2572d8e057e067696d5e75999fcec1736b8963f3bf92satok                            g = g / 2;
2573d8e057e067696d5e75999fcec1736b8963f3bf92satok                        } else {
2574d8e057e067696d5e75999fcec1736b8963f3bf92satok                            g = (0XFF - g) / 2;
2575d8e057e067696d5e75999fcec1736b8963f3bf92satok                        }
2576d8e057e067696d5e75999fcec1736b8963f3bf92satok                        break;
2577d8e057e067696d5e75999fcec1736b8963f3bf92satok                    case NOTHING:
2578d8e057e067696d5e75999fcec1736b8963f3bf92satok                        return DEFAULT_TRANSPARENT_COLOR;
2579d8e057e067696d5e75999fcec1736b8963f3bf92satok                    default:
2580d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Log.e(TAG, "--- getMarqueeColor: got illigal marquee ID.");
2581d8e057e067696d5e75999fcec1736b8963f3bf92satok                        return DEFAULT_TRANSPARENT_COLOR;
2582d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2583d8e057e067696d5e75999fcec1736b8963f3bf92satok                return Color.argb(a, r, g, b);
2584d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2585d8e057e067696d5e75999fcec1736b8963f3bf92satok
2586d8e057e067696d5e75999fcec1736b8963f3bf92satok            private boolean checkType(int type) {
2587d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (type == SCROLL || type == ALTERNATE) {
2588d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
2589d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else {
2590d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.e(LOG_TAG, "--- Invalid type of MarqueeSpan");
2591d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return false;
2592d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2593d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2594d8e057e067696d5e75999fcec1736b8963f3bf92satok
2595d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
2596d8e057e067696d5e75999fcec1736b8963f3bf92satok            public void updateDrawState(TextPaint tp) {
2597d8e057e067696d5e75999fcec1736b8963f3bf92satok                tp.bgColor = mMarqueeColor;
2598d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2599d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2600d8e057e067696d5e75999fcec1736b8963f3bf92satok
2601d8e057e067696d5e75999fcec1736b8963f3bf92satok        public static class RescalableImageSpan extends ImageSpan {
2602d8e057e067696d5e75999fcec1736b8963f3bf92satok            Uri mContentUri;
2603d8e057e067696d5e75999fcec1736b8963f3bf92satok            private Drawable mDrawable;
2604d8e057e067696d5e75999fcec1736b8963f3bf92satok            private Context mContext;
2605d8e057e067696d5e75999fcec1736b8963f3bf92satok            public int mIntrinsicWidth = -1;
2606d8e057e067696d5e75999fcec1736b8963f3bf92satok            public int mIntrinsicHeight = -1;
2607d8e057e067696d5e75999fcec1736b8963f3bf92satok            private final int MAXWIDTH;
2608d8e057e067696d5e75999fcec1736b8963f3bf92satok
2609d8e057e067696d5e75999fcec1736b8963f3bf92satok            public RescalableImageSpan(Context context, Uri uri, int maxwidth) {
2610d8e057e067696d5e75999fcec1736b8963f3bf92satok                super(context, uri);
2611d8e057e067696d5e75999fcec1736b8963f3bf92satok                mContext = context;
2612d8e057e067696d5e75999fcec1736b8963f3bf92satok                mContentUri = uri;
2613d8e057e067696d5e75999fcec1736b8963f3bf92satok                MAXWIDTH = maxwidth;
2614d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2615d8e057e067696d5e75999fcec1736b8963f3bf92satok
2616d8e057e067696d5e75999fcec1736b8963f3bf92satok            public RescalableImageSpan(Context context, int resourceId, int maxwidth) {
2617d8e057e067696d5e75999fcec1736b8963f3bf92satok                super(context, resourceId);
2618d8e057e067696d5e75999fcec1736b8963f3bf92satok                mContext = context;
2619d8e057e067696d5e75999fcec1736b8963f3bf92satok                MAXWIDTH = maxwidth;
2620d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2621d8e057e067696d5e75999fcec1736b8963f3bf92satok
2622d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
2623d8e057e067696d5e75999fcec1736b8963f3bf92satok            public Drawable getDrawable() {
2624d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (mDrawable != null) {
2625d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return mDrawable;
2626d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else if (mContentUri != null) {
2627d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Bitmap bitmap = null;
2628d8e057e067696d5e75999fcec1736b8963f3bf92satok                    System.gc();
2629d8e057e067696d5e75999fcec1736b8963f3bf92satok                    try {
2630d8e057e067696d5e75999fcec1736b8963f3bf92satok                        InputStream is =
2631d8e057e067696d5e75999fcec1736b8963f3bf92satok                                mContext.getContentResolver().openInputStream(mContentUri);
2632d8e057e067696d5e75999fcec1736b8963f3bf92satok                        BitmapFactory.Options opt = new BitmapFactory.Options();
2633d8e057e067696d5e75999fcec1736b8963f3bf92satok                        opt.inJustDecodeBounds = true;
2634d8e057e067696d5e75999fcec1736b8963f3bf92satok                        BitmapFactory.decodeStream(is, null, opt);
2635d8e057e067696d5e75999fcec1736b8963f3bf92satok                        is.close();
2636d8e057e067696d5e75999fcec1736b8963f3bf92satok                        is = mContext.getContentResolver().openInputStream(mContentUri);
2637d8e057e067696d5e75999fcec1736b8963f3bf92satok                        int width, height;
2638d8e057e067696d5e75999fcec1736b8963f3bf92satok                        width = opt.outWidth;
2639d8e057e067696d5e75999fcec1736b8963f3bf92satok                        height = opt.outHeight;
2640d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mIntrinsicWidth = width;
2641d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mIntrinsicHeight = height;
2642d8e057e067696d5e75999fcec1736b8963f3bf92satok                        if (opt.outWidth > MAXWIDTH) {
2643d8e057e067696d5e75999fcec1736b8963f3bf92satok                            width = MAXWIDTH;
2644d8e057e067696d5e75999fcec1736b8963f3bf92satok                            height = height * MAXWIDTH / opt.outWidth;
2645d8e057e067696d5e75999fcec1736b8963f3bf92satok                            Rect padding = new Rect(0, 0, width, height);
2646d8e057e067696d5e75999fcec1736b8963f3bf92satok                            bitmap = BitmapFactory.decodeStream(is, padding, null);
2647d8e057e067696d5e75999fcec1736b8963f3bf92satok                        } else {
2648d8e057e067696d5e75999fcec1736b8963f3bf92satok                            bitmap = BitmapFactory.decodeStream(is);
2649d8e057e067696d5e75999fcec1736b8963f3bf92satok                        }
2650d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
2651d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mDrawable.setBounds(0, 0, width, height);
2652d8e057e067696d5e75999fcec1736b8963f3bf92satok                        is.close();
2653d8e057e067696d5e75999fcec1736b8963f3bf92satok                    } catch (Exception e) {
2654d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Log.e(LOG_TAG, "Failed to loaded content " + mContentUri, e);
2655d8e057e067696d5e75999fcec1736b8963f3bf92satok                        return null;
2656d8e057e067696d5e75999fcec1736b8963f3bf92satok                    } catch (OutOfMemoryError e) {
2657d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Log.e(LOG_TAG, "OutOfMemoryError");
2658d8e057e067696d5e75999fcec1736b8963f3bf92satok                        return null;
2659d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
2660d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else {
2661d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mDrawable = super.getDrawable();
2662d8e057e067696d5e75999fcec1736b8963f3bf92satok                    rescaleBigImage(mDrawable);
2663d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mIntrinsicWidth = mDrawable.getIntrinsicWidth();
2664d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mIntrinsicHeight = mDrawable.getIntrinsicHeight();
2665d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2666d8e057e067696d5e75999fcec1736b8963f3bf92satok                return mDrawable;
2667d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2668d8e057e067696d5e75999fcec1736b8963f3bf92satok
2669d8e057e067696d5e75999fcec1736b8963f3bf92satok            public boolean isOverSize() {
2670d8e057e067696d5e75999fcec1736b8963f3bf92satok                return (getDrawable().getIntrinsicWidth() > MAXWIDTH);
2671d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2672d8e057e067696d5e75999fcec1736b8963f3bf92satok
2673d8e057e067696d5e75999fcec1736b8963f3bf92satok            public Uri getContentUri() {
2674d8e057e067696d5e75999fcec1736b8963f3bf92satok                return mContentUri;
2675d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2676d8e057e067696d5e75999fcec1736b8963f3bf92satok
2677d8e057e067696d5e75999fcec1736b8963f3bf92satok            private void rescaleBigImage(Drawable image) {
2678d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (DBG) {
2679d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.d(LOG_TAG, "--- rescaleBigImage:");
2680d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2681d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (MAXWIDTH < 0) {
2682d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return;
2683d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2684d8e057e067696d5e75999fcec1736b8963f3bf92satok                int image_width = image.getIntrinsicWidth();
2685d8e057e067696d5e75999fcec1736b8963f3bf92satok                int image_height = image.getIntrinsicHeight();
2686d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (DBG) {
2687d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.d(LOG_TAG, "--- rescaleBigImage:" + image_width + "," + image_height
2688d8e057e067696d5e75999fcec1736b8963f3bf92satok                            + "," + MAXWIDTH);
2689d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2690d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (image_width > MAXWIDTH) {
2691d8e057e067696d5e75999fcec1736b8963f3bf92satok                    image_width = MAXWIDTH;
2692d8e057e067696d5e75999fcec1736b8963f3bf92satok                    image_height = image_height * MAXWIDTH / image_width;
2693d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2694d8e057e067696d5e75999fcec1736b8963f3bf92satok                image.setBounds(0, 0, image_width, image_height);
2695d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2696d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2697d8e057e067696d5e75999fcec1736b8963f3bf92satok
2698d8e057e067696d5e75999fcec1736b8963f3bf92satok        public static class HorizontalLineDrawable extends ShapeDrawable {
2699d8e057e067696d5e75999fcec1736b8963f3bf92satok            private Spannable mSpannable;
2700d8e057e067696d5e75999fcec1736b8963f3bf92satok            private int mWidth;
2701d8e057e067696d5e75999fcec1736b8963f3bf92satok            private static boolean DBG_HL = false;
2702d8e057e067696d5e75999fcec1736b8963f3bf92satok
2703d8e057e067696d5e75999fcec1736b8963f3bf92satok            public HorizontalLineDrawable(int color, int width, Spannable spannable) {
2704d8e057e067696d5e75999fcec1736b8963f3bf92satok                super(new RectShape());
2705d8e057e067696d5e75999fcec1736b8963f3bf92satok                mSpannable = spannable;
2706d8e057e067696d5e75999fcec1736b8963f3bf92satok                mWidth = width;
2707d8e057e067696d5e75999fcec1736b8963f3bf92satok                renewColor(color);
2708d8e057e067696d5e75999fcec1736b8963f3bf92satok                renewBounds(width);
2709d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2710d8e057e067696d5e75999fcec1736b8963f3bf92satok
2711d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
2712d8e057e067696d5e75999fcec1736b8963f3bf92satok            public void draw(Canvas canvas) {
2713d8e057e067696d5e75999fcec1736b8963f3bf92satok                renewColor();
2714d8e057e067696d5e75999fcec1736b8963f3bf92satok                Rect rect = new Rect(0, 9, mWidth, 11);
2715d8e057e067696d5e75999fcec1736b8963f3bf92satok                canvas.drawRect(rect, getPaint());
2716d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2717d8e057e067696d5e75999fcec1736b8963f3bf92satok
2718d8e057e067696d5e75999fcec1736b8963f3bf92satok            public void renewBounds(int width) {
2719d8e057e067696d5e75999fcec1736b8963f3bf92satok                int MARGIN = 20;
2720d8e057e067696d5e75999fcec1736b8963f3bf92satok                int HEIGHT = 20;
2721d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (DBG_HL) {
2722d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.d(LOG_TAG, "--- renewBounds:" + width);
2723d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2724d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (width > MARGIN) {
2725d8e057e067696d5e75999fcec1736b8963f3bf92satok                    width -= MARGIN;
2726d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2727d8e057e067696d5e75999fcec1736b8963f3bf92satok                mWidth = width;
2728d8e057e067696d5e75999fcec1736b8963f3bf92satok                setBounds(0, 0, width, HEIGHT);
2729d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2730d8e057e067696d5e75999fcec1736b8963f3bf92satok
2731d8e057e067696d5e75999fcec1736b8963f3bf92satok            private void renewColor(int color) {
2732d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (DBG_HL) {
2733d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.d(LOG_TAG, "--- renewColor:" + color);
2734d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2735d8e057e067696d5e75999fcec1736b8963f3bf92satok                getPaint().setColor(color);
2736d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2737d8e057e067696d5e75999fcec1736b8963f3bf92satok
2738d8e057e067696d5e75999fcec1736b8963f3bf92satok            private void renewColor() {
2739d8e057e067696d5e75999fcec1736b8963f3bf92satok                HorizontalLineSpan parent = getParentSpan();
2740d8e057e067696d5e75999fcec1736b8963f3bf92satok                Spannable text = mSpannable;
2741d8e057e067696d5e75999fcec1736b8963f3bf92satok                int start = text.getSpanStart(parent);
2742d8e057e067696d5e75999fcec1736b8963f3bf92satok                int end = text.getSpanEnd(parent);
2743d8e057e067696d5e75999fcec1736b8963f3bf92satok                ForegroundColorSpan[] spans =
2744d8e057e067696d5e75999fcec1736b8963f3bf92satok                        text.getSpans(start, end, ForegroundColorSpan.class);
2745d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (DBG_HL) {
2746d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.d(LOG_TAG, "--- renewColor:" + spans.length);
2747d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2748d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (spans.length > 0) {
2749d8e057e067696d5e75999fcec1736b8963f3bf92satok                    renewColor(spans[spans.length - 1].getForegroundColor());
2750d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2751d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2752d8e057e067696d5e75999fcec1736b8963f3bf92satok
2753d8e057e067696d5e75999fcec1736b8963f3bf92satok            private HorizontalLineSpan getParentSpan() {
2754d8e057e067696d5e75999fcec1736b8963f3bf92satok                Spannable text = mSpannable;
2755d8e057e067696d5e75999fcec1736b8963f3bf92satok                HorizontalLineSpan[] images =
2756d8e057e067696d5e75999fcec1736b8963f3bf92satok                        text.getSpans(0, text.length(), HorizontalLineSpan.class);
2757d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (images.length > 0) {
2758d8e057e067696d5e75999fcec1736b8963f3bf92satok                    for (HorizontalLineSpan image : images) {
2759d8e057e067696d5e75999fcec1736b8963f3bf92satok                        if (image.getDrawable() == this) {
2760d8e057e067696d5e75999fcec1736b8963f3bf92satok                            return image;
2761d8e057e067696d5e75999fcec1736b8963f3bf92satok                        }
2762d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
2763d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2764d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(LOG_TAG, "---renewBounds: Couldn't find");
2765d8e057e067696d5e75999fcec1736b8963f3bf92satok                return null;
2766d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2767d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2768d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
2769d8e057e067696d5e75999fcec1736b8963f3bf92satok
2770d8e057e067696d5e75999fcec1736b8963f3bf92satok    public static class ColorPaletteDrawable extends ShapeDrawable {
2771d8e057e067696d5e75999fcec1736b8963f3bf92satok        private Rect mRect;
2772d8e057e067696d5e75999fcec1736b8963f3bf92satok
2773d8e057e067696d5e75999fcec1736b8963f3bf92satok        public ColorPaletteDrawable(int color, int width, int height, int mergin) {
2774d8e057e067696d5e75999fcec1736b8963f3bf92satok            super(new RectShape());
2775d8e057e067696d5e75999fcec1736b8963f3bf92satok            mRect = new Rect(mergin, mergin, width - mergin, height - mergin);
2776d8e057e067696d5e75999fcec1736b8963f3bf92satok            getPaint().setColor(color);
2777d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2778d8e057e067696d5e75999fcec1736b8963f3bf92satok
2779d8e057e067696d5e75999fcec1736b8963f3bf92satok        @Override
2780d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void draw(Canvas canvas) {
2781d8e057e067696d5e75999fcec1736b8963f3bf92satok            canvas.drawRect(mRect, getPaint());
2782d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2783d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
2784d8e057e067696d5e75999fcec1736b8963f3bf92satok
2785d8e057e067696d5e75999fcec1736b8963f3bf92satok    public class EditModeActions {
2786d8e057e067696d5e75999fcec1736b8963f3bf92satok
2787d8e057e067696d5e75999fcec1736b8963f3bf92satok        private static final String TAG = "EditModeActions";
2788d8e057e067696d5e75999fcec1736b8963f3bf92satok        private static final boolean DBG = true;
2789d8e057e067696d5e75999fcec1736b8963f3bf92satok        private EditStyledText mEST;
2790d8e057e067696d5e75999fcec1736b8963f3bf92satok        private EditorManager mManager;
2791d8e057e067696d5e75999fcec1736b8963f3bf92satok        private StyledTextDialog mDialog;
2792d8e057e067696d5e75999fcec1736b8963f3bf92satok
2793d8e057e067696d5e75999fcec1736b8963f3bf92satok        private int mMode = EditStyledText.MODE_NOTHING;
2794d8e057e067696d5e75999fcec1736b8963f3bf92satok
2795d8e057e067696d5e75999fcec1736b8963f3bf92satok        private HashMap<Integer, EditModeActionBase> mActionMap =
2796d8e057e067696d5e75999fcec1736b8963f3bf92satok                new HashMap<Integer, EditModeActionBase>();
2797d8e057e067696d5e75999fcec1736b8963f3bf92satok
2798d8e057e067696d5e75999fcec1736b8963f3bf92satok        private NothingAction mNothingAction = new NothingAction();
2799d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CopyAction mCopyAction = new CopyAction();
2800d8e057e067696d5e75999fcec1736b8963f3bf92satok        private PasteAction mPasteAction = new PasteAction();
2801d8e057e067696d5e75999fcec1736b8963f3bf92satok        private SelectAction mSelectAction = new SelectAction();
2802d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CutAction mCutAction = new CutAction();
2803d8e057e067696d5e75999fcec1736b8963f3bf92satok        private SelectAllAction mSelectAllAction = new SelectAllAction();
2804d8e057e067696d5e75999fcec1736b8963f3bf92satok        private HorizontalLineAction mHorizontalLineAction = new HorizontalLineAction();
2805d8e057e067696d5e75999fcec1736b8963f3bf92satok        private StopSelectionAction mStopSelectionAction = new StopSelectionAction();
2806d8e057e067696d5e75999fcec1736b8963f3bf92satok        private ClearStylesAction mClearStylesAction = new ClearStylesAction();
2807d8e057e067696d5e75999fcec1736b8963f3bf92satok        private ImageAction mImageAction = new ImageAction();
2808d8e057e067696d5e75999fcec1736b8963f3bf92satok        private BackgroundColorAction mBackgroundColorAction = new BackgroundColorAction();
2809d8e057e067696d5e75999fcec1736b8963f3bf92satok        private PreviewAction mPreviewAction = new PreviewAction();
2810d8e057e067696d5e75999fcec1736b8963f3bf92satok        private CancelAction mCancelEditAction = new CancelAction();
2811d8e057e067696d5e75999fcec1736b8963f3bf92satok        private TextViewAction mTextViewAction = new TextViewAction();
2812d8e057e067696d5e75999fcec1736b8963f3bf92satok        private StartEditAction mStartEditAction = new StartEditAction();
2813d8e057e067696d5e75999fcec1736b8963f3bf92satok        private EndEditAction mEndEditAction = new EndEditAction();
2814d8e057e067696d5e75999fcec1736b8963f3bf92satok        private ResetAction mResetAction = new ResetAction();
2815d8e057e067696d5e75999fcec1736b8963f3bf92satok        private ShowMenuAction mShowMenuAction = new ShowMenuAction();
2816d8e057e067696d5e75999fcec1736b8963f3bf92satok        private AlignAction mAlignAction = new AlignAction();
2817d8e057e067696d5e75999fcec1736b8963f3bf92satok        private TelopAction mTelopAction = new TelopAction();
2818d8e057e067696d5e75999fcec1736b8963f3bf92satok        private SwingAction mSwingAction = new SwingAction();
2819d8e057e067696d5e75999fcec1736b8963f3bf92satok        private MarqueeDialogAction mMarqueeDialogAction = new MarqueeDialogAction();
2820d8e057e067696d5e75999fcec1736b8963f3bf92satok        private ColorAction mColorAction = new ColorAction();
2821d8e057e067696d5e75999fcec1736b8963f3bf92satok        private SizeAction mSizeAction = new SizeAction();
2822d8e057e067696d5e75999fcec1736b8963f3bf92satok
2823d8e057e067696d5e75999fcec1736b8963f3bf92satok        EditModeActions(EditStyledText est, EditorManager manager, StyledTextDialog dialog) {
2824d8e057e067696d5e75999fcec1736b8963f3bf92satok            mEST = est;
2825d8e057e067696d5e75999fcec1736b8963f3bf92satok            mManager = manager;
2826d8e057e067696d5e75999fcec1736b8963f3bf92satok            mDialog = dialog;
2827d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_NOTHING, mNothingAction);
2828d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_COPY, mCopyAction);
2829d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_PASTE, mPasteAction);
2830d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_SELECT, mSelectAction);
2831d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_CUT, mCutAction);
2832d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_SELECTALL, mSelectAllAction);
2833d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_HORIZONTALLINE, mHorizontalLineAction);
2834d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_STOP_SELECT, mStopSelectionAction);
2835d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_CLEARSTYLES, mClearStylesAction);
2836d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_IMAGE, mImageAction);
2837d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_BGCOLOR, mBackgroundColorAction);
2838d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_PREVIEW, mPreviewAction);
2839d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_CANCEL, mCancelEditAction);
2840d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_TEXTVIEWFUNCTION, mTextViewAction);
2841d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_START_EDIT, mStartEditAction);
2842d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_END_EDIT, mEndEditAction);
2843d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_RESET, mResetAction);
2844d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_SHOW_MENU, mShowMenuAction);
2845d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_ALIGN, mAlignAction);
2846d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_TELOP, mTelopAction);
2847d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_SWING, mSwingAction);
2848d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_MARQUEE, mMarqueeDialogAction);
2849d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_COLOR, mColorAction);
2850d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(EditStyledText.MODE_SIZE, mSizeAction);
2851d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2852d8e057e067696d5e75999fcec1736b8963f3bf92satok
2853d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void addAction(int modeId, EditModeActionBase action) {
2854d8e057e067696d5e75999fcec1736b8963f3bf92satok            mActionMap.put(modeId, action);
2855d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2856d8e057e067696d5e75999fcec1736b8963f3bf92satok
2857d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onAction(int newMode, Object[] params) {
2858d8e057e067696d5e75999fcec1736b8963f3bf92satok            getAction(newMode).addParams(params);
2859d8e057e067696d5e75999fcec1736b8963f3bf92satok            mMode = newMode;
2860d8e057e067696d5e75999fcec1736b8963f3bf92satok            doNext(newMode);
2861d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2862d8e057e067696d5e75999fcec1736b8963f3bf92satok
2863d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onAction(int newMode, Object param) {
2864d8e057e067696d5e75999fcec1736b8963f3bf92satok            onAction(newMode, new Object[] { param });
2865d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2866d8e057e067696d5e75999fcec1736b8963f3bf92satok
2867d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onAction(int newMode) {
2868d8e057e067696d5e75999fcec1736b8963f3bf92satok            onAction(newMode, null);
2869d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2870d8e057e067696d5e75999fcec1736b8963f3bf92satok
2871d8e057e067696d5e75999fcec1736b8963f3bf92satok        public void onSelectAction() {
2872d8e057e067696d5e75999fcec1736b8963f3bf92satok            doNext(EditStyledText.MODE_SELECT);
2873d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2874d8e057e067696d5e75999fcec1736b8963f3bf92satok
2875d8e057e067696d5e75999fcec1736b8963f3bf92satok        private EditModeActionBase getAction(int mode) {
2876d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (mActionMap.containsKey(mode)) {
2877d8e057e067696d5e75999fcec1736b8963f3bf92satok                return mActionMap.get(mode);
2878d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2879d8e057e067696d5e75999fcec1736b8963f3bf92satok            return null;
2880d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2881d8e057e067696d5e75999fcec1736b8963f3bf92satok
2882d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean doNext() {
2883d8e057e067696d5e75999fcec1736b8963f3bf92satok            return doNext(mMode);
2884d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2885d8e057e067696d5e75999fcec1736b8963f3bf92satok
2886d8e057e067696d5e75999fcec1736b8963f3bf92satok        public boolean doNext(int mode) {
2887d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (DBG) {
2888d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.d(TAG, "--- do the next action: " + mode + "," + mManager.getSelectState());
2889d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2890d8e057e067696d5e75999fcec1736b8963f3bf92satok            EditModeActionBase action = getAction(mode);
2891d8e057e067696d5e75999fcec1736b8963f3bf92satok            if (action == null) {
2892d8e057e067696d5e75999fcec1736b8963f3bf92satok                Log.e(TAG, "--- invalid action error.");
2893d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2894d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2895d8e057e067696d5e75999fcec1736b8963f3bf92satok            switch (mManager.getSelectState()) {
2896d8e057e067696d5e75999fcec1736b8963f3bf92satok                case EditStyledText.STATE_SELECT_OFF:
2897d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return action.doNotSelected();
2898d8e057e067696d5e75999fcec1736b8963f3bf92satok                case EditStyledText.STATE_SELECT_ON:
2899d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return action.doStartPosIsSelected();
2900d8e057e067696d5e75999fcec1736b8963f3bf92satok                case EditStyledText.STATE_SELECTED:
2901d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return action.doEndPosIsSelected();
2902d8e057e067696d5e75999fcec1736b8963f3bf92satok                case EditStyledText.STATE_SELECT_FIX:
2903d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (mManager.isWaitInput()) {
2904d8e057e067696d5e75999fcec1736b8963f3bf92satok                        return action.doSelectionIsFixedAndWaitingInput();
2905d8e057e067696d5e75999fcec1736b8963f3bf92satok                    } else {
2906d8e057e067696d5e75999fcec1736b8963f3bf92satok                        return action.doSelectionIsFixed();
2907d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
2908d8e057e067696d5e75999fcec1736b8963f3bf92satok                default:
2909d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return false;
2910d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2911d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2912d8e057e067696d5e75999fcec1736b8963f3bf92satok
2913d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class EditModeActionBase {
2914d8e057e067696d5e75999fcec1736b8963f3bf92satok            private Object[] mParams;
2915d8e057e067696d5e75999fcec1736b8963f3bf92satok
2916d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean canOverWrap() {
2917d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2918d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2919d8e057e067696d5e75999fcec1736b8963f3bf92satok
2920d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean canSelect() {
2921d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2922d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2923d8e057e067696d5e75999fcec1736b8963f3bf92satok
2924d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean canWaitInput() {
2925d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2926d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2927d8e057e067696d5e75999fcec1736b8963f3bf92satok
2928d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean needSelection() {
2929d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2930d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2931d8e057e067696d5e75999fcec1736b8963f3bf92satok
2932d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean isLine() {
2933d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2934d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2935d8e057e067696d5e75999fcec1736b8963f3bf92satok
2936d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
2937d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2938d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2939d8e057e067696d5e75999fcec1736b8963f3bf92satok
2940d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doStartPosIsSelected() {
2941d8e057e067696d5e75999fcec1736b8963f3bf92satok                return doNotSelected();
2942d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2943d8e057e067696d5e75999fcec1736b8963f3bf92satok
2944d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doEndPosIsSelected() {
2945d8e057e067696d5e75999fcec1736b8963f3bf92satok                return doStartPosIsSelected();
2946d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2947d8e057e067696d5e75999fcec1736b8963f3bf92satok
2948d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doSelectionIsFixed() {
2949d8e057e067696d5e75999fcec1736b8963f3bf92satok                return doEndPosIsSelected();
2950d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2951d8e057e067696d5e75999fcec1736b8963f3bf92satok
2952d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doSelectionIsFixedAndWaitingInput() {
2953d8e057e067696d5e75999fcec1736b8963f3bf92satok                return doEndPosIsSelected();
2954d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2955d8e057e067696d5e75999fcec1736b8963f3bf92satok
2956d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean fixSelection() {
2957d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.finishComposingText();
2958d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.setSelectState(EditStyledText.STATE_SELECT_FIX);
2959d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
2960d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2961d8e057e067696d5e75999fcec1736b8963f3bf92satok
2962d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected void addParams(Object[] o) {
2963d8e057e067696d5e75999fcec1736b8963f3bf92satok                mParams = o;
2964d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2965d8e057e067696d5e75999fcec1736b8963f3bf92satok
2966d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected Object getParam(int num) {
2967d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (mParams == null || num > mParams.length) {
2968d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (DBG) {
2969d8e057e067696d5e75999fcec1736b8963f3bf92satok                        Log.d(TAG, "--- Number of the parameter is out of bound.");
2970d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
2971d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return null;
2972d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else {
2973d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return mParams[num];
2974d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2975d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2976d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2977d8e057e067696d5e75999fcec1736b8963f3bf92satok
2978d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class NothingAction extends EditModeActionBase {
2979d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
2980d8e057e067696d5e75999fcec1736b8963f3bf92satok
2981d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class TextViewActionBase extends EditModeActionBase {
2982d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
2983d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
2984d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (mManager.getEditMode() == EditStyledText.MODE_NOTHING
2985d8e057e067696d5e75999fcec1736b8963f3bf92satok                        || mManager.getEditMode() == EditStyledText.MODE_SELECT) {
2986d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.setEditMode(mMode);
2987d8e057e067696d5e75999fcec1736b8963f3bf92satok                    onSelectAction();
2988d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
2989d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
2990d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
2991d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
2992d8e057e067696d5e75999fcec1736b8963f3bf92satok
2993d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
2994d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doEndPosIsSelected() {
2995d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (mManager.getEditMode() == EditStyledText.MODE_NOTHING
2996d8e057e067696d5e75999fcec1736b8963f3bf92satok                        || mManager.getEditMode() == EditStyledText.MODE_SELECT) {
2997d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.setEditMode(mMode);
2998d8e057e067696d5e75999fcec1736b8963f3bf92satok                    fixSelection();
2999d8e057e067696d5e75999fcec1736b8963f3bf92satok                    doNext();
3000d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3001d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else if (mManager.getEditMode() != mMode) {
3002d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.resetEdit();
3003d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.setEditMode(mMode);
3004d8e057e067696d5e75999fcec1736b8963f3bf92satok                    doNext();
3005d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3006d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3007d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
3008d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3009d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3010d8e057e067696d5e75999fcec1736b8963f3bf92satok
3011d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class TextViewAction extends TextViewActionBase {
3012d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3013d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doEndPosIsSelected() {
3014d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (super.doEndPosIsSelected()) {
3015d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3016d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3017d8e057e067696d5e75999fcec1736b8963f3bf92satok                Object param = getParam(0);
3018d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (param != null && param instanceof Integer) {
3019d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mEST.onTextContextMenuItem((Integer) param);
3020d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3021d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.resetEdit();
3022d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3023d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3024d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3025d8e057e067696d5e75999fcec1736b8963f3bf92satok
3026d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class CopyAction extends TextViewActionBase {
3027d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3028d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doEndPosIsSelected() {
3029d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (super.doEndPosIsSelected()) {
3030d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3031d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3032d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.copyToClipBoard();
3033d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.resetEdit();
3034d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3035d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3036d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3037d8e057e067696d5e75999fcec1736b8963f3bf92satok
3038d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class CutAction extends TextViewActionBase {
3039d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3040d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doEndPosIsSelected() {
3041d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (super.doEndPosIsSelected()) {
3042d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3043d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3044d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.cutToClipBoard();
3045d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.resetEdit();
3046d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3047d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3048d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3049d8e057e067696d5e75999fcec1736b8963f3bf92satok
3050d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class SelectAction extends EditModeActionBase {
3051d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3052d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3053d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (mManager.isTextSelected()) {
3054d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.e(TAG, "Selection is off, but selected");
3055d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3056d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.setSelectStartPos();
3057d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.sendHintMessage(EditStyledText.HINT_MSG_SELECT_END);
3058d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3059d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3060d8e057e067696d5e75999fcec1736b8963f3bf92satok
3061d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3062d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doStartPosIsSelected() {
3063d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (mManager.isTextSelected()) {
3064d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.e(TAG, "Selection now start, but selected");
3065d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3066d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.setSelectEndPos();
3067d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.sendHintMessage(EditStyledText.HINT_MSG_PUSH_COMPETE);
3068d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (mManager.getEditMode() != EditStyledText.MODE_SELECT) {
3069d8e057e067696d5e75999fcec1736b8963f3bf92satok                    doNext(mManager.getEditMode()); // doNextHandle needs edit mode in editor.
3070d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3071d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3072d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3073d8e057e067696d5e75999fcec1736b8963f3bf92satok
3074d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3075d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doSelectionIsFixed() {
3076d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
3077d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3078d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3079d8e057e067696d5e75999fcec1736b8963f3bf92satok
3080d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class PasteAction extends EditModeActionBase {
3081d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3082d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3083d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.pasteFromClipboard();
3084d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.resetEdit();
3085d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3086d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3087d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3088d8e057e067696d5e75999fcec1736b8963f3bf92satok
3089d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class SelectAllAction extends EditModeActionBase {
3090d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3091d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3092d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.selectAll();
3093d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3094d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3095d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3096d8e057e067696d5e75999fcec1736b8963f3bf92satok
3097d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class HorizontalLineAction extends EditModeActionBase {
3098d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3099d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3100d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.insertHorizontalLine();
3101d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3102d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3103d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3104d8e057e067696d5e75999fcec1736b8963f3bf92satok
3105d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class ClearStylesAction extends EditModeActionBase {
3106d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3107d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3108d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.clearStyles();
3109d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3110d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3111d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3112d8e057e067696d5e75999fcec1736b8963f3bf92satok
3113d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class StopSelectionAction extends EditModeActionBase {
3114d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3115d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3116d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.fixSelectionAndDoNextAction();
3117d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3118d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3119d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3120d8e057e067696d5e75999fcec1736b8963f3bf92satok
3121d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class CancelAction extends EditModeActionBase {
3122d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3123d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3124d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.cancelViewManagers();
3125d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3126d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3127d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3128d8e057e067696d5e75999fcec1736b8963f3bf92satok
3129d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class ImageAction extends EditModeActionBase {
3130d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3131d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3132d8e057e067696d5e75999fcec1736b8963f3bf92satok                Object param = getParam(0);
3133d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (param != null) {
3134d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (param instanceof Uri) {
3135d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mManager.insertImageFromUri((Uri) param);
3136d8e057e067696d5e75999fcec1736b8963f3bf92satok                    } else if (param instanceof Integer) {
3137d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mManager.insertImageFromResId((Integer) param);
3138d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
3139d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else {
3140d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mEST.showInsertImageSelectAlertDialog();
3141d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3142d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3143d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3144d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3145d8e057e067696d5e75999fcec1736b8963f3bf92satok
3146d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class BackgroundColorAction extends EditModeActionBase {
3147d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3148d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3149d8e057e067696d5e75999fcec1736b8963f3bf92satok                mDialog.onShowBackgroundColorAlertDialog();
3150d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3151d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3152d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3153d8e057e067696d5e75999fcec1736b8963f3bf92satok
3154d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class PreviewAction extends EditModeActionBase {
3155d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3156d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3157d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.showPreview();
3158d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3159d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3160d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3161d8e057e067696d5e75999fcec1736b8963f3bf92satok
3162d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class StartEditAction extends EditModeActionBase {
3163d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3164d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3165d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.startEdit();
3166d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3167d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3168d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3169d8e057e067696d5e75999fcec1736b8963f3bf92satok
3170d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class EndEditAction extends EditModeActionBase {
3171d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3172d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3173d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.endEdit();
3174d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3175d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3176d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3177d8e057e067696d5e75999fcec1736b8963f3bf92satok
3178d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class ResetAction extends EditModeActionBase {
3179d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3180d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3181d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.resetEdit();
3182d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3183d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3184d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3185d8e057e067696d5e75999fcec1736b8963f3bf92satok
3186d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class ShowMenuAction extends EditModeActionBase {
3187d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3188d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3189d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.showMenuAlertDialog();
3190d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3191d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3192d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3193d8e057e067696d5e75999fcec1736b8963f3bf92satok
3194d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class SetSpanActionBase extends EditModeActionBase {
3195d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3196d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doNotSelected() {
3197d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (mManager.getEditMode() == EditStyledText.MODE_NOTHING
3198d8e057e067696d5e75999fcec1736b8963f3bf92satok                        || mManager.getEditMode() == EditStyledText.MODE_SELECT) {
3199d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.setEditMode(mMode);
3200d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.setInternalSelection(mEST.getSelectionStart(),
3201d8e057e067696d5e75999fcec1736b8963f3bf92satok                            mEST.getSelectionEnd());
3202d8e057e067696d5e75999fcec1736b8963f3bf92satok                    fixSelection();
3203d8e057e067696d5e75999fcec1736b8963f3bf92satok                    doNext();
3204d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3205d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else if (mManager.getEditMode() != mMode) {
3206d8e057e067696d5e75999fcec1736b8963f3bf92satok                    Log.d(TAG, "--- setspanactionbase" + mManager.getEditMode() + "," + mMode);
3207d8e057e067696d5e75999fcec1736b8963f3bf92satok                    if (!mManager.isWaitInput()) {
3208d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mManager.resetEdit();
3209d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mManager.setEditMode(mMode);
3210d8e057e067696d5e75999fcec1736b8963f3bf92satok                    } else {
3211d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mManager.setEditMode(EditStyledText.MODE_NOTHING);
3212d8e057e067696d5e75999fcec1736b8963f3bf92satok                        mManager.setSelectState(EditStyledText.STATE_SELECT_OFF);
3213d8e057e067696d5e75999fcec1736b8963f3bf92satok                    }
3214d8e057e067696d5e75999fcec1736b8963f3bf92satok                    doNext();
3215d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3216d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3217d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
3218d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3219d8e057e067696d5e75999fcec1736b8963f3bf92satok
3220d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3221d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doStartPosIsSelected() {
3222d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (mManager.getEditMode() == EditStyledText.MODE_NOTHING
3223d8e057e067696d5e75999fcec1736b8963f3bf92satok                        || mManager.getEditMode() == EditStyledText.MODE_SELECT) {
3224d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.setEditMode(mMode);
3225d8e057e067696d5e75999fcec1736b8963f3bf92satok                    onSelectAction();
3226d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3227d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3228d8e057e067696d5e75999fcec1736b8963f3bf92satok                return doNotSelected();
3229d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3230d8e057e067696d5e75999fcec1736b8963f3bf92satok
3231d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3232d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doEndPosIsSelected() {
3233d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (mManager.getEditMode() == EditStyledText.MODE_NOTHING
3234d8e057e067696d5e75999fcec1736b8963f3bf92satok                        || mManager.getEditMode() == EditStyledText.MODE_SELECT) {
3235d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.setEditMode(mMode);
3236d8e057e067696d5e75999fcec1736b8963f3bf92satok                    fixSelection();
3237d8e057e067696d5e75999fcec1736b8963f3bf92satok                    doNext();
3238d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3239d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3240d8e057e067696d5e75999fcec1736b8963f3bf92satok                return doStartPosIsSelected();
3241d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3242d8e057e067696d5e75999fcec1736b8963f3bf92satok
3243d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3244d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doSelectionIsFixed() {
3245d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (doEndPosIsSelected()) {
3246d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3247d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3248d8e057e067696d5e75999fcec1736b8963f3bf92satok                mEST.sendHintMessage(EditStyledText.HINT_MSG_NULL);
3249d8e057e067696d5e75999fcec1736b8963f3bf92satok
3250d8e057e067696d5e75999fcec1736b8963f3bf92satok                return false;
3251d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3252d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3253d8e057e067696d5e75999fcec1736b8963f3bf92satok
3254d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class AlignAction extends SetSpanActionBase {
3255d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3256d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doSelectionIsFixed() {
3257d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (super.doSelectionIsFixed()) {
3258d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3259d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3260d8e057e067696d5e75999fcec1736b8963f3bf92satok                mDialog.onShowAlignAlertDialog();
3261d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3262d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3263d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3264d8e057e067696d5e75999fcec1736b8963f3bf92satok
3265d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class TelopAction extends SetSpanActionBase {
3266d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3267d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doSelectionIsFixed() {
3268d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (super.doSelectionIsFixed()) {
3269d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3270d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3271d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.setTelop();
3272d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3273d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3274d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3275d8e057e067696d5e75999fcec1736b8963f3bf92satok
3276d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class SwingAction extends SetSpanActionBase {
3277d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3278d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doSelectionIsFixed() {
3279d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (super.doSelectionIsFixed()) {
3280d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3281d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3282d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.setSwing();
3283d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3284d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3285d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3286d8e057e067696d5e75999fcec1736b8963f3bf92satok
3287d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class MarqueeDialogAction extends SetSpanActionBase {
3288d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3289d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doSelectionIsFixed() {
3290d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (super.doSelectionIsFixed()) {
3291d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3292d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3293d8e057e067696d5e75999fcec1736b8963f3bf92satok                mDialog.onShowMarqueeAlertDialog();
3294d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3295d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3296d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3297d8e057e067696d5e75999fcec1736b8963f3bf92satok
3298d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class ColorAction extends SetSpanActionBase {
3299d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3300d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doSelectionIsFixed() {
3301d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (super.doSelectionIsFixed()) {
3302d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3303d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3304d8e057e067696d5e75999fcec1736b8963f3bf92satok                mDialog.onShowForegroundColorAlertDialog();
3305d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3306d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3307d8e057e067696d5e75999fcec1736b8963f3bf92satok
3308d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3309d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doSelectionIsFixedAndWaitingInput() {
3310d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (super.doSelectionIsFixedAndWaitingInput()) {
3311d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3312d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3313d8e057e067696d5e75999fcec1736b8963f3bf92satok                int size = mManager.getSizeWaitInput();
3314d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.setItemColor(mManager.getColorWaitInput(), false);
3315d8e057e067696d5e75999fcec1736b8963f3bf92satok                // selection was resumed
3316d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (!mManager.isWaitInput()) {
3317d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.setItemSize(size, false);
3318d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.resetEdit();
3319d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else {
3320d8e057e067696d5e75999fcec1736b8963f3bf92satok                    fixSelection();
3321d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mDialog.onShowForegroundColorAlertDialog();
3322d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3323d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3324d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3325d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3326d8e057e067696d5e75999fcec1736b8963f3bf92satok
3327d8e057e067696d5e75999fcec1736b8963f3bf92satok        public class SizeAction extends SetSpanActionBase {
3328d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3329d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doSelectionIsFixed() {
3330d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (super.doSelectionIsFixed()) {
3331d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3332d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3333d8e057e067696d5e75999fcec1736b8963f3bf92satok                mDialog.onShowSizeAlertDialog();
3334d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3335d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3336d8e057e067696d5e75999fcec1736b8963f3bf92satok
3337d8e057e067696d5e75999fcec1736b8963f3bf92satok            @Override
3338d8e057e067696d5e75999fcec1736b8963f3bf92satok            protected boolean doSelectionIsFixedAndWaitingInput() {
3339d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (super.doSelectionIsFixedAndWaitingInput()) {
3340d8e057e067696d5e75999fcec1736b8963f3bf92satok                    return true;
3341d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3342d8e057e067696d5e75999fcec1736b8963f3bf92satok                int color = mManager.getColorWaitInput();
3343d8e057e067696d5e75999fcec1736b8963f3bf92satok                mManager.setItemSize(mManager.getSizeWaitInput(), false);
3344d8e057e067696d5e75999fcec1736b8963f3bf92satok                if (!mManager.isWaitInput()) {
3345d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.setItemColor(color, false);
3346d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mManager.resetEdit();
3347d8e057e067696d5e75999fcec1736b8963f3bf92satok                } else {
3348d8e057e067696d5e75999fcec1736b8963f3bf92satok                    fixSelection();
3349d8e057e067696d5e75999fcec1736b8963f3bf92satok                    mDialog.onShowSizeAlertDialog();
3350d8e057e067696d5e75999fcec1736b8963f3bf92satok                }
3351d8e057e067696d5e75999fcec1736b8963f3bf92satok                return true;
3352d8e057e067696d5e75999fcec1736b8963f3bf92satok            }
3353d8e057e067696d5e75999fcec1736b8963f3bf92satok        }
3354d8e057e067696d5e75999fcec1736b8963f3bf92satok    }
3355d8e057e067696d5e75999fcec1736b8963f3bf92satok}
3356