summaryrefslogtreecommitdiffstats
path: root/src/com/android/photos
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/photos')
-rw-r--r--src/com/android/photos/AlbumSetFragment.java126
-rw-r--r--src/com/android/photos/GalleryActivity.java145
-rw-r--r--src/com/android/photos/MultiChoiceManager.java190
-rw-r--r--src/com/android/photos/PhotoSetFragment.java139
-rw-r--r--src/com/android/photos/SelectionManager.java76
-rw-r--r--src/com/android/photos/adapters/AlbumSetCursorAdapter.java89
-rw-r--r--src/com/android/photos/adapters/PhotoThumbnailAdapter.java8
-rw-r--r--src/com/android/photos/data/AlbumSetLoader.java7
-rw-r--r--src/com/android/photos/data/PhotoProvider.java27
-rw-r--r--src/com/android/photos/data/PhotoSetLoader.java17
-rw-r--r--src/com/android/photos/shims/LoaderCompatShim.java5
-rw-r--r--src/com/android/photos/shims/MediaItemsLoader.java37
-rw-r--r--src/com/android/photos/shims/MediaSetLoader.java48
-rw-r--r--src/com/android/photos/views/SquareImageView.java53
14 files changed, 705 insertions, 262 deletions
diff --git a/src/com/android/photos/AlbumSetFragment.java b/src/com/android/photos/AlbumSetFragment.java
index 0d4fcc023..d0bc81fd6 100644
--- a/src/com/android/photos/AlbumSetFragment.java
+++ b/src/com/android/photos/AlbumSetFragment.java
@@ -21,42 +21,54 @@ import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.Loader;
import android.database.Cursor;
-import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.os.Bundle;
-import android.text.format.DateFormat;
+import android.provider.MediaStore.Files.FileColumns;
+import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
-import android.widget.CursorAdapter;
import android.widget.GridView;
-import android.widget.ImageView;
-import android.widget.ProgressBar;
-import android.widget.TextView;
import android.widget.Toast;
import com.android.gallery3d.R;
+import com.android.photos.adapters.AlbumSetCursorAdapter;
import com.android.photos.data.AlbumSetLoader;
import com.android.photos.shims.LoaderCompatShim;
import com.android.photos.shims.MediaSetLoader;
-import java.util.Date;
+import java.util.ArrayList;
public class AlbumSetFragment extends Fragment implements OnItemClickListener,
- LoaderCallbacks<Cursor> {
+ LoaderCallbacks<Cursor>, MultiChoiceManager.Delegate, SelectionManager.Client {
private GridView mAlbumSetView;
private View mEmptyView;
private AlbumSetCursorAdapter mAdapter;
+ private LoaderCompatShim<Cursor> mLoaderCompatShim;
+ private MultiChoiceManager mMultiChoiceManager;
+ private SelectionManager mSelectionManager;
private static final int LOADER_ALBUMSET = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mAdapter = new AlbumSetCursorAdapter(getActivity());
+ Context context = getActivity();
+ mAdapter = new AlbumSetCursorAdapter(context);
+ mMultiChoiceManager = new MultiChoiceManager(context, this);
+ mMultiChoiceManager.setSelectionManager(mSelectionManager);
+ }
+
+ @Override
+ public void setSelectionManager(SelectionManager manager) {
+ mSelectionManager = manager;
+ if (mMultiChoiceManager != null) {
+ mMultiChoiceManager.setSelectionManager(manager);
+ }
}
@Override
@@ -67,6 +79,8 @@ public class AlbumSetFragment extends Fragment implements OnItemClickListener,
mEmptyView = root.findViewById(android.R.id.empty);
mEmptyView.setVisibility(View.GONE);
mAlbumSetView.setAdapter(mAdapter);
+ mAlbumSetView.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL);
+ mAlbumSetView.setMultiChoiceModeListener(mMultiChoiceManager);
mAlbumSetView.setOnItemClickListener(this);
getLoaderManager().initLoader(LOADER_ALBUMSET, null, this);
updateEmptyStatus();
@@ -78,6 +92,7 @@ public class AlbumSetFragment extends Fragment implements OnItemClickListener,
// TODO: Switch to AlbumSetLoader
MediaSetLoader loader = new MediaSetLoader(getActivity());
mAdapter.setDrawableFactory(loader);
+ mLoaderCompatShim = loader;
return loader;
}
@@ -100,63 +115,54 @@ public class AlbumSetFragment extends Fragment implements OnItemClickListener,
@Override
public void onItemClick(AdapterView<?> av, View v, int pos, long id) {
- Cursor c = (Cursor) av.getItemAtPosition(pos);
- int albumId = c.getInt(AlbumSetLoader.INDEX_ID);
- // TODO launch an activity showing the photos in the album
- Toast.makeText(v.getContext(), "Clicked " + albumId, Toast.LENGTH_SHORT).show();
+ if (mLoaderCompatShim == null) {
+ // Not fully initialized yet, discard
+ return;
+ }
+ Cursor item = (Cursor) mAdapter.getItem(pos);
+ Toast.makeText(v.getContext(),
+ "Tapped " + item.getInt(AlbumSetLoader.INDEX_ID),
+ Toast.LENGTH_SHORT).show();
}
- private static class AlbumSetCursorAdapter extends CursorAdapter {
+ @Override
+ public int getItemMediaType(Object item) {
+ return FileColumns.MEDIA_TYPE_NONE;
+ }
- private LoaderCompatShim<Cursor> mDrawableFactory;
+ @Override
+ public int getItemSupportedOperations(Object item) {
+ return ((Cursor) item).getInt(AlbumSetLoader.INDEX_SUPPORTED_OPERATIONS);
+ }
- public void setDrawableFactory(LoaderCompatShim<Cursor> factory) {
- mDrawableFactory = factory;
- }
- private Date mDate = new Date(); // Used for converting timestamps for display
+ @Override
+ public Object getItemAtPosition(int position) {
+ return mAdapter.getItem(position);
+ }
- public AlbumSetCursorAdapter(Context context) {
- super(context, null, false);
- }
+ @Override
+ public ArrayList<Uri> getSubItemUrisForItem(Object item) {
+ return mLoaderCompatShim.urisForSubItems((Cursor) item);
+ }
- @Override
- public void bindView(View v, Context context, Cursor cursor) {
- TextView titleTextView = (TextView) v.findViewById(
- R.id.album_set_item_title);
- titleTextView.setText(cursor.getString(AlbumSetLoader.INDEX_TITLE));
-
- TextView dateTextView = (TextView) v.findViewById(
- R.id.album_set_item_date);
- long timestamp = cursor.getLong(AlbumSetLoader.INDEX_TIMESTAMP);
- if (timestamp > 0) {
- mDate.setTime(timestamp);
- dateTextView.setText(DateFormat.getMediumDateFormat(context).format(mDate));
- } else {
- dateTextView.setText(null);
- }
-
- ProgressBar uploadProgressBar = (ProgressBar) v.findViewById(
- R.id.album_set_item_upload_progress);
- if (cursor.getInt(AlbumSetLoader.INDEX_COUNT_PENDING_UPLOAD) > 0) {
- uploadProgressBar.setVisibility(View.VISIBLE);
- uploadProgressBar.setProgress(50);
- } else {
- uploadProgressBar.setVisibility(View.INVISIBLE);
- }
-
- ImageView thumbImageView = (ImageView) v.findViewById(
- R.id.album_set_item_image);
- Drawable recycle = thumbImageView.getDrawable();
- Drawable drawable = mDrawableFactory.drawableForItem(cursor, recycle);
- if (recycle != drawable) {
- thumbImageView.setImageDrawable(drawable);
- }
- }
+ @Override
+ public Object getPathForItemAtPosition(int position) {
+ return mLoaderCompatShim.getPathForItem((Cursor) mAdapter.getItem(position));
+ }
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return LayoutInflater.from(context).inflate(
- R.layout.album_set_item, parent, false);
- }
+ @Override
+ public void deleteItemWithPath(Object itemPath) {
+ mLoaderCompatShim.deleteItemWithPath(itemPath);
}
+
+ @Override
+ public SparseBooleanArray getSelectedItemPositions() {
+ return mAlbumSetView.getCheckedItemPositions();
+ }
+
+ @Override
+ public int getSelectedItemCount() {
+ return mAlbumSetView.getCheckedItemCount();
+ }
+
}
diff --git a/src/com/android/photos/GalleryActivity.java b/src/com/android/photos/GalleryActivity.java
index 2335658d1..ddf04e365 100644
--- a/src/com/android/photos/GalleryActivity.java
+++ b/src/com/android/photos/GalleryActivity.java
@@ -21,49 +21,53 @@ import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
+import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
+import android.support.v13.app.FragmentPagerAdapter;
+import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;
import com.android.camera.CameraActivity;
import com.android.gallery3d.R;
+import java.util.ArrayList;
+
public class GalleryActivity extends Activity {
- private final String FTAG_PHOTOSET = "PhotoSet";
- private final String FTAG_ALBUMSET = "AlbumSet";
private SelectionManager mSelectionManager;
+ private ViewPager mViewPager;
+ private TabsAdapter mTabsAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mSelectionManager = new SelectionManager(this);
+ mViewPager = new ViewPager(this);
+ mViewPager.setId(R.id.viewpager);
+ setContentView(mViewPager);
- setupActionBar();
- }
-
- protected SelectionManager getSelectionManager() {
- if (mSelectionManager == null) {
- mSelectionManager = new SelectionManager(this);
- }
- return mSelectionManager;
- }
-
- private void setupActionBar() {
ActionBar ab = getActionBar();
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ab.setDisplayShowHomeEnabled(false);
ab.setDisplayShowTitleEnabled(false);
- Tab tab = ab.newTab();
- tab.setText(R.string.tab_photos);
- tab.setTabListener(new TabListener<PhotoSetFragment>(this,
- FTAG_PHOTOSET, PhotoSetFragment.class));
- ab.addTab(tab, true);
- tab = ab.newTab();
- tab.setText(R.string.tab_albums);
- tab.setTabListener(new TabListener<AlbumSetFragment>(this,
- FTAG_ALBUMSET, AlbumSetFragment.class));
- ab.addTab(tab);
+
+ mTabsAdapter = new TabsAdapter(this, mViewPager);
+ mTabsAdapter.addTab(ab.newTab().setText(R.string.tab_photos),
+ PhotoSetFragment.class, null);
+ mTabsAdapter.addTab(ab.newTab().setText(R.string.tab_albums),
+ AlbumSetFragment.class, null);
+
+ if (savedInstanceState != null) {
+ ab.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}
@Override
@@ -85,49 +89,88 @@ public class GalleryActivity extends Activity {
}
}
- private static class TabListener<T extends Fragment> implements ActionBar.TabListener {
- private Fragment mFragment;
- private final Activity mActivity;
- private final String mTag;
- private final Class<T> mClass;
-
- /** Constructor used each time a new tab is created.
- * @param activity The host Activity, used to instantiate the fragment
- * @param tag The identifier tag for the fragment
- * @param clz The fragment's Class, used to instantiate the fragment
- */
- public TabListener(Activity activity, String tag, Class<T> clz) {
+ public static class TabsAdapter extends FragmentPagerAdapter implements
+ ActionBar.TabListener, ViewPager.OnPageChangeListener {
+
+ private final GalleryActivity mActivity;
+ private final ActionBar mActionBar;
+ private final ViewPager mViewPager;
+ private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
+
+ static final class TabInfo {
+
+ private final Class<?> clss;
+ private final Bundle args;
+
+ TabInfo(Class<?> _class, Bundle _args) {
+ clss = _class;
+ args = _args;
+ }
+ }
+
+ public TabsAdapter(GalleryActivity activity, ViewPager pager) {
+ super(activity.getFragmentManager());
mActivity = activity;
- mTag = tag;
- mClass = clz;
+ mActionBar = activity.getActionBar();
+ mViewPager = pager;
+ mViewPager.setAdapter(this);
+ mViewPager.setOnPageChangeListener(this);
+ }
+
+ public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
+ TabInfo info = new TabInfo(clss, args);
+ tab.setTag(info);
+ tab.setTabListener(this);
+ mTabs.add(info);
+ mActionBar.addTab(tab);
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mTabs.size();
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ TabInfo info = mTabs.get(position);
+ Fragment item = Fragment.instantiate(mActivity, info.clss.getName(),
+ info.args);
+ ((SelectionManager.Client) item).setSelectionManager(
+ mActivity.mSelectionManager);
+ return item;
}
- /* The following are each of the ActionBar.TabListener callbacks */
+ @Override
+ public void onPageScrolled(int position, float positionOffset,
+ int positionOffsetPixels) {
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ mActionBar.setSelectedNavigationItem(position);
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ }
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
- // Check if the fragment is already initialized
- if (mFragment == null) {
- // If not, instantiate and add it to the activity
- mFragment = Fragment.instantiate(mActivity, mClass.getName());
- ft.add(android.R.id.content, mFragment, mTag);
- } else {
- // If it exists, simply attach it in order to show it
- ft.attach(mFragment);
+ Object tag = tab.getTag();
+ for (int i = 0; i < mTabs.size(); i++) {
+ if (mTabs.get(i) == tag) {
+ mViewPager.setCurrentItem(i);
+ }
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
- if (mFragment != null) {
- // Detach the fragment, because another one is being attached
- ft.detach(mFragment);
- }
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
- // User selected the already selected tab. Usually do nothing.
}
}
}
diff --git a/src/com/android/photos/MultiChoiceManager.java b/src/com/android/photos/MultiChoiceManager.java
new file mode 100644
index 000000000..e00c842fe
--- /dev/null
+++ b/src/com/android/photos/MultiChoiceManager.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2013 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.photos;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.util.SparseBooleanArray;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.AbsListView.MultiChoiceModeListener;
+import android.widget.ShareActionProvider;
+import android.widget.ShareActionProvider.OnShareTargetSelectedListener;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.data.MediaObject;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MultiChoiceManager implements MultiChoiceModeListener,
+ OnShareTargetSelectedListener, SelectionManager.SelectedUriSource {
+
+ public interface Delegate {
+ public SparseBooleanArray getSelectedItemPositions();
+ public int getSelectedItemCount();
+ public int getItemMediaType(Object item);
+ public int getItemSupportedOperations(Object item);
+ public ArrayList<Uri> getSubItemUrisForItem(Object item);
+ public Object getItemAtPosition(int position);
+ public Object getPathForItemAtPosition(int position);
+ public void deleteItemWithPath(Object itemPath);
+ }
+
+ private SelectionManager mSelectionManager;
+ private ShareActionProvider mShareActionProvider;
+ private ActionMode mActionMode;
+ private int numSubItemsCollected = 0;
+ private Context mContext;
+ private Delegate mDelegate;
+
+ private ArrayList<Uri> mSelectedUrisArray = new ArrayList<Uri>();
+
+ public MultiChoiceManager(Context context, Delegate delegate) {
+ mContext = context;
+ mDelegate = delegate;
+ }
+
+ public void setSelectionManager(SelectionManager selectionManager) {
+ mSelectionManager = selectionManager;
+ }
+
+ @Override
+ public ArrayList<Uri> getSelectedShareableUris() {
+ return mSelectedUrisArray;
+ }
+
+ private void updateSelectedTitle(ActionMode mode) {
+ int count = mDelegate.getSelectedItemCount();
+ mode.setTitle(mContext.getResources().getQuantityString(
+ R.plurals.number_of_items_selected, count, count));
+ }
+
+ @Override
+ public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
+ boolean checked) {
+ updateSelectedTitle(mode);
+ Object item = mDelegate.getItemAtPosition(position);
+
+ ArrayList<Uri> subItems = mDelegate.getSubItemUrisForItem(item);
+ if (checked) {
+ mSelectedUrisArray.addAll(subItems);
+ numSubItemsCollected += subItems.size();
+ } else {
+ mSelectedUrisArray.removeAll(subItems);
+ numSubItemsCollected -= subItems.size();
+ }
+
+ mSelectionManager.onItemSelectedStateChanged(mShareActionProvider,
+ mDelegate.getItemMediaType(item),
+ mDelegate.getItemSupportedOperations(item),
+ checked);
+ updateActionItemVisibilities(mode.getMenu(),
+ mSelectionManager.getSupportedOperations());
+ }
+
+ private void updateActionItemVisibilities(Menu menu, int supportedOperations) {
+ MenuItem shareItem = menu.findItem(R.id.menu_share);
+ MenuItem deleteItem = menu.findItem(R.id.menu_delete);
+ shareItem.setVisible((supportedOperations & MediaObject.SUPPORT_SHARE) > 0);
+ deleteItem.setVisible((supportedOperations & MediaObject.SUPPORT_DELETE) > 0);
+ }
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ mSelectionManager.setSelectedUriSource(this);
+ mActionMode = mode;
+ MenuInflater inflater = mode.getMenuInflater();
+ inflater.inflate(R.menu.gallery_multiselect, menu);
+ MenuItem menuItem = menu.findItem(R.id.menu_share);
+ mShareActionProvider = (ShareActionProvider) menuItem.getActionProvider();
+ mShareActionProvider.setOnShareTargetSelectedListener(this);
+ updateSelectedTitle(mode);
+ return true;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ // onDestroyActionMode gets called when the share target was selected,
+ // but apparently before the ArrayList is serialized in the intent
+ // so we can't clear the old one here.
+ mSelectedUrisArray = new ArrayList<Uri>();
+ mSelectionManager.onClearSelection();
+ mSelectionManager.setSelectedUriSource(null);
+ mShareActionProvider = null;
+ mActionMode = null;
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ updateSelectedTitle(mode);
+ return false;
+ }
+
+ @Override
+ public boolean onShareTargetSelected(ShareActionProvider provider, Intent intent) {
+ mActionMode.finish();
+ return false;
+ }
+
+ private static class BulkDeleteTask extends AsyncTask<Void, Void, Void> {
+ private Delegate mDelegate;
+ private List<Object> mPaths;
+
+ public BulkDeleteTask(Delegate delegate, List<Object> paths) {
+ mDelegate = delegate;
+ mPaths = paths;
+ }
+
+ @Override
+ protected Void doInBackground(Void... ignored) {
+ for (Object path : mPaths) {
+ mDelegate.deleteItemWithPath(path);
+ }
+ return null;
+ }
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.menu_delete:
+ BulkDeleteTask deleteTask = new BulkDeleteTask(mDelegate,
+ getPathsForSelectedItems());
+ deleteTask.execute();
+ mode.finish();
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private List<Object> getPathsForSelectedItems() {
+ List<Object> paths = new ArrayList<Object>();
+ SparseBooleanArray selected = mDelegate.getSelectedItemPositions();
+ for (int i = 0; i < selected.size(); i++) {
+ if (selected.valueAt(i)) {
+ paths.add(mDelegate.getPathForItemAtPosition(i));
+ }
+ }
+ return paths;
+ }
+}
diff --git a/src/com/android/photos/PhotoSetFragment.java b/src/com/android/photos/PhotoSetFragment.java
index 25d80360d..b485cd051 100644
--- a/src/com/android/photos/PhotoSetFragment.java
+++ b/src/com/android/photos/PhotoSetFragment.java
@@ -18,41 +18,31 @@ package com.android.photos;
import android.app.Fragment;
import android.app.LoaderManager.LoaderCallbacks;
+import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.SparseBooleanArray;
-import android.view.ActionMode;
import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
-import android.widget.ShareActionProvider;
-import android.widget.ShareActionProvider.OnShareTargetSelectedListener;
import com.android.gallery3d.R;
import com.android.gallery3d.app.Gallery;
-import com.android.gallery3d.data.MediaItem;
import com.android.photos.adapters.PhotoThumbnailAdapter;
import com.android.photos.data.PhotoSetLoader;
import com.android.photos.shims.LoaderCompatShim;
import com.android.photos.shims.MediaItemsLoader;
import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
-public class PhotoSetFragment extends Fragment implements LoaderCallbacks<Cursor>,
- OnItemClickListener, SelectionManager.SelectedUriSource, MultiChoiceModeListener,
- OnShareTargetSelectedListener {
+public class PhotoSetFragment extends Fragment implements OnItemClickListener,
+ LoaderCallbacks<Cursor>, MultiChoiceManager.Delegate, SelectionManager.Client {
private static final int LOADER_PHOTOSET = 1;
@@ -62,14 +52,24 @@ public class PhotoSetFragment extends Fragment implements LoaderCallbacks<Cursor
private boolean mInitialLoadComplete = false;
private LoaderCompatShim<Cursor> mLoaderCompatShim;
private PhotoThumbnailAdapter mAdapter;
+ private MultiChoiceManager mMultiChoiceManager;
private SelectionManager mSelectionManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- GalleryActivity activity = (GalleryActivity) getActivity();
- mSelectionManager = activity.getSelectionManager();
- mAdapter = new PhotoThumbnailAdapter(activity);
+ Context context = getActivity();
+ mAdapter = new PhotoThumbnailAdapter(context);
+ mMultiChoiceManager = new MultiChoiceManager(context, this);
+ mMultiChoiceManager.setSelectionManager(mSelectionManager);
+ }
+
+ @Override
+ public void setSelectionManager(SelectionManager manager) {
+ mSelectionManager = manager;
+ if (mMultiChoiceManager != null) {
+ mMultiChoiceManager.setSelectionManager(manager);
+ }
}
@Override
@@ -84,7 +84,7 @@ public class PhotoSetFragment extends Fragment implements LoaderCallbacks<Cursor
mEmptyView.setVisibility(View.GONE);
mPhotoSetView.setAdapter(mAdapter);
mPhotoSetView.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL);
- mPhotoSetView.setMultiChoiceModeListener(this);
+ mPhotoSetView.setMultiChoiceModeListener(mMultiChoiceManager);
getLoaderManager().initLoader(LOADER_PHOTOSET, null, this);
updateEmptyStatus();
return root;
@@ -129,112 +129,51 @@ public class PhotoSetFragment extends Fragment implements LoaderCallbacks<Cursor
updateEmptyStatus();
}
- private Set<Uri> mSelectedUris = new HashSet<Uri>();
- private ArrayList<Uri> mSelectedUrisArray = new ArrayList<Uri>();
-
@Override
- public ArrayList<Uri> getSelectedShareableUris() {
- mSelectedUrisArray.clear();
- mSelectedUrisArray.addAll(mSelectedUris);
- return mSelectedUrisArray;
- }
-
- public ArrayList<Uri> getSelectedShareableUrisUncached() {
- mSelectedUrisArray.clear();
- SparseBooleanArray selected = mPhotoSetView.getCheckedItemPositions();
-
- for (int i = 0; i < selected.size(); i++) {
- if (selected.valueAt(i)) {
- Cursor item = mAdapter.getItem(selected.keyAt(i));
- int supported = item.getInt(PhotoSetLoader.INDEX_SUPPORTED_OPERATIONS);
- if ((supported & MediaItem.SUPPORT_SHARE) > 0) {
- mSelectedUrisArray.add(mLoaderCompatShim.uriForItem(item));
- }
- }
- }
-
- return mSelectedUrisArray;
+ public void onLoaderReset(Loader<Cursor> loader) {
}
@Override
- public void onLoaderReset(Loader<Cursor> loader) {
+ public int getItemMediaType(Object item) {
+ return ((Cursor) item).getInt(PhotoSetLoader.INDEX_MEDIA_TYPE);
}
-
- private ShareActionProvider mShareActionProvider;
- private ActionMode mActionMode;
- private boolean mSharePending = false;
-
- private void updateSelectedTitle(ActionMode mode) {
- int count = mPhotoSetView.getCheckedItemCount();
- mode.setTitle(getResources().getQuantityString(
- R.plurals.number_of_items_selected, count, count));
+ @Override
+ public int getItemSupportedOperations(Object item) {
+ return ((Cursor) item).getInt(PhotoSetLoader.INDEX_SUPPORTED_OPERATIONS);
}
@Override
- public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
- boolean checked) {
- updateSelectedTitle(mode);
- Cursor item = mAdapter.getItem(position);
-
- if (checked) {
- mSelectedUris.add(mLoaderCompatShim.uriForItem(item));
- } else {
- mSelectedUris.remove(mLoaderCompatShim.uriForItem(item));
- }
-
- mSelectionManager.onItemSelectedStateChanged(mShareActionProvider,
- item.getInt(PhotoSetLoader.INDEX_MEDIA_TYPE),
- item.getInt(PhotoSetLoader.INDEX_SUPPORTED_OPERATIONS),
- checked);
+ public Object getItemAtPosition(int position) {
+ return mAdapter.getItem(position);
}
+ private ArrayList<Uri> mSubItemUriTemp = new ArrayList<Uri>(1);
@Override
- public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- mSelectionManager.setSelectedUriSource(PhotoSetFragment.this);
- mActionMode = mode;
- MenuInflater inflater = mode.getMenuInflater();
- inflater.inflate(R.menu.gallery_multiselect, menu);
- MenuItem menuItem = menu.findItem(R.id.menu_share);
- mShareActionProvider = (ShareActionProvider) menuItem.getActionProvider();
- mShareActionProvider.setOnShareTargetSelectedListener(this);
- updateSelectedTitle(mode);
- return true;
+ public ArrayList<Uri> getSubItemUrisForItem(Object item) {
+ mSubItemUriTemp.clear();
+ mSubItemUriTemp.add(mLoaderCompatShim.uriForItem((Cursor) item));
+ return mSubItemUriTemp;
}
+
@Override
- public void onDestroyActionMode(ActionMode mode) {
- mSelectedUris.clear();
- if (mSharePending) {
- // onDestroyActionMode gets called when the share target was selected,
- // but apparently before the ArrayList is serialized in the intent
- // so we can't clear the old one here.
- mSelectedUrisArray = new ArrayList<Uri>();
- mSharePending = false;
- } else {
- mSelectedUrisArray.clear();
- }
- mSelectionManager.onClearSelection();
- mSelectionManager.setSelectedUriSource(null);
- mShareActionProvider = null;
- mActionMode = null;
+ public Object getPathForItemAtPosition(int position) {
+ return mLoaderCompatShim.getPathForItem(mAdapter.getItem(position));
}
@Override
- public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
- updateSelectedTitle(mode);
- return false;
+ public void deleteItemWithPath(Object itemPath) {
+ mLoaderCompatShim.deleteItemWithPath(itemPath);
}
@Override
- public boolean onShareTargetSelected(ShareActionProvider provider, Intent intent) {
- mSharePending = true;
- mActionMode.finish();
- return false;
+ public SparseBooleanArray getSelectedItemPositions() {
+ return mPhotoSetView.getCheckedItemPositions();
}
@Override
- public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- return false;
+ public int getSelectedItemCount() {
+ return mPhotoSetView.getCheckedItemCount();
}
}
diff --git a/src/com/android/photos/SelectionManager.java b/src/com/android/photos/SelectionManager.java
index d7e61d19a..ce340c731 100644
--- a/src/com/android/photos/SelectionManager.java
+++ b/src/com/android/photos/SelectionManager.java
@@ -16,22 +16,22 @@
package com.android.photos;
-import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.nfc.NfcAdapter;
+import android.nfc.NfcAdapter.CreateBeamUrisCallback;
import android.nfc.NfcEvent;
import android.provider.MediaStore.Files.FileColumns;
import android.widget.ShareActionProvider;
import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
import com.android.gallery3d.util.GalleryUtils;
import java.util.ArrayList;
-public class SelectionManager implements NfcAdapter.CreateBeamUrisCallback {
+public class SelectionManager {
private Activity mActivity;
private NfcAdapter mNfcAdapter;
private SelectedUriSource mUriSource;
@@ -41,12 +41,23 @@ public class SelectionManager implements NfcAdapter.CreateBeamUrisCallback {
public ArrayList<Uri> getSelectedShareableUris();
}
- @TargetApi(16)
+ public interface Client {
+ public void setSelectionManager(SelectionManager manager);
+ }
+
public SelectionManager(Activity activity) {
mActivity = activity;
if (ApiHelper.AT_LEAST_16) {
mNfcAdapter = NfcAdapter.getDefaultAdapter(mActivity);
- mNfcAdapter.setBeamPushUrisCallback(this, mActivity);
+ mNfcAdapter.setBeamPushUrisCallback(new CreateBeamUrisCallback() {
+ @Override
+ public Uri[] createBeamUris(NfcEvent arg0) {
+ // This will have been preceded by a call to onItemSelectedStateChange
+ if (mCachedShareableUris == null) return null;
+ return mCachedShareableUris.toArray(
+ new Uri[mCachedShareableUris.size()]);
+ }
+ }, mActivity);
}
}
@@ -69,10 +80,10 @@ public class SelectionManager implements NfcAdapter.CreateBeamUrisCallback {
mSelectedTotalCount += increment;
mCachedShareableUris = null;
- if ((itemSupportedOperations & MediaItem.SUPPORT_DELETE) > 0) {
+ if ((itemSupportedOperations & MediaObject.SUPPORT_DELETE) > 0) {
mSelectedDeletableCount += increment;
}
- if ((itemSupportedOperations & MediaItem.SUPPORT_SHARE) > 0) {
+ if ((itemSupportedOperations & MediaObject.SUPPORT_SHARE) > 0) {
mSelectedShareableCount += increment;
if (itemType == FileColumns.MEDIA_TYPE_IMAGE) {
mSelectedShareableImageCount += increment;
@@ -86,24 +97,42 @@ public class SelectionManager implements NfcAdapter.CreateBeamUrisCallback {
mShareIntent.setAction(null).setType(null);
} else if (mSelectedShareableCount >= 1) {
mCachedShareableUris = mUriSource.getSelectedShareableUris();
- if (mSelectedShareableImageCount == mSelectedShareableCount) {
- mShareIntent.setType(GalleryUtils.MIME_TYPE_IMAGE);
- } else if (mSelectedShareableVideoCount == mSelectedShareableCount) {
- mShareIntent.setType(GalleryUtils.MIME_TYPE_VIDEO);
- } else {
- mShareIntent.setType(GalleryUtils.MIME_TYPE_ALL);
- }
- if (mSelectedShareableCount == 1) {
- mShareIntent.setAction(Intent.ACTION_SEND);
- mShareIntent.putExtra(Intent.EXTRA_STREAM, mCachedShareableUris.get(0));
+ if (mCachedShareableUris.size() == 0) {
+ mShareIntent.setAction(null).setType(null);
} else {
- mShareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
- mShareIntent.putExtra(Intent.EXTRA_STREAM, mCachedShareableUris);
+ if (mSelectedShareableImageCount == mSelectedShareableCount) {
+ mShareIntent.setType(GalleryUtils.MIME_TYPE_IMAGE);
+ } else if (mSelectedShareableVideoCount == mSelectedShareableCount) {
+ mShareIntent.setType(GalleryUtils.MIME_TYPE_VIDEO);
+ } else {
+ mShareIntent.setType(GalleryUtils.MIME_TYPE_ALL);
+ }
+ if (mCachedShareableUris.size() == 1) {
+ mShareIntent.setAction(Intent.ACTION_SEND);
+ mShareIntent.putExtra(Intent.EXTRA_STREAM, mCachedShareableUris.get(0));
+ } else {
+ mShareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
+ mShareIntent.putExtra(Intent.EXTRA_STREAM, mCachedShareableUris);
+ }
}
}
share.setShareIntent(mShareIntent);
- // TODO update deletability, editability, etc.
+ // TODO update editability, etc.
+ }
+
+ public int getSupportedOperations() {
+ if (mSelectedTotalCount == 0) {
+ return 0;
+ }
+ int supported = 0;
+ if (mSelectedDeletableCount == mSelectedTotalCount) {
+ supported |= MediaObject.SUPPORT_DELETE;
+ }
+ if (mSelectedShareableCount > 0) {
+ supported |= MediaObject.SUPPORT_SHARE;
+ }
+ return supported;
}
public void onClearSelection() {
@@ -116,11 +145,4 @@ public class SelectionManager implements NfcAdapter.CreateBeamUrisCallback {
mShareIntent.removeExtra(Intent.EXTRA_STREAM);
mShareIntent.setAction(null).setType(null);
}
-
- @Override
- public Uri[] createBeamUris(NfcEvent event) {
- // This will have been preceded by a call to onItemSelectedStateChange
- if (mCachedShareableUris == null) return null;
- return mCachedShareableUris.toArray(new Uri[mCachedShareableUris.size()]);
- }
}
diff --git a/src/com/android/photos/adapters/AlbumSetCursorAdapter.java b/src/com/android/photos/adapters/AlbumSetCursorAdapter.java
new file mode 100644
index 000000000..c387f8f47
--- /dev/null
+++ b/src/com/android/photos/adapters/AlbumSetCursorAdapter.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013 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.photos.adapters;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.drawable.Drawable;
+import android.text.format.DateFormat;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CursorAdapter;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.android.gallery3d.R;
+import com.android.photos.data.AlbumSetLoader;
+import com.android.photos.shims.LoaderCompatShim;
+
+import java.util.Date;
+
+public class AlbumSetCursorAdapter extends CursorAdapter {
+
+ private LoaderCompatShim<Cursor> mDrawableFactory;
+
+ public void setDrawableFactory(LoaderCompatShim<Cursor> factory) {
+ mDrawableFactory = factory;
+ }
+ private Date mDate = new Date(); // Used for converting timestamps for display
+
+ public AlbumSetCursorAdapter(Context context) {
+ super(context, null, false);
+ }
+
+ @Override
+ public void bindView(View v, Context context, Cursor cursor) {
+ TextView titleTextView = (TextView) v.findViewById(
+ R.id.album_set_item_title);
+ titleTextView.setText(cursor.getString(AlbumSetLoader.INDEX_TITLE));
+
+ TextView dateTextView = (TextView) v.findViewById(
+ R.id.album_set_item_date);
+ long timestamp = cursor.getLong(AlbumSetLoader.INDEX_TIMESTAMP);
+ if (timestamp > 0) {
+ mDate.setTime(timestamp);
+ dateTextView.setText(DateFormat.getMediumDateFormat(context).format(mDate));
+ } else {
+ dateTextView.setText(null);
+ }
+
+ ProgressBar uploadProgressBar = (ProgressBar) v.findViewById(
+ R.id.album_set_item_upload_progress);
+ if (cursor.getInt(AlbumSetLoader.INDEX_COUNT_PENDING_UPLOAD) > 0) {
+ uploadProgressBar.setVisibility(View.VISIBLE);
+ uploadProgressBar.setProgress(50);
+ } else {
+ uploadProgressBar.setVisibility(View.INVISIBLE);
+ }
+
+ ImageView thumbImageView = (ImageView) v.findViewById(
+ R.id.album_set_item_image);
+ Drawable recycle = thumbImageView.getDrawable();
+ Drawable drawable = mDrawableFactory.drawableForItem(cursor, recycle);
+ if (recycle != drawable) {
+ thumbImageView.setImageDrawable(drawable);
+ }
+ }
+
+ @Override
+ public View newView(Context context, Cursor cursor, ViewGroup parent) {
+ return LayoutInflater.from(context).inflate(
+ R.layout.album_set_item, parent, false);
+ }
+}
diff --git a/src/com/android/photos/adapters/PhotoThumbnailAdapter.java b/src/com/android/photos/adapters/PhotoThumbnailAdapter.java
index 5715795da..1190b8c85 100644
--- a/src/com/android/photos/adapters/PhotoThumbnailAdapter.java
+++ b/src/com/android/photos/adapters/PhotoThumbnailAdapter.java
@@ -22,9 +22,7 @@ import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
import android.widget.CursorAdapter;
-import android.widget.GridView;
import android.widget.ImageView;
import com.android.gallery3d.R;
@@ -48,7 +46,7 @@ public class PhotoThumbnailAdapter extends CursorAdapter implements GalleryThumb
@Override
public void bindView(View view, Context context, Cursor cursor) {
- ImageView iv = (ImageView) view;
+ ImageView iv = (ImageView) view.findViewById(R.id.thumbnail);
Drawable recycle = iv.getDrawable();
Drawable drawable = mDrawableFactory.drawableForItem(cursor, recycle);
if (recycle != drawable) {
@@ -59,10 +57,6 @@ public class PhotoThumbnailAdapter extends CursorAdapter implements GalleryThumb
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = mInflater.inflate(R.layout.photo_set_item, parent, false);
- LayoutParams params = view.getLayoutParams();
- int columnWidth = ((GridView) parent).getColumnWidth();
- params.height = columnWidth;
- view.setLayoutParams(params);
return view;
}
diff --git a/src/com/android/photos/data/AlbumSetLoader.java b/src/com/android/photos/data/AlbumSetLoader.java
index b2b5204e6..940473255 100644
--- a/src/com/android/photos/data/AlbumSetLoader.java
+++ b/src/com/android/photos/data/AlbumSetLoader.java
@@ -12,6 +12,7 @@ public class AlbumSetLoader {
public static final int INDEX_THUMBNAIL_HEIGHT = 5;
public static final int INDEX_COUNT_PENDING_UPLOAD = 6;
public static final int INDEX_COUNT = 7;
+ public static final int INDEX_SUPPORTED_OPERATIONS = 8;
public static final String[] PROJECTION = {
"_id",
@@ -21,7 +22,8 @@ public class AlbumSetLoader {
"thumb_width",
"thumb_height",
"count_pending_upload",
- "_count"
+ "_count",
+ "supported_operations"
};
public static final MatrixCursor MOCK = createRandomCursor(30);
@@ -44,7 +46,8 @@ public class AlbumSetLoader {
0,
0,
(random < .3 ? 1 : 0),
- 1
+ 1,
+ 0
};
return row;
}
diff --git a/src/com/android/photos/data/PhotoProvider.java b/src/com/android/photos/data/PhotoProvider.java
index 7127f979f..8413206b1 100644
--- a/src/com/android/photos/data/PhotoProvider.java
+++ b/src/com/android/photos/data/PhotoProvider.java
@@ -84,7 +84,7 @@ public class PhotoProvider extends SQLiteContentProvider {
*/
public static interface Photos extends BaseColumns {
/** Internal database table used for basic photo information. */
- public static final String TABLE = "photo";
+ public static final String TABLE = "photos";
/** Content URI for basic photo and video information. */
public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, TABLE);
@@ -123,7 +123,7 @@ public class PhotoProvider extends SQLiteContentProvider {
*/
public static interface Albums extends BaseColumns {
/** Internal database table used album information. */
- public static final String TABLE = "album";
+ public static final String TABLE = "albums";
/** Content URI for album information. */
public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, TABLE);
@@ -267,7 +267,7 @@ public class PhotoProvider extends SQLiteContentProvider {
Photos.MIME_TYPE,
};
- private static final String[] BASE_COLUMNS_ID = {
+ protected static final String[] BASE_COLUMNS_ID = {
BaseColumns._ID,
};
@@ -502,15 +502,17 @@ public class PhotoProvider extends SQLiteContentProvider {
String[] selectionArgs, Uri uri) {
switch (match) {
case MATCH_PHOTO:
- case MATCH_PHOTO_ID: {
+ case MATCH_PHOTO_ID:
deleteCascadeMetadata(db, selection, selectionArgs);
break;
- }
case MATCH_ALBUM:
- case MATCH_ALBUM_ID: {
+ case MATCH_ALBUM_ID:
deleteCascadePhotos(db, selection, selectionArgs);
break;
- }
+ case MATCH_ACCOUNT:
+ case MATCH_ACCOUNT_ID:
+ deleteCascadeAccounts(db, selection, selectionArgs);
+ break;
}
String table = getTableFromMatch(match, uri);
int deleted = db.delete(table, selection, selectionArgs);
@@ -520,6 +522,17 @@ public class PhotoProvider extends SQLiteContentProvider {
return deleted;
}
+ private void deleteCascadeAccounts(SQLiteDatabase db, String accountSelect, String[] args) {
+ // Delete all photos associated with the account
+ String photoWhere = nestWhere(Photos.ACCOUNT_ID, Accounts.TABLE, accountSelect);
+ deleteCascadeMetadata(db, photoWhere, args);
+ db.delete(Photos.TABLE, photoWhere, args);
+
+ // Delete all albums that are associated with this account
+ String albumWhere = nestWhere(Albums.ACCOUNT_ID, Accounts.TABLE, accountSelect);
+ db.delete(Albums.TABLE, albumWhere, args);
+ }
+
private void deleteCascadePhotos(SQLiteDatabase db, String albumSelect,
String[] selectArgs) {
String photoWhere = nestWhere(Photos.ALBUM_ID, Albums.TABLE, albumSelect);
diff --git a/src/com/android/photos/data/PhotoSetLoader.java b/src/com/android/photos/data/PhotoSetLoader.java
index 72c8e93cc..56c82c4a9 100644
--- a/src/com/android/photos/data/PhotoSetLoader.java
+++ b/src/com/android/photos/data/PhotoSetLoader.java
@@ -29,6 +29,8 @@ import android.provider.MediaStore.Files.FileColumns;
import com.android.photos.drawables.DataUriThumbnailDrawable;
import com.android.photos.shims.LoaderCompatShim;
+import java.util.ArrayList;
+
public class PhotoSetLoader extends CursorLoader implements LoaderCompatShim<Cursor> {
public static final String SUPPORTED_OPERATIONS = "supported_operations";
@@ -95,4 +97,19 @@ public class PhotoSetLoader extends CursorLoader implements LoaderCompatShim<Cur
public Uri uriForItem(Cursor item) {
return null;
}
+
+ @Override
+ public ArrayList<Uri> urisForSubItems(Cursor item) {
+ return null;
+ }
+
+ @Override
+ public void deleteItemWithPath(Object path) {
+
+ }
+
+ @Override
+ public Object getPathForItem(Cursor item) {
+ return null;
+ }
}
diff --git a/src/com/android/photos/shims/LoaderCompatShim.java b/src/com/android/photos/shims/LoaderCompatShim.java
index 9da4436aa..d5bf710de 100644
--- a/src/com/android/photos/shims/LoaderCompatShim.java
+++ b/src/com/android/photos/shims/LoaderCompatShim.java
@@ -19,8 +19,13 @@ package com.android.photos.shims;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import java.util.ArrayList;
+
public interface LoaderCompatShim<T> {
Drawable drawableForItem(T item, Drawable recycle);
Uri uriForItem(T item);
+ ArrayList<Uri> urisForSubItems(T item);
+ void deleteItemWithPath(Object path);
+ Object getPathForItem(T item);
}
diff --git a/src/com/android/photos/shims/MediaItemsLoader.java b/src/com/android/photos/shims/MediaItemsLoader.java
index fa41c8ec8..d75823404 100644
--- a/src/com/android/photos/shims/MediaItemsLoader.java
+++ b/src/com/android/photos/shims/MediaItemsLoader.java
@@ -28,12 +28,16 @@ import android.util.SparseArray;
import com.android.gallery3d.data.ContentListener;
import com.android.gallery3d.data.DataManager;
import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
import com.android.gallery3d.data.MediaSet;
import com.android.gallery3d.data.MediaSet.ItemConsumer;
import com.android.gallery3d.data.MediaSet.SyncListener;
+import com.android.gallery3d.data.Path;
import com.android.gallery3d.util.Future;
import com.android.photos.data.PhotoSetLoader;
+import java.util.ArrayList;
+
/**
* Returns all MediaItems in a MediaSet, wrapping them in a cursor to appear
* like a PhotoSetLoader
@@ -47,6 +51,7 @@ public class MediaItemsLoader extends AsyncTaskLoader<Cursor> implements LoaderC
};
private final MediaSet mMediaSet;
+ private final DataManager mDataManager;
private Future<Integer> mSyncTask = null;
private ContentListener mObserver = new ContentListener() {
@Override
@@ -58,14 +63,15 @@ public class MediaItemsLoader extends AsyncTaskLoader<Cursor> implements LoaderC
public MediaItemsLoader(Context context) {
super(context);
- DataManager dm = DataManager.from(context);
- String path = dm.getTopSetPath(DataManager.INCLUDE_ALL);
- mMediaSet = dm.getMediaSet(path);
+ mDataManager = DataManager.from(context);
+ String path = mDataManager.getTopSetPath(DataManager.INCLUDE_ALL);
+ mMediaSet = mDataManager.getMediaSet(path);
}
public MediaItemsLoader(Context context, String parentPath) {
super(context);
- mMediaSet = DataManager.from(getContext()).getMediaSet(parentPath);
+ mDataManager = DataManager.from(getContext());
+ mMediaSet = mDataManager.getMediaSet(parentPath);
}
@Override
@@ -157,4 +163,27 @@ public class MediaItemsLoader extends AsyncTaskLoader<Cursor> implements LoaderC
return mi == null ? null : mi.getContentUri();
}
+ @Override
+ public ArrayList<Uri> urisForSubItems(Cursor item) {
+ return null;
+ }
+
+ @Override
+ public void deleteItemWithPath(Object path) {
+ MediaObject o = mDataManager.getMediaObject((Path) path);
+ if (o != null) {
+ o.delete();
+ }
+ }
+
+ @Override
+ public Object getPathForItem(Cursor item) {
+ int index = item.getInt(PhotoSetLoader.INDEX_ID);
+ MediaItem mi = mMediaItems.get(index);
+ if (mi != null) {
+ return mi.getPath();
+ }
+ return null;
+ }
+
}
diff --git a/src/com/android/photos/shims/MediaSetLoader.java b/src/com/android/photos/shims/MediaSetLoader.java
index 96c7485bb..d200807f9 100644
--- a/src/com/android/photos/shims/MediaSetLoader.java
+++ b/src/com/android/photos/shims/MediaSetLoader.java
@@ -26,7 +26,9 @@ import android.net.Uri;
import com.android.gallery3d.data.ContentListener;
import com.android.gallery3d.data.DataManager;
import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.Path;
import com.android.gallery3d.data.MediaSet.SyncListener;
import com.android.gallery3d.util.Future;
import com.android.photos.data.AlbumSetLoader;
@@ -46,6 +48,7 @@ public class MediaSetLoader extends AsyncTaskLoader<Cursor> implements LoaderCom
};
private final MediaSet mMediaSet;
+ private final DataManager mDataManager;
private Future<Integer> mSyncTask = null;
private ContentListener mObserver = new ContentListener() {
@Override
@@ -58,14 +61,15 @@ public class MediaSetLoader extends AsyncTaskLoader<Cursor> implements LoaderCom
public MediaSetLoader(Context context) {
super(context);
- DataManager dm = DataManager.from(context);
- String path = dm.getTopSetPath(DataManager.INCLUDE_ALL);
- mMediaSet = dm.getMediaSet(path);
+ mDataManager = DataManager.from(context);
+ String path = mDataManager.getTopSetPath(DataManager.INCLUDE_ALL);
+ mMediaSet = mDataManager.getMediaSet(path);
}
public MediaSetLoader(Context context, String path) {
super(context);
- mMediaSet = DataManager.from(getContext()).getMediaSet(path);
+ mDataManager = DataManager.from(getContext());
+ mMediaSet = mDataManager.getMediaSet(path);
}
@Override
@@ -111,6 +115,7 @@ public class MediaSetLoader extends AsyncTaskLoader<Cursor> implements LoaderCom
row[AlbumSetLoader.INDEX_ID] = i;
row[AlbumSetLoader.INDEX_TITLE] = m.getName();
row[AlbumSetLoader.INDEX_COUNT] = m.getMediaItemCount();
+ row[AlbumSetLoader.INDEX_SUPPORTED_OPERATIONS] = m.getSupportedOperations();
MediaItem coverItem = m.getCoverMediaItem();
if (coverItem != null) {
row[AlbumSetLoader.INDEX_TIMESTAMP] = coverItem.getDateInMs();
@@ -147,4 +152,39 @@ public class MediaSetLoader extends AsyncTaskLoader<Cursor> implements LoaderCom
MediaSet ms = mMediaSet.getSubMediaSet(index);
return ms == null ? null : ms.getContentUri();
}
+
+ @Override
+ public ArrayList<Uri> urisForSubItems(Cursor item) {
+ int index = item.getInt(AlbumSetLoader.INDEX_ID);
+ MediaSet ms = mMediaSet.getSubMediaSet(index);
+ if (ms == null) return null;
+ final ArrayList<Uri> result = new ArrayList<Uri>();
+ ms.enumerateMediaItems(new MediaSet.ItemConsumer() {
+ @Override
+ public void consume(int index, MediaItem item) {
+ if (item != null) {
+ result.add(item.getContentUri());
+ }
+ }
+ });
+ return result;
+ }
+
+ @Override
+ public void deleteItemWithPath(Object path) {
+ MediaObject o = mDataManager.getMediaObject((Path) path);
+ if (o != null) {
+ o.delete();
+ }
+ }
+
+ @Override
+ public Object getPathForItem(Cursor item) {
+ int index = item.getInt(AlbumSetLoader.INDEX_ID);
+ MediaSet ms = mMediaSet.getSubMediaSet(index);
+ if (ms != null) {
+ return ms.getPath();
+ }
+ return null;
+ }
}
diff --git a/src/com/android/photos/views/SquareImageView.java b/src/com/android/photos/views/SquareImageView.java
new file mode 100644
index 000000000..14eff1077
--- /dev/null
+++ b/src/com/android/photos/views/SquareImageView.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 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.photos.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+
+public class SquareImageView extends ImageView {
+
+ public SquareImageView(Context context) {
+ super(context);
+ }
+
+ public SquareImageView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ if (widthMode == MeasureSpec.EXACTLY && heightMode != MeasureSpec.EXACTLY) {
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ int height = width;
+ if (heightMode == MeasureSpec.AT_MOST) {
+ height = Math.min(height, MeasureSpec.getSize(heightMeasureSpec));
+ }
+ setMeasuredDimension(width, height);
+ } else {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+ }
+}