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.

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

mercurial