1/*
2 * Copyright (C) 2011 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 */
16package com.android.browser;
17
18import android.app.SearchManager;
19import android.content.Context;
20import android.content.Intent;
21import android.graphics.Bitmap;
22import android.graphics.drawable.Drawable;
23import android.os.Bundle;
24import android.text.Editable;
25import android.text.TextWatcher;
26import android.util.AttributeSet;
27import android.view.KeyEvent;
28import android.view.View;
29import android.view.View.OnClickListener;
30import android.view.View.OnFocusChangeListener;
31import android.webkit.WebView;
32import android.widget.ImageView;
33import android.widget.LinearLayout;
34
35import com.android.browser.UrlInputView.UrlInputListener;
36
37public class NavigationBarBase extends LinearLayout implements
38        OnClickListener, UrlInputListener, OnFocusChangeListener,
39        TextWatcher {
40
41    protected BaseUi mBaseUi;
42    protected TitleBar mTitleBar;
43    protected UiController mUiController;
44    protected UrlInputView mUrlInput;
45
46    private ImageView mFavicon;
47    private ImageView mLockIcon;
48
49    public NavigationBarBase(Context context) {
50        super(context);
51    }
52
53    public NavigationBarBase(Context context, AttributeSet attrs) {
54        super(context, attrs);
55    }
56
57    public NavigationBarBase(Context context, AttributeSet attrs, int defStyle) {
58        super(context, attrs, defStyle);
59    }
60
61    @Override
62    protected void onFinishInflate() {
63        super.onFinishInflate();
64        mLockIcon = (ImageView) findViewById(R.id.lock);
65        mFavicon = (ImageView) findViewById(R.id.favicon);
66        mUrlInput = (UrlInputView) findViewById(R.id.url);
67        mUrlInput.setUrlInputListener(this);
68        mUrlInput.setOnFocusChangeListener(this);
69        mUrlInput.setSelectAllOnFocus(true);
70        mUrlInput.addTextChangedListener(this);
71    }
72
73    public void setTitleBar(TitleBar titleBar) {
74        mTitleBar = titleBar;
75        mBaseUi = mTitleBar.getUi();
76        mUiController = mTitleBar.getUiController();
77        mUrlInput.setController(mUiController);
78    }
79
80    public void setLock(Drawable d) {
81        if (mLockIcon == null) return;
82        if (d == null) {
83            mLockIcon.setVisibility(View.GONE);
84        } else {
85            mLockIcon.setImageDrawable(d);
86            mLockIcon.setVisibility(View.VISIBLE);
87        }
88    }
89
90    public void setFavicon(Bitmap icon) {
91        if (mFavicon == null) return;
92        mFavicon.setImageDrawable(mBaseUi.getFaviconDrawable(icon));
93    }
94
95    @Override
96    public void onClick(View v) {
97    }
98
99    @Override
100    public void onFocusChange(View view, boolean hasFocus) {
101        // if losing focus and not in touch mode, leave as is
102        if (hasFocus || view.isInTouchMode() || mUrlInput.needsUpdate()) {
103            setFocusState(hasFocus);
104        }
105        if (hasFocus) {
106            mBaseUi.showTitleBar();
107        } else if (!mUrlInput.needsUpdate()) {
108            mUrlInput.dismissDropDown();
109            mUrlInput.hideIME();
110            if (mUrlInput.getText().length() == 0) {
111                Tab currentTab = mUiController.getTabControl().getCurrentTab();
112                if (currentTab != null) {
113                    setDisplayTitle(currentTab.getUrl());
114                }
115            }
116            mBaseUi.suggestHideTitleBar();
117        }
118        mUrlInput.clearNeedsUpdate();
119    }
120
121    protected void setFocusState(boolean focus) {
122    }
123
124    public boolean isEditingUrl() {
125        return mUrlInput.hasFocus();
126    }
127
128    void stopEditingUrl() {
129        WebView currentTopWebView = mUiController.getCurrentTopWebView();
130        if (currentTopWebView != null) {
131            currentTopWebView.requestFocus();
132        }
133    }
134
135    void setDisplayTitle(String title) {
136        if (!isEditingUrl()) {
137            if (!title.equals(mUrlInput.getText().toString())) {
138                mUrlInput.setText(title, false);
139            }
140        }
141    }
142
143    void setIncognitoMode(boolean incognito) {
144        mUrlInput.setIncognitoMode(incognito);
145    }
146
147    void clearCompletions() {
148        mUrlInput.dismissDropDown();
149    }
150
151 // UrlInputListener implementation
152
153    /**
154     * callback from suggestion dropdown
155     * user selected a suggestion
156     */
157    @Override
158    public void onAction(String text, String extra, String source) {
159        stopEditingUrl();
160        if (UrlInputView.TYPED.equals(source)) {
161            String url = UrlUtils.smartUrlFilter(text, false);
162            Tab t = mBaseUi.getActiveTab();
163            // Only shortcut javascript URIs for now, as there is special
164            // logic in UrlHandler for other schemas
165            if (url != null && t != null && url.startsWith("javascript:")) {
166                mUiController.loadUrl(t, url);
167                setDisplayTitle(text);
168                return;
169            }
170        }
171        Intent i = new Intent();
172        String action = Intent.ACTION_SEARCH;
173        i.setAction(action);
174        i.putExtra(SearchManager.QUERY, text);
175        if (extra != null) {
176            i.putExtra(SearchManager.EXTRA_DATA_KEY, extra);
177        }
178        if (source != null) {
179            Bundle appData = new Bundle();
180            appData.putString(com.android.common.Search.SOURCE, source);
181            i.putExtra(SearchManager.APP_DATA, appData);
182        }
183        mUiController.handleNewIntent(i);
184        setDisplayTitle(text);
185    }
186
187    @Override
188    public void onDismiss() {
189        final Tab currentTab = mBaseUi.getActiveTab();
190        mBaseUi.hideTitleBar();
191        post(new Runnable() {
192            public void run() {
193                clearFocus();
194                if (currentTab != null) {
195                    setDisplayTitle(currentTab.getUrl());
196                }
197            }
198        });
199    }
200
201    /**
202     * callback from the suggestion dropdown
203     * copy text to input field and stay in edit mode
204     */
205    @Override
206    public void onCopySuggestion(String text) {
207        mUrlInput.setText(text, true);
208        if (text != null) {
209            mUrlInput.setSelection(text.length());
210        }
211    }
212
213    public void setCurrentUrlIsBookmark(boolean isBookmark) {
214    }
215
216    @Override
217    public boolean dispatchKeyEventPreIme(KeyEvent evt) {
218        if (evt.getKeyCode() == KeyEvent.KEYCODE_BACK) {
219            // catch back key in order to do slightly more cleanup than usual
220            stopEditingUrl();
221            return true;
222        }
223        return super.dispatchKeyEventPreIme(evt);
224    }
225
226    /**
227     * called from the Ui when the user wants to edit
228     * @param clearInput clear the input field
229     */
230    void startEditingUrl(boolean clearInput, boolean forceIME) {
231        // editing takes preference of progress
232        setVisibility(View.VISIBLE);
233        if (mTitleBar.useQuickControls()) {
234            mTitleBar.getProgressView().setVisibility(View.GONE);
235        }
236        if (!mUrlInput.hasFocus()) {
237            mUrlInput.requestFocus();
238        }
239        if (clearInput) {
240            mUrlInput.setText("");
241        }
242        if (forceIME) {
243            mUrlInput.showIME();
244        }
245    }
246
247    public void onProgressStarted() {
248    }
249
250    public void onProgressStopped() {
251    }
252
253    public boolean isMenuShowing() {
254        return false;
255    }
256
257    public void onTabDataChanged(Tab tab) {
258    }
259
260    public void onVoiceResult(String s) {
261        startEditingUrl(true, true);
262        onCopySuggestion(s);
263    }
264
265    @Override
266    public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
267
268    @Override
269    public void onTextChanged(CharSequence s, int start, int before, int count) { }
270
271    @Override
272    public void afterTextChanged(Editable s) { }
273
274}
275