Bug 1060544 - Part 2: persist Bookmarks panel folder r?liuche
This allows us to restore the previously opened bookmarks folder when returning to
the bookmarks panel. I.e. when you open a bookmarks folder (including the smartfolders),
select a bookmark, and then return (via the back button, or quick-history via long-pressing
the back button), we will return to the bookmarks folder that was opened.
We don't persist the scroll position, that's a separate issue, in
Bug 993552.
MozReview-Commit-ID: 3EhIvlXOgAU
--- a/mobile/android/base/java/org/mozilla/gecko/home/BookmarksListAdapter.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/BookmarksListAdapter.java
@@ -114,17 +114,17 @@ class BookmarksListAdapter extends Multi
*/
public enum FolderType {
BOOKMARKS,
SCREENSHOTS,
}
// mParentStack holds folder info instances (id + title) that allow
// us to navigate back up the folder hierarchy.
- private final LinkedList<FolderInfo> mParentStack;
+ private LinkedList<FolderInfo> mParentStack;
// Refresh folder listener.
private OnRefreshFolderListener mListener;
private FolderType openFolderType = FolderType.BOOKMARKS;
public BookmarksListAdapter(Context context, Cursor cursor, List<FolderInfo> parentStack) {
// Initializing with a null cursor.
@@ -132,16 +132,21 @@ class BookmarksListAdapter extends Multi
if (parentStack == null) {
mParentStack = new LinkedList<FolderInfo>();
} else {
mParentStack = new LinkedList<FolderInfo>(parentStack);
}
}
+ public void restoreData(List<FolderInfo> parentStack) {
+ mParentStack = new LinkedList<FolderInfo>(parentStack);
+ notifyDataSetChanged();
+ }
+
public List<FolderInfo> getParentStack() {
return Collections.unmodifiableList(mParentStack);
}
public FolderType getOpenFolderType() {
return openFolderType;
}
--- a/mobile/android/base/java/org/mozilla/gecko/home/BookmarksPanel.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/BookmarksPanel.java
@@ -1,15 +1,17 @@
/* -*- 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 java.util.ArrayList;
+import java.util.LinkedList;
import java.util.List;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.R;
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.home.BookmarksListAdapter.FolderInfo;
import org.mozilla.gecko.home.BookmarksListAdapter.OnRefreshFolderListener;
@@ -17,16 +19,18 @@ import org.mozilla.gecko.home.BookmarksL
import org.mozilla.gecko.home.HomeContextMenuInfo.RemoveItemType;
import org.mozilla.gecko.home.HomePager.OnUrlOpenListener;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.database.Cursor;
import android.os.Bundle;
+import android.os.Parcelable;
+import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.ImageView;
import android.widget.TextView;
@@ -57,24 +61,39 @@ public class BookmarksPanel extends Home
// Reference to the View to display when there are no results.
private View mEmptyView;
// Callback for cursor loaders.
private CursorLoaderCallbacks mLoaderCallbacks;
@Override
+ public void restoreData(@NonNull Bundle data) {
+ ArrayList<FolderInfo> stack = data.getParcelableArrayList("parentStack");
+ if (stack == null) {
+ return;
+ }
+
+ if (mListAdapter == null) {
+ mSavedParentStack = new LinkedList<FolderInfo>(stack);
+ } else {
+ mListAdapter.restoreData(stack);
+ }
+ }
+
+ @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.home_bookmarks_panel, container, false);
mList = (BookmarksListView) view.findViewById(R.id.bookmarks_list);
mList.setContextMenuInfoFactory(new HomeContextMenuInfo.Factory() {
@Override
- public HomeContextMenuInfo makeInfoForCursor(View view, int position, long id, Cursor cursor) {
+ public HomeContextMenuInfo makeInfoForCursor(View view, int position, long id,
+ Cursor cursor) {
final int type = cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks.TYPE));
if (type == Bookmarks.TYPE_FOLDER) {
// We don't show a context menu for folders
return null;
}
final HomeContextMenuInfo info = new HomeContextMenuInfo(view, position, id);
info.url = cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.URL));
info.title = cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.TITLE));
@@ -146,17 +165,26 @@ public class BookmarksPanel extends Home
// The parent stack is saved just so that the folder state can be
// restored on rotation.
mSavedParentStack = mListAdapter.getParentStack();
}
}
@Override
protected void load() {
- getLoaderManager().initLoader(LOADER_ID_BOOKMARKS_LIST, null, mLoaderCallbacks);
+ final Bundle bundle;
+ if (mSavedParentStack != null && mSavedParentStack.size() > 1) {
+ bundle = new Bundle();
+ bundle.putParcelable(BOOKMARKS_FOLDER_INFO, mSavedParentStack.get(0));
+ bundle.putParcelable(BOOKMARKS_REFRESH_TYPE, RefreshType.CHILD);
+ } else {
+ bundle = null;
+ }
+
+ getLoaderManager().initLoader(LOADER_ID_BOOKMARKS_LIST, bundle, mLoaderCallbacks);
}
private void updateUiFromCursor(Cursor c) {
if ((c == null || c.getCount() == 0) && mEmptyView == null) {
// Set empty page view. We delay this so that the empty view won't flash.
final ViewStub emptyViewStub = (ViewStub) getView().findViewById(R.id.home_empty_view_stub);
mEmptyView = emptyViewStub.inflate();
@@ -227,16 +255,29 @@ public class BookmarksPanel extends Home
return new BookmarksLoader(getActivity(), folderInfo, refreshType);
}
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
BookmarksLoader bl = (BookmarksLoader) loader;
mListAdapter.swapCursor(c, bl.getFolderInfo(), bl.getRefreshType());
+
+ if (mPanelStateChangeListener != null) {
+ final List<FolderInfo> parentStack = mListAdapter.getParentStack();
+ final Bundle bundle = new Bundle();
+
+ // Bundle likes to store ArrayLists or Arrays, but we've got a generic List (which
+ // is actually an unmodifiable wrapper around a LinkedList). We'll need to do a
+ // LinkedList conversion at the other end, when saving we need to use this awkward
+ // syntax to create an Array.
+ bundle.putParcelableArrayList("parentStack", new ArrayList<FolderInfo>(parentStack));
+
+ mPanelStateChangeListener.onStateChanged(bundle);
+ }
updateUiFromCursor(c);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
if (mList != null) {
mListAdapter.swapCursor(null);
}