mobile/android/base/home/BookmarksPanel.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 package org.mozilla.gecko.home;
     8 import java.util.List;
    10 import org.mozilla.gecko.R;
    11 import org.mozilla.gecko.db.BrowserContract.Bookmarks;
    12 import org.mozilla.gecko.db.BrowserDB;
    13 import org.mozilla.gecko.home.BookmarksListAdapter.FolderInfo;
    14 import org.mozilla.gecko.home.BookmarksListAdapter.OnRefreshFolderListener;
    15 import org.mozilla.gecko.home.BookmarksListAdapter.RefreshType;
    16 import org.mozilla.gecko.home.HomePager.OnUrlOpenListener;
    18 import android.app.Activity;
    19 import android.content.Context;
    20 import android.content.res.Configuration;
    21 import android.database.Cursor;
    22 import android.os.Bundle;
    23 import android.support.v4.app.LoaderManager.LoaderCallbacks;
    24 import android.support.v4.content.Loader;
    25 import android.view.LayoutInflater;
    26 import android.view.View;
    27 import android.view.ViewGroup;
    28 import android.view.ViewStub;
    29 import android.widget.ImageView;
    30 import android.widget.TextView;
    32 /**
    33  * A page in about:home that displays a ListView of bookmarks.
    34  */
    35 public class BookmarksPanel extends HomeFragment {
    36     public static final String LOGTAG = "GeckoBookmarksPanel";
    38     // Cursor loader ID for list of bookmarks.
    39     private static final int LOADER_ID_BOOKMARKS_LIST = 0;
    41     // Information about the target bookmarks folder.
    42     private static final String BOOKMARKS_FOLDER_INFO = "folder_info";
    44     // Refresh type for folder refreshing loader.
    45     private static final String BOOKMARKS_REFRESH_TYPE = "refresh_type";
    47     // List of bookmarks.
    48     private BookmarksListView mList;
    50     // Adapter for list of bookmarks.
    51     private BookmarksListAdapter mListAdapter;
    53     // Adapter's parent stack.
    54     private List<FolderInfo> mSavedParentStack;
    56     // Reference to the View to display when there are no results.
    57     private View mEmptyView;
    59     // Callback for cursor loaders.
    60     private CursorLoaderCallbacks mLoaderCallbacks;
    62     @Override
    63     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    64         final View view = inflater.inflate(R.layout.home_bookmarks_panel, container, false);
    66         mList = (BookmarksListView) view.findViewById(R.id.bookmarks_list);
    68         mList.setContextMenuInfoFactory(new HomeContextMenuInfo.Factory() {
    69             @Override
    70             public HomeContextMenuInfo makeInfoForCursor(View view, int position, long id, Cursor cursor) {
    71                 final int type = cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks.TYPE));
    72                 if (type == Bookmarks.TYPE_FOLDER) {
    73                     // We don't show a context menu for folders
    74                     return null;
    75                 }
    76                 final HomeContextMenuInfo info = new HomeContextMenuInfo(view, position, id);
    77                 info.url = cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.URL));
    78                 info.title = cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.TITLE));
    79                 info.bookmarkId = cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks._ID));
    80                 return info;
    81             }
    82         });
    84         return view;
    85     }
    87     @Override
    88     public void onViewCreated(View view, Bundle savedInstanceState) {
    89         super.onViewCreated(view, savedInstanceState);
    91         OnUrlOpenListener listener = null;
    92         try {
    93             listener = (OnUrlOpenListener) getActivity();
    94         } catch (ClassCastException e) {
    95             throw new ClassCastException(getActivity().toString()
    96                     + " must implement HomePager.OnUrlOpenListener");
    97         }
    99         mList.setTag(HomePager.LIST_TAG_BOOKMARKS);
   100         mList.setOnUrlOpenListener(listener);
   102         registerForContextMenu(mList);
   103     }
   105     @Override
   106     public void onActivityCreated(Bundle savedInstanceState) {
   107         super.onActivityCreated(savedInstanceState);
   109         final Activity activity = getActivity();
   111         // Setup the list adapter.
   112         mListAdapter = new BookmarksListAdapter(activity, null, mSavedParentStack);
   113         mListAdapter.setOnRefreshFolderListener(new OnRefreshFolderListener() {
   114             @Override
   115             public void onRefreshFolder(FolderInfo folderInfo, RefreshType refreshType) {
   116                 // Restart the loader with folder as the argument.
   117                 Bundle bundle = new Bundle();
   118                 bundle.putParcelable(BOOKMARKS_FOLDER_INFO, folderInfo);
   119                 bundle.putParcelable(BOOKMARKS_REFRESH_TYPE, refreshType);
   120                 getLoaderManager().restartLoader(LOADER_ID_BOOKMARKS_LIST, bundle, mLoaderCallbacks);
   121             }
   122         });
   123         mList.setAdapter(mListAdapter);
   125         // Create callbacks before the initial loader is started.
   126         mLoaderCallbacks = new CursorLoaderCallbacks();
   127         loadIfVisible();
   128     }
   130     @Override
   131     public void onDestroyView() {
   132         mList = null;
   133         mListAdapter = null;
   134         mEmptyView = null;
   135         super.onDestroyView();
   136     }
   138     @Override
   139     public void onConfigurationChanged(Configuration newConfig) {
   140         super.onConfigurationChanged(newConfig);
   142         // Reattach the fragment, forcing a reinflation of its view.
   143         // We use commitAllowingStateLoss() instead of commit() here to avoid
   144         // an IllegalStateException. If the phone is rotated while Fennec
   145         // is in the background, onConfigurationChanged() is fired.
   146         // onConfigurationChanged() is called before onResume(), so
   147         // using commit() would throw an IllegalStateException since it can't
   148         // be used between the Activity's onSaveInstanceState() and
   149         // onResume().
   150         if (isVisible()) {
   151             // The parent stack is saved just so that the folder state can be
   152             // restored on rotation.
   153             mSavedParentStack = mListAdapter.getParentStack();
   155             getFragmentManager().beginTransaction()
   156                                 .detach(this)
   157                                 .attach(this)
   158                                 .commitAllowingStateLoss();
   159         }
   160     }
   162     @Override
   163     protected void load() {
   164         getLoaderManager().initLoader(LOADER_ID_BOOKMARKS_LIST, null, mLoaderCallbacks);
   165     }
   167     private void updateUiFromCursor(Cursor c) {
   168         if ((c == null || c.getCount() == 0) && mEmptyView == null) {
   169             // Set empty page view. We delay this so that the empty view won't flash.
   170             final ViewStub emptyViewStub = (ViewStub) getView().findViewById(R.id.home_empty_view_stub);
   171             mEmptyView = emptyViewStub.inflate();
   173             final ImageView emptyIcon = (ImageView) mEmptyView.findViewById(R.id.home_empty_image);
   174             emptyIcon.setImageResource(R.drawable.icon_bookmarks_empty);
   176             final TextView emptyText = (TextView) mEmptyView.findViewById(R.id.home_empty_text);
   177             emptyText.setText(R.string.home_bookmarks_empty);
   179             mList.setEmptyView(mEmptyView);
   180         }
   181     }
   183     /**
   184      * Loader for the list for bookmarks.
   185      */
   186     private static class BookmarksLoader extends SimpleCursorLoader {
   187         private final FolderInfo mFolderInfo;
   188         private final RefreshType mRefreshType;
   190         public BookmarksLoader(Context context) {
   191             this(context, new FolderInfo(Bookmarks.FIXED_ROOT_ID), RefreshType.CHILD);
   192         }
   194         public BookmarksLoader(Context context, FolderInfo folderInfo, RefreshType refreshType) {
   195             super(context);
   196             mFolderInfo = folderInfo;
   197             mRefreshType = refreshType;
   198         }
   200         @Override
   201         public Cursor loadCursor() {
   202             return BrowserDB.getBookmarksInFolder(getContext().getContentResolver(), mFolderInfo.id);
   203         }
   205         @Override
   206         public void onContentChanged() {
   207             // Invalidate the cached value that keeps track of whether or
   208             // not desktop bookmarks exist.
   209             BrowserDB.invalidateCachedState();
   210             super.onContentChanged();
   211         }
   213         public FolderInfo getFolderInfo() {
   214             return mFolderInfo;
   215         }
   217         public RefreshType getRefreshType() {
   218             return mRefreshType;
   219         }
   220     }
   222     /**
   223      * Loader callbacks for the LoaderManager of this fragment.
   224      */
   225     private class CursorLoaderCallbacks implements LoaderCallbacks<Cursor> {
   226         @Override
   227         public Loader<Cursor> onCreateLoader(int id, Bundle args) {
   228             if (args == null) {
   229                 return new BookmarksLoader(getActivity());
   230             } else {
   231                 FolderInfo folderInfo = (FolderInfo) args.getParcelable(BOOKMARKS_FOLDER_INFO);
   232                 RefreshType refreshType = (RefreshType) args.getParcelable(BOOKMARKS_REFRESH_TYPE);
   233                 return new BookmarksLoader(getActivity(), folderInfo, refreshType);
   234             }
   235         }
   237         @Override
   238         public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
   239             BookmarksLoader bl = (BookmarksLoader) loader;
   240             mListAdapter.swapCursor(c, bl.getFolderInfo(), bl.getRefreshType());
   241             updateUiFromCursor(c);
   242         }
   244         @Override
   245         public void onLoaderReset(Loader<Cursor> loader) {
   246             if (mList != null) {
   247                 mListAdapter.swapCursor(null);
   248             }
   249         }
   250     }
   251 }

mercurial