Add progress dialog for delete operation and make the close button work
diff --git a/res/layout/image_gallery_2.xml b/res/layout/image_gallery_2.xml
index 390a6e4..b2a9365 100644
--- a/res/layout/image_gallery_2.xml
+++ b/res/layout/image_gallery_2.xml
@@ -60,6 +60,7 @@
android:visibility="gone"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
+ android:clickable="false"
android:layout_alignParentBottom="true"
android:paddingTop="5dip"
android:paddingLeft="4dip"
@@ -67,19 +68,19 @@
android:paddingBottom="1dip"
android:background="@android:drawable/bottom_bar">
- <Button android:id="@+id/share"
+ <Button android:id="@+id/button_share"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="@string/multiselect_share" />
- <Button android:id="@+id/delete"
+ <Button android:id="@+id/button_delete"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="@string/multiselect_delete" />
- <Button android:id="@+id/close"
+ <Button android:id="@+id/button_close"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 70d7ff3..ebffaa1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -604,5 +604,11 @@
<!-- Title shown on the button which will close the multiselction mode -->
<string name="multiselect_close">Close</string>
+
+ <!-- The title of the progress dialog which will be shown for tasks that may take a long time -->
+ <string name="progress_dialog_title">In progress</string>
+
+ <!-- The messsage shown on progress dialog when deleting images -->
+ <string name="delete_images_message">Deleting images, please wait\u2026</string>
</resources>
diff --git a/src/com/android/camera/ImageGallery.java b/src/com/android/camera/ImageGallery.java
index a0050b0..79021ae 100644
--- a/src/com/android/camera/ImageGallery.java
+++ b/src/com/android/camera/ImageGallery.java
@@ -16,6 +16,8 @@
package com.android.camera;
+import com.android.camera.gallery.BaseCancelable;
+import com.android.camera.gallery.Cancelable;
import com.android.camera.gallery.IImage;
import com.android.camera.gallery.IImageList;
import com.android.camera.gallery.VideoObject;
@@ -52,8 +54,10 @@
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
+import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
@@ -89,6 +93,8 @@
GridViewSpecial mGvs;
+ private final PriorityTaskQueue mPriorityQueue = new PriorityTaskQueue(1);
+
// The index of the first picture in GridViewSpecial.
private int mSelectedIndex = GridViewSpecial.SELECT_NONE;
private float mScrollPosition = INVALID_POSITION;
@@ -116,6 +122,10 @@
mFooterOrganizeView = findViewById(R.id.footer_organize);
+ // consume all click events on the footer view
+ mFooterOrganizeView.setOnClickListener(Util.getNullOnClickListener());
+ initializeFooterButtons();
+
if (isPickIntent()) {
mVideoSizeLimit = getIntent().getLongExtra(
MediaStore.EXTRA_SIZE_LIMIT, Long.MAX_VALUE);
@@ -130,6 +140,26 @@
mLoader = new ImageLoader(mHandler);
}
+ private void initializeFooterButtons() {
+ Button deleteButton = (Button) findViewById(R.id.button_delete);
+ deleteButton.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ onDeleteClicked();
+ }
+ });
+
+ Button closeButton = (Button) findViewById(R.id.button_close);
+ closeButton.setOnClickListener( new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ closeMultiSelectMode();
+ }
+ });
+ }
+
private MenuItem addSlideShowMenu(Menu menu, int position) {
return menu.add(0, 207, position, R.string.slide_show)
.setOnMenuItemClickListener(
@@ -484,12 +514,11 @@
item.setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
- if (mMultiSelected == null) {
- mMultiSelected = new HashSet<IImage>();
+ if (isInMultiSelectMode()) {
+ closeMultiSelectMode();
} else {
- mMultiSelected = null;
+ openMultiSelectMode();
}
- mGvs.invalidateAllImages();
return true;
}
});
@@ -939,4 +968,53 @@
mFooterOrganizeView.startAnimation(mFooterDisappear);
}
}
+
+ private void onDeleteClicked() {
+ Cancelable<Void> task = new BaseCancelable<Void>() {
+
+ @Override
+ public boolean requestCancel() {
+ return false;
+ }
+
+ @Override
+ protected Void execute() {
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ return null;
+ }
+
+ };
+ postBackgroundTask(
+ getResources().getString(R.string.delete_images_message),
+ task);
+
+ }
+
+ private <T> void postBackgroundTask(String message, Cancelable<T> task) {
+ String title = getResources().getString(R.string.progress_dialog_title);
+ PriorityTask<T> pTask = PriorityTask.wrap(task);
+ Util.showProgressDialog(this, title, message, pTask);
+ mPriorityQueue.add(pTask);
+ }
+
+ private boolean isInMultiSelectMode() {
+ return mMultiSelected != null;
+ }
+
+ private void closeMultiSelectMode() {
+ if (mMultiSelected == null) return;
+ mMultiSelected = null;
+ mGvs.invalidateAllImages();
+ hideFooter();
+ }
+
+ private void openMultiSelectMode() {
+ if (mMultiSelected != null) return;
+ mMultiSelected = new HashSet<IImage>();
+ mGvs.invalidateAllImages();
+ }
}
diff --git a/src/com/android/camera/PriorityTask.java b/src/com/android/camera/PriorityTask.java
index a060071..82750af 100644
--- a/src/com/android/camera/PriorityTask.java
+++ b/src/com/android/camera/PriorityTask.java
@@ -81,6 +81,38 @@
setPriority(priority);
}
+ private static class CancelableAdapter<T> extends PriorityTask<T> {
+ private final Cancelable<T> mTask;
+
+ public CancelableAdapter(Cancelable<T> task, int priority) {
+ super(priority);
+ mTask = task;
+ }
+
+ @Override
+ public boolean requestCancel() {
+ if (super.requestCancel()) {
+ mTask.requestCancel();
+ return true;
+ }
+ return false;
+ }
+
+
+ @Override
+ protected T execute() throws Exception {
+ return mTask.get();
+ }
+ }
+
+ public static <T> PriorityTask<T> wrap(Cancelable<T> task, int priority) {
+ return new CancelableAdapter<T>(task, priority);
+ }
+
+ public static <T> PriorityTask<T> wrap(Cancelable<T> task) {
+ return new CancelableAdapter<T>(task, PRIORITY_DEFAULT);
+ }
+
/**
* Executes the task. Subclasses should override this function. Note: if
* this function throws an <code>InterruptedException</code>, the task will
@@ -294,4 +326,4 @@
void resetState() {
mState = STATE_INITIAL;
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java
index 449319b..4991d0e 100644
--- a/src/com/android/camera/Util.java
+++ b/src/com/android/camera/Util.java
@@ -18,7 +18,9 @@
import com.android.camera.gallery.IImage;
+import android.app.ProgressDialog;
import android.content.ContentResolver;
+import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
@@ -28,6 +30,8 @@
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
@@ -40,6 +44,8 @@
public class Util {
private static final String TAG = "db.Util";
+ private static OnClickListener sNullOnClickListener;
+
private Util() {
}
@@ -369,4 +375,35 @@
}
Log.d(tag, msg + " --- stack trace ends.");
}
+
+ public static <T> void showProgressDialog(final Context context,
+ String title, String message, PriorityTask<T> task) {
+ final ProgressDialog dialog =
+ ProgressDialog.show(context, title, message);
+
+ task.addCallback(new PriorityTask.Callback<T>() {
+
+ public void onCanceled(PriorityTask<T> t) {
+ dialog.dismiss();
+ }
+
+ public void onFail(PriorityTask<T> t, Throwable error) {
+ dialog.dismiss();
+ }
+
+ public void onResultAvailable(PriorityTask<T> t, T result) {
+ dialog.dismiss();
+ }
+ });
+ }
+
+ public synchronized static OnClickListener getNullOnClickListener() {
+ if (sNullOnClickListener == null) {
+ sNullOnClickListener = new OnClickListener() {
+ public void onClick(View v) {
+ }
+ };
+ }
+ return sNullOnClickListener;
+ }
}