// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.chrome.browser.bookmarks; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import org.chromium.chrome.R; import org.chromium.components.bookmarks.BookmarkId; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * BaseAdapter for BookmarkDrawerListView. It manages items to list there. */ class BookmarkDrawerListViewAdapter extends BaseAdapter { static final int TYPE_FOLDER = 0; static final int TYPE_DIVIDER = -1; static final int TYPE_FOLDERS_TITLE = -2; static final int VIEW_TYPE_ITEM = 0; static final int VIEW_TYPE_DIVIDER = 1; static final int VIEW_TYPE_TITLE = 2; private BookmarkDelegate mDelegate; private List<Item> mTopSection = new ArrayList<Item>(); private List<Item> mBottomSection = new ArrayList<Item>(); // array containing the order of sections private List<?>[] mSections = {mTopSection, mBottomSection}; private BookmarkId mDesktopNodeId = null; private BookmarkId mMobileNodeId = null; private BookmarkId mOthersNodeId = null; private List<BookmarkId> mManagedAndPartnerFolderIds = null; /** * Represents each item in the list. */ static class Item { final int mType; final BookmarkId mFolderId; Item(int itemType) { mType = itemType; mFolderId = null; } Item(BookmarkId folderId) { assert folderId != null; mType = TYPE_FOLDER; mFolderId = folderId; } @Override public int hashCode() { // hash function generated by Eclipse final int prime = 31; int result = 1; result = prime * result + ((mFolderId == null) ? 0 : mFolderId.hashCode()); result = prime * result + mType; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Item other = (Item) obj; if (mFolderId == null) { if (other.mFolderId != null) return false; } else if (!mFolderId.equals(other.mFolderId)) { return false; } if (mType != other.mType) { return false; } return true; } } private void repopulateTopSection() { mTopSection.clear(); if (mDelegate.getModel().isFolderVisible(mMobileNodeId)) { mTopSection.add(new Item(mMobileNodeId)); } if (mDelegate.getModel().isFolderVisible(mDesktopNodeId)) { mTopSection.add(new Item(mDesktopNodeId)); } if (mDelegate.getModel().isFolderVisible(mOthersNodeId)) { mTopSection.add(new Item(mOthersNodeId)); } if (mManagedAndPartnerFolderIds != null) { for (BookmarkId id : mManagedAndPartnerFolderIds) { mTopSection.add(new Item(id)); } } } void updateList() { mDesktopNodeId = mDelegate.getModel().getDesktopFolderId(); mMobileNodeId = mDelegate.getModel().getMobileFolderId(); mOthersNodeId = mDelegate.getModel().getOtherFolderId(); mManagedAndPartnerFolderIds = mDelegate.getModel().getTopLevelFolderIDs(true, false); repopulateTopSection(); setTopFolders(mDelegate.getModel().getTopLevelFolderIDs(false, true)); notifyDataSetChanged(); } /** * Sets folders to show. */ void setTopFolders(List<BookmarkId> folders) { mBottomSection.clear(); if (folders.size() > 0) { // Add a divider and title to the top of the section. mBottomSection.add(new Item(TYPE_DIVIDER)); mBottomSection.add(new Item(TYPE_FOLDERS_TITLE)); } // Add the rest of the items. for (BookmarkId id : folders) { mBottomSection.add(new Item(id)); } } /** * Clear everything so that it doesn't have any entry. */ void clear() { mTopSection.clear(); mBottomSection.clear(); } void setBookmarkUIDelegate(BookmarkDelegate delegate) { mDelegate = delegate; } /** * Get the position in the list of a given item * @param item Item to search for * @return index of the item or -1 if not found */ int positionOfItem(Item item) { int offset = 0; for (List<?> section : mSections) { int index = section.indexOf(item); if (index != -1) { return offset + index; } // If not found in current section, offset the potential result by // the section size. offset += section.size(); } return -1; } /** * Get the position in the list of a given bookmark folder id * @param id Id of bookmark folder * @return index of bookmark folder or -1 if not found */ int positionOfBookmarkId(BookmarkId id) { return positionOfItem(new Item(id)); } /** * Get item position of the given mode. */ int getItemPosition(int state, Object modeDetail) { if (state == BookmarkUIState.STATE_FOLDER) { Set<BookmarkId> topLevelFolderParents = new HashSet<>(); topLevelFolderParents.addAll(mDelegate.getModel().getTopLevelFolderParentIDs()); topLevelFolderParents.add(mDesktopNodeId); topLevelFolderParents.add(mOthersNodeId); topLevelFolderParents.add(mMobileNodeId); // Find top folder id that contains |folder|. BookmarkId topFolderId = (BookmarkId) modeDetail; while (true) { BookmarkId parentId = mDelegate.getModel().getBookmarkById(topFolderId).getParentId(); if (topLevelFolderParents.contains(parentId)) { break; } topFolderId = parentId; } return positionOfBookmarkId(topFolderId); } return -1; } // BaseAdapter implementations. @Override public boolean areAllItemsEnabled() { return false; } @Override public boolean isEnabled(int position) { Item item = (Item) getItem(position); return item.mType != TYPE_DIVIDER && item.mType != TYPE_FOLDERS_TITLE; } @Override public int getItemViewType(int position) { Item item = (Item) getItem(position); if (item.mType == TYPE_DIVIDER) { return VIEW_TYPE_DIVIDER; } else if (item.mType == TYPE_FOLDERS_TITLE) { return VIEW_TYPE_TITLE; } else { return VIEW_TYPE_ITEM; } } @Override public int getViewTypeCount() { return 3; } @Override public int getCount() { int sum = 0; for (List<?> section : mSections) { sum += section.size(); } return sum; } @Override public long getItemId(int position) { return position; } @Override public Object getItem(int position) { if (position < 0) { return null; } for (List<?> section : mSections) { if (position < section.size()) { return section.get(position); } position -= section.size(); } return null; } @Override public View getView(int position, View convertView, ViewGroup parent) { final Item item = (Item) getItem(position); // Inflate view if convertView is null. if (convertView == null) { final int itemViewType = getItemViewType(position); if (itemViewType == VIEW_TYPE_ITEM) { convertView = LayoutInflater.from(parent.getContext()).inflate( R.layout.bookmark_drawer_item, parent, false); } else if (itemViewType == VIEW_TYPE_DIVIDER) { convertView = LayoutInflater.from(parent.getContext()).inflate( R.layout.bookmark_divider, parent, false); } else if (itemViewType == VIEW_TYPE_TITLE) { convertView = LayoutInflater.from(parent.getContext()).inflate( R.layout.bookmark_drawer_title, parent, false); } else { assert false : "Invalid item view type."; } } if (item.mType == TYPE_DIVIDER) return convertView; if (item.mType == TYPE_FOLDERS_TITLE) { String title = convertView.getContext().getResources().getString( R.string.bookmark_drawer_folders); ((TextView) convertView).setText(title); return convertView; } final BookmarkDrawerListItemView listItemView = (BookmarkDrawerListItemView) convertView; String title; int iconDrawableId; switch (item.mType) { case TYPE_FOLDER: title = mDelegate.getModel().getBookmarkById(item.mFolderId).getTitle(); if (mManagedAndPartnerFolderIds != null && mManagedAndPartnerFolderIds.contains(item.mFolderId)) { iconDrawableId = R.drawable.bookmark_managed; } else if (item.mFolderId.equals(mMobileNodeId) || item.mFolderId.equals(mOthersNodeId) || item.mFolderId.equals(mDesktopNodeId)) { iconDrawableId = R.drawable.bookmark_folder; } else { iconDrawableId = 0; } break; default: title = ""; iconDrawableId = 0; assert false; } listItemView.setText(title); listItemView.setIcon(iconDrawableId); return convertView; } }