summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/ui/SelectionManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/ui/SelectionManager.java')
-rw-r--r--src/com/android/gallery3d/ui/SelectionManager.java251
1 files changed, 251 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/ui/SelectionManager.java b/src/com/android/gallery3d/ui/SelectionManager.java
new file mode 100644
index 000000000..be6811bc1
--- /dev/null
+++ b/src/com/android/gallery3d/ui/SelectionManager.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2010 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.gallery3d.ui;
+
+import com.android.gallery3d.app.AbstractGalleryActivity;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.Path;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+public class SelectionManager {
+ @SuppressWarnings("unused")
+ private static final String TAG = "SelectionManager";
+
+ public static final int ENTER_SELECTION_MODE = 1;
+ public static final int LEAVE_SELECTION_MODE = 2;
+ public static final int SELECT_ALL_MODE = 3;
+
+ private Set<Path> mClickedSet;
+ private MediaSet mSourceMediaSet;
+ private SelectionListener mListener;
+ private DataManager mDataManager;
+ private boolean mInverseSelection;
+ private boolean mIsAlbumSet;
+ private boolean mInSelectionMode;
+ private boolean mAutoLeave = true;
+ private int mTotal;
+
+ public interface SelectionListener {
+ public void onSelectionModeChange(int mode);
+ public void onSelectionChange(Path path, boolean selected);
+ }
+
+ public SelectionManager(AbstractGalleryActivity activity, boolean isAlbumSet) {
+ mDataManager = activity.getDataManager();
+ mClickedSet = new HashSet<Path>();
+ mIsAlbumSet = isAlbumSet;
+ mTotal = -1;
+ }
+
+ // Whether we will leave selection mode automatically once the number of
+ // selected items is down to zero.
+ public void setAutoLeaveSelectionMode(boolean enable) {
+ mAutoLeave = enable;
+ }
+
+ public void setSelectionListener(SelectionListener listener) {
+ mListener = listener;
+ }
+
+ public void selectAll() {
+ mInverseSelection = true;
+ mClickedSet.clear();
+ enterSelectionMode();
+ if (mListener != null) mListener.onSelectionModeChange(SELECT_ALL_MODE);
+ }
+
+ public void deSelectAll() {
+ leaveSelectionMode();
+ mInverseSelection = false;
+ mClickedSet.clear();
+ }
+
+ public boolean inSelectAllMode() {
+ return mInverseSelection;
+ }
+
+ public boolean inSelectionMode() {
+ return mInSelectionMode;
+ }
+
+ public void enterSelectionMode() {
+ if (mInSelectionMode) return;
+
+ mInSelectionMode = true;
+ if (mListener != null) mListener.onSelectionModeChange(ENTER_SELECTION_MODE);
+ }
+
+ public void leaveSelectionMode() {
+ if (!mInSelectionMode) return;
+
+ mInSelectionMode = false;
+ mInverseSelection = false;
+ mClickedSet.clear();
+ if (mListener != null) mListener.onSelectionModeChange(LEAVE_SELECTION_MODE);
+ }
+
+ public boolean isItemSelected(Path itemId) {
+ return mInverseSelection ^ mClickedSet.contains(itemId);
+ }
+
+ private int getTotalCount() {
+ if (mSourceMediaSet == null) return -1;
+
+ if (mTotal < 0) {
+ mTotal = mIsAlbumSet
+ ? mSourceMediaSet.getSubMediaSetCount()
+ : mSourceMediaSet.getMediaItemCount();
+ }
+ return mTotal;
+ }
+
+ public int getSelectedCount() {
+ int count = mClickedSet.size();
+ if (mInverseSelection) {
+ count = getTotalCount() - count;
+ }
+ return count;
+ }
+
+ public void toggle(Path path) {
+ if (mClickedSet.contains(path)) {
+ mClickedSet.remove(path);
+ } else {
+ enterSelectionMode();
+ mClickedSet.add(path);
+ }
+
+ // Convert to inverse selection mode if everything is selected.
+ int count = getSelectedCount();
+ if (count == getTotalCount()) {
+ selectAll();
+ }
+
+ if (mListener != null) mListener.onSelectionChange(path, isItemSelected(path));
+ if (count == 0 && mAutoLeave) {
+ leaveSelectionMode();
+ }
+ }
+
+ private static boolean expandMediaSet(ArrayList<Path> items, MediaSet set, int maxSelection) {
+ int subCount = set.getSubMediaSetCount();
+ for (int i = 0; i < subCount; i++) {
+ if (!expandMediaSet(items, set.getSubMediaSet(i), maxSelection)) {
+ return false;
+ }
+ }
+ int total = set.getMediaItemCount();
+ int batch = 50;
+ int index = 0;
+
+ while (index < total) {
+ int count = index + batch < total
+ ? batch
+ : total - index;
+ ArrayList<MediaItem> list = set.getMediaItem(index, count);
+ if (list != null
+ && list.size() > (maxSelection - items.size())) {
+ return false;
+ }
+ for (MediaItem item : list) {
+ items.add(item.getPath());
+ }
+ index += batch;
+ }
+ return true;
+ }
+
+ public ArrayList<Path> getSelected(boolean expandSet) {
+ return getSelected(expandSet, Integer.MAX_VALUE);
+ }
+
+ public ArrayList<Path> getSelected(boolean expandSet, int maxSelection) {
+ ArrayList<Path> selected = new ArrayList<Path>();
+ if (mIsAlbumSet) {
+ if (mInverseSelection) {
+ int total = getTotalCount();
+ for (int i = 0; i < total; i++) {
+ MediaSet set = mSourceMediaSet.getSubMediaSet(i);
+ Path id = set.getPath();
+ if (!mClickedSet.contains(id)) {
+ if (expandSet) {
+ if (!expandMediaSet(selected, set, maxSelection)) {
+ return null;
+ }
+ } else {
+ selected.add(id);
+ if (selected.size() > maxSelection) {
+ return null;
+ }
+ }
+ }
+ }
+ } else {
+ for (Path id : mClickedSet) {
+ if (expandSet) {
+ if (!expandMediaSet(selected, mDataManager.getMediaSet(id),
+ maxSelection)) {
+ return null;
+ }
+ } else {
+ selected.add(id);
+ if (selected.size() > maxSelection) {
+ return null;
+ }
+ }
+ }
+ }
+ } else {
+ if (mInverseSelection) {
+ int total = getTotalCount();
+ int index = 0;
+ while (index < total) {
+ int count = Math.min(total - index, MediaSet.MEDIAITEM_BATCH_FETCH_COUNT);
+ ArrayList<MediaItem> list = mSourceMediaSet.getMediaItem(index, count);
+ for (MediaItem item : list) {
+ Path id = item.getPath();
+ if (!mClickedSet.contains(id)) {
+ selected.add(id);
+ if (selected.size() > maxSelection) {
+ return null;
+ }
+ }
+ }
+ index += count;
+ }
+ } else {
+ for (Path id : mClickedSet) {
+ selected.add(id);
+ if (selected.size() > maxSelection) {
+ return null;
+ }
+ }
+ }
+ }
+ return selected;
+ }
+
+ public void setSourceMediaSet(MediaSet set) {
+ mSourceMediaSet = set;
+ mTotal = -1;
+ }
+}