blob: 55888aaad7a97eda0b9533795a3d3f3c1f7e3899 [file] [log] [blame]
/*
* Copyright (C) 2011 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.contacts.group;
import com.android.contacts.ContactPhotoManager;
import com.android.contacts.GroupMemberLoader;
import com.android.contacts.GroupMetaDataLoader;
import com.android.contacts.R;
import com.android.contacts.interactions.GroupDeletionDialogFragment;
import com.android.contacts.list.ContactTileAdapter;
import com.android.contacts.list.ContactTileAdapter.DisplayType;
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
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;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.TextView;
/**
* Displays the details of a group and shows a list of actions possible for the group.
*/
public class GroupDetailFragment extends Fragment implements OnScrollListener {
public static interface Listener {
/**
* The group title has been loaded
*/
public void onGroupTitleUpdated(String title);
/**
* The number of group members has been determined
*/
public void onGroupSizeUpdated(String size);
/**
* User decided to go to Edit-Mode
*/
public void onEditRequested(Uri groupUri);
}
private static final String TAG = "GroupDetailFragment";
private static final int LOADER_METADATA = 0;
private static final int LOADER_MEMBERS = 1;
private Context mContext;
private View mRootView;
private TextView mGroupTitle;
private TextView mGroupSize;
private ListView mMemberListView;
private Listener mListener;
private ContactTileAdapter mAdapter;
private ContactPhotoManager mPhotoManager;
private Uri mGroupUri;
private long mGroupId;
private String mGroupName;
private boolean mOptionsMenuEditable;
private boolean mCloseActivityAfterDelete;
public GroupDetailFragment() {
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = activity;
Resources res = getResources();
int columnCount = res.getInteger(R.integer.contact_tile_column_count);
mAdapter = new ContactTileAdapter(activity, mContactTileListener, columnCount,
DisplayType.GROUP_MEMBERS);
configurePhotoLoader();
}
@Override
public void onDetach() {
super.onDetach();
mContext = null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
setHasOptionsMenu(true);
mRootView = inflater.inflate(R.layout.group_detail_fragment, container, false);
mGroupTitle = (TextView) mRootView.findViewById(R.id.group_title);
mGroupSize = (TextView) mRootView.findViewById(R.id.group_size);
mMemberListView = (ListView) mRootView.findViewById(android.R.id.list);
return mRootView;
}
public void loadGroup(Uri groupUri) {
mGroupUri= groupUri;
startGroupMetadataLoader();
}
public void setQuickContact(boolean enableQuickContact) {
mAdapter.setQuickContact(enableQuickContact);
}
private void configureAdapter(long groupId) {
mGroupId = groupId;
mMemberListView.setAdapter(mAdapter);
}
private void configurePhotoLoader() {
if (mContext != null) {
if (mPhotoManager == null) {
mPhotoManager = ContactPhotoManager.getInstance(mContext);
}
if (mMemberListView != null) {
mMemberListView.setOnScrollListener(this);
}
if (mAdapter != null) {
mAdapter.setPhotoLoader(mPhotoManager);
}
}
}
public void setListener(Listener value) {
mListener = value;
}
/**
* Start the loader to retrieve the metadata for this group.
*/
private void startGroupMetadataLoader() {
getLoaderManager().destroyLoader(LOADER_METADATA);
getLoaderManager().restartLoader(LOADER_METADATA, null, mGroupMetadataLoaderListener);
}
/**
* Start the loader to retrieve the list of group members.
*/
private void startGroupMembersLoader() {
getLoaderManager().destroyLoader(LOADER_MEMBERS);
getLoaderManager().restartLoader(LOADER_MEMBERS, null, mGroupMemberListLoaderListener);
}
private final ContactTileAdapter.Listener mContactTileListener =
new ContactTileAdapter.Listener() {
@Override
public void onContactSelected(Uri contactUri) {
// TODO: Launch Quick Contact
}
};
/**
* The listener for the group metadata loader.
*/
private final LoaderManager.LoaderCallbacks<Cursor> mGroupMetadataLoaderListener =
new LoaderCallbacks<Cursor>() {
@Override
public CursorLoader onCreateLoader(int id, Bundle args) {
return new GroupMetaDataLoader(mContext, mGroupUri);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
data.moveToPosition(-1);
if (data.moveToNext()) {
boolean deleted = data.getInt(GroupMetaDataLoader.DELETED) == 1;
if (!deleted) {
bindGroupMetaData(data);
// Retrieve the list of members
configureAdapter(mGroupId);
startGroupMembersLoader();
return;
}
}
updateSize(null);
updateTitle(null);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {}
};
/**
* The listener for the group members list loader
*/
private final LoaderManager.LoaderCallbacks<Cursor> mGroupMemberListLoaderListener =
new LoaderCallbacks<Cursor>() {
@Override
public CursorLoader onCreateLoader(int id, Bundle args) {
return new GroupMemberLoader(mContext, mGroupId);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
updateSize(Integer.toString(data.getCount()));
mAdapter.loadFromCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {}
};
private void bindGroupMetaData(Cursor cursor) {
cursor.moveToPosition(-1);
if (cursor.moveToNext()) {
mGroupId = cursor.getLong(GroupMetaDataLoader.GROUP_ID);
mGroupName = cursor.getString(GroupMetaDataLoader.TITLE);
updateTitle(mGroupName);
// TODO: Replace by real button
final String action = cursor.getString(GroupMetaDataLoader.ACTION);
final String actionUri = cursor.getString(GroupMetaDataLoader.ACTION_URI);
Log.d(TAG, "Group open action: " + action + ", uri: " + actionUri);
}
}
private void updateTitle(String title) {
if (mGroupTitle != null) {
mGroupTitle.setText(title);
} else {
mListener.onGroupTitleUpdated(title);
}
}
private void updateSize(String size) {
if (mGroupSize != null) {
mGroupSize.setText(size);
} else {
mListener.onGroupSizeUpdated(size);
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
mPhotoManager.pause();
} else {
mPhotoManager.resume();
}
}
@Override
public void onCreateOptionsMenu(Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.view_group, menu);
}
public boolean isOptionsMenuChanged() {
return mOptionsMenuEditable != isGroupEditable();
}
public boolean isGroupEditable() {
// TODO: This should check the group_is_read_only flag. Modify GroupMetaDataLoader.
// Bug: 4601729.
return mGroupUri != null;
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
mOptionsMenuEditable = isGroupEditable();
final MenuItem editMenu = menu.findItem(R.id.menu_edit_group);
editMenu.setVisible(mOptionsMenuEditable);
final MenuItem deleteMenu = menu.findItem(R.id.menu_delete_group);
deleteMenu.setVisible(mOptionsMenuEditable);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_edit_group: {
if (mListener != null) mListener.onEditRequested(mGroupUri);
break;
}
case R.id.menu_delete_group: {
GroupDeletionDialogFragment.show(getFragmentManager(), mGroupId, mGroupName,
mCloseActivityAfterDelete);
return true;
}
}
return false;
}
public void closeActivityAfterDelete(boolean closeActivity) {
mCloseActivityAfterDelete = closeActivity;
}
}