author | Sriram Ramasubramanian <sriram@mozilla.com> |
Fri, 14 Jun 2013 12:00:59 -0700 | |
changeset 143343 | 6cd11ae108b510c079347d326444ea0f984da7a9 |
parent 143342 | 21426026164f1af92898e64c88fb8dc05d42270b |
child 143344 | 202981fc6c93a92e4ec42dd4b13f50055f7a2a7d |
push id | 25130 |
push user | lrocha@mozilla.com |
push date | Wed, 21 Aug 2013 09:41:27 +0000 |
treeherder | mozilla-central@b2486721572e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | margaret |
bugs | 883300 |
milestone | 24.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/mobile/android/base/GeckoViewsFactory.java +++ b/mobile/android/base/GeckoViewsFactory.java @@ -1,16 +1,17 @@ /* 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 org.mozilla.gecko.gfx.LayerView; import org.mozilla.gecko.home.BookmarkFolderView; +import org.mozilla.gecko.home.BookmarksListView; import org.mozilla.gecko.home.FadedTextView; import org.mozilla.gecko.home.TwoLinePageRow; import org.mozilla.gecko.menu.MenuItemDefault; import org.mozilla.gecko.widget.AboutHomeView; import org.mozilla.gecko.widget.AddonsSection; import org.mozilla.gecko.widget.FaviconView; import org.mozilla.gecko.widget.IconTabWidget; import org.mozilla.gecko.widget.LastTabsSection; @@ -84,16 +85,17 @@ public final class GeckoViewsFactory imp mFactoryMap.put("ImageButton", GeckoImageButton.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("ImageView", GeckoImageView.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("LinearLayout", GeckoLinearLayout.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("RelativeLayout", GeckoRelativeLayout.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("TextSwitcher", GeckoTextSwitcher.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("TextView", GeckoTextView.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("FaviconView", FaviconView.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("home.BookmarkFolderView", BookmarkFolderView.class.getConstructor(arg1Class, arg2Class)); + mFactoryMap.put("home.BookmarksListView", BookmarksListView.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("home.FadedTextView", FadedTextView.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("home.TwoLinePageRow", TwoLinePageRow.class.getConstructor(arg1Class, arg2Class)); } catch (NoSuchMethodException nsme) { Log.e(LOGTAG, "Unable to initialize views factory", nsme); } } // Making this a singleton class.
--- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -208,16 +208,17 @@ FENNEC_JAVA_FILES = \ gfx/SubdocumentScrollHelper.java \ gfx/TextLayer.java \ gfx/TextureGenerator.java \ gfx/TextureReaper.java \ gfx/TileLayer.java \ gfx/TouchEventHandler.java \ gfx/ViewTransform.java \ gfx/VirtualLayer.java \ + home/BookmarksListView.java \ home/BookmarksPage.java \ home/BookmarkFolderView.java \ home/HomeFragment.java \ home/HomeListView.java \ home/HomePager.java \ home/HomePagerTabStrip.java \ home/FadedTextView.java \ home/TwoLinePageRow.java \
new file mode 100644 --- /dev/null +++ b/mobile/android/base/home/BookmarksListView.java @@ -0,0 +1,334 @@ +/* -*- 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.home; + +import org.mozilla.gecko.R; +import org.mozilla.gecko.db.BrowserContract.Bookmarks; +import org.mozilla.gecko.db.BrowserDB; +import org.mozilla.gecko.db.BrowserDB.URLColumns; +import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; +import org.mozilla.gecko.util.GamepadUtils; +import org.mozilla.gecko.util.ThreadUtils; + +import android.content.Context; +import android.database.Cursor; +import android.os.AsyncTask; +import android.util.AttributeSet; +import android.util.Pair; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.SimpleCursorAdapter; + +import java.util.LinkedList; + +public class BookmarksListView extends HomeListView + implements AdapterView.OnItemClickListener{ + + public static final String LOGTAG = "GeckoBookmarksListView"; + + private int mFolderId = Bookmarks.FIXED_ROOT_ID; + private String mFolderTitle = ""; + + private BookmarksListAdapter mCursorAdapter = null; + private BookmarksQueryTask mQueryTask = null; + + // Folder title for the currently shown list of bookmarks. + private BookmarkFolderView mFolderView; + + public BookmarksListView(Context context) { + this(context, null); + } + + public BookmarksListView(Context context, AttributeSet attrs) { + this(context, attrs, android.R.attr.listViewStyle); + } + + public BookmarksListView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + // Folder title view, is always in open state. + mFolderView = (BookmarkFolderView) LayoutInflater.from(context).inflate(R.layout.bookmark_folder_row, null); + mFolderView.open(); + } + + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + + // Intialize the adapter. + mCursorAdapter = new BookmarksListAdapter(getContext()); + + // We need to add the header before we set the adapter, hence make it null + refreshListWithCursor(null); + + setOnItemClickListener(this); + setOnKeyListener(GamepadUtils.getListItemClickDispatcher()); + + mQueryTask = new BookmarksQueryTask(); + mQueryTask.execute(); + } + + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + // Can't use getters for adapter. It will create one if null. + if (mCursorAdapter != null) { + final Cursor cursor = mCursorAdapter.getCursor(); + mCursorAdapter = null; + + // Gingerbread locks the DB when closing a cursor, so do it in the background. + ThreadUtils.postToBackgroundThread(new Runnable() { + @Override + public void run() { + if (cursor != null && !cursor.isClosed()) + cursor.close(); + } + }); + } + } + + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + final ListView list = (ListView) parent; + final int headerCount = list.getHeaderViewsCount(); + + // If we tap on the header view, move back to parent folder. + if (headerCount == 1 && position == 0) { + mCursorAdapter.moveToParentFolder(); + return; + } + + final Cursor cursor = mCursorAdapter.getCursor(); + if (cursor == null) { + return; + } + + // The header view takes up a spot in the list + if (headerCount == 1) { + position--; + } + + cursor.moveToPosition(position); + + int type = cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks.TYPE)); + if (type == Bookmarks.TYPE_FOLDER) { + // If we're clicking on a folder, update adapter to move to that folder + final int folderId = cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks._ID)); + final String folderTitle = mCursorAdapter.getFolderTitle(position); + mCursorAdapter.moveToChildFolder(folderId, folderTitle); + } else { + // Otherwise, just open the URL + final String url = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.URL)); + OnUrlOpenListener listener = getOnUrlOpenListener(); + if (listener != null) { + listener.onUrlOpen(url); + } + } + } + + private void refreshListWithCursor(Cursor cursor) { + // We need to add the header before we set the adapter, hence making it null. + setAdapter(null); + + // Add a header view based on the root folder. + if (mFolderId == Bookmarks.FIXED_ROOT_ID) { + if (getHeaderViewsCount() == 1) { + removeHeaderView(mFolderView); + } + } else { + if (getHeaderViewsCount() == 0) { + addHeaderView(mFolderView, null, true); + } + + mFolderView.setText(mFolderTitle); + } + + // This will update the cursorAdapter to use the new one if it already exists. + mCursorAdapter.changeCursor(cursor); + setAdapter(mCursorAdapter); + + // Reset the task. + mQueryTask = null; + } + + /** + * Adapter to back the ListView with a list of bookmarks. + */ + private class BookmarksListAdapter extends SimpleCursorAdapter { + private static final int VIEW_TYPE_ITEM = 0; + private static final int VIEW_TYPE_FOLDER = 1; + + private static final int VIEW_TYPE_COUNT = 2; + + // mParentStack holds folder id/title pairs that allow us to navigate + // back up the folder heirarchy. + private LinkedList<Pair<Integer, String>> mParentStack; + + public BookmarksListAdapter(Context context) { + // Initializing with a null cursor. + super(context, -1, null, new String[] {}, new int[] {}); + + mParentStack = new LinkedList<Pair<Integer, String>>(); + + // Add the root folder to the stack + Pair<Integer, String> rootFolder = new Pair<Integer, String>(mFolderId, mFolderTitle); + mParentStack.addFirst(rootFolder); + } + + // Refresh the current folder by executing a new task. + private void refreshCurrentFolder() { + // Cancel any pre-existing async refresh tasks + if (mQueryTask != null) { + mQueryTask.cancel(false); + } + + Pair<Integer, String> folderPair = mParentStack.getFirst(); + mFolderId = folderPair.first; + mFolderTitle = folderPair.second; + + mQueryTask = new BookmarksQueryTask(); + mQueryTask.execute(new Integer(mFolderId)); + } + + /** + * Moves to parent folder, if one exists. + */ + public void moveToParentFolder() { + // If we're already at the root, we can't move to a parent folder + if (mParentStack.size() != 1) { + mParentStack.removeFirst(); + refreshCurrentFolder(); + } + } + + /** + * Moves to child folder, given a folderId. + * + * @param folderId The id of the folder to show. + * @param folderTitle The title of the folder to show. + */ + public void moveToChildFolder(int folderId, String folderTitle) { + Pair<Integer, String> folderPair = new Pair<Integer, String>(folderId, folderTitle); + mParentStack.addFirst(folderPair); + refreshCurrentFolder(); + } + + /** + * {@inheritDoc} + */ + @Override + public int getItemViewType(int position) { + Cursor c = getCursor(); + + if (c.moveToPosition(position) && + c.getInt(c.getColumnIndexOrThrow(Bookmarks.TYPE)) == Bookmarks.TYPE_FOLDER) { + return VIEW_TYPE_FOLDER; + } + + // Default to retuning normal item type + return VIEW_TYPE_ITEM; + } + + /** + * {@inheritDoc} + */ + @Override + public int getViewTypeCount() { + return VIEW_TYPE_COUNT; + } + + /** + * Get the title of the folder for a given position. + * + * @param position The position of the view. + * @return The title of the folder at the position. + */ + public String getFolderTitle(int position) { + Cursor c = getCursor(); + if (!c.moveToPosition(position)) { + return ""; + } + + String guid = c.getString(c.getColumnIndexOrThrow(Bookmarks.GUID)); + + // If we don't have a special GUID, just return the folder title from the DB. + if (guid == null || guid.length() == 12) { + return c.getString(c.getColumnIndexOrThrow(Bookmarks.TITLE)); + } + + // Use localized strings for special folder names. + if (guid.equals(Bookmarks.FAKE_DESKTOP_FOLDER_GUID)) { + return getResources().getString(R.string.bookmarks_folder_desktop); + } else if (guid.equals(Bookmarks.MENU_FOLDER_GUID)) { + return getResources().getString(R.string.bookmarks_folder_menu); + } else if (guid.equals(Bookmarks.TOOLBAR_FOLDER_GUID)) { + return getResources().getString(R.string.bookmarks_folder_toolbar); + } else if (guid.equals(Bookmarks.UNFILED_FOLDER_GUID)) { + return getResources().getString(R.string.bookmarks_folder_unfiled); + } + + // If for some reason we have a folder with a special GUID, but it's not one of + // the special folders we expect in the UI, just return the title from the DB. + return c.getString(c.getColumnIndexOrThrow(Bookmarks.TITLE)); + } + + /** + * {@inheritDoc} + */ + @Override + public View getView(int position, View convertView, ViewGroup parent) { + final int viewType = getItemViewType(position); + + if (convertView == null) { + if (viewType == VIEW_TYPE_ITEM) { + convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_item_row, null); + } else { + convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.bookmark_folder_row, null); + } + } + + Cursor cursor = getCursor(); + if (!cursor.moveToPosition(position)) { + throw new IllegalStateException("Couldn't move cursor to position " + position); + } + + if (viewType == VIEW_TYPE_ITEM) { + TwoLinePageRow row = (TwoLinePageRow) convertView; + row.updateFromCursor(cursor); + } else { + BookmarkFolderView row = (BookmarkFolderView) convertView; + row.setText(getFolderTitle(position)); + } + + return convertView; + } + } + + /** + * AsyncTask to query the DB for bookmarks. + */ + private class BookmarksQueryTask extends AsyncTask<Integer, Void, Cursor> { + @Override + protected Cursor doInBackground(Integer... folderIds) { + int folderId = Bookmarks.FIXED_ROOT_ID; + + if (folderIds.length != 0) { + folderId = folderIds[0].intValue(); + } + + return BrowserDB.getBookmarksInFolder(getContext().getContentResolver(), folderId); + } + + @Override + protected void onPostExecute(final Cursor cursor) { + refreshListWithCursor(cursor); + } + } +}
--- a/mobile/android/base/home/BookmarksPage.java +++ b/mobile/android/base/home/BookmarksPage.java @@ -1,57 +1,33 @@ /* -*- 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.home; import org.mozilla.gecko.R; -import org.mozilla.gecko.db.BrowserContract.Bookmarks; -import org.mozilla.gecko.db.BrowserDB; -import org.mozilla.gecko.db.BrowserDB.URLColumns; import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; -import org.mozilla.gecko.util.GamepadUtils; -import org.mozilla.gecko.util.ThreadUtils; import android.app.Activity; -import android.content.Context; import android.content.res.Configuration; -import android.database.Cursor; -import android.os.AsyncTask; import android.os.Bundle; -import android.util.Pair; import android.view.LayoutInflater; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ListView; -import android.widget.SimpleCursorAdapter; - -import java.util.LinkedList; /** * A page in about:home that displays a ListView of bookmarks. */ -public class BookmarksPage extends HomeFragment implements AdapterView.OnItemClickListener { +public class BookmarksPage extends HomeFragment { public static final String LOGTAG = "GeckoBookmarksPage"; - private int mFolderId = Bookmarks.FIXED_ROOT_ID; - private String mFolderTitle = ""; - - private BookmarksListAdapter mCursorAdapter = null; - private BookmarksQueryTask mQueryTask = null; - // The view shown by the fragment. - private HomeListView mList; - - // Folder title for the currently shown list of bookmarks. - private BookmarkFolderView mFolderView; + private BookmarksListView mList; // On URL open listener private OnUrlOpenListener mUrlOpenListener; public BookmarksPage() { mUrlOpenListener = null; } @@ -60,75 +36,44 @@ public class BookmarksPage extends HomeF super.onAttach(activity); try { mUrlOpenListener = (OnUrlOpenListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement HomePager.OnUrlOpenListener"); } - - // Intialize the adapter. - mCursorAdapter = new BookmarksListAdapter(getActivity()); } @Override public void onDetach() { super.onDetach(); mUrlOpenListener = null; - - // Can't use getters for adapter. It will create one if null. - if (mCursorAdapter != null) { - final Cursor cursor = mCursorAdapter.getCursor(); - mCursorAdapter = null; - - // Gingerbread locks the DB when closing a cursor, so do it in the background. - ThreadUtils.postToBackgroundThread(new Runnable() { - @Override - public void run() { - if (cursor != null && !cursor.isClosed()) - cursor.close(); - } - }); - } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); return inflater.inflate(R.layout.home_bookmarks_page, null); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - mList = (HomeListView) view.findViewById(R.id.bookmarks_list); - - // Folder title view, is always in open state. - mFolderView = (BookmarkFolderView) LayoutInflater.from(getActivity()).inflate(R.layout.bookmark_folder_row, null); - mFolderView.open(); - - // We need to add the header before we set the adapter, hence make it null - refreshListWithCursor(null); - - mList.setOnItemClickListener(this); - mList.setOnKeyListener(GamepadUtils.getListItemClickDispatcher()); + mList = (BookmarksListView) view.findViewById(R.id.bookmarks_list); + mList.setOnUrlOpenListener(mUrlOpenListener); registerForContextMenu(mList); - - mQueryTask = new BookmarksQueryTask(); - mQueryTask.execute(); } @Override public void onDestroyView() { mList = null; - mFolderView = null; super.onDestroyView(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Reattach the fragment, forcing a reinflation of its view. @@ -141,246 +86,9 @@ public class BookmarksPage extends HomeF // onResume(). if (isVisible()) { getFragmentManager().beginTransaction() .detach(this) .attach(this) .commitAllowingStateLoss(); } } - - @Override - public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - final ListView list = (ListView) parent; - final int headerCount = list.getHeaderViewsCount(); - - // If we tap on the header view, move back to parent folder. - if (headerCount == 1 && position == 0) { - mCursorAdapter.moveToParentFolder(); - return; - } - - final Cursor cursor = mCursorAdapter.getCursor(); - if (cursor == null) { - return; - } - - // The header view takes up a spot in the list - if (headerCount == 1) { - position--; - } - - cursor.moveToPosition(position); - - int type = cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks.TYPE)); - if (type == Bookmarks.TYPE_FOLDER) { - // If we're clicking on a folder, update adapter to move to that folder - final int folderId = cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks._ID)); - final String folderTitle = mCursorAdapter.getFolderTitle(position); - mCursorAdapter.moveToChildFolder(folderId, folderTitle); - } else { - // Otherwise, just open the URL - final String url = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.URL)); - if (mUrlOpenListener != null) { - mUrlOpenListener.onUrlOpen(url); - } - } - } - - private void refreshListWithCursor(Cursor cursor) { - // We need to add the header before we set the adapter, hence making it null. - mList.setAdapter(null); - - // Add a header view based on the root folder. - if (mFolderId == Bookmarks.FIXED_ROOT_ID) { - if (mList.getHeaderViewsCount() == 1) { - mList.removeHeaderView(mFolderView); - } - } else { - if (mList.getHeaderViewsCount() == 0) { - mList.addHeaderView(mFolderView, null, true); - } - - mFolderView.setText(mFolderTitle); - } - - // This will update the cursorAdapter to use the new one if it already exists. - mCursorAdapter.changeCursor(cursor); - mList.setAdapter(mCursorAdapter); - - // Reset the task. - mQueryTask = null; - } - - /** - * Adapter to back the ListView with a list of bookmarks. - */ - private class BookmarksListAdapter extends SimpleCursorAdapter { - private static final int VIEW_TYPE_ITEM = 0; - private static final int VIEW_TYPE_FOLDER = 1; - - private static final int VIEW_TYPE_COUNT = 2; - - // mParentStack holds folder id/title pairs that allow us to navigate - // back up the folder heirarchy. - private LinkedList<Pair<Integer, String>> mParentStack; - - public BookmarksListAdapter(Context context) { - // Initializing with a null cursor. - super(context, -1, null, new String[] {}, new int[] {}); - - mParentStack = new LinkedList<Pair<Integer, String>>(); - - // Add the root folder to the stack - Pair<Integer, String> rootFolder = new Pair<Integer, String>(mFolderId, mFolderTitle); - mParentStack.addFirst(rootFolder); - } - - // Refresh the current folder by executing a new task. - private void refreshCurrentFolder() { - // Cancel any pre-existing async refresh tasks - if (mQueryTask != null) { - mQueryTask.cancel(false); - } - - Pair<Integer, String> folderPair = mParentStack.getFirst(); - mFolderId = folderPair.first; - mFolderTitle = folderPair.second; - - mQueryTask = new BookmarksQueryTask(); - mQueryTask.execute(new Integer(mFolderId)); - } - - /** - * Moves to parent folder, if one exists. - */ - public void moveToParentFolder() { - // If we're already at the root, we can't move to a parent folder - if (mParentStack.size() != 1) { - mParentStack.removeFirst(); - refreshCurrentFolder(); - } - } - - /** - * Moves to child folder, given a folderId. - * - * @param folderId The id of the folder to show. - * @param folderTitle The title of the folder to show. - */ - public void moveToChildFolder(int folderId, String folderTitle) { - Pair<Integer, String> folderPair = new Pair<Integer, String>(folderId, folderTitle); - mParentStack.addFirst(folderPair); - refreshCurrentFolder(); - } - - /** - * {@inheritDoc} - */ - @Override - public int getItemViewType(int position) { - Cursor c = getCursor(); - - if (c.moveToPosition(position) && - c.getInt(c.getColumnIndexOrThrow(Bookmarks.TYPE)) == Bookmarks.TYPE_FOLDER) { - return VIEW_TYPE_FOLDER; - } - - // Default to retuning normal item type - return VIEW_TYPE_ITEM; - } - - /** - * {@inheritDoc} - */ - @Override - public int getViewTypeCount() { - return VIEW_TYPE_COUNT; - } - - /** - * Get the title of the folder for a given position. - * - * @param position The position of the view. - * @return The title of the folder at the position. - */ - public String getFolderTitle(int position) { - Cursor c = getCursor(); - if (!c.moveToPosition(position)) { - return ""; - } - - String guid = c.getString(c.getColumnIndexOrThrow(Bookmarks.GUID)); - - // If we don't have a special GUID, just return the folder title from the DB. - if (guid == null || guid.length() == 12) { - return c.getString(c.getColumnIndexOrThrow(Bookmarks.TITLE)); - } - - // Use localized strings for special folder names. - if (guid.equals(Bookmarks.FAKE_DESKTOP_FOLDER_GUID)) { - return getResources().getString(R.string.bookmarks_folder_desktop); - } else if (guid.equals(Bookmarks.MENU_FOLDER_GUID)) { - return getResources().getString(R.string.bookmarks_folder_menu); - } else if (guid.equals(Bookmarks.TOOLBAR_FOLDER_GUID)) { - return getResources().getString(R.string.bookmarks_folder_toolbar); - } else if (guid.equals(Bookmarks.UNFILED_FOLDER_GUID)) { - return getResources().getString(R.string.bookmarks_folder_unfiled); - } - - // If for some reason we have a folder with a special GUID, but it's not one of - // the special folders we expect in the UI, just return the title from the DB. - return c.getString(c.getColumnIndexOrThrow(Bookmarks.TITLE)); - } - - /** - * {@inheritDoc} - */ - @Override - public View getView(int position, View convertView, ViewGroup parent) { - final int viewType = getItemViewType(position); - - if (convertView == null) { - if (viewType == VIEW_TYPE_ITEM) { - convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_item_row, null); - } else { - convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.bookmark_folder_row, null); - } - } - - Cursor cursor = getCursor(); - if (!cursor.moveToPosition(position)) { - throw new IllegalStateException("Couldn't move cursor to position " + position); - } - - if (viewType == VIEW_TYPE_ITEM) { - TwoLinePageRow row = (TwoLinePageRow) convertView; - row.updateFromCursor(cursor); - } else { - BookmarkFolderView row = (BookmarkFolderView) convertView; - row.setText(getFolderTitle(position)); - } - - return convertView; - } - } - - /** - * AsyncTask to query the DB for bookmarks. - */ - private class BookmarksQueryTask extends AsyncTask<Integer, Void, Cursor> { - @Override - protected Cursor doInBackground(Integer... folderIds) { - int folderId = Bookmarks.FIXED_ROOT_ID; - - if (folderIds.length != 0) { - folderId = folderIds[0].intValue(); - } - - return BrowserDB.getBookmarksInFolder(getActivity().getContentResolver(), folderId); - } - - @Override - protected void onPostExecute(final Cursor cursor) { - refreshListWithCursor(cursor); - } - } }
--- a/mobile/android/base/home/HomeListView.java +++ b/mobile/android/base/home/HomeListView.java @@ -3,16 +3,17 @@ * 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.home; import org.mozilla.gecko.db.BrowserContract.Bookmarks; import org.mozilla.gecko.db.BrowserContract.Combined; import org.mozilla.gecko.db.BrowserDB.URLColumns; +import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; import android.content.Context; import android.database.Cursor; import android.util.AttributeSet; import android.view.ContextMenu.ContextMenuInfo; import android.view.MotionEvent; import android.view.View; @@ -25,16 +26,19 @@ import android.widget.ListView; * when any of its rows is long pressed. */ public class HomeListView extends ListView implements OnItemLongClickListener { // ContextMenuInfo associated with the currently long pressed list item. private HomeContextMenuInfo mContextMenuInfo; + // On URL open listener + private OnUrlOpenListener mUrlOpenListener; + public HomeListView(Context context) { this(context, null); } public HomeListView(Context context, AttributeSet attrs) { this(context, attrs, android.R.attr.listViewStyle); } @@ -61,16 +65,24 @@ public class HomeListView extends ListVi return showContextMenuForChild(HomeListView.this); } @Override public ContextMenuInfo getContextMenuInfo() { return mContextMenuInfo; } + public OnUrlOpenListener getOnUrlOpenListener() { + return mUrlOpenListener; + } + + public void setOnUrlOpenListener(OnUrlOpenListener listener) { + mUrlOpenListener = listener; + } + /** * A ContextMenuInfo for HomeListView that adds details from the cursor. */ public static class HomeContextMenuInfo extends AdapterContextMenuInfo { public int rowId; public String url; public byte[] favicon; public String title;
--- a/mobile/android/base/resources/layout/home_bookmarks_page.xml +++ b/mobile/android/base/resources/layout/home_bookmarks_page.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <!-- 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/. --> -<org.mozilla.gecko.home.HomeListView xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/bookmarks_list" - android:layout_width="fill_parent" - android:layout_height="fill_parent"/> +<org.mozilla.gecko.home.BookmarksListView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/bookmarks_list" + android:layout_width="fill_parent" + android:layout_height="fill_parent"/>