blob: f695372fdfaa229bccada4b195224df1c36d6a7c [file] [log] [blame]
Owen Lina2fba682011-08-17 22:07:43 +08001/*
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
Owen Lina2fba682011-08-17 22:07:43 +080025import 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;
Owen Lina2fba682011-08-17 22:07:43 +080039 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;
Chih-Chung Chang70a73a72011-09-19 11:09:39 +080046 private Path mPressedPath;
Owen Lina2fba682011-08-17 22:07:43 +080047
48 public interface SelectionListener {
49 public void onSelectionModeChange(int mode);
50 public void onSelectionChange(Path path, boolean selected);
51 }
52
53 public SelectionManager(GalleryContext galleryContext, boolean isAlbumSet) {
Owen Lina2fba682011-08-17 22:07:43 +080054 mDataManager = galleryContext.getDataManager();
Owen Lina2fba682011-08-17 22:07:43 +080055 mClickedSet = new HashSet<Path>();
56 mIsAlbumSet = isAlbumSet;
57 mTotal = -1;
58 }
59
60 // Whether we will leave selection mode automatically once the number of
61 // selected items is down to zero.
62 public void setAutoLeaveSelectionMode(boolean enable) {
63 mAutoLeave = enable;
64 }
65
66 public void setSelectionListener(SelectionListener listener) {
67 mListener = listener;
68 }
69
70 public void selectAll() {
Owen Lina2fba682011-08-17 22:07:43 +080071 mInverseSelection = true;
72 mClickedSet.clear();
Ray Chendf483f42011-09-10 15:29:51 +080073 enterSelectionMode();
Owen Lina2fba682011-08-17 22:07:43 +080074 if (mListener != null) mListener.onSelectionModeChange(SELECT_ALL_MODE);
75 }
76
77 public void deSelectAll() {
78 leaveSelectionMode();
79 mInverseSelection = false;
80 mClickedSet.clear();
81 }
82
83 public boolean inSelectAllMode() {
84 return mInverseSelection;
85 }
86
87 public boolean inSelectionMode() {
88 return mInSelectionMode;
89 }
90
91 public void enterSelectionMode() {
92 if (mInSelectionMode) return;
93
94 mInSelectionMode = true;
Owen Lina2fba682011-08-17 22:07:43 +080095 if (mListener != null) mListener.onSelectionModeChange(ENTER_SELECTION_MODE);
96 }
97
98 public void leaveSelectionMode() {
99 if (!mInSelectionMode) return;
100
101 mInSelectionMode = false;
102 mInverseSelection = false;
103 mClickedSet.clear();
104 if (mListener != null) mListener.onSelectionModeChange(LEAVE_SELECTION_MODE);
105 }
106
107 public boolean isItemSelected(Path itemId) {
108 return mInverseSelection ^ mClickedSet.contains(itemId);
109 }
110
111 public int getSelectedCount() {
112 int count = mClickedSet.size();
113 if (mInverseSelection) {
114 if (mTotal < 0) {
115 mTotal = mIsAlbumSet
116 ? mSourceMediaSet.getSubMediaSetCount()
117 : mSourceMediaSet.getMediaItemCount();
118 }
119 count = mTotal - count;
120 }
121 return count;
122 }
123
124 public void toggle(Path path) {
125 if (mClickedSet.contains(path)) {
126 mClickedSet.remove(path);
127 } else {
128 enterSelectionMode();
129 mClickedSet.add(path);
130 }
131
132 if (mListener != null) mListener.onSelectionChange(path, isItemSelected(path));
133 if (getSelectedCount() == 0 && mAutoLeave) {
134 leaveSelectionMode();
135 }
136 }
137
Chih-Chung Chang70a73a72011-09-19 11:09:39 +0800138 public void setPressedPath(Path path) {
139 mPressedPath = path;
140 }
141
142 public boolean isPressedPath(Path path) {
143 return path != null && path == mPressedPath;
144 }
145
Owen Lina2fba682011-08-17 22:07:43 +0800146 private static void expandMediaSet(ArrayList<Path> items, MediaSet set) {
147 int subCount = set.getSubMediaSetCount();
148 for (int i = 0; i < subCount; i++) {
149 expandMediaSet(items, set.getSubMediaSet(i));
150 }
151 int total = set.getMediaItemCount();
152 int batch = 50;
153 int index = 0;
154
155 while (index < total) {
156 int count = index + batch < total
157 ? batch
158 : total - index;
159 ArrayList<MediaItem> list = set.getMediaItem(index, count);
160 for (MediaItem item : list) {
161 items.add(item.getPath());
162 }
163 index += batch;
164 }
165 }
166
167 public ArrayList<Path> getSelected(boolean expandSet) {
168 ArrayList<Path> selected = new ArrayList<Path>();
169 if (mIsAlbumSet) {
170 if (mInverseSelection) {
171 int max = mSourceMediaSet.getSubMediaSetCount();
172 for (int i = 0; i < max; i++) {
173 MediaSet set = mSourceMediaSet.getSubMediaSet(i);
174 Path id = set.getPath();
175 if (!mClickedSet.contains(id)) {
176 if (expandSet) {
177 expandMediaSet(selected, set);
178 } else {
179 selected.add(id);
180 }
181 }
182 }
183 } else {
184 for (Path id : mClickedSet) {
185 if (expandSet) {
186 expandMediaSet(selected, mDataManager.getMediaSet(id));
187 } else {
188 selected.add(id);
189 }
190 }
191 }
192 } else {
193 if (mInverseSelection) {
194
195 int total = mSourceMediaSet.getMediaItemCount();
196 int index = 0;
197 while (index < total) {
198 int count = Math.min(total - index, MediaSet.MEDIAITEM_BATCH_FETCH_COUNT);
199 ArrayList<MediaItem> list = mSourceMediaSet.getMediaItem(index, count);
200 for (MediaItem item : list) {
201 Path id = item.getPath();
202 if (!mClickedSet.contains(id)) selected.add(id);
203 }
204 index += count;
205 }
206 } else {
207 for (Path id : mClickedSet) {
208 selected.add(id);
209 }
210 }
211 }
212 return selected;
213 }
214
215 public void setSourceMediaSet(MediaSet set) {
216 mSourceMediaSet = set;
217 mTotal = -1;
218 }
Owen Lina2fba682011-08-17 22:07:43 +0800219}