mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 759041 - Move all pages tab to interface. r=lucasr
This commit is contained in:
parent
a2de6910df
commit
7a3a9be374
@ -223,7 +223,6 @@ public class AwesomeBar extends GeckoActivity implements GeckoEventListener {
|
||||
}
|
||||
});
|
||||
|
||||
registerForContextMenu(mAwesomeTabs.findViewById(R.id.all_pages_list));
|
||||
registerForContextMenu(mAwesomeTabs.findViewById(R.id.bookmarks_list));
|
||||
registerForContextMenu(mAwesomeTabs.findViewById(R.id.history_list));
|
||||
|
||||
|
@ -28,7 +28,6 @@ import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.FilterQueryProvider;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
@ -37,8 +36,6 @@ import android.widget.SimpleExpandableListAdapter;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
@ -47,8 +44,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
|
||||
import org.mozilla.gecko.db.BrowserContract.Combined;
|
||||
@ -58,7 +53,6 @@ import org.mozilla.gecko.db.BrowserDB.URLColumns;
|
||||
public class AwesomeBarTabs extends TabHost {
|
||||
private static final String LOGTAG = "GeckoAwesomeBarTabs";
|
||||
|
||||
private static final String ALL_PAGES_TAB = "all";
|
||||
private static final String BOOKMARKS_TAB = "bookmarks";
|
||||
private static final String HISTORY_TAB = "history";
|
||||
|
||||
@ -70,13 +64,11 @@ public class AwesomeBarTabs extends TabHost {
|
||||
private OnUrlOpenListener mUrlOpenListener;
|
||||
private ContentResolver mContentResolver;
|
||||
private ContentObserver mContentObserver;
|
||||
private SearchEngine mSuggestEngine;
|
||||
private ArrayList<SearchEngine> mSearchEngines;
|
||||
|
||||
private BookmarksQueryTask mBookmarksQueryTask;
|
||||
private HistoryQueryTask mHistoryQueryTask;
|
||||
|
||||
private AwesomeBarCursorAdapter mAllPagesCursorAdapter;
|
||||
private AllPagesTab mAllPagesTab;
|
||||
private BookmarksListAdapter mBookmarksAdapter;
|
||||
private SimpleExpandableListAdapter mHistoryAdapter;
|
||||
|
||||
@ -99,13 +91,6 @@ public class AwesomeBarTabs extends TabHost {
|
||||
public ImageView bookmarkIconView;
|
||||
}
|
||||
|
||||
private class SearchEntryViewHolder {
|
||||
public FlowLayout suggestionView;
|
||||
public ImageView iconView;
|
||||
public LinearLayout userEnteredView;
|
||||
public TextView userEnteredTextView;
|
||||
}
|
||||
|
||||
private class HistoryListAdapter extends SimpleExpandableListAdapter {
|
||||
public HistoryListAdapter(Context context, List<? extends Map<String, ?>> groupData,
|
||||
int groupLayout, String[] groupFrom, int[] groupTo,
|
||||
@ -611,250 +596,6 @@ public class AwesomeBarTabs extends TabHost {
|
||||
}
|
||||
}
|
||||
|
||||
private interface AwesomeBarItem {
|
||||
public void onClick();
|
||||
}
|
||||
|
||||
private class AwesomeBarCursorAdapter extends SimpleCursorAdapter {
|
||||
private String mSearchTerm;
|
||||
|
||||
private static final int ROW_SEARCH = 0;
|
||||
private static final int ROW_STANDARD = 1;
|
||||
|
||||
private class AwesomeBarCursorItem implements AwesomeBarItem {
|
||||
private Cursor mCursor;
|
||||
|
||||
public AwesomeBarCursorItem(Cursor cursor) {
|
||||
mCursor = cursor;
|
||||
}
|
||||
|
||||
public void onClick() {
|
||||
String url = mCursor.getString(mCursor.getColumnIndexOrThrow(URLColumns.URL));
|
||||
if (mUrlOpenListener != null) {
|
||||
int display = mCursor.getInt(mCursor.getColumnIndexOrThrow(Combined.DISPLAY));
|
||||
if (display == Combined.DISPLAY_READER) {
|
||||
url = getReaderForUrl(url);
|
||||
}
|
||||
|
||||
mUrlOpenListener.onUrlOpen(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class AwesomeBarSearchEngineItem implements AwesomeBarItem {
|
||||
private String mSearchEngine;
|
||||
|
||||
public AwesomeBarSearchEngineItem(String searchEngine) {
|
||||
mSearchEngine = searchEngine;
|
||||
}
|
||||
|
||||
public void onClick() {
|
||||
if (mUrlOpenListener != null)
|
||||
mUrlOpenListener.onSearch(mSearchEngine, mSearchTerm);
|
||||
}
|
||||
}
|
||||
|
||||
public AwesomeBarCursorAdapter(Context context) {
|
||||
super(context, -1, null, new String[] {}, new int[] {});
|
||||
mSearchTerm = "";
|
||||
}
|
||||
|
||||
public void filter(String searchTerm) {
|
||||
mSearchTerm = searchTerm;
|
||||
getFilter().filter(searchTerm);
|
||||
}
|
||||
|
||||
private int getSuggestEngineCount() {
|
||||
return (mSearchTerm.length() == 0 || mSuggestEngine == null) ? 0 : 1;
|
||||
}
|
||||
|
||||
// Add the search engines to the number of reported results.
|
||||
@Override
|
||||
public int getCount() {
|
||||
final int resultCount = super.getCount();
|
||||
|
||||
// don't show search engines or suggestions if search field is empty
|
||||
if (mSearchTerm.length() == 0)
|
||||
return resultCount;
|
||||
|
||||
return resultCount + mSearchEngines.size() + getSuggestEngineCount();
|
||||
}
|
||||
|
||||
// If an item is part of the cursor result set, return that entry.
|
||||
// Otherwise, return the search engine data.
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
int engineIndex = getEngineIndex(position);
|
||||
|
||||
if (engineIndex == -1) {
|
||||
// return awesomebar result
|
||||
position -= getSuggestEngineCount();
|
||||
return new AwesomeBarCursorItem((Cursor) super.getItem(position));
|
||||
}
|
||||
|
||||
// return search engine
|
||||
return new AwesomeBarSearchEngineItem(getEngine(engineIndex).name);
|
||||
}
|
||||
|
||||
private SearchEngine getEngine(int index) {
|
||||
final int suggestEngineCount = getSuggestEngineCount();
|
||||
if (index < suggestEngineCount)
|
||||
return mSuggestEngine;
|
||||
return mSearchEngines.get(index - suggestEngineCount);
|
||||
}
|
||||
|
||||
private int getEngineIndex(int position) {
|
||||
final int resultCount = super.getCount();
|
||||
final int suggestEngineCount = getSuggestEngineCount();
|
||||
|
||||
// return suggest engine index
|
||||
if (position < suggestEngineCount)
|
||||
return 0;
|
||||
|
||||
// not an engine
|
||||
if (position - suggestEngineCount < resultCount)
|
||||
return -1;
|
||||
|
||||
// return search engine index
|
||||
return position - resultCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return getEngineIndex(position) == -1 ? ROW_STANDARD : ROW_SEARCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
// view can be either a standard awesomebar row or a search engine row
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int position) {
|
||||
// If the suggestion row only contains one item (the user-entered
|
||||
// query), allow the entire row to be clickable; clicking the row
|
||||
// has the same effect as clicking the single suggestion. If the
|
||||
// row contains multiple items, clicking the row will do nothing.
|
||||
int index = getEngineIndex(position);
|
||||
if (index != -1) {
|
||||
return getEngine(index).suggestions.isEmpty();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
if (getItemViewType(position) == ROW_SEARCH) {
|
||||
SearchEntryViewHolder viewHolder = null;
|
||||
|
||||
if (convertView == null) {
|
||||
convertView = mInflater.inflate(R.layout.awesomebar_suggestion_row, null);
|
||||
|
||||
viewHolder = new SearchEntryViewHolder();
|
||||
viewHolder.suggestionView = (FlowLayout) convertView.findViewById(R.id.suggestion_layout);
|
||||
viewHolder.iconView = (ImageView) convertView.findViewById(R.id.suggestion_icon);
|
||||
viewHolder.userEnteredView = (LinearLayout) convertView.findViewById(R.id.suggestion_user_entered);
|
||||
viewHolder.userEnteredTextView = (TextView) convertView.findViewById(R.id.suggestion_text);
|
||||
|
||||
convertView.setTag(viewHolder);
|
||||
} else {
|
||||
viewHolder = (SearchEntryViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
bindSearchEngineView(getEngine(getEngineIndex(position)), viewHolder);
|
||||
} else {
|
||||
AwesomeEntryViewHolder viewHolder = null;
|
||||
|
||||
if (convertView == null) {
|
||||
convertView = mInflater.inflate(R.layout.awesomebar_row, null);
|
||||
|
||||
viewHolder = new AwesomeEntryViewHolder();
|
||||
viewHolder.titleView = (TextView) convertView.findViewById(R.id.title);
|
||||
viewHolder.urlView = (TextView) convertView.findViewById(R.id.url);
|
||||
viewHolder.faviconView = (ImageView) convertView.findViewById(R.id.favicon);
|
||||
viewHolder.bookmarkIconView = (ImageView) convertView.findViewById(R.id.bookmark_icon);
|
||||
|
||||
convertView.setTag(viewHolder);
|
||||
} else {
|
||||
viewHolder = (AwesomeEntryViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
position -= getSuggestEngineCount();
|
||||
Cursor cursor = getCursor();
|
||||
if (!cursor.moveToPosition(position))
|
||||
throw new IllegalStateException("Couldn't move cursor to position " + position);
|
||||
|
||||
updateTitle(viewHolder.titleView, cursor);
|
||||
updateUrl(viewHolder.urlView, cursor);
|
||||
updateFavicon(viewHolder.faviconView, cursor);
|
||||
updateBookmarkIcon(viewHolder.bookmarkIconView, cursor);
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private void bindSearchEngineView(final SearchEngine engine, SearchEntryViewHolder viewHolder) {
|
||||
// when a suggestion is clicked, do a search
|
||||
OnClickListener clickListener = new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (mUrlOpenListener != null) {
|
||||
String suggestion = ((TextView) v.findViewById(R.id.suggestion_text)).getText().toString();
|
||||
mUrlOpenListener.onSearch(engine.name, suggestion);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// when a suggestion is long-clicked, copy the suggestion into the URL EditText
|
||||
OnLongClickListener longClickListener = new OnLongClickListener() {
|
||||
public boolean onLongClick(View v) {
|
||||
if (mUrlOpenListener != null) {
|
||||
String suggestion = ((TextView) v.findViewById(R.id.suggestion_text)).getText().toString();
|
||||
mUrlOpenListener.onEditSuggestion(suggestion);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// set the search engine icon (e.g., Google) for the row
|
||||
FlowLayout suggestionView = viewHolder.suggestionView;
|
||||
viewHolder.iconView.setImageDrawable(engine.icon);
|
||||
|
||||
// user-entered search term is first suggestion
|
||||
viewHolder.userEnteredTextView.setText(mSearchTerm);
|
||||
viewHolder.userEnteredView.setOnClickListener(clickListener);
|
||||
|
||||
// add additional suggestions given by this engine
|
||||
int recycledSuggestionCount = suggestionView.getChildCount();
|
||||
int suggestionCount = engine.suggestions.size();
|
||||
int i = 0;
|
||||
for (i = 0; i < suggestionCount; i++) {
|
||||
String suggestion = engine.suggestions.get(i);
|
||||
View suggestionItem = null;
|
||||
|
||||
// reuse suggestion views from recycled view, if possible
|
||||
if (i+1 < recycledSuggestionCount) {
|
||||
suggestionItem = suggestionView.getChildAt(i+1);
|
||||
suggestionItem.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
suggestionItem = mInflater.inflate(R.layout.awesomebar_suggestion_item, null);
|
||||
((ImageView) suggestionItem.findViewById(R.id.suggestion_magnifier)).setVisibility(View.GONE);
|
||||
suggestionView.addView(suggestionItem);
|
||||
}
|
||||
((TextView) suggestionItem.findViewById(R.id.suggestion_text)).setText(suggestion);
|
||||
|
||||
suggestionItem.setOnClickListener(clickListener);
|
||||
suggestionItem.setOnLongClickListener(longClickListener);
|
||||
}
|
||||
|
||||
// hide extra suggestions that have been recycled
|
||||
for (++i; i < recycledSuggestionCount; i++) {
|
||||
suggestionView.getChildAt(i).setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public AwesomeBarTabs(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
@ -862,7 +603,6 @@ public class AwesomeBarTabs extends TabHost {
|
||||
|
||||
mContext = context;
|
||||
mInflated = false;
|
||||
mSearchEngines = new ArrayList<SearchEngine>();
|
||||
mContentResolver = context.getContentResolver();
|
||||
mContentObserver = null;
|
||||
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
@ -920,7 +660,23 @@ public class AwesomeBarTabs extends TabHost {
|
||||
filter("");
|
||||
}
|
||||
|
||||
private TabSpec addAwesomeTab(String id, int titleId, TabHost.TabContentFactory factory) {
|
||||
TabSpec tab = getTabSpec(id, titleId);
|
||||
tab.setContent(factory);
|
||||
addTab(tab);
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
private TabSpec addAwesomeTab(String id, int titleId, int contentId) {
|
||||
TabSpec tab = getTabSpec(id, titleId);
|
||||
tab.setContent(contentId);
|
||||
addTab(tab);
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
private TabSpec getTabSpec(String id, int titleId) {
|
||||
TabSpec tab = newTabSpec(id);
|
||||
|
||||
View indicatorView = mInflater.inflate(R.layout.awesomebar_tab_indicator, null);
|
||||
@ -934,9 +690,6 @@ public class AwesomeBarTabs extends TabHost {
|
||||
title.setText(titleId);
|
||||
|
||||
tab.setIndicator(indicatorView);
|
||||
tab.setContent(contentId);
|
||||
|
||||
addTab(tab);
|
||||
|
||||
return tab;
|
||||
}
|
||||
@ -944,36 +697,10 @@ public class AwesomeBarTabs extends TabHost {
|
||||
private void addAllPagesTab() {
|
||||
Log.d(LOGTAG, "Creating All Pages tab");
|
||||
|
||||
addAwesomeTab(ALL_PAGES_TAB,
|
||||
R.string.awesomebar_all_pages_title,
|
||||
R.id.all_pages_list);
|
||||
|
||||
// Load the list using a custom adapter so we can create the bitmaps
|
||||
mAllPagesCursorAdapter = new AwesomeBarCursorAdapter(mContext);
|
||||
|
||||
mAllPagesCursorAdapter.setFilterQueryProvider(new FilterQueryProvider() {
|
||||
public Cursor runQuery(CharSequence constraint) {
|
||||
long start = SystemClock.uptimeMillis();
|
||||
|
||||
Cursor c = BrowserDB.filter(mContentResolver, constraint, MAX_RESULTS);
|
||||
c.getCount(); // ensure the query runs at least once
|
||||
|
||||
long end = SystemClock.uptimeMillis();
|
||||
Log.i(LOGTAG, "Got cursor in " + (end - start) + "ms");
|
||||
|
||||
return c;
|
||||
}
|
||||
});
|
||||
|
||||
final ListView allPagesList = (ListView) findViewById(R.id.all_pages_list);
|
||||
|
||||
allPagesList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
((AwesomeBarItem) allPagesList.getItemAtPosition(position)).onClick();
|
||||
}
|
||||
});
|
||||
|
||||
allPagesList.setAdapter(mAllPagesCursorAdapter);
|
||||
mAllPagesTab = new AllPagesTab(mContext);
|
||||
addAwesomeTab(mAllPagesTab.getTag(),
|
||||
mAllPagesTab.getTitleStringId(),
|
||||
mAllPagesTab.getFactory());
|
||||
}
|
||||
|
||||
private void addBookmarksTab() {
|
||||
@ -1112,12 +839,11 @@ public class AwesomeBarTabs extends TabHost {
|
||||
|
||||
public void setOnUrlOpenListener(OnUrlOpenListener listener) {
|
||||
mUrlOpenListener = listener;
|
||||
mAllPagesTab.setUrlListener(listener);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
Cursor allPagesCursor = mAllPagesCursorAdapter.getCursor();
|
||||
if (allPagesCursor != null)
|
||||
allPagesCursor.close();
|
||||
mAllPagesTab.destroy();
|
||||
|
||||
if (mBookmarksAdapter != null) {
|
||||
Cursor bookmarksCursor = mBookmarksAdapter.getCursor();
|
||||
@ -1134,7 +860,7 @@ public class AwesomeBarTabs extends TabHost {
|
||||
setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
|
||||
|
||||
// Ensure the 'All Pages' tab is selected
|
||||
setCurrentTabByTag(ALL_PAGES_TAB);
|
||||
setCurrentTabByTag(mAllPagesTab.getTag());
|
||||
|
||||
// Restore normal focus behavior on tab host
|
||||
setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
|
||||
@ -1144,35 +870,9 @@ public class AwesomeBarTabs extends TabHost {
|
||||
getTabWidget().setVisibility(tabsVisibility);
|
||||
|
||||
// Perform the actual search
|
||||
mAllPagesCursorAdapter.filter(searchTerm);
|
||||
mAllPagesTab.filter(searchTerm);
|
||||
}
|
||||
|
||||
private Drawable getDrawableFromDataURI(String dataURI) {
|
||||
String base64 = dataURI.substring(dataURI.indexOf(',') + 1);
|
||||
Drawable drawable = null;
|
||||
try {
|
||||
byte[] bytes = GeckoAppShell.decodeBase64(base64, GeckoAppShell.BASE64_DEFAULT);
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
|
||||
drawable = Drawable.createFromStream(stream, "src");
|
||||
stream.close();
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.i(LOGTAG, "exception while decoding drawable: " + base64, e);
|
||||
} catch (IOException e) { }
|
||||
return drawable;
|
||||
}
|
||||
|
||||
private class SearchEngine {
|
||||
public String name;
|
||||
public Drawable icon;
|
||||
public ArrayList<String> suggestions;
|
||||
|
||||
public SearchEngine(String name, Drawable icon) {
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
this.suggestions = new ArrayList<String>();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets suggestions associated with the current suggest engine.
|
||||
* If there is no suggest engine, this does nothing.
|
||||
@ -1180,10 +880,7 @@ public class AwesomeBarTabs extends TabHost {
|
||||
public void setSuggestions(final ArrayList<String> suggestions) {
|
||||
GeckoAppShell.getMainHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
if (mSuggestEngine != null) {
|
||||
mSuggestEngine.suggestions = suggestions;
|
||||
mAllPagesCursorAdapter.notifyDataSetChanged();
|
||||
}
|
||||
mAllPagesTab.setSuggestions(suggestions);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1191,32 +888,10 @@ public class AwesomeBarTabs extends TabHost {
|
||||
/**
|
||||
* Sets search engines to be shown for user-entered queries.
|
||||
*/
|
||||
public void setSearchEngines(String suggestEngineName, JSONArray engines) {
|
||||
final ArrayList<SearchEngine> searchEngines = new ArrayList<SearchEngine>();
|
||||
SearchEngine suggestEngine = null;
|
||||
for (int i = 0; i < engines.length(); i++) {
|
||||
try {
|
||||
JSONObject engineJSON = engines.getJSONObject(i);
|
||||
String name = engineJSON.getString("name");
|
||||
String iconURI = engineJSON.getString("iconURI");
|
||||
Drawable icon = getDrawableFromDataURI(iconURI);
|
||||
if (name.equals(suggestEngineName)) {
|
||||
suggestEngine = new SearchEngine(name, icon);
|
||||
} else {
|
||||
searchEngines.add(new SearchEngine(name, icon));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "Error getting search engine JSON", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final SearchEngine suggestEngineArg = suggestEngine;
|
||||
public void setSearchEngines(final String suggestEngineName, final JSONArray engines) {
|
||||
GeckoAppShell.getMainHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
mSuggestEngine = suggestEngineArg;
|
||||
mSearchEngines = searchEngines;
|
||||
mAllPagesCursorAdapter.notifyDataSetChanged();
|
||||
mAllPagesTab.setSearchEngines(suggestEngineName, engines);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ FENNEC_JAVA_FILES = \
|
||||
AlertNotification.java \
|
||||
AwesomeBar.java \
|
||||
awesomebar/AwesomeBarTab.java \
|
||||
awesomebar/AllPagesTab.java \
|
||||
AwesomeBarTabs.java \
|
||||
BrowserApp.java \
|
||||
BrowserToolbar.java \
|
||||
|
500
mobile/android/base/awesomebar/AllPagesTab.java
Normal file
500
mobile/android/base/awesomebar/AllPagesTab.java
Normal file
@ -0,0 +1,500 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.view.View;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.app.Activity;
|
||||
import android.widget.AdapterView;
|
||||
import android.database.Cursor;
|
||||
import android.widget.AdapterView;
|
||||
import android.util.Log;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.Toast;
|
||||
import android.widget.SimpleCursorAdapter;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TabHost.TabContentFactory;
|
||||
import android.view.ViewGroup;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.content.Intent;
|
||||
import android.widget.FilterQueryProvider;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONException;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.db.BrowserDB.URLColumns;
|
||||
import org.mozilla.gecko.db.BrowserContract.Combined;
|
||||
|
||||
public class AllPagesTab extends AwesomeBarTab {
|
||||
public static final String LOGTAG = "ALL_PAGES";
|
||||
private static final String TAG = "allPages";
|
||||
private SearchEngine mSuggestEngine;
|
||||
private ArrayList<SearchEngine> mSearchEngines;
|
||||
private ListView mView = null;
|
||||
private AwesomeBarCursorAdapter mCursorAdapter = null;
|
||||
|
||||
private class SearchEntryViewHolder {
|
||||
public FlowLayout suggestionView;
|
||||
public ImageView iconView;
|
||||
public LinearLayout userEnteredView;
|
||||
public TextView userEnteredTextView;
|
||||
}
|
||||
|
||||
public AllPagesTab(Context context) {
|
||||
super(context);
|
||||
mSearchEngines = new ArrayList<SearchEngine>();
|
||||
}
|
||||
|
||||
public TabContentFactory getFactory() {
|
||||
return new TabContentFactory() {
|
||||
public View createTabContent(String tag) {
|
||||
final ListView list = getListView();
|
||||
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
handleItemClick(parent, view, position, id);
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int getTitleStringId() {
|
||||
return R.string.awesomebar_all_pages_title;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
public ListView getListView() {
|
||||
if (mView == null) {
|
||||
mView = new ListView(mContext, null, R.style.AwesomeBarList);
|
||||
((Activity)mContext).registerForContextMenu(mView);
|
||||
mView.setTag(TAG);
|
||||
AwesomeBarCursorAdapter adapter = getCursorAdapter();
|
||||
mView.setAdapter(adapter);
|
||||
}
|
||||
return mView;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
AwesomeBarCursorAdapter adapter = getCursorAdapter();
|
||||
if (adapter == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Cursor cursor = adapter.getCursor();
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
public void filter(String searchTerm) {
|
||||
AwesomeBarCursorAdapter adapter = getCursorAdapter();
|
||||
adapter.filter(searchTerm);
|
||||
}
|
||||
|
||||
protected AwesomeBarCursorAdapter getCursorAdapter() {
|
||||
if (mCursorAdapter == null) {
|
||||
// Load the list using a custom adapter so we can create the bitmaps
|
||||
mCursorAdapter = new AwesomeBarCursorAdapter(mContext);
|
||||
|
||||
mCursorAdapter.setFilterQueryProvider(new FilterQueryProvider() {
|
||||
public Cursor runQuery(CharSequence constraint) {
|
||||
long start = SystemClock.uptimeMillis();
|
||||
|
||||
Cursor c = BrowserDB.filter(getContentResolver(), constraint, MAX_RESULTS);
|
||||
c.getCount();
|
||||
|
||||
long end = SystemClock.uptimeMillis();
|
||||
Log.i(LOGTAG, "Got cursor in " + (end - start) + "ms");
|
||||
|
||||
return c;
|
||||
}
|
||||
});
|
||||
}
|
||||
return mCursorAdapter;
|
||||
}
|
||||
|
||||
private interface AwesomeBarItem {
|
||||
public void onClick();
|
||||
}
|
||||
|
||||
private class AwesomeBarCursorAdapter extends SimpleCursorAdapter {
|
||||
private String mSearchTerm;
|
||||
|
||||
private static final int ROW_SEARCH = 0;
|
||||
private static final int ROW_STANDARD = 1;
|
||||
|
||||
private class AwesomeBarCursorItem implements AwesomeBarItem {
|
||||
private Cursor mCursor;
|
||||
|
||||
public AwesomeBarCursorItem(Cursor cursor) {
|
||||
mCursor = cursor;
|
||||
}
|
||||
|
||||
public void onClick() {
|
||||
AwesomeBarTabs.OnUrlOpenListener listener = getUrlListener();
|
||||
if (listener == null)
|
||||
return;
|
||||
|
||||
String url = mCursor.getString(mCursor.getColumnIndexOrThrow(URLColumns.URL));
|
||||
|
||||
int display = mCursor.getInt(mCursor.getColumnIndexOrThrow(Combined.DISPLAY));
|
||||
if (display == Combined.DISPLAY_READER) {
|
||||
url = getReaderForUrl(url);
|
||||
}
|
||||
listener.onUrlOpen(url);
|
||||
}
|
||||
}
|
||||
|
||||
private class AwesomeBarSearchEngineItem implements AwesomeBarItem {
|
||||
private String mSearchEngine;
|
||||
|
||||
public AwesomeBarSearchEngineItem(String searchEngine) {
|
||||
mSearchEngine = searchEngine;
|
||||
}
|
||||
|
||||
public void onClick() {
|
||||
AwesomeBarTabs.OnUrlOpenListener listener = getUrlListener();
|
||||
if (listener != null)
|
||||
listener.onSearch(mSearchEngine, mSearchTerm);
|
||||
}
|
||||
}
|
||||
|
||||
public AwesomeBarCursorAdapter(Context context) {
|
||||
super(context, -1, null, new String[] {}, new int[] {});
|
||||
mSearchTerm = "";
|
||||
}
|
||||
|
||||
public void filter(String searchTerm) {
|
||||
mSearchTerm = searchTerm;
|
||||
getFilter().filter(searchTerm);
|
||||
}
|
||||
|
||||
private int getSuggestEngineCount() {
|
||||
return (mSearchTerm.length() == 0 || mSuggestEngine == null) ? 0 : 1;
|
||||
}
|
||||
|
||||
// Add the search engines to the number of reported results.
|
||||
@Override
|
||||
public int getCount() {
|
||||
final int resultCount = super.getCount();
|
||||
|
||||
// don't show search engines or suggestions if search field is empty
|
||||
if (mSearchTerm.length() == 0)
|
||||
return resultCount;
|
||||
|
||||
return resultCount + mSearchEngines.size() + getSuggestEngineCount();
|
||||
}
|
||||
|
||||
// If an item is part of the cursor result set, return that entry.
|
||||
// Otherwise, return the search engine data.
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
int engineIndex = getEngineIndex(position);
|
||||
|
||||
if (engineIndex == -1) {
|
||||
// return awesomebar result
|
||||
position -= getSuggestEngineCount();
|
||||
return new AwesomeBarCursorItem((Cursor) super.getItem(position));
|
||||
}
|
||||
|
||||
// return search engine
|
||||
return new AwesomeBarSearchEngineItem(getEngine(engineIndex).name);
|
||||
}
|
||||
|
||||
private SearchEngine getEngine(int index) {
|
||||
final int suggestEngineCount = getSuggestEngineCount();
|
||||
if (index < suggestEngineCount)
|
||||
return mSuggestEngine;
|
||||
return mSearchEngines.get(index - suggestEngineCount);
|
||||
}
|
||||
|
||||
private int getEngineIndex(int position) {
|
||||
final int resultCount = super.getCount();
|
||||
final int suggestEngineCount = getSuggestEngineCount();
|
||||
|
||||
// return suggest engine index
|
||||
if (position < suggestEngineCount)
|
||||
return 0;
|
||||
|
||||
// not an engine
|
||||
if (position - suggestEngineCount < resultCount)
|
||||
return -1;
|
||||
|
||||
// return search engine index
|
||||
return position - resultCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return getEngineIndex(position) == -1 ? ROW_STANDARD : ROW_SEARCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
// view can be either a standard awesomebar row or a search engine row
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int position) {
|
||||
// If the suggestion row only contains one item (the user-entered
|
||||
// query), allow the entire row to be clickable; clicking the row
|
||||
// has the same effect as clicking the single suggestion. If the
|
||||
// row contains multiple items, clicking the row will do nothing.
|
||||
int index = getEngineIndex(position);
|
||||
if (index != -1) {
|
||||
return getEngine(index).suggestions.isEmpty();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
if (getItemViewType(position) == ROW_SEARCH) {
|
||||
SearchEntryViewHolder viewHolder = null;
|
||||
|
||||
if (convertView == null) {
|
||||
convertView = getInflater().inflate(R.layout.awesomebar_suggestion_row, null);
|
||||
|
||||
viewHolder = new SearchEntryViewHolder();
|
||||
viewHolder.suggestionView = (FlowLayout) convertView.findViewById(R.id.suggestion_layout);
|
||||
viewHolder.iconView = (ImageView) convertView.findViewById(R.id.suggestion_icon);
|
||||
viewHolder.userEnteredView = (LinearLayout) convertView.findViewById(R.id.suggestion_user_entered);
|
||||
viewHolder.userEnteredTextView = (TextView) convertView.findViewById(R.id.suggestion_text);
|
||||
|
||||
convertView.setTag(viewHolder);
|
||||
} else {
|
||||
viewHolder = (SearchEntryViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
bindSearchEngineView(getEngine(getEngineIndex(position)), viewHolder);
|
||||
} else {
|
||||
AwesomeEntryViewHolder viewHolder = null;
|
||||
|
||||
if (convertView == null) {
|
||||
convertView = getInflater().inflate(R.layout.awesomebar_row, null);
|
||||
|
||||
viewHolder = new AwesomeEntryViewHolder();
|
||||
viewHolder.titleView = (TextView) convertView.findViewById(R.id.title);
|
||||
viewHolder.urlView = (TextView) convertView.findViewById(R.id.url);
|
||||
viewHolder.faviconView = (ImageView) convertView.findViewById(R.id.favicon);
|
||||
viewHolder.bookmarkIconView = (ImageView) convertView.findViewById(R.id.bookmark_icon);
|
||||
|
||||
convertView.setTag(viewHolder);
|
||||
} else {
|
||||
viewHolder = (AwesomeEntryViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
position -= getSuggestEngineCount();
|
||||
Cursor cursor = getCursor();
|
||||
if (!cursor.moveToPosition(position))
|
||||
throw new IllegalStateException("Couldn't move cursor to position " + position);
|
||||
|
||||
updateTitle(viewHolder.titleView, cursor);
|
||||
updateUrl(viewHolder.urlView, cursor);
|
||||
updateFavicon(viewHolder.faviconView, cursor);
|
||||
updateBookmarkIcon(viewHolder.bookmarkIconView, cursor);
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private void bindSearchEngineView(final SearchEngine engine, SearchEntryViewHolder viewHolder) {
|
||||
// when a suggestion is clicked, do a search
|
||||
OnClickListener clickListener = new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
AwesomeBarTabs.OnUrlOpenListener listener = getUrlListener();
|
||||
if (listener != null) {
|
||||
String suggestion = ((TextView) v.findViewById(R.id.suggestion_text)).getText().toString();
|
||||
listener.onSearch(engine.name, suggestion);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// when a suggestion is long-clicked, copy the suggestion into the URL EditText
|
||||
OnLongClickListener longClickListener = new OnLongClickListener() {
|
||||
public boolean onLongClick(View v) {
|
||||
AwesomeBarTabs.OnUrlOpenListener listener = getUrlListener();
|
||||
if (listener != null) {
|
||||
String suggestion = ((TextView) v.findViewById(R.id.suggestion_text)).getText().toString();
|
||||
listener.onEditSuggestion(suggestion);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// set the search engine icon (e.g., Google) for the row
|
||||
FlowLayout suggestionView = viewHolder.suggestionView;
|
||||
viewHolder.iconView.setImageDrawable(engine.icon);
|
||||
|
||||
// user-entered search term is first suggestion
|
||||
viewHolder.userEnteredTextView.setText(mSearchTerm);
|
||||
viewHolder.userEnteredView.setOnClickListener(clickListener);
|
||||
|
||||
// add additional suggestions given by this engine
|
||||
int recycledSuggestionCount = suggestionView.getChildCount();
|
||||
int suggestionCount = engine.suggestions.size();
|
||||
int i = 0;
|
||||
for (i = 0; i < suggestionCount; i++) {
|
||||
String suggestion = engine.suggestions.get(i);
|
||||
View suggestionItem = null;
|
||||
|
||||
// reuse suggestion views from recycled view, if possible
|
||||
if (i+1 < recycledSuggestionCount) {
|
||||
suggestionItem = suggestionView.getChildAt(i+1);
|
||||
suggestionItem.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
suggestionItem = getInflater().inflate(R.layout.awesomebar_suggestion_item, null);
|
||||
((ImageView) suggestionItem.findViewById(R.id.suggestion_magnifier)).setVisibility(View.GONE);
|
||||
suggestionView.addView(suggestionItem);
|
||||
}
|
||||
((TextView) suggestionItem.findViewById(R.id.suggestion_text)).setText(suggestion);
|
||||
|
||||
suggestionItem.setOnClickListener(clickListener);
|
||||
suggestionItem.setOnLongClickListener(longClickListener);
|
||||
}
|
||||
|
||||
// hide extra suggestions that have been recycled
|
||||
for (++i; i < recycledSuggestionCount; i++) {
|
||||
suggestionView.getChildAt(i).setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private class SearchEngine {
|
||||
public String name;
|
||||
public Drawable icon;
|
||||
public ArrayList<String> suggestions;
|
||||
|
||||
public SearchEngine(String name) {
|
||||
this(name, null);
|
||||
}
|
||||
|
||||
public SearchEngine(String name, Drawable icon) {
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
this.suggestions = new ArrayList<String>();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the suggest engine, which will show suggestions for user-entered queries.
|
||||
* If the suggest engine has already been set, it will be replaced, and its
|
||||
* suggestions will be copied to the new suggest engine.
|
||||
*/
|
||||
public void setSuggestEngine(String name, Drawable icon) {
|
||||
// We currently save the suggest engine in shared preferences, so this
|
||||
// method is called immediately when the AwesomeBar is created. It's
|
||||
// called again in setSuggestions(), when the list of search engines is
|
||||
// received from Gecko (in case the suggestion engine has changed).
|
||||
final SearchEngine suggestEngine = new SearchEngine(name, icon);
|
||||
if (mSuggestEngine != null)
|
||||
suggestEngine.suggestions = mSuggestEngine.suggestions;
|
||||
|
||||
mSuggestEngine = suggestEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets suggestions associated with the current suggest engine.
|
||||
* If there is no suggest engine, this does nothing.
|
||||
*/
|
||||
public void setSuggestions(final ArrayList<String> suggestions) {
|
||||
if (mSuggestEngine != null) {
|
||||
mSuggestEngine.suggestions = suggestions;
|
||||
getCursorAdapter().notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets search engines to be shown for user-entered queries.
|
||||
*/
|
||||
public void setSearchEngines(String suggestEngine, JSONArray engines) {
|
||||
mSearchEngines = new ArrayList<SearchEngine>();
|
||||
for (int i = 0; i < engines.length(); i++) {
|
||||
try {
|
||||
JSONObject engineJSON = engines.getJSONObject(i);
|
||||
String name = engineJSON.getString("name");
|
||||
String iconURI = engineJSON.getString("iconURI");
|
||||
Drawable icon = getDrawableFromDataURI(iconURI);
|
||||
if (name.equals(suggestEngine)) {
|
||||
setSuggestEngine(name, icon);
|
||||
} else {
|
||||
mSearchEngines.add(new SearchEngine(name, icon));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "Error getting search engine JSON", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
AwesomeBarCursorAdapter adapter = getCursorAdapter();
|
||||
if (adapter != null)
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private Drawable getDrawableFromDataURI(String dataURI) {
|
||||
String base64 = dataURI.substring(dataURI.indexOf(',') + 1);
|
||||
Drawable drawable = null;
|
||||
try {
|
||||
byte[] bytes = GeckoAppShell.decodeBase64(base64, GeckoAppShell.BASE64_DEFAULT);
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
|
||||
drawable = Drawable.createFromStream(stream, "src");
|
||||
stream.close();
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.i(LOGTAG, "exception while decoding drawable: " + base64, e);
|
||||
} catch (IOException e) { }
|
||||
return drawable;
|
||||
}
|
||||
|
||||
public void handleItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
ListView listview = getListView();
|
||||
if (listview == null)
|
||||
return;
|
||||
|
||||
AwesomeBarItem item = (AwesomeBarItem)listview.getItemAtPosition(position);
|
||||
item.onClick();
|
||||
}
|
||||
|
||||
protected void updateBookmarkIcon(ImageView bookmarkIconView, Cursor cursor) {
|
||||
int bookmarkIdIndex = cursor.getColumnIndexOrThrow(Combined.BOOKMARK_ID);
|
||||
long id = cursor.getLong(bookmarkIdIndex);
|
||||
|
||||
int displayIndex = cursor.getColumnIndexOrThrow(Combined.DISPLAY);
|
||||
int display = cursor.getInt(displayIndex);
|
||||
|
||||
// The bookmark id will be 0 (null in database) when the url
|
||||
// is not a bookmark.
|
||||
int visibility = (id == 0 ? View.GONE : View.VISIBLE);
|
||||
bookmarkIconView.setVisibility(visibility);
|
||||
|
||||
if (display == Combined.DISPLAY_READER) {
|
||||
bookmarkIconView.setImageResource(R.drawable.ic_awesomebar_reader);
|
||||
} else {
|
||||
bookmarkIconView.setImageResource(R.drawable.ic_awesomebar_star);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,18 +5,32 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TabHost.TabContentFactory;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserContract.Combined;
|
||||
import org.mozilla.gecko.db.BrowserDB.URLColumns;
|
||||
|
||||
abstract public class AwesomeBarTab {
|
||||
abstract public String getTag();
|
||||
abstract public int getTitleStringId();
|
||||
abstract public void destroy();
|
||||
abstract public TabContentFactory getFactory();
|
||||
|
||||
private AwesomeBarTabs.OnUrlOpenListener mListener;
|
||||
private LayoutInflater mInflater = null;
|
||||
private ContentResolver mContentResolver = null;
|
||||
private Resources mResources;
|
||||
// FIXME: This value should probably come from a prefs key
|
||||
public static final int MAX_RESULTS = 100;
|
||||
protected Context mContext = null;
|
||||
@ -31,4 +45,70 @@ abstract public class AwesomeBarTab {
|
||||
public ImageView faviconView;
|
||||
public ImageView bookmarkIconView;
|
||||
}
|
||||
|
||||
protected LayoutInflater getInflater() {
|
||||
if (mInflater == null) {
|
||||
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
}
|
||||
return mInflater;
|
||||
}
|
||||
|
||||
protected AwesomeBarTabs.OnUrlOpenListener getUrlListener() {
|
||||
return mListener;
|
||||
}
|
||||
|
||||
protected void setUrlListener(AwesomeBarTabs.OnUrlOpenListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
protected ContentResolver getContentResolver() {
|
||||
if (mContentResolver == null) {
|
||||
mContentResolver = mContext.getContentResolver();
|
||||
}
|
||||
return mContentResolver;
|
||||
}
|
||||
|
||||
protected Resources getResources() {
|
||||
if (mResources == null) {
|
||||
mResources = mContext.getResources();
|
||||
}
|
||||
return mResources;
|
||||
}
|
||||
|
||||
protected String getReaderForUrl(String url) {
|
||||
// FIXME: still need to define the final way to open items from
|
||||
// reading list. For now, we're using an about:reader page.
|
||||
return "about:reader?url=" + url;
|
||||
}
|
||||
|
||||
protected void updateFavicon(ImageView faviconView, Cursor cursor) {
|
||||
byte[] b = cursor.getBlob(cursor.getColumnIndexOrThrow(URLColumns.FAVICON));
|
||||
if (b == null) {
|
||||
faviconView.setImageDrawable(null);
|
||||
} else {
|
||||
Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
|
||||
faviconView.setImageBitmap(bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateTitle(TextView titleView, Cursor cursor) {
|
||||
int titleIndex = cursor.getColumnIndexOrThrow(URLColumns.TITLE);
|
||||
String title = cursor.getString(titleIndex);
|
||||
|
||||
// Use the URL instead of an empty title for consistency with the normal URL
|
||||
// bar view - this is the equivalent of getDisplayTitle() in Tab.java
|
||||
if (TextUtils.isEmpty(title)) {
|
||||
int urlIndex = cursor.getColumnIndexOrThrow(URLColumns.URL);
|
||||
title = cursor.getString(urlIndex);
|
||||
}
|
||||
|
||||
titleView.setText(title);
|
||||
}
|
||||
|
||||
protected void updateUrl(TextView urlView, Cursor cursor) {
|
||||
int urlIndex = cursor.getColumnIndexOrThrow(URLColumns.URL);
|
||||
String url = cursor.getString(urlIndex);
|
||||
|
||||
urlView.setText(url);
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,6 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
<ListView android:id="@+id/all_pages_list"
|
||||
style="@style/AwesomeBarList"/>
|
||||
|
||||
<ListView android:id="@+id/bookmarks_list"
|
||||
style="@style/AwesomeBarList"/>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user