| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.android.browser; |
| |
| import android.app.SearchManager; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.graphics.Bitmap; |
| import android.graphics.drawable.Drawable; |
| import android.os.Bundle; |
| import android.speech.RecognizerResultsIntent; |
| import android.util.AttributeSet; |
| import android.view.KeyEvent; |
| import android.view.Menu; |
| import android.view.MenuItem; |
| import android.view.View; |
| import android.view.View.OnClickListener; |
| import android.view.View.OnFocusChangeListener; |
| import android.webkit.WebView; |
| import android.widget.ImageView; |
| import android.widget.LinearLayout; |
| import android.widget.PopupMenu; |
| import android.widget.PopupMenu.OnMenuItemClickListener; |
| |
| import com.android.browser.UI.DropdownChangeListener; |
| import com.android.browser.UrlInputView.UrlInputListener; |
| import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher; |
| |
| import java.util.List; |
| |
| public class NavigationBarBase extends LinearLayout implements OnClickListener, |
| OnMenuItemClickListener, UrlInputListener, OnFocusChangeListener, |
| TextChangeWatcher { |
| |
| protected BaseUi mBaseUi; |
| protected TitleBar mTitleBar; |
| protected UiController mUiController; |
| protected UrlInputView mUrlInput; |
| protected boolean mInVoiceMode = false; |
| |
| private ImageView mFavicon; |
| private ImageView mLockIcon; |
| private View mUaSwitcher; |
| |
| public NavigationBarBase(Context context) { |
| super(context); |
| } |
| |
| public NavigationBarBase(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| } |
| |
| public NavigationBarBase(Context context, AttributeSet attrs, int defStyle) { |
| super(context, attrs, defStyle); |
| } |
| |
| @Override |
| protected void onFinishInflate() { |
| super.onFinishInflate(); |
| mLockIcon = (ImageView) findViewById(R.id.lock); |
| mFavicon = (ImageView) findViewById(R.id.favicon); |
| mUrlInput = (UrlInputView) findViewById(R.id.url); |
| mUrlInput.setUrlInputListener(this); |
| mUrlInput.setController(mUiController); |
| mUrlInput.setOnFocusChangeListener(this); |
| mUrlInput.setSelectAllOnFocus(true); |
| mUrlInput.addQueryTextWatcher(this); |
| } |
| |
| public void setTitleBar(TitleBar titleBar) { |
| mTitleBar = titleBar; |
| mBaseUi = mTitleBar.getUi(); |
| mUiController = mTitleBar.getUiController(); |
| } |
| |
| public void setLock(Drawable d) { |
| if (mLockIcon == null) return; |
| if (d == null) { |
| mLockIcon.setVisibility(View.GONE); |
| } else { |
| mLockIcon.setImageDrawable(d); |
| mLockIcon.setVisibility(View.VISIBLE); |
| } |
| } |
| |
| public void setFavicon(Bitmap icon) { |
| if (mFavicon == null) return; |
| mFavicon.setImageDrawable(mBaseUi.getFaviconDrawable(icon)); |
| } |
| |
| public void setUaSwitcher(View v) { |
| if (mUaSwitcher != null) { |
| mUaSwitcher.setOnClickListener(null); |
| } |
| mUaSwitcher = v; |
| mUaSwitcher.setOnClickListener(this); |
| } |
| |
| @Override |
| public void onClick(View v) { |
| if (mUaSwitcher == v) { |
| BrowserSettings settings = BrowserSettings.getInstance(); |
| WebView web = mTitleBar.getCurrentWebView(); |
| if (web == null) return; |
| boolean desktop = settings.hasDesktopUseragent(web); |
| PopupMenu popup = new PopupMenu(mContext, mUaSwitcher); |
| Menu menu = popup.getMenu(); |
| popup.getMenuInflater().inflate(R.menu.ua_switcher, menu); |
| menu.findItem(R.id.ua_mobile_menu_id).setChecked(!desktop); |
| menu.findItem(R.id.ua_desktop_menu_id).setChecked(desktop); |
| popup.setOnMenuItemClickListener(this); |
| popup.show(); |
| } |
| } |
| |
| @Override |
| public boolean onMenuItemClick(MenuItem item) { |
| BrowserSettings settings = BrowserSettings.getInstance(); |
| WebView web = mTitleBar.getCurrentWebView(); |
| if (web == null) return false; |
| boolean desktop = settings.hasDesktopUseragent(web); |
| switch (item.getItemId()) { |
| case R.id.ua_mobile_menu_id: |
| if (desktop) { |
| settings.toggleDesktopUseragent(web); |
| web.loadUrl(web.getOriginalUrl()); |
| } |
| return true; |
| case R.id.ua_desktop_menu_id: |
| if (!desktop) { |
| settings.toggleDesktopUseragent(web); |
| web.loadUrl(web.getOriginalUrl()); |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| public void onFocusChange(View view, boolean hasFocus) { |
| // if losing focus and not in touch mode, leave as is |
| if (hasFocus || view.isInTouchMode() || mUrlInput.needsUpdate()) { |
| setFocusState(hasFocus); |
| } |
| if (hasFocus) { |
| mBaseUi.showTitleBar(); |
| mUrlInput.forceIme(); |
| if (mInVoiceMode) { |
| mUrlInput.forceFilter(); |
| } |
| } else if (!mUrlInput.needsUpdate()) { |
| mUrlInput.dismissDropDown(); |
| mUrlInput.hideIME(); |
| if (mUrlInput.getText().length() == 0) { |
| Tab currentTab = mUiController.getTabControl().getCurrentTab(); |
| if (currentTab != null) { |
| mUrlInput.setText(currentTab.getUrl(), false); |
| } |
| } |
| mBaseUi.suggestHideTitleBar(); |
| } |
| mUrlInput.clearNeedsUpdate(); |
| } |
| |
| protected void setFocusState(boolean focus) { |
| } |
| |
| protected void setSearchMode(boolean voiceSearchEnabled) {} |
| |
| public boolean isEditingUrl() { |
| return mUrlInput.hasFocus(); |
| } |
| |
| void stopEditingUrl() { |
| mUrlInput.clearFocus(); |
| } |
| |
| void setDisplayTitle(String title) { |
| if (!isEditingUrl()) { |
| mUrlInput.setText(title, false); |
| } |
| } |
| |
| // UrlInput text watcher |
| |
| @Override |
| public void onTextChanged(String newText) { |
| if (mUrlInput.hasFocus()) { |
| // clear voice mode when user types |
| setInVoiceMode(false, null); |
| } |
| } |
| |
| // voicesearch |
| |
| public void setInVoiceMode(boolean voicemode, List<String> voiceResults) { |
| mInVoiceMode = voicemode; |
| mUrlInput.setVoiceResults(voiceResults); |
| } |
| |
| void setIncognitoMode(boolean incognito) { |
| mUrlInput.setIncognitoMode(incognito); |
| } |
| |
| void clearCompletions() { |
| mUrlInput.setSuggestedText(null); |
| } |
| |
| // UrlInputListener implementation |
| |
| /** |
| * callback from suggestion dropdown |
| * user selected a suggestion |
| */ |
| @Override |
| public void onAction(String text, String extra, String source) { |
| mUiController.getCurrentTopWebView().requestFocus(); |
| if (UrlInputView.TYPED.equals(source)) { |
| String url = UrlUtils.smartUrlFilter(text, false); |
| Tab t = mBaseUi.getActiveTab(); |
| // Only shortcut javascript URIs for now, as there is special |
| // logic in UrlHandler for other schemas |
| if (url != null && t != null && url.startsWith("javascript:")) { |
| mUiController.loadUrl(t, url); |
| setDisplayTitle(text); |
| return; |
| } |
| } |
| Intent i = new Intent(); |
| String action = null; |
| if (UrlInputView.VOICE.equals(source)) { |
| action = RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS; |
| source = null; |
| } else { |
| action = Intent.ACTION_SEARCH; |
| } |
| i.setAction(action); |
| i.putExtra(SearchManager.QUERY, text); |
| if (extra != null) { |
| i.putExtra(SearchManager.EXTRA_DATA_KEY, extra); |
| } |
| if (source != null) { |
| Bundle appData = new Bundle(); |
| appData.putString(com.android.common.Search.SOURCE, source); |
| i.putExtra(SearchManager.APP_DATA, appData); |
| } |
| mUiController.handleNewIntent(i); |
| setDisplayTitle(text); |
| } |
| |
| @Override |
| public void onDismiss() { |
| final Tab currentTab = mBaseUi.getActiveTab(); |
| mBaseUi.hideTitleBar(); |
| post(new Runnable() { |
| public void run() { |
| clearFocus(); |
| if ((currentTab != null) && !mInVoiceMode) { |
| setDisplayTitle(currentTab.getUrl()); |
| } |
| } |
| }); |
| } |
| |
| /** |
| * callback from the suggestion dropdown |
| * copy text to input field and stay in edit mode |
| */ |
| @Override |
| public void onCopySuggestion(String text) { |
| mUrlInput.setText(text, true); |
| if (text != null) { |
| mUrlInput.setSelection(text.length()); |
| } |
| } |
| |
| public void setCurrentUrlIsBookmark(boolean isBookmark) { |
| } |
| |
| @Override |
| public boolean dispatchKeyEventPreIme(KeyEvent evt) { |
| if (evt.getKeyCode() == KeyEvent.KEYCODE_BACK) { |
| // catch back key in order to do slightly more cleanup than usual |
| mUrlInput.clearFocus(); |
| return true; |
| } |
| return super.dispatchKeyEventPreIme(evt); |
| } |
| |
| void registerDropdownChangeListener(DropdownChangeListener d) { |
| mUrlInput.registerDropdownChangeListener(d); |
| } |
| |
| /** |
| * called from the Ui when the user wants to edit |
| * @param clearInput clear the input field |
| */ |
| void startEditingUrl(boolean clearInput) { |
| // editing takes preference of progress |
| setVisibility(View.VISIBLE); |
| if (mTitleBar.useQuickControls()) { |
| mTitleBar.getProgressView().setVisibility(View.GONE); |
| } |
| if (!mUrlInput.hasFocus()) { |
| mUrlInput.requestFocus(); |
| } |
| if (clearInput) { |
| mUrlInput.setText(""); |
| } else if (mInVoiceMode) { |
| mUrlInput.showDropDown(); |
| } |
| } |
| |
| public void onProgressStarted() { |
| } |
| |
| public void onProgressStopped() { |
| } |
| |
| } |