blob: 96a59801926ede0350778b0c80afb8283f905ab9 [file] [log] [blame]
Michael Kolbfe251992010-07-08 15:41:55 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.browser;
18
19import android.app.SearchManager;
20import android.content.ContentResolver;
21import android.content.Context;
22import android.database.Cursor;
Michael Kolb513286f2010-09-09 12:55:12 -070023import android.graphics.Color;
Michael Kolbfe251992010-07-08 15:41:55 -070024import android.graphics.drawable.Drawable;
Michael Kolb513286f2010-09-09 12:55:12 -070025import android.text.Editable;
26import android.text.SpannableStringBuilder;
27import android.text.TextWatcher;
28import android.text.style.BackgroundColorSpan;
Michael Kolbfe251992010-07-08 15:41:55 -070029import android.util.AttributeSet;
Michael Kolbc7485ae2010-09-03 10:10:58 -070030import android.util.Log;
Michael Kolb513286f2010-09-09 12:55:12 -070031import android.view.ActionMode;
Michael Kolbfe251992010-07-08 15:41:55 -070032import android.view.KeyEvent;
33import android.view.LayoutInflater;
34import android.view.View;
Michael Kolb513286f2010-09-09 12:55:12 -070035import android.view.View.OnClickListener;
Michael Kolba2b2ba82010-08-04 17:54:03 -070036import android.view.View.OnFocusChangeListener;
Michael Kolbfe251992010-07-08 15:41:55 -070037import android.view.ViewGroup;
38import android.view.inputmethod.InputMethodManager;
Michael Kolbfe251992010-07-08 15:41:55 -070039import android.widget.AutoCompleteTextView;
40import android.widget.CursorAdapter;
41import android.widget.Filterable;
Michael Kolb513286f2010-09-09 12:55:12 -070042import android.widget.ImageButton;
Michael Kolbfe251992010-07-08 15:41:55 -070043import android.widget.ImageView;
44import android.widget.TextView;
Michael Kolbed217742010-08-10 17:52:34 -070045import android.widget.TextView.OnEditorActionListener;
Michael Kolbfe251992010-07-08 15:41:55 -070046
47/**
48 * url/search input view
49 * handling suggestions
50 */
Michael Kolba2b2ba82010-08-04 17:54:03 -070051public class UrlInputView extends AutoCompleteTextView
Michael Kolb513286f2010-09-09 12:55:12 -070052 implements OnFocusChangeListener, OnClickListener, OnEditorActionListener {
Michael Kolbfe251992010-07-08 15:41:55 -070053
54 private UrlInputListener mListener;
55 private InputMethodManager mInputManager;
56 private SuggestionsAdapter mAdapter;
Michael Kolbc7485ae2010-09-03 10:10:58 -070057
58 private OnFocusChangeListener mWrappedFocusListener;
Michael Kolbfe251992010-07-08 15:41:55 -070059
60 public UrlInputView(Context context, AttributeSet attrs, int defStyle) {
61 super(context, attrs, defStyle);
62 init(context);
63 }
64
65 public UrlInputView(Context context, AttributeSet attrs) {
66 super(context, attrs);
67 init(context);
68 }
69
70 public UrlInputView(Context context) {
71 super(context);
72 init(context);
73 }
74
75 private void init(Context ctx) {
Michael Kolbfe251992010-07-08 15:41:55 -070076 mInputManager = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
Michael Kolbed217742010-08-10 17:52:34 -070077 setOnEditorActionListener(this);
Michael Kolbc7485ae2010-09-03 10:10:58 -070078 super.setOnFocusChangeListener(this);
Michael Kolbfe251992010-07-08 15:41:55 -070079 final ContentResolver cr = mContext.getContentResolver();
80 mAdapter = new SuggestionsAdapter(mContext,
81 BrowserProvider.getBookmarksSuggestions(cr, null));
82 setAdapter(mAdapter);
Michael Kolbc7485ae2010-09-03 10:10:58 -070083 setSelectAllOnFocus(false);
Michael Kolb513286f2010-09-09 12:55:12 -070084 }
85
86 @Override
87 public ActionMode startActionMode(ActionMode.Callback callback) {
88 // suppress selection action mode
89 return null;
Michael Kolbc7485ae2010-09-03 10:10:58 -070090 }
91
92 @Override
93 public void setOnFocusChangeListener(OnFocusChangeListener focusListener) {
94 mWrappedFocusListener = focusListener;
Michael Kolbfe251992010-07-08 15:41:55 -070095 }
96
Michael Kolba2b2ba82010-08-04 17:54:03 -070097 @Override
Michael Kolbed217742010-08-10 17:52:34 -070098 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
99 finishInput(getText().toString());
100 return true;
101 }
Michael Kolbc7485ae2010-09-03 10:10:58 -0700102
103 @Override
Michael Kolba2b2ba82010-08-04 17:54:03 -0700104 public void onFocusChange(View v, boolean hasFocus) {
Michael Kolba2b2ba82010-08-04 17:54:03 -0700105 if (hasFocus) {
106 forceIme();
107 } else {
108 finishInput(null);
109 }
Michael Kolbc7485ae2010-09-03 10:10:58 -0700110 if (mWrappedFocusListener != null) {
111 mWrappedFocusListener.onFocusChange(v, hasFocus);
112 }
Michael Kolba2b2ba82010-08-04 17:54:03 -0700113 }
114
115 @Override
Michael Kolb513286f2010-09-09 12:55:12 -0700116 public void onClick(View view) {
117 if (view instanceof ImageButton) {
118 // user pressed edit search button
119 String text = mAdapter.getViewString((View)view.getParent());
120 mListener.onEdit(text);
121 } else {
122 // user selected dropdown item
123 String url = mAdapter.getViewString(view);
124 finishInput(url);
125 }
Michael Kolba2b2ba82010-08-04 17:54:03 -0700126 }
127
Michael Kolbfe251992010-07-08 15:41:55 -0700128 public void setUrlInputListener(UrlInputListener listener) {
129 mListener = listener;
130 }
131
132 public void forceIme() {
133 mInputManager.showSoftInput(this, 0);
134 }
135
136 private void finishInput(String url) {
137 this.dismissDropDown();
Michael Kolbc7485ae2010-09-03 10:10:58 -0700138 this.setSelection(0,0);
Michael Kolbfe251992010-07-08 15:41:55 -0700139 mInputManager.hideSoftInputFromWindow(getWindowToken(), 0);
140 if (url == null) {
141 mListener.onDismiss();
142 } else {
143 mListener.onAction(url);
144 }
Michael Kolbfe251992010-07-08 15:41:55 -0700145 }
146
147 @Override
148 public boolean onKeyPreIme(int keyCode, KeyEvent evt) {
149 if (keyCode == KeyEvent.KEYCODE_BACK) {
150 // catch back key in order to do slightly more cleanup than usual
151 finishInput(null);
152 return true;
153 }
154 return super.onKeyPreIme(keyCode, evt);
155 }
156
157 interface UrlInputListener {
Michael Kolbfe251992010-07-08 15:41:55 -0700158 public void onDismiss();
Michael Kolbfe251992010-07-08 15:41:55 -0700159 public void onAction(String text);
Michael Kolb513286f2010-09-09 12:55:12 -0700160 public void onEdit(String text);
Michael Kolbfe251992010-07-08 15:41:55 -0700161 }
162
163 /**
164 * adapter used by suggestion dropdown
165 */
166 class SuggestionsAdapter extends CursorAdapter implements Filterable {
167
168 private Cursor mLastCursor;
169 private ContentResolver mContent;
170 private int mIndexText1;
171 private int mIndexText2;
172 private int mIndexIcon;
173
174 public SuggestionsAdapter(Context context, Cursor c) {
175 super(context, c);
176 mContent = context.getContentResolver();
177 mIndexText1 = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1);
178 mIndexText2 = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2_URL);
179 mIndexIcon = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1);
180 }
181
182 public String getViewString(View view) {
183 TextView tv2 = (TextView) view.findViewById(android.R.id.text2);
184 if (tv2.getText().length() > 0) {
185 return tv2.getText().toString();
186 } else {
187 TextView tv1 = (TextView) view.findViewById(android.R.id.text1);
188 return tv1.getText().toString();
189 }
190 }
191
192 @Override
193 public View newView(Context context, Cursor cursor, ViewGroup parent) {
194 final LayoutInflater inflater = LayoutInflater.from(context);
195 final View view = inflater.inflate(
Michael Kolb513286f2010-09-09 12:55:12 -0700196 R.layout.url_dropdown_item, parent, false);
Michael Kolbfe251992010-07-08 15:41:55 -0700197 bindView(view, context, cursor);
198 return view;
199 }
200
201 @Override
202 public void bindView(View view, Context context, Cursor cursor) {
203 TextView tv1 = (TextView) view.findViewById(android.R.id.text1);
204 TextView tv2 = (TextView) view.findViewById(android.R.id.text2);
205 ImageView ic1 = (ImageView) view.findViewById(R.id.icon1);
Michael Kolb513286f2010-09-09 12:55:12 -0700206 View ic2 = view.findViewById(R.id.icon2);
Michael Kolbfe251992010-07-08 15:41:55 -0700207 tv1.setText(cursor.getString(mIndexText1));
208 String url = cursor.getString(mIndexText2);
209 tv2.setText((url != null) ? url : "");
Michael Kolb513286f2010-09-09 12:55:12 -0700210 ic2.setOnClickListener(UrlInputView.this);
Michael Kolbfe251992010-07-08 15:41:55 -0700211 // assume an id
212 try {
213 int id = Integer.parseInt(cursor.getString(mIndexIcon));
214 Drawable d = context.getResources().getDrawable(id);
215 ic1.setImageDrawable(d);
Michael Kolb513286f2010-09-09 12:55:12 -0700216 ic2.setVisibility((id == R.drawable.ic_search_category_suggest)? View.VISIBLE : View.GONE);
Michael Kolbfe251992010-07-08 15:41:55 -0700217 } catch (NumberFormatException nfx) {
218 }
Michael Kolb513286f2010-09-09 12:55:12 -0700219 view.setOnClickListener(UrlInputView.this);
Michael Kolbfe251992010-07-08 15:41:55 -0700220 }
221
222 @Override
223 public String convertToString(Cursor cursor) {
224 return cursor.getString(mIndexText1);
225 }
226
227 @Override
228 public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
229 if (getFilterQueryProvider() != null) {
230 return getFilterQueryProvider().runQuery(constraint);
231 }
232 mLastCursor = BrowserProvider.getBookmarksSuggestions(mContent,
233 (constraint != null) ? constraint.toString() : null);
234 return mLastCursor;
235 }
236
237 }
238
239}