package edu.mit.mobile.android.livingpostcards;
/*
* Copyright (C) 2012-2013 MIT Mobile Experience Lab
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation version 2
* of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.IOException;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.stackoverflow.ArrayUtils;
import edu.mit.mobile.android.flipr.R;
import edu.mit.mobile.android.imagecache.ImageCache;
import edu.mit.mobile.android.imagecache.ImageLoaderAdapter;
import edu.mit.mobile.android.imagecache.SimpleThumbnailCursorAdapter;
import edu.mit.mobile.android.livingpostcards.auth.Authenticator;
import edu.mit.mobile.android.livingpostcards.data.Card;
import edu.mit.mobile.android.locast.data.PrivatelyAuthorable;
import edu.mit.mobile.android.locast.sync.LocastSyncService;
public class CardListFragment extends ListFragment implements LoaderCallbacks<Cursor>,
OnItemClickListener, OnClickListener {
private static final String[] FROM = { Card.COL_TITLE, Card.COL_AUTHOR, Card.COL_COVER_PHOTO,
Card.COL_THUMBNAIL, Card.COL_DRAFT };
private static final int[] TO = { R.id.title, R.id.author, R.id.card_media_thumbnail,
R.id.card_media_thumbnail };
private static final String[] PROJECTION = ArrayUtils.concat(new String[] { Card._ID,
Card.COL_PRIVACY, Card.COL_AUTHOR_URI, Card.COL_WEB_URL }, FROM);
private SimpleThumbnailCursorAdapter mAdapter;
ImageCache mImageCache;
public static final String ARG_CARD_DIR_URI = "uri";
private Uri mCards = Card.CONTENT_URI;
private float mDensity;
private static final String TAG = CardListFragment.class.getSimpleName();
private static final int[] IMAGE_IDS = new int[] { R.id.card_media_thumbnail };
public CardListFragment() {
super();
}
public static CardListFragment instantiate(Uri cardDir) {
final Bundle b = new Bundle();
b.putParcelable(ARG_CARD_DIR_URI, cardDir);
final CardListFragment f = new CardListFragment();
f.setArguments(b);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Bundle args = getArguments();
if (args != null) {
final Uri newUri = args.getParcelable(ARG_CARD_DIR_URI);
mCards = newUri != null ? newUri : mCards;
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.card_list_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
view.findViewById(R.id.new_card).setOnClickListener(this);
// add a footer so that there's enough room for the content even with the red button at the
// bottom
final ListView lv = getListView();
lv.addFooterView(
getLayoutInflater(savedInstanceState).inflate(R.layout.scroll_footer, lv, false),
null, false);
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mImageCache = ImageCache.getInstance(getActivity());
mAdapter = new SimpleThumbnailCursorAdapter(getActivity(), R.layout.card_list_item, null,
FROM, TO, IMAGE_IDS, 0) {
@Override
public void bindView(View v, Context context, Cursor c) {
super.bindView(v, context, c);
((TextView) v.findViewById(R.id.title)).setText(Card.getTitle(context, c));
}
};
setListAdapter(new ImageLoaderAdapter(getActivity(), mAdapter, mImageCache, IMAGE_IDS, 133,
100, ImageLoaderAdapter.UNIT_DIP));
getListView().setOnItemClickListener(this);
getLoaderManager().initLoader(0, null, this);
LocastSyncService.startExpeditedAutomaticSync(getActivity(), mCards.buildUpon().query(null)
.build());
registerForContextMenu(getListView());
mDensity = getActivity().getResources().getDisplayMetrics().density;
}
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
return new CursorLoader(getActivity(), mCards, PROJECTION, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor c) {
mAdapter.swapCursor(c);
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
mAdapter.swapCursor(null);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final Uri item = ContentUris.withAppendedId(mCards, id);
final Cursor c = mAdapter.getCursor();
c.moveToPosition(position);
if (Card.isDraft(c)) {
startActivity(new Intent(Intent.ACTION_EDIT, item));
} else {
startActivity(new Intent(Intent.ACTION_VIEW, item));
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
getActivity().getMenuInflater().inflate(R.menu.activity_card_view, menu);
final Cursor c = mAdapter.getCursor();
if (c == null) {
return;
}
final String myUserUri = Authenticator.getUserUri(getActivity());
final boolean isEditable = PrivatelyAuthorable.canEdit(myUserUri, c);
menu.findItem(R.id.delete).setVisible(isEditable);
menu.findItem(R.id.edit).setVisible(isEditable);
menu.setHeaderTitle(Card.getTitle(getActivity(), c));
Drawable icon;
try {
String iconUrl = c.getString(c.getColumnIndexOrThrow(Card.COL_COVER_PHOTO));
if (iconUrl == null || iconUrl.length() == 0) {
iconUrl = c.getString(c.getColumnIndexOrThrow(Card.COL_THUMBNAIL));
}
icon = mImageCache.loadImage(0, Uri.parse(iconUrl), (int) (133 * mDensity),
(int) (100 * mDensity));
if (icon != null) {
menu.setHeaderIcon(new InsetDrawable(icon, (int) (5 * mDensity)));
}
} catch (final IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (final IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void send(Cursor c) {
final String mWebUrl = c.getString(c.getColumnIndexOrThrow(Card.COL_WEB_URL));
if (mWebUrl == null) {
Toast.makeText(getActivity(), R.string.err_share_intent_no_web_url_editable,
Toast.LENGTH_LONG).show();
return;
}
startActivity(Card.createShareIntent(getActivity(), mWebUrl,
Card.getTitle(getActivity(), c)));
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
} catch (final ClassCastException e) {
Log.e(TAG, "bad menuInfo", e);
return false;
}
final Uri card = ContentUris.withAppendedId(mCards, info.id);
switch (item.getItemId()) {
case R.id.share:
send(mAdapter.getCursor());
return true;
case R.id.edit:
startActivity(new Intent(Intent.ACTION_EDIT, card));
return true;
case R.id.delete:
startActivity(new Intent(Intent.ACTION_DELETE, card));
return true;
default:
return super.onContextItemSelected(item);
}
}
private void createNewCard() {
final Intent intent = new Intent(Intent.ACTION_INSERT, Card.CONTENT_URI);
startActivity(intent);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.new_card:
createNewCard();
break;
default:
break;
}
}
}