Bug 862798 - Add "Reading List" page to new about:home. r=bnicholson,sriram
☠☠ backed out by 35f62a290d4e ☠ ☠
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Tue, 02 Jul 2013 21:40:29 -0700
changeset 151363 7f1cfc8c84e830e6519b9cefbe019c727aea5f12
parent 151362 639d74175e959efaf71779165f8027d800e58c7e
child 151364 35f62a290d4e942bde0e048dae1591cc81a3d586
push idunknown
push userunknown
push dateunknown
reviewersbnicholson, sriram
bugs862798
milestone24.0a1
Bug 862798 - Add "Reading List" page to new about:home. r=bnicholson,sriram
mobile/android/base/Makefile.in
mobile/android/base/home/HomePager.java
mobile/android/base/home/ReadingListPage.java
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -215,16 +215,17 @@ FENNEC_JAVA_FILES = \
   home/BookmarkThumbnailView.java \
   home/BrowserSearch.java \
   home/HomeFragment.java \
   home/HomeListView.java \
   home/HomePager.java \
   home/HomePagerTabStrip.java \
   home/FadedTextView.java \
   home/FaviconsLoader.java \
+  home/ReadingListPage.java
   home/SearchEngine.java \
   home/SearchEngineRow.java \
   home/SimpleCursorLoader.java \
   home/SuggestClient.java \
   home/TopBookmarkItemView.java \
   home/TopBookmarksAdapter.java \
   home/TopBookmarksView.java \
   home/TwoLinePageRow.java \
--- a/mobile/android/base/home/HomePager.java
+++ b/mobile/android/base/home/HomePager.java
@@ -23,17 +23,18 @@ import java.util.EnumSet;
 
 public class HomePager extends ViewPager {
     private final Context mContext;
     private volatile boolean mLoaded;
 
     // List of pages in order.
     private enum Page {
         VISITED,
-        BOOKMARKS
+        BOOKMARKS,
+        READING_LIST
     }
 
     private EnumMap<Page, Fragment> mPages = new EnumMap<Page, Fragment>(Page.class);
 
     public interface OnUrlOpenListener {
         public void onUrlOpen(String url);
     }
 
@@ -54,16 +55,17 @@ public class HomePager extends ViewPager
      */
     public void show(FragmentManager fm) {
         mLoaded = true;
         TabsAdapter adapter = new TabsAdapter(fm);
 
         // Add the pages to the adapter in order.
         adapter.addTab(Page.VISITED, VisitedPage.class, null, getContext().getString(R.string.visited_title));
         adapter.addTab(Page.BOOKMARKS, BookmarksPage.class, null, getContext().getString(R.string.bookmarks_title));
+        adapter.addTab(Page.READING_LIST, ReadingListPage.class, null, getContext().getString(R.string.reading_list));
 
         setAdapter(adapter);
 
         // Set the bookmarks page as the landing page.
         setCurrentItem(1, false);
         setVisibility(VISIBLE);
     }
 
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/home/ReadingListPage.java
@@ -0,0 +1,183 @@
+/* -*- 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.home.TwoLinePageRow;
+import org.mozilla.gecko.ReaderModeUtils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.support.v4.app.LoaderManager.LoaderCallbacks;
+import android.support.v4.content.Loader;
+import android.support.v4.widget.CursorAdapter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ListView;
+
+/**
+ * Fragment that displays reading list contents in a ListView.
+ */
+public class ReadingListPage extends HomeFragment {
+    // Cursor loader ID for reading list
+    private static final int READING_LIST_LOADER_ID = 0;
+
+    // Adapter for the list of reading list items
+    private ReadingListAdapter mAdapter;
+
+    // The view shown by the fragment
+    private ListView mList;
+
+    // Callbacks used for the reading list and favicon cursor loaders
+    private CursorLoaderCallbacks mCursorLoaderCallbacks;
+
+    // On URL open listener
+    private OnUrlOpenListener mUrlOpenListener;
+
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+
+        try {
+            mUrlOpenListener = (OnUrlOpenListener) activity;
+        } catch (ClassCastException e) {
+            throw new ClassCastException(activity.toString()
+                    + " must implement HomePager.OnUrlOpenListener");
+        }
+    }
+
+    @Override
+    public void onDetach() {
+        super.onDetach();
+
+        mUrlOpenListener = null;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        // All list views are styled to look the same with a global activity theme.
+        // If the style of the list changes, inflate it from an XML.
+        mList = new HomeListView(container.getContext());
+        return mList;
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        mList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                final Cursor c = mAdapter.getCursor();
+                if (c == null || !c.moveToPosition(position)) {
+                    return;
+                }
+
+                String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL));
+                url = ReaderModeUtils.getAboutReaderForUrl(url, true);
+                mUrlOpenListener.onUrlOpen(url);
+            }
+        });
+
+        registerForContextMenu(mList);
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+        mList = null;
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        mAdapter = new ReadingListAdapter(getActivity(), null);
+        mList.setAdapter(mAdapter);
+
+        // Create callbacks before the initial loader is started.
+        mCursorLoaderCallbacks = new CursorLoaderCallbacks();
+
+        // Reconnect to the loader only if it's present.
+        getLoaderManager().initLoader(READING_LIST_LOADER_ID, null, mCursorLoaderCallbacks);
+    }
+
+    /**
+     * Cursor loader for the list of reading list items.
+     */
+    private static class ReadingListLoader extends SimpleCursorLoader {
+        public ReadingListLoader(Context context) {
+            super(context);
+        }
+
+        @Override
+        public Cursor loadCursor() {
+            return BrowserDB.getBookmarksInFolder(getContext().getContentResolver(), Bookmarks.FIXED_READING_LIST_ID);
+        }
+    }
+
+    /**
+     * Cursor adapter for the list of reading list items.
+     */
+    private class ReadingListAdapter extends CursorAdapter {
+        public ReadingListAdapter(Context context, Cursor cursor) {
+            super(context, cursor);
+        }
+
+        @Override
+        public void bindView(View view, Context context, Cursor cursor) {
+            final TwoLinePageRow row = (TwoLinePageRow) view;
+            row.updateFromCursor(cursor);
+        }
+
+        @Override
+        public View newView(Context context, Cursor cursor, ViewGroup parent) {
+            return LayoutInflater.from(parent.getContext()).inflate(R.layout.home_item_row, parent, false);
+        }
+    }
+
+    /**
+     * LoaderCallbacks implementation that interacts with the LoaderManager. 
+     */
+    private class CursorLoaderCallbacks implements LoaderCallbacks<Cursor> {
+        @Override
+        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+            switch(id) {
+                case READING_LIST_LOADER_ID:
+                    return new ReadingListLoader(getActivity());
+            }
+            return null;
+        }
+
+        @Override
+        public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
+            final int loaderId = loader.getId();
+            switch(loaderId) {
+                case READING_LIST_LOADER_ID:
+                    mAdapter.swapCursor(c);
+                    break;
+           }
+        }
+
+        @Override
+        public void onLoaderReset(Loader<Cursor> loader) {
+            final int loaderId = loader.getId();
+            switch(loaderId) {
+                case READING_LIST_LOADER_ID:
+                    mAdapter.swapCursor(null);
+                    break;
+            }
+        }
+    }
+}