From 9db9529bdb7490ccd72fbe66f7e9c9d7cdd73899 Mon Sep 17 00:00:00 2001 From: John Reck Date: Mon, 20 Jun 2011 13:00:12 -0700 Subject: Re-enable list view mode Bug: 4645489 Change-Id: Id6eab53a6cb73083781c96a41bfeffec6eae0498 --- res/layout/bookmark_list.xml | 13 +- res/layout/bookmarks.xml | 11 +- .../android/browser/BrowserBookmarksAdapter.java | 4 + src/com/android/browser/BrowserBookmarksPage.java | 94 +--- .../browser/view/BookmarkExpandableGridView.java | 480 ------------------- .../browser/view/BookmarkExpandableView.java | 514 +++++++++++++++++++++ 6 files changed, 539 insertions(+), 577 deletions(-) delete mode 100644 src/com/android/browser/view/BookmarkExpandableGridView.java create mode 100644 src/com/android/browser/view/BookmarkExpandableView.java diff --git a/res/layout/bookmark_list.xml b/res/layout/bookmark_list.xml index 7413ca833..4425a26c3 100644 --- a/res/layout/bookmark_list.xml +++ b/res/layout/bookmark_list.xml @@ -14,29 +14,30 @@ limitations under the License. --> - + android:paddingLeft="16dip" + android:background="@drawable/bookmark_thumb_selector"> - + diff --git a/res/layout/bookmarks.xml b/res/layout/bookmarks.xml index 4a13c6f79..e02e2ff91 100644 --- a/res/layout/bookmarks.xml +++ b/res/layout/bookmarks.xml @@ -31,7 +31,7 @@ - - , IconListener, - BreadCrumbView.Controller, OnMenuItemClickListener, OnChildClickListener { + LoaderManager.LoaderCallbacks, BreadCrumbView.Controller, + OnMenuItemClickListener, OnChildClickListener { public static class ExtraDragState { public int childPosition; @@ -94,14 +92,13 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte static final String ACCOUNT_TYPE = "account_type"; static final String ACCOUNT_NAME = "account_name"; - static final int VIEW_THUMBNAILS = 1; - static final int VIEW_LIST = 2; + public static final int VIEW_THUMBNAILS = 1; + public static final int VIEW_LIST = 2; static final String PREF_SELECTED_VIEW = "bookmarks_view"; BookmarksPageCallbacks mCallbacks; View mRoot; - BookmarkExpandableGridView mGrid; - ListView mList; + BookmarkExpandableView mGrid; boolean mDisableNewWindow; boolean mEnableContextMenu = true; View mEmptyView; @@ -167,7 +164,6 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte @Override public void onLoaderReset(Loader loader) { - // TODO: Figure out what to do here (if anything?) } @Override @@ -326,8 +322,6 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(getActivity()); mCurrentView = prefs.getInt(PREF_SELECTED_VIEW, getDefaultView()); - // TODO: Support list view - mCurrentView = VIEW_THUMBNAILS; Bundle args = getArguments(); mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false); @@ -341,12 +335,10 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte mRoot = inflater.inflate(R.layout.bookmarks, container, false); mEmptyView = mRoot.findViewById(android.R.id.empty); - mGrid = (BookmarkExpandableGridView) mRoot.findViewById(R.id.grid); + mGrid = (BookmarkExpandableView) mRoot.findViewById(R.id.grid); mGrid.setOnChildClickListener(this); mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail); mGrid.setBreadcrumbController(this); - mList = (ListView) mRoot.findViewById(R.id.list); - // TODO: mList.setOnItemClickListener(this); setEnableContextMenu(mEnableContextMenu); mDragHandler = new BookmarkDragHandler(getActivity(), mDragController, mGrid.getDragAdapter()); @@ -355,9 +347,6 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte LoaderManager lm = getLoaderManager(); lm.restartLoader(LOADER_ACCOUNTS, null, this); - // Add our own listener in case there are favicons that have yet to be loaded. - CombinedBookmarkHistoryView.getIconListenerSet().addListener(this); - return mRoot; } @@ -378,34 +367,14 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte lm.destroyLoader(id); } mBookmarkAdapters.clear(); - - CombinedBookmarkHistoryView.getIconListenerSet().removeListener(this); - } - - @Override - public void onReceivedIcon(String url, Bitmap icon) { - // A new favicon has been loaded, so let anything attached to the adapter know about it - // so new icons will be loaded. - // TODO: Notify all of data set changed - // TODO: Wait, is this even needed? Won't this trigger a DB change anyway? } private BrowserBookmarksAdapter getChildAdapter(int groupPosition) { - if (mCurrentView == VIEW_THUMBNAILS) { - return mGrid.getChildAdapter(groupPosition); - } else { - // TODO: Support expandable list - return null; - } + return mGrid.getChildAdapter(groupPosition); } private BreadCrumbView getBreadCrumbs(int groupPosition) { - if (mCurrentView == VIEW_THUMBNAILS) { - return mGrid.getBreadCrumbs(groupPosition); - } else { - // TODO: Support expandable list - return null; - } + return mGrid.getBreadCrumbs(groupPosition); } @Override @@ -566,11 +535,10 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte } void selectView(int view) { - // TODO: Support list view - view = mCurrentView; if (view == mCurrentView) { return; } + mCurrentView = view; SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); Editor edit = prefs.edit(); edit.putInt(PREF_SELECTED_VIEW, mCurrentView); @@ -578,31 +546,7 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte if (mEmptyView.getVisibility() == View.VISIBLE) { return; } - setupBookmarkView(); - } - - private void setupBookmarkView() { - // TODO: Support list view -// mAdapter.selectView(mCurrentView); -// switch (mCurrentView) { -// case VIEW_THUMBNAILS: -// mList.setAdapter(null); -// SharedPreferences prefs = PreferenceManager -// .getDefaultSharedPreferences(getActivity()); -// String accountName = prefs.getString(PREF_ACCOUNT_NAME, null); -// mGrid.addAccount(accountName, mAdapter); -// mGrid.setVisibility(View.VISIBLE); -// mList.setVisibility(View.GONE); -// break; -// case VIEW_LIST: -// mGrid.clearAccounts(); -// if (mList.getAdapter() != mAdapter) { -// mList.setAdapter(mAdapter); -// } -// mGrid.setVisibility(View.GONE); -// mList.setVisibility(View.VISIBLE); -// break; -// } + mGrid.selectView(mCurrentView); } /** @@ -662,14 +606,6 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte mGrid.setLongClickable(false); } } - if (mList != null) { - if (mEnableContextMenu) { - registerForContextMenu(mList); - } else { - unregisterForContextMenu(mList); - mList.setLongClickable(false); - } - } } private BookmarkDragController mDragController = new BookmarkDragController() { @@ -702,11 +638,7 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte @Override public void actionItemClicked(View v, BookmarkDragState state) { if (v.getId() == R.id.info) { - if (mCurrentView == VIEW_THUMBNAILS) { - mGrid.showContextMenuForState(state); - } else { - // TODO: Support expandable list - } + mGrid.showContextMenuForState(state); } else { ExtraDragState extraState = (ExtraDragState) state.extraState; handleContextItem(v.getId(), extraState.groupPosition, diff --git a/src/com/android/browser/view/BookmarkExpandableGridView.java b/src/com/android/browser/view/BookmarkExpandableGridView.java deleted file mode 100644 index c8811d1c1..000000000 --- a/src/com/android/browser/view/BookmarkExpandableGridView.java +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.browser.view; - -import android.content.Context; -import android.database.Cursor; -import android.database.DataSetObserver; -import android.provider.BrowserContract; -import android.util.AttributeSet; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseExpandableListAdapter; -import android.widget.ExpandableListAdapter; -import android.widget.ExpandableListView; -import android.widget.FrameLayout; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.android.browser.BookmarkDragHandler; -import com.android.browser.BookmarkDragHandler.BookmarkDragAdapter; -import com.android.browser.BookmarkDragHandler.BookmarkDragState; -import com.android.browser.BreadCrumbView; -import com.android.browser.BrowserBookmarksAdapter; -import com.android.browser.BrowserBookmarksPage.ExtraDragState; -import com.android.browser.R; -import com.android.internal.view.menu.MenuBuilder; - -import java.util.ArrayList; -import java.util.HashMap; - -public class BookmarkExpandableGridView extends ExpandableListView - implements BreadCrumbView.Controller { - - private BookmarkAccountAdapter mAdapter; - private int mColumnWidth; - private Context mContext; - private OnChildClickListener mOnChildClickListener; - private ContextMenuInfo mContextMenuInfo = null; - private OnCreateContextMenuListener mOnCreateContextMenuListener; - private boolean mLongClickable; - private BreadCrumbView.Controller mBreadcrumbController; - private BookmarkDragHandler mDragHandler; - private int mMaxColumnCount; - - public BookmarkExpandableGridView(Context context) { - super(context); - init(context); - } - - public BookmarkExpandableGridView(Context context, AttributeSet attrs) { - super(context, attrs); - init(context); - } - - public BookmarkExpandableGridView( - Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(context); - } - - void init(Context context) { - mContext = context; - setItemsCanFocus(true); - setLongClickable(false); - mMaxColumnCount = mContext.getResources() - .getInteger(R.integer.max_bookmark_columns); - mAdapter = new BookmarkAccountAdapter(mContext); - super.setAdapter(mAdapter); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int width = MeasureSpec.getSize(widthMeasureSpec); - int widthMode = MeasureSpec.getMode(widthMeasureSpec); - if (width > 0) { - mAdapter.measureChildren(width); - if (mAdapter.mRowPadding > 0) { - width -= mAdapter.mRowPadding * 2; - } - widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, widthMode); - } - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - if (width != getMeasuredWidth()) { - mAdapter.measureChildren(getMeasuredWidth()); - } - } - - @Override - public void setAdapter(ExpandableListAdapter adapter) { - throw new RuntimeException("Not supported"); - } - - public void setColumnWidthFromLayout(int layout) { - LayoutInflater infalter = LayoutInflater.from(mContext); - View v = infalter.inflate(layout, this, false); - v.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); - mColumnWidth = v.getMeasuredWidth(); - } - - public void clearAccounts() { - mAdapter.clear(); - } - - public void addAccount(String accountName, BrowserBookmarksAdapter adapter) { - // First, check if it already exists - int indexOf = mAdapter.mGroups.indexOf(accountName); - if (indexOf >= 0) { - BrowserBookmarksAdapter existing = mAdapter.mChildren.get(indexOf); - if (existing != adapter) { - existing.unregisterDataSetObserver(mAdapter.mObserver); - // Replace the existing one - mAdapter.mChildren.remove(indexOf); - mAdapter.mChildren.add(indexOf, adapter); - adapter.registerDataSetObserver(mAdapter.mObserver); - } - } else { - mAdapter.mGroups.add(accountName); - mAdapter.mChildren.add(adapter); - adapter.registerDataSetObserver(mAdapter.mObserver); - } - mAdapter.notifyDataSetChanged(); - expandGroup(mAdapter.getGroupCount() - 1); - } - - @Override - public void setOnChildClickListener(OnChildClickListener onChildClickListener) { - mOnChildClickListener = onChildClickListener; - } - - @Override - public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) { - mOnCreateContextMenuListener = l; - if (!mLongClickable) { - mLongClickable = true; - if (mAdapter != null) { - mAdapter.notifyDataSetChanged(); - } - } - } - - @Override - public void createContextMenu(ContextMenu menu) { - // The below is copied from View - we want to bypass the override - // in AbsListView - - ContextMenuInfo menuInfo = getContextMenuInfo(); - - // Sets the current menu info so all items added to menu will have - // my extra info set. - ((MenuBuilder)menu).setCurrentMenuInfo(menuInfo); - - onCreateContextMenu(menu); - if (mOnCreateContextMenuListener != null) { - mOnCreateContextMenuListener.onCreateContextMenu(menu, this, menuInfo); - } - - // Clear the extra information so subsequent items that aren't mine don't - // have my extra info. - ((MenuBuilder)menu).setCurrentMenuInfo(null); - - if (mParent != null) { - mParent.createContextMenu(menu); - } - } - - @Override - public boolean showContextMenuForChild(View originalView) { - int groupPosition = (Integer) originalView.getTag(R.id.group_position); - int childPosition = (Integer) originalView.getTag(R.id.child_position); - - mContextMenuInfo = new BookmarkContextMenuInfo(childPosition, - groupPosition); - if (getParent() != null) { - getParent().showContextMenuForChild(this); - } - - return true; - } - - @Override - public void onTop(BreadCrumbView view, int level, Object data) { - if (mBreadcrumbController != null) { - mBreadcrumbController.onTop(view, level, data); - } - } - - public void setBreadcrumbController(BreadCrumbView.Controller controller) { - mBreadcrumbController = controller; - } - - @Override - protected ContextMenuInfo getContextMenuInfo() { - return mContextMenuInfo; - } - - public BrowserBookmarksAdapter getChildAdapter(int groupPosition) { - return mAdapter.mChildren.get(groupPosition); - } - - public BookmarkDragAdapter getDragAdapter() { - return mDragAdapter; - } - - public void showContextMenuForState(BookmarkDragState state) { - ExtraDragState extraState = (ExtraDragState) state.extraState; - mContextMenuInfo = new BookmarkContextMenuInfo( - extraState.childPosition, - extraState.groupPosition); - if (getParent() != null) { - getParent().showContextMenuForChild(BookmarkExpandableGridView.this); - } - } - - private BookmarkDragAdapter mDragAdapter = new BookmarkDragAdapter() { - - @Override - public void setBookmarkDragHandler(BookmarkDragHandler handler) { - mDragHandler = handler; - } - - @Override - public Cursor getItemForView(View v) { - int groupPosition = (Integer) v.getTag(R.id.group_position); - int childPosition = (Integer) v.getTag(R.id.child_position); - return getChildAdapter(groupPosition).getItem(childPosition); - } - - }; - - private OnClickListener mChildClickListener = new OnClickListener() { - - @Override - public void onClick(View v) { - int groupPosition = (Integer) v.getTag(R.id.group_position); - int childPosition = (Integer) v.getTag(R.id.child_position); - long id = (Long) v.getTag(R.id.child_id); - if (mOnChildClickListener != null) { - mOnChildClickListener.onChildClick(BookmarkExpandableGridView.this, - v, groupPosition, childPosition, id); - } - } - }; - - private OnClickListener mGroupOnClickListener = new OnClickListener() { - - @Override - public void onClick(View v) { - int groupPosition = (Integer) v.getTag(R.id.group_position); - if (isGroupExpanded(groupPosition)) { - collapseGroup(groupPosition); - } else { - expandGroup(groupPosition, true); - } - } - }; - - private OnLongClickListener mChildOnLongClickListener = new OnLongClickListener() { - - @Override - public boolean onLongClick(View v) { - ExtraDragState state = new ExtraDragState(); - state.groupPosition = (Integer) v.getTag(R.id.group_position); - state.childPosition = (Integer) v.getTag(R.id.child_position); - long id = (Long) v.getTag(R.id.child_id); - Cursor c = getChildAdapter(state.groupPosition) - .getItem(state.childPosition); - return mDragHandler.startDrag(v, c, id, state); - } - }; - - public BreadCrumbView getBreadCrumbs(int groupPosition) { - return mAdapter.getBreadCrumbView(groupPosition); - } - - class BookmarkAccountAdapter extends BaseExpandableListAdapter { - ArrayList mChildren; - ArrayList mGroups; - HashMap mBreadcrumbs = - new HashMap(); - LayoutInflater mInflater; - int mRowCount = 1; // assume at least 1 child fits in a row - int mLastViewWidth = -1; - int mRowPadding = -1; - DataSetObserver mObserver = new DataSetObserver() { - @Override - public void onChanged() { - notifyDataSetChanged(); - } - - @Override - public void onInvalidated() { - notifyDataSetChanged(); - } - }; - - public BookmarkAccountAdapter(Context context) { - mContext = context; - mInflater = LayoutInflater.from(mContext); - mChildren = new ArrayList(); - mGroups = new ArrayList(); - } - - public void clear() { - mGroups.clear(); - mChildren.clear(); - notifyDataSetChanged(); - } - - @Override - public Object getChild(int groupPosition, int childPosition) { - return mChildren.get(groupPosition).getItem(childPosition); - } - - @Override - public long getChildId(int groupPosition, int childPosition) { - return childPosition; - } - - @Override - public View getChildView(int groupPosition, int childPosition, - boolean isLastChild, View convertView, ViewGroup parent) { - if (convertView == null) { - convertView = mInflater.inflate(R.layout.bookmark_grid_row, parent, false); - } - LinearLayout row = (LinearLayout) convertView; - if (row.getChildCount() > mRowCount) { - row.removeViews(mRowCount, row.getChildCount() - mRowCount); - } - for (int i = 0; i < mRowCount; i++) { - View cv = null; - if (row.getChildCount() > i) { - cv = row.getChildAt(i); - } - int realChildPosition = (childPosition * mRowCount) + i; - BrowserBookmarksAdapter childAdapter = mChildren.get(groupPosition); - if (realChildPosition < childAdapter.getCount()) { - View v = childAdapter.getView(realChildPosition, cv, row); - v.setTag(R.id.group_position, groupPosition); - v.setTag(R.id.child_position, realChildPosition); - v.setTag(R.id.child_id, childAdapter.getItemId(realChildPosition)); - v.setOnClickListener(mChildClickListener); - v.setLongClickable(mLongClickable); - if (mDragHandler != null) { - v.setOnLongClickListener(mChildOnLongClickListener); - mDragHandler.registerBookmarkDragHandler(v); - } - if (cv == null) { - row.addView(v); - } else if (cv != v) { - row.removeViewAt(i); - row.addView(v, i); - } else { - cv.setVisibility(View.VISIBLE); - } - } else if (cv != null) { - cv.setVisibility(View.GONE); - } - } - return row; - } - - @Override - public int getChildrenCount(int groupPosition) { - return (int) Math.ceil( - mChildren.get(groupPosition).getCount() / (float)mRowCount); - } - - @Override - public Object getGroup(int groupPosition) { - return mChildren.get(groupPosition); - } - - @Override - public int getGroupCount() { - return mGroups.size(); - } - - public void measureChildren(int viewWidth) { - if (mLastViewWidth == viewWidth) return; - - int rowCount = viewWidth / mColumnWidth; - if (mMaxColumnCount > 0) { - rowCount = Math.min(rowCount, mMaxColumnCount); - } - int rowPadding = (viewWidth - (rowCount * mColumnWidth)) / 2; - boolean notify = rowCount != mRowCount || rowPadding != mRowPadding; - mRowCount = rowCount; - mRowPadding = rowPadding; - mLastViewWidth = viewWidth; - if (notify) { - notifyDataSetChanged(); - } - } - - @Override - public long getGroupId(int groupPosition) { - return groupPosition; - } - - @Override - public View getGroupView(int groupPosition, boolean isExpanded, - View view, ViewGroup parent) { - if (view == null) { - view = mInflater.inflate(R.layout.bookmark_group_view, parent, false); - view.setOnClickListener(mGroupOnClickListener); - } - view.setTag(R.id.group_position, groupPosition); - FrameLayout crumbHolder = (FrameLayout) view.findViewById(R.id.crumb_holder); - crumbHolder.removeAllViews(); - BreadCrumbView crumbs = getBreadCrumbView(groupPosition); - if (crumbs.getParent() != null) { - ((ViewGroup)crumbs.getParent()).removeView(crumbs); - } - crumbHolder.addView(crumbs); - TextView name = (TextView) view.findViewById(R.id.group_name); - String groupName = mGroups.get(groupPosition); - if (groupName == null) { - groupName = mContext.getString(R.string.local_bookmarks); - } - name.setText(groupName); - return view; - } - - public BreadCrumbView getBreadCrumbView(int groupPosition) { - BreadCrumbView crumbs = mBreadcrumbs.get(groupPosition); - if (crumbs == null) { - crumbs = (BreadCrumbView) - mInflater.inflate(R.layout.bookmarks_header, null); - crumbs.setController(BookmarkExpandableGridView.this); - crumbs.setUseBackButton(true); - crumbs.setMaxVisible(2); - String bookmarks = mContext.getString(R.string.bookmarks); - crumbs.pushView(bookmarks, false, - BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER); - crumbs.setTag(R.id.group_position, groupPosition); - mBreadcrumbs.put(groupPosition, crumbs); - } - return crumbs; - } - - @Override - public boolean hasStableIds() { - return false; - } - - @Override - public boolean isChildSelectable(int groupPosition, int childPosition) { - return true; - } - } - - public static class BookmarkContextMenuInfo implements ContextMenuInfo { - - private BookmarkContextMenuInfo(int childPosition, int groupPosition) { - this.childPosition = childPosition; - this.groupPosition = groupPosition; - } - - public int childPosition; - public int groupPosition; - } - -} diff --git a/src/com/android/browser/view/BookmarkExpandableView.java b/src/com/android/browser/view/BookmarkExpandableView.java new file mode 100644 index 000000000..6f5fdaa99 --- /dev/null +++ b/src/com/android/browser/view/BookmarkExpandableView.java @@ -0,0 +1,514 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.browser.view; + +import android.content.Context; +import android.database.Cursor; +import android.database.DataSetObserver; +import android.provider.BrowserContract; +import android.util.AttributeSet; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseExpandableListAdapter; +import android.widget.ExpandableListAdapter; +import android.widget.ExpandableListView; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.android.browser.BookmarkDragHandler; +import com.android.browser.BookmarkDragHandler.BookmarkDragAdapter; +import com.android.browser.BookmarkDragHandler.BookmarkDragState; +import com.android.browser.BreadCrumbView; +import com.android.browser.BrowserBookmarksAdapter; +import com.android.browser.BrowserBookmarksPage; +import com.android.browser.BrowserBookmarksPage.ExtraDragState; +import com.android.browser.R; +import com.android.internal.view.menu.MenuBuilder; + +import java.util.ArrayList; +import java.util.HashMap; + +public class BookmarkExpandableView extends ExpandableListView + implements BreadCrumbView.Controller { + + private BookmarkAccountAdapter mAdapter; + private int mColumnWidth; + private Context mContext; + private OnChildClickListener mOnChildClickListener; + private ContextMenuInfo mContextMenuInfo = null; + private OnCreateContextMenuListener mOnCreateContextMenuListener; + private boolean mLongClickable; + private BreadCrumbView.Controller mBreadcrumbController; + private BookmarkDragHandler mDragHandler; + private int mMaxColumnCount; + private int mCurrentView = -1; + + public BookmarkExpandableView(Context context) { + super(context); + init(context); + } + + public BookmarkExpandableView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public BookmarkExpandableView( + Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context); + } + + void init(Context context) { + mContext = context; + setItemsCanFocus(true); + setLongClickable(false); + mMaxColumnCount = mContext.getResources() + .getInteger(R.integer.max_bookmark_columns); + mAdapter = new BookmarkAccountAdapter(mContext); + super.setAdapter(mAdapter); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int width = MeasureSpec.getSize(widthMeasureSpec); + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + if (width > 0) { + mAdapter.measureChildren(width); + if (mAdapter.mRowPadding > 0) { + width -= mAdapter.mRowPadding * 2; + } + widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, widthMode); + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + if (width != getMeasuredWidth()) { + mAdapter.measureChildren(getMeasuredWidth()); + } + } + + @Override + public void setAdapter(ExpandableListAdapter adapter) { + throw new RuntimeException("Not supported"); + } + + public void setColumnWidthFromLayout(int layout) { + LayoutInflater infalter = LayoutInflater.from(mContext); + View v = infalter.inflate(layout, this, false); + v.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); + mColumnWidth = v.getMeasuredWidth(); + } + + public void clearAccounts() { + mAdapter.clear(); + } + + public void addAccount(String accountName, BrowserBookmarksAdapter adapter) { + // First, check if it already exists + int indexOf = mAdapter.mGroups.indexOf(accountName); + if (indexOf >= 0) { + BrowserBookmarksAdapter existing = mAdapter.mChildren.get(indexOf); + if (existing != adapter) { + existing.unregisterDataSetObserver(mAdapter.mObserver); + // Replace the existing one + mAdapter.mChildren.remove(indexOf); + mAdapter.mChildren.add(indexOf, adapter); + adapter.registerDataSetObserver(mAdapter.mObserver); + } + } else { + if (mCurrentView >= 0) { + adapter.selectView(mCurrentView); + } + mAdapter.mGroups.add(accountName); + mAdapter.mChildren.add(adapter); + adapter.registerDataSetObserver(mAdapter.mObserver); + } + mAdapter.notifyDataSetChanged(); + expandGroup(mAdapter.getGroupCount() - 1); + } + + @Override + public void setOnChildClickListener(OnChildClickListener onChildClickListener) { + mOnChildClickListener = onChildClickListener; + } + + @Override + public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) { + mOnCreateContextMenuListener = l; + if (!mLongClickable) { + mLongClickable = true; + if (mAdapter != null) { + mAdapter.notifyDataSetChanged(); + } + } + } + + @Override + public void createContextMenu(ContextMenu menu) { + // The below is copied from View - we want to bypass the override + // in AbsListView + + ContextMenuInfo menuInfo = getContextMenuInfo(); + + // Sets the current menu info so all items added to menu will have + // my extra info set. + ((MenuBuilder)menu).setCurrentMenuInfo(menuInfo); + + onCreateContextMenu(menu); + if (mOnCreateContextMenuListener != null) { + mOnCreateContextMenuListener.onCreateContextMenu(menu, this, menuInfo); + } + + // Clear the extra information so subsequent items that aren't mine don't + // have my extra info. + ((MenuBuilder)menu).setCurrentMenuInfo(null); + + if (mParent != null) { + mParent.createContextMenu(menu); + } + } + + @Override + public boolean showContextMenuForChild(View originalView) { + int groupPosition = (Integer) originalView.getTag(R.id.group_position); + int childPosition = (Integer) originalView.getTag(R.id.child_position); + + mContextMenuInfo = new BookmarkContextMenuInfo(childPosition, + groupPosition); + if (getParent() != null) { + getParent().showContextMenuForChild(this); + } + + return true; + } + + @Override + public void onTop(BreadCrumbView view, int level, Object data) { + if (mBreadcrumbController != null) { + mBreadcrumbController.onTop(view, level, data); + } + } + + public void setBreadcrumbController(BreadCrumbView.Controller controller) { + mBreadcrumbController = controller; + } + + @Override + protected ContextMenuInfo getContextMenuInfo() { + return mContextMenuInfo; + } + + public BrowserBookmarksAdapter getChildAdapter(int groupPosition) { + return mAdapter.mChildren.get(groupPosition); + } + + public BookmarkDragAdapter getDragAdapter() { + return mDragAdapter; + } + + public void showContextMenuForState(BookmarkDragState state) { + ExtraDragState extraState = (ExtraDragState) state.extraState; + mContextMenuInfo = new BookmarkContextMenuInfo( + extraState.childPosition, + extraState.groupPosition); + if (getParent() != null) { + getParent().showContextMenuForChild(BookmarkExpandableView.this); + } + } + + private BookmarkDragAdapter mDragAdapter = new BookmarkDragAdapter() { + + @Override + public void setBookmarkDragHandler(BookmarkDragHandler handler) { + mDragHandler = handler; + } + + @Override + public Cursor getItemForView(View v) { + int groupPosition = (Integer) v.getTag(R.id.group_position); + int childPosition = (Integer) v.getTag(R.id.child_position); + return getChildAdapter(groupPosition).getItem(childPosition); + } + + }; + + private OnClickListener mChildClickListener = new OnClickListener() { + + @Override + public void onClick(View v) { + int groupPosition = (Integer) v.getTag(R.id.group_position); + int childPosition = (Integer) v.getTag(R.id.child_position); + long id = (Long) v.getTag(R.id.child_id); + if (mOnChildClickListener != null) { + mOnChildClickListener.onChildClick(BookmarkExpandableView.this, + v, groupPosition, childPosition, id); + } + } + }; + + private OnClickListener mGroupOnClickListener = new OnClickListener() { + + @Override + public void onClick(View v) { + int groupPosition = (Integer) v.getTag(R.id.group_position); + if (isGroupExpanded(groupPosition)) { + collapseGroup(groupPosition); + } else { + expandGroup(groupPosition, true); + } + } + }; + + private OnLongClickListener mChildOnLongClickListener = new OnLongClickListener() { + + @Override + public boolean onLongClick(View v) { + ExtraDragState state = new ExtraDragState(); + state.groupPosition = (Integer) v.getTag(R.id.group_position); + state.childPosition = (Integer) v.getTag(R.id.child_position); + long id = (Long) v.getTag(R.id.child_id); + Cursor c = getChildAdapter(state.groupPosition) + .getItem(state.childPosition); + return mDragHandler.startDrag(v, c, id, state); + } + }; + + public BreadCrumbView getBreadCrumbs(int groupPosition) { + return mAdapter.getBreadCrumbView(groupPosition); + } + + public void selectView(int view) { + mCurrentView = view; + for (BrowserBookmarksAdapter adapter : mAdapter.mChildren) { + adapter.selectView(mCurrentView); + } + mAdapter.notifyDataSetChanged(); + } + + class BookmarkAccountAdapter extends BaseExpandableListAdapter { + ArrayList mChildren; + ArrayList mGroups; + HashMap mBreadcrumbs = + new HashMap(); + LayoutInflater mInflater; + int mRowCount = 1; // assume at least 1 child fits in a row + int mLastViewWidth = -1; + int mRowPadding = -1; + DataSetObserver mObserver = new DataSetObserver() { + @Override + public void onChanged() { + notifyDataSetChanged(); + } + + @Override + public void onInvalidated() { + notifyDataSetChanged(); + } + }; + + public BookmarkAccountAdapter(Context context) { + mContext = context; + mInflater = LayoutInflater.from(mContext); + mChildren = new ArrayList(); + mGroups = new ArrayList(); + } + + public void clear() { + mGroups.clear(); + mChildren.clear(); + notifyDataSetChanged(); + } + + @Override + public Object getChild(int groupPosition, int childPosition) { + return mChildren.get(groupPosition).getItem(childPosition); + } + + @Override + public long getChildId(int groupPosition, int childPosition) { + return childPosition; + } + + @Override + public View getChildView(int groupPosition, int childPosition, + boolean isLastChild, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = mInflater.inflate(R.layout.bookmark_grid_row, parent, false); + } + BrowserBookmarksAdapter childAdapter = mChildren.get(groupPosition); + int rowCount = mRowCount; + if (childAdapter.getViewMode() == BrowserBookmarksPage.VIEW_LIST) { + rowCount = 1; + } + LinearLayout row = (LinearLayout) convertView; + if (row.getChildCount() > rowCount) { + row.removeViews(rowCount, row.getChildCount() - rowCount); + } + for (int i = 0; i < rowCount; i++) { + View cv = null; + if (row.getChildCount() > i) { + cv = row.getChildAt(i); + } + int realChildPosition = (childPosition * rowCount) + i; + if (realChildPosition < childAdapter.getCount()) { + View v = childAdapter.getView(realChildPosition, cv, row); + v.setTag(R.id.group_position, groupPosition); + v.setTag(R.id.child_position, realChildPosition); + v.setTag(R.id.child_id, childAdapter.getItemId(realChildPosition)); + v.setOnClickListener(mChildClickListener); + v.setLongClickable(mLongClickable); + if (mDragHandler != null) { + v.setOnLongClickListener(mChildOnLongClickListener); + mDragHandler.registerBookmarkDragHandler(v); + } + if (cv == null) { + row.addView(v); + } else if (cv != v) { + row.removeViewAt(i); + row.addView(v, i); + } else { + cv.setVisibility(View.VISIBLE); + } + } else if (cv != null) { + cv.setVisibility(View.GONE); + } + } + return row; + } + + @Override + public int getChildrenCount(int groupPosition) { + BrowserBookmarksAdapter adapter = mChildren.get(groupPosition); + if (adapter.getViewMode() == BrowserBookmarksPage.VIEW_LIST) { + return adapter.getCount(); + } + return (int) Math.ceil(adapter.getCount() / (float)mRowCount); + } + + @Override + public Object getGroup(int groupPosition) { + return mChildren.get(groupPosition); + } + + @Override + public int getGroupCount() { + return mGroups.size(); + } + + public void measureChildren(int viewWidth) { + if (mLastViewWidth == viewWidth) return; + + int rowCount = viewWidth / mColumnWidth; + if (mMaxColumnCount > 0) { + rowCount = Math.min(rowCount, mMaxColumnCount); + } + int rowPadding = (viewWidth - (rowCount * mColumnWidth)) / 2; + boolean notify = rowCount != mRowCount || rowPadding != mRowPadding; + mRowCount = rowCount; + mRowPadding = rowPadding; + mLastViewWidth = viewWidth; + if (notify) { + notifyDataSetChanged(); + } + } + + @Override + public long getGroupId(int groupPosition) { + return groupPosition; + } + + @Override + public View getGroupView(int groupPosition, boolean isExpanded, + View view, ViewGroup parent) { + if (view == null) { + view = mInflater.inflate(R.layout.bookmark_group_view, parent, false); + view.setOnClickListener(mGroupOnClickListener); + } + view.setTag(R.id.group_position, groupPosition); + FrameLayout crumbHolder = (FrameLayout) view.findViewById(R.id.crumb_holder); + crumbHolder.removeAllViews(); + BreadCrumbView crumbs = getBreadCrumbView(groupPosition); + if (crumbs.getParent() != null) { + ((ViewGroup)crumbs.getParent()).removeView(crumbs); + } + crumbHolder.addView(crumbs); + TextView name = (TextView) view.findViewById(R.id.group_name); + String groupName = mGroups.get(groupPosition); + if (groupName == null) { + groupName = mContext.getString(R.string.local_bookmarks); + } + name.setText(groupName); + return view; + } + + public BreadCrumbView getBreadCrumbView(int groupPosition) { + BreadCrumbView crumbs = mBreadcrumbs.get(groupPosition); + if (crumbs == null) { + crumbs = (BreadCrumbView) + mInflater.inflate(R.layout.bookmarks_header, null); + crumbs.setController(BookmarkExpandableView.this); + crumbs.setUseBackButton(true); + crumbs.setMaxVisible(2); + String bookmarks = mContext.getString(R.string.bookmarks); + crumbs.pushView(bookmarks, false, + BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER); + crumbs.setTag(R.id.group_position, groupPosition); + mBreadcrumbs.put(groupPosition, crumbs); + } + return crumbs; + } + + @Override + public boolean hasStableIds() { + return false; + } + + @Override + public boolean isChildSelectable(int groupPosition, int childPosition) { + return true; + } + + @Override + public int getChildTypeCount() { + return 2; + } + + @Override + public int getChildType(int groupPosition, int childPosition) { + BrowserBookmarksAdapter adapter = mChildren.get(groupPosition); + if (adapter.getViewMode() == BrowserBookmarksPage.VIEW_LIST) { + return 1; + } + return 0; + } + } + + public static class BookmarkContextMenuInfo implements ContextMenuInfo { + + private BookmarkContextMenuInfo(int childPosition, int groupPosition) { + this.childPosition = childPosition; + this.groupPosition = groupPosition; + } + + public int childPosition; + public int groupPosition; + } + +} -- cgit v1.2.3