• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.gallery3d.ui;
18 
19 import com.android.gallery3d.app.GalleryContext;
20 import com.android.gallery3d.data.DataManager;
21 import com.android.gallery3d.data.MediaItem;
22 import com.android.gallery3d.data.MediaSet;
23 import com.android.gallery3d.data.Path;
24 
25 import java.util.ArrayList;
26 import java.util.HashSet;
27 import java.util.Set;
28 
29 public 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 {
onSelectionModeChange(int mode)48         public void onSelectionModeChange(int mode);
onSelectionChange(Path path, boolean selected)49         public void onSelectionChange(Path path, boolean selected);
50     }
51 
SelectionManager(GalleryContext galleryContext, boolean isAlbumSet)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.
setAutoLeaveSelectionMode(boolean enable)61     public void setAutoLeaveSelectionMode(boolean enable) {
62         mAutoLeave = enable;
63     }
64 
setSelectionListener(SelectionListener listener)65     public void setSelectionListener(SelectionListener listener) {
66         mListener = listener;
67     }
68 
selectAll()69     public void selectAll() {
70         mInverseSelection = true;
71         mClickedSet.clear();
72         enterSelectionMode();
73         if (mListener != null) mListener.onSelectionModeChange(SELECT_ALL_MODE);
74     }
75 
deSelectAll()76     public void deSelectAll() {
77         leaveSelectionMode();
78         mInverseSelection = false;
79         mClickedSet.clear();
80     }
81 
inSelectAllMode()82     public boolean inSelectAllMode() {
83         return mInverseSelection;
84     }
85 
inSelectionMode()86     public boolean inSelectionMode() {
87         return mInSelectionMode;
88     }
89 
enterSelectionMode()90     public void enterSelectionMode() {
91         if (mInSelectionMode) return;
92 
93         mInSelectionMode = true;
94         if (mListener != null) mListener.onSelectionModeChange(ENTER_SELECTION_MODE);
95     }
96 
leaveSelectionMode()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 
isItemSelected(Path itemId)106     public boolean isItemSelected(Path itemId) {
107         return mInverseSelection ^ mClickedSet.contains(itemId);
108     }
109 
getTotalCount()110     private int getTotalCount() {
111         if (mSourceMediaSet == null) return -1;
112 
113         if (mTotal < 0) {
114             mTotal = mIsAlbumSet
115                     ? mSourceMediaSet.getSubMediaSetCount()
116                     : mSourceMediaSet.getMediaItemCount();
117         }
118         return mTotal;
119     }
120 
getSelectedCount()121     public int getSelectedCount() {
122         int count = mClickedSet.size();
123         if (mInverseSelection) {
124             count = getTotalCount() - count;
125         }
126         return count;
127     }
128 
toggle(Path path)129     public void toggle(Path path) {
130         if (mClickedSet.contains(path)) {
131             mClickedSet.remove(path);
132         } else {
133             enterSelectionMode();
134             mClickedSet.add(path);
135         }
136 
137         // Convert to inverse selection mode if everything is selected.
138         int count = getSelectedCount();
139         if (count == getTotalCount()) {
140             selectAll();
141         }
142 
143         if (mListener != null) mListener.onSelectionChange(path, isItemSelected(path));
144         if (count == 0 && mAutoLeave) {
145             leaveSelectionMode();
146         }
147     }
148 
expandMediaSet(ArrayList<Path> items, MediaSet set)149     private static void expandMediaSet(ArrayList<Path> items, MediaSet set) {
150         int subCount = set.getSubMediaSetCount();
151         for (int i = 0; i < subCount; i++) {
152             expandMediaSet(items, set.getSubMediaSet(i));
153         }
154         int total = set.getMediaItemCount();
155         int batch = 50;
156         int index = 0;
157 
158         while (index < total) {
159             int count = index + batch < total
160                     ? batch
161                     : total - index;
162             ArrayList<MediaItem> list = set.getMediaItem(index, count);
163             for (MediaItem item : list) {
164                 items.add(item.getPath());
165             }
166             index += batch;
167         }
168     }
169 
170     public ArrayList<Path> getSelected(boolean expandSet) {
171         ArrayList<Path> selected = new ArrayList<Path>();
172         if (mIsAlbumSet) {
173             if (mInverseSelection) {
174                 int total = getTotalCount();
175                 for (int i = 0; i < total; i++) {
176                     MediaSet set = mSourceMediaSet.getSubMediaSet(i);
177                     Path id = set.getPath();
178                     if (!mClickedSet.contains(id)) {
179                         if (expandSet) {
180                             expandMediaSet(selected, set);
181                         } else {
182                             selected.add(id);
183                         }
184                     }
185                 }
186             } else {
187                 for (Path id : mClickedSet) {
188                     if (expandSet) {
189                         expandMediaSet(selected, mDataManager.getMediaSet(id));
190                     } else {
191                         selected.add(id);
192                     }
193                 }
194             }
195         } else {
196             if (mInverseSelection) {
197                 int total = getTotalCount();
198                 int index = 0;
199                 while (index < total) {
200                     int count = Math.min(total - index, MediaSet.MEDIAITEM_BATCH_FETCH_COUNT);
201                     ArrayList<MediaItem> list = mSourceMediaSet.getMediaItem(index, count);
202                     for (MediaItem item : list) {
203                         Path id = item.getPath();
204                         if (!mClickedSet.contains(id)) selected.add(id);
205                     }
206                     index += count;
207                 }
208             } else {
209                 for (Path id : mClickedSet) {
210                     selected.add(id);
211                 }
212             }
213         }
214         return selected;
215     }
216 
217     public void setSourceMediaSet(MediaSet set) {
218         mSourceMediaSet = set;
219         mTotal = -1;
220     }
221 }
222