/*
* Copyright (C) 2007-2008 Esmertec AG. Copyright (C) 2007-2008 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 org.awesomeapp.messenger.ui;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.ResourceCursorAdapter;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
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.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import org.awesomeapp.messenger.ImApp;
import org.awesomeapp.messenger.Preferences;
import org.awesomeapp.messenger.provider.Imps;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import im.zom.messenger.R;
/** Activity used to pick a contact. */
public class ContactsPickerActivity extends BaseActivity {
public final static String EXTRA_EXCLUDED_CONTACTS = "excludes";
public final static String EXTRA_RESULT_USERNAME = "result";
public final static String EXTRA_RESULT_USERNAMES = "results";
public final static String EXTRA_RESULT_PROVIDER = "provider";
public final static String EXTRA_RESULT_ACCOUNT = "account";
public final static String EXTRA_RESULT_MESSAGE = "message";
private int REQUEST_CODE_ADD_CONTACT = 9999;
private ContactAdapter mAdapter;
private MyLoaderCallbacks mLoaderCallbacks;
private ContactListListener mListener = null;
private Uri mUri = Imps.Contacts.CONTENT_URI;
private Handler mHandler = new Handler();
private String mExcludeClause;
Uri mData;
private String mSearchString;
SearchView mSearchView = null;
ListView mListView = null;
// The loader's unique id. Loader ids are specific to the Activity or
// Fragment in which they reside.
private static final int LOADER_ID = 1;
// The callbacks through which we will interact with the LoaderManager.
private LoaderManager.LoaderCallbacks<Cursor> mCallbacks;
private boolean mIsCABDestroyed= true;
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_contact_picker_multi, menu);
return false;
}
@Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
if (menuItem.getItemId() == R.id.action_start_chat)
{
SparseBooleanArray checkedPos = mListView.getCheckedItemPositions();
multiFinish(checkedPos);
return true;
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode actionMode) {
mAdapter.clearSelection();
mIsCABDestroyed = true;
}
};
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
((ImApp)getApplication()).setAppTheme(this);
setContentView(R.layout.contacts_picker_activity);
if (getIntent().getData() != null)
mUri = getIntent().getData();
mListView = (ListView)findViewById(R.id.contactsList);
mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
multiStart(i);
//getSupportActionBar().startActionMode(mActionModeCallback);
return true;
}
});
mListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
private int nr = 0;
@Override
public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_contact_picker_multi, menu);
return true;
}
@Override
public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.action_start_chat)
{
SparseBooleanArray checkedPos = mListView.getCheckedItemPositions();
multiFinish(checkedPos);
return true;
}
return false;
}
@Override
public void onDestroyActionMode(android.view.ActionMode mode) {
nr = 0;
mAdapter.clearSelection();
mIsCABDestroyed = true;
}
@Override
public void onItemCheckedStateChanged(android.view.ActionMode mode, int position, long id, boolean checked) {
mAdapter.setNewSelection(position, checked);
if (!checked)
mAdapter.removeSelection(position);
}
});
mListView.setOnItemClickListener(new OnItemClickListener ()
{
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
if(mIsCABDestroyed) {
mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
//do your action command here
}
if (mListView.getChoiceMode() == ListView.CHOICE_MODE_MULTIPLE_MODAL) {
//mAdapter.getItem(position);
boolean newChecked = !mListView.isItemChecked(position);
mListView.setItemChecked(position, newChecked);
mAdapter.setNewSelection(position, newChecked);
if (!newChecked)
mAdapter.removeSelection(position);
}
else {
Cursor cursor = (Cursor) mAdapter.getItem(position);
Intent data = new Intent();
data.putExtra(EXTRA_RESULT_USERNAME, cursor.getString(ContactListItem.COLUMN_CONTACT_USERNAME));
data.putExtra(EXTRA_RESULT_PROVIDER, cursor.getLong(ContactListItem.COLUMN_CONTACT_PROVIDER));
data.putExtra(EXTRA_RESULT_ACCOUNT, cursor.getLong(ContactListItem.COLUMN_CONTACT_ACCOUNT));
setResult(RESULT_OK, data);
finish();
}
}
});
doFilterAsync("");
}
private void multiStart (int i)
{
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListView.startActionMode(mActionModeCallback);
if (i != -1)
mAdapter.setNewSelection(i, true);
mIsCABDestroyed = false; // mark readiness to switch back to SINGLE CHOICE after the CABis destroyed
}
private void multiFinish (SparseBooleanArray positions)
{
ArrayList<String> users = new ArrayList<String>();
ArrayList<Integer> providers = new ArrayList<Integer>();
ArrayList<Integer> accounts = new ArrayList<Integer>();
for (int i = 0; i < positions.size(); i++)
{
if (positions.valueAt(i)) {
Cursor cursor = (Cursor) mAdapter.getItem(i);
users.add(cursor.getString(ContactListItem.COLUMN_CONTACT_USERNAME));
providers.add((int) cursor.getLong(ContactListItem.COLUMN_CONTACT_PROVIDER));
accounts.add((int) cursor.getLong(ContactListItem.COLUMN_CONTACT_ACCOUNT));
}
}
Intent data = new Intent();
data.putStringArrayListExtra(EXTRA_RESULT_USERNAMES, users);
data.putIntegerArrayListExtra(EXTRA_RESULT_PROVIDER, providers);
data.putIntegerArrayListExtra(EXTRA_RESULT_ACCOUNT, accounts);
setResult(RESULT_OK, data);
finish();
}
@Override
protected void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
if (response == RESULT_OK)
if (request == REQUEST_CODE_ADD_CONTACT)
{
String newContact = data.getExtras().getString(ContactsPickerActivity.EXTRA_RESULT_USERNAME);
if (newContact != null)
{
Intent dataNew = new Intent();
long providerId = data.getExtras().getLong(ContactsPickerActivity.EXTRA_RESULT_PROVIDER);
dataNew.putExtra(EXTRA_RESULT_USERNAME, newContact);
dataNew.putExtra(EXTRA_RESULT_PROVIDER, providerId);
setResult(RESULT_OK, dataNew);
finish();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.contact_list_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
mSearchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.menu_search));
if (mSearchView != null )
{
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
mSearchView.setIconifiedByDefault(false);
SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener()
{
public boolean onQueryTextChange(String newText)
{
mSearchString = newText;
doFilterAsync(mSearchString);
return true;
}
public boolean onQueryTextSubmit(String query)
{
mSearchString = query;
doFilterAsync(mSearchString);
return true;
}
};
mSearchView.setOnQueryTextListener(queryTextListener);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId())
{
case R.id.menu_new_group_chat:
multiStart(-1);
// getSupportActionBar().startActionMode(mActionModeCallback);
return true;
}
return super.onOptionsItemSelected(item);
}
public void doFilterAsync (final String query)
{
doFilter(query);
}
boolean mAwaitingUpdate = false;
public synchronized void doFilter(String filterString) {
mSearchString = filterString;
if (mAdapter == null) {
mAdapter = new ContactAdapter(ContactsPickerActivity.this, R.layout.contact_view);
mListView.setAdapter(mAdapter);
mLoaderCallbacks = new MyLoaderCallbacks();
getSupportLoaderManager().initLoader(LOADER_ID, null, mLoaderCallbacks);
} else {
if (!mAwaitingUpdate)
{
mAwaitingUpdate = true;
mHandler.postDelayed(new Runnable ()
{
public void run ()
{
getSupportLoaderManager().restartLoader(LOADER_ID, null, mLoaderCallbacks);
mAwaitingUpdate = false;
}
},1000);
}
}
}
private Cursor mCursor;
@Override
protected void onDestroy() {
super.onDestroy();
if (mCursor != null && (!mCursor.isClosed()))
mCursor.close();
}
private class ContactAdapter extends ResourceCursorAdapter {
private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();
public ContactAdapter(Context context, int view) {
super(context, view, null,0);
}
@Override
public boolean hasStableIds() {
return true;
}
public void setNewSelection(int position, boolean value) {
mSelection.put(position, value);
notifyDataSetChanged();
}
public boolean isPositionChecked(int position) {
Boolean result = mSelection.get(position);
return result == null ? false : result;
}
public Set<Integer> getCurrentCheckedPosition() {
return mSelection.keySet();
}
public void removeSelection(int position) {
mSelection.remove(position);
notifyDataSetChanged();
}
public void clearSelection() {
mSelection = new HashMap<Integer, Boolean>();
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);//let the adapter handle setting up the row views
v.setBackgroundColor(getResources().getColor(android.R.color.transparent));
if (mSelection.get(position) != null) {
v.setBackgroundColor(getResources().getColor(R.color.holo_blue_light));
}
return super.getView(position, convertView, parent);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
ContactListItem v = (ContactListItem) view;
ContactViewHolder holder = (ContactViewHolder)view.getTag();
if (holder == null) {
holder = new ContactViewHolder(v);
holder.mLine1 = (TextView) view.findViewById(R.id.line1);
holder.mLine2 = (TextView) view.findViewById(R.id.line2);
holder.mAvatar = (ImageView)view.findViewById(R.id.avatar);
holder.mSubBox = view.findViewById(R.id.subscriptionBox);
holder.mButtonSubApprove = (Button)view.findViewById(R.id.btnApproveSubscription);
holder.mButtonSubDecline = (Button)view.findViewById(R.id.btnDeclineSubscription);
//holder.mStatusIcon = (ImageView)view.findViewById(R.id.statusIcon);
//holder.mStatusText = (TextView)view.findViewById(R.id.statusText);
//holder.mEncryptionIcon = (ImageView)view.findViewById(R.id.encryptionIcon);
holder.mContainer = view.findViewById(R.id.message_container);
// holder.mMediaThumb = (ImageView)findViewById(R.id.media_thumbnail);
view.setTag(holder);
}
v.bind(holder, cursor, mSearchString, false);
}
}
class MyLoaderCallbacks implements LoaderCallbacks<Cursor> {
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
StringBuilder buf = new StringBuilder();
if (mSearchString != null) {
buf.append('(');
buf.append(Imps.Contacts.NICKNAME);
buf.append(" LIKE ");
DatabaseUtils.appendValueToSql(buf, "%" + mSearchString + "%");
buf.append(" OR ");
buf.append(Imps.Contacts.USERNAME);
buf.append(" LIKE ");
DatabaseUtils.appendValueToSql(buf, "%" + mSearchString + "%");
buf.append(')');
buf.append(" AND ");
}
buf.append(Imps.Contacts.TYPE).append('=').append(Imps.Contacts.TYPE_NORMAL);
CursorLoader loader = new CursorLoader(ContactsPickerActivity.this, mUri, ContactListItem.CONTACT_PROJECTION,
buf == null ? null : buf.toString(), null, Imps.Contacts.MODE_AND_ALPHA_SORT_ORDER);
// loader.setUpdateThrottle(50L);
return loader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor newCursor) {
mAdapter.swapCursor(newCursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
}
public interface ContactListListener {
public void openChat (Cursor c);
public void showProfile (Cursor c);
}
}