SelectionManager.java revision e99a6ba365b388985bb5f4238002d90c2df28251
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.gallery3d.ui; 18 19import com.android.gallery3d.app.GalleryContext; 20import com.android.gallery3d.data.DataManager; 21import com.android.gallery3d.data.MediaItem; 22import com.android.gallery3d.data.MediaSet; 23import com.android.gallery3d.data.Path; 24 25import java.util.ArrayList; 26import java.util.HashSet; 27import java.util.Set; 28 29public class SelectionManager { 30 @SuppressWarnings("unused") 31 private static final String TAG = "SelectionManager"; 32 33 public static final int ENTER_SELECTION_MODE = 1; 34 public static final int LEAVE_SELECTION_MODE = 2; 35 public static final int SELECT_ALL_MODE = 3; 36 37 private Set<Path> mClickedSet; 38 private MediaSet mSourceMediaSet; 39 private SelectionListener mListener; 40 private DataManager mDataManager; 41 private boolean mInverseSelection; 42 private boolean mIsAlbumSet; 43 private boolean mInSelectionMode; 44 private boolean mAutoLeave = true; 45 private int mTotal; 46 47 public interface SelectionListener { 48 public void onSelectionModeChange(int mode); 49 public void onSelectionChange(Path path, boolean selected); 50 } 51 52 public SelectionManager(GalleryContext galleryContext, boolean isAlbumSet) { 53 mDataManager = galleryContext.getDataManager(); 54 mClickedSet = new HashSet<Path>(); 55 mIsAlbumSet = isAlbumSet; 56 mTotal = -1; 57 } 58 59 // Whether we will leave selection mode automatically once the number of 60 // selected items is down to zero. 61 public void setAutoLeaveSelectionMode(boolean enable) { 62 mAutoLeave = enable; 63 } 64 65 public void setSelectionListener(SelectionListener listener) { 66 mListener = listener; 67 } 68 69 public void selectAll() { 70 mInverseSelection = true; 71 mClickedSet.clear(); 72 enterSelectionMode(); 73 if (mListener != null) mListener.onSelectionModeChange(SELECT_ALL_MODE); 74 } 75 76 public void deSelectAll() { 77 leaveSelectionMode(); 78 mInverseSelection = false; 79 mClickedSet.clear(); 80 } 81 82 public boolean inSelectAllMode() { 83 return mInverseSelection; 84 } 85 86 public boolean inSelectionMode() { 87 return mInSelectionMode; 88 } 89 90 public void enterSelectionMode() { 91 if (mInSelectionMode) return; 92 93 mInSelectionMode = true; 94 if (mListener != null) mListener.onSelectionModeChange(ENTER_SELECTION_MODE); 95 } 96 97 public void leaveSelectionMode() { 98 if (!mInSelectionMode) return; 99 100 mInSelectionMode = false; 101 mInverseSelection = false; 102 mClickedSet.clear(); 103 if (mListener != null) mListener.onSelectionModeChange(LEAVE_SELECTION_MODE); 104 } 105 106 public boolean isItemSelected(Path itemId) { 107 return mInverseSelection ^ mClickedSet.contains(itemId); 108 } 109 110 public int getSelectedCount() { 111 int count = mClickedSet.size(); 112 if (mInverseSelection) { 113 if (mTotal < 0) { 114 mTotal = mIsAlbumSet 115 ? mSourceMediaSet.getSubMediaSetCount() 116 : mSourceMediaSet.getMediaItemCount(); 117 } 118 count = mTotal - count; 119 } 120 return count; 121 } 122 123 public void toggle(Path path) { 124 if (mClickedSet.contains(path)) { 125 mClickedSet.remove(path); 126 } else { 127 enterSelectionMode(); 128 mClickedSet.add(path); 129 } 130 131 if (mListener != null) mListener.onSelectionChange(path, isItemSelected(path)); 132 if (getSelectedCount() == 0 && mAutoLeave) { 133 leaveSelectionMode(); 134 } 135 } 136 137 private static void expandMediaSet(ArrayList<Path> items, MediaSet set) { 138 int subCount = set.getSubMediaSetCount(); 139 for (int i = 0; i < subCount; i++) { 140 expandMediaSet(items, set.getSubMediaSet(i)); 141 } 142 int total = set.getMediaItemCount(); 143 int batch = 50; 144 int index = 0; 145 146 while (index < total) { 147 int count = index + batch < total 148 ? batch 149 : total - index; 150 ArrayList<MediaItem> list = set.getMediaItem(index, count); 151 for (MediaItem item : list) { 152 items.add(item.getPath()); 153 } 154 index += batch; 155 } 156 } 157 158 public ArrayList<Path> getSelected(boolean expandSet) { 159 ArrayList<Path> selected = new ArrayList<Path>(); 160 if (mIsAlbumSet) { 161 if (mInverseSelection) { 162 int max = mSourceMediaSet.getSubMediaSetCount(); 163 for (int i = 0; i < max; i++) { 164 MediaSet set = mSourceMediaSet.getSubMediaSet(i); 165 Path id = set.getPath(); 166 if (!mClickedSet.contains(id)) { 167 if (expandSet) { 168 expandMediaSet(selected, set); 169 } else { 170 selected.add(id); 171 } 172 } 173 } 174 } else { 175 for (Path id : mClickedSet) { 176 if (expandSet) { 177 expandMediaSet(selected, mDataManager.getMediaSet(id)); 178 } else { 179 selected.add(id); 180 } 181 } 182 } 183 } else { 184 if (mInverseSelection) { 185 186 int total = mSourceMediaSet.getMediaItemCount(); 187 int index = 0; 188 while (index < total) { 189 int count = Math.min(total - index, MediaSet.MEDIAITEM_BATCH_FETCH_COUNT); 190 ArrayList<MediaItem> list = mSourceMediaSet.getMediaItem(index, count); 191 for (MediaItem item : list) { 192 Path id = item.getPath(); 193 if (!mClickedSet.contains(id)) selected.add(id); 194 } 195 index += count; 196 } 197 } else { 198 for (Path id : mClickedSet) { 199 selected.add(id); 200 } 201 } 202 } 203 return selected; 204 } 205 206 public void setSourceMediaSet(MediaSet set) { 207 mSourceMediaSet = set; 208 mTotal = -1; 209 } 210} 211