ContactList refactoring of contacts query and add muc list.
authorVincent V.<marseille@beem-project.com>
Mon, 20 Feb 2012 18:20:41 +0100
changeset 931 067387e7ab43
parent 930 ea7b1aeb5980
child 932 cdbfa28949bb
ContactList refactoring of contacts query and add muc list. MUCs are now registered in the provider during the sync
src/com/beem/project/beem/BeemApplication.java
src/com/beem/project/beem/BeemService.java
src/com/beem/project/beem/BeemSync.java
src/com/beem/project/beem/providers/MUCs.java
src/com/beem/project/beem/providers/MUCsProvider.java
src/com/beem/project/beem/ui/ContactList.java
--- a/src/com/beem/project/beem/BeemApplication.java	Fri Jan 27 11:31:23 2012 +0100
+++ b/src/com/beem/project/beem/BeemApplication.java	Mon Feb 20 18:20:41 2012 +0100
@@ -91,7 +91,13 @@
     public static final String CHAT_HISTORY_KEY = "settings_chat_history_path";
 
     //TODO add the other one
+    // String not use for reference but all around the application
     public static final String BEEM_PACKAGE = "com.beem.project.beem";
+    
+    // String for the contact list
+    public static final String ALL_CONTACT= "all_contact";    
+    public static final String NO_GROUP = "no_group";
+    public static final String MUC = "muc";
 
     private boolean mIsConnected;
     private boolean mIsAccountConfigured;
--- a/src/com/beem/project/beem/BeemService.java	Fri Jan 27 11:31:23 2012 +0100
+++ b/src/com/beem/project/beem/BeemService.java	Mon Feb 20 18:20:41 2012 +0100
@@ -490,8 +490,10 @@
 		    if (connection != null) {
 			BeemSync sync = new BeemSync(getBaseContext());
 			XMPPConnection xmppCo = connection.getAdaptee();
-			if (xmppCo != null)
+			if (xmppCo != null) {
 			    sync.manageRoster(xmppCo.getRoster(), accountName);
+			    sync.syncMUC(xmppCo, accountName);
+			}
 		    }
 		    BeemNotification.StopSyncNotification(getBaseContext());
 		    break;
@@ -566,7 +568,9 @@
 
 	    }
 	}
-	//Bookmark : Muc 
+	//Bookmark : Muc
+	//TODO : Get muc from provider and connect
+	//TODO : Add muc in BeemSync
 	if (mConnection.containsKey(accountName)) {
 	    Connection xmppCo = mConnection.get(accountName).getAdaptee();
 	    Collection<BookmarkedConference> list = null;
--- a/src/com/beem/project/beem/BeemSync.java	Fri Jan 27 11:31:23 2012 +0100
+++ b/src/com/beem/project/beem/BeemSync.java	Mon Feb 20 18:20:41 2012 +0100
@@ -31,11 +31,16 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collection;
 
+import org.jivesoftware.smack.Connection;
 import org.jivesoftware.smack.Roster;
 import org.jivesoftware.smack.RosterEntry;
 import org.jivesoftware.smack.RosterGroup;
+import org.jivesoftware.smack.XMPPException;
 import org.jivesoftware.smack.packet.Presence;
+import org.jivesoftware.smackx.bookmark.BookmarkManager;
+import org.jivesoftware.smackx.bookmark.BookmarkedConference;
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
@@ -50,6 +55,7 @@
 import android.provider.ContactsContract;
 import android.util.Log;
 
+import com.beem.project.beem.providers.MUCs;
 import com.beem.project.beem.service.BeemAvatarCache;
 import com.beem.project.beem.utils.Status;
 
@@ -113,7 +119,7 @@
 	}
 
 	ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
-	addVirtualGroup(ops, account, "All Contact");
+	addVirtualGroup(ops, account, "All Contact", BeemApplication.ALL_CONTACT);
 	for (RosterGroup group : r.getGroups()) {
 	    if (group != null) {
 		manageGroup(ops, account, group);
@@ -121,8 +127,9 @@
 	    if (ops.size() > NB_DB_OPERATION)
 		executeOperation(ops);
 	}
-	addVirtualGroup(ops, account, "No Group");
-	addVirtualGroup(ops, account, "Muc");
+	//TODO: Link entry without group to the NoGRoupID
+	addVirtualGroup(ops, account, "No Group", BeemApplication.NO_GROUP);
+	addVirtualGroup(ops, account, "Muc", BeemApplication.MUC);
 	if (ops.size() > 0)
 	    executeOperation(ops);
 	for (RosterEntry entry : r.getEntries()) {
@@ -318,6 +325,42 @@
 	ops.add(builder.build());
     }
 
+    public void syncMUC(Connection xmppCo, String accoutname) {
+	Collection<BookmarkedConference> list = null;
+	try {
+	    BookmarkManager bm = BookmarkManager.getBookmarkManager(xmppCo);
+	    list = bm.getBookmarkedConferences();
+	} catch (XMPPException e) {
+	    Log.e(TAG, "BookmarkManager", e);
+	}
+	for (BookmarkedConference bookmarkedConference : list) {
+	    ContentValues values = new ContentValues();
+	    values.put(MUCs.NAME, bookmarkedConference.getName());
+	    values.put(MUCs.JID, bookmarkedConference.getJid());
+	    values.put(MUCs.AUTO_JOIN, bookmarkedConference.isAutoJoin());
+	    values.put(MUCs.SHARED, bookmarkedConference.isShared());
+	    values.put(MUCs.NICKNAME, bookmarkedConference.getNickname());
+	    values.put(MUCs.PASSWORD, bookmarkedConference.getPassword());
+	    values.put(MUCs.ACCOUNT_NAME, accoutname);
+	    values.put(MUCs.ACCOUNT_TYPE, BeemApplication.BEEM_PACKAGE);
+	    Log.e(TAG, "MUC " + bookmarkedConference.getName());
+	    mContext.getContentResolver().insert(MUCs.CONTENT_URI, values);
+
+	    //	    if (bookmarkedConference.isAutoJoin()) {
+	    //		MultiUserChat muc2 = new MultiUserChat(xmppCo, bookmarkedConference.getJid());
+	    //
+	    //		DiscussionHistory history = new DiscussionHistory();
+	    //		history.setMaxStanzas(5);
+	    //		try {
+	    //		    muc2.join(bookmarkedConference.getNickname(), bookmarkedConference.getPassword(), history,
+	    //			SmackConfiguration.getPacketReplyTimeout());
+	    //		} catch (XMPPException e) {
+	    //		    Log.e(TAG, "MUC Join Problem", e);
+	    //		}
+	    //	    }
+	}
+    }
+
     /**
      * Get contact ID from android database.
      * @param account The account related
@@ -368,11 +411,14 @@
      * @param account The account related
      * @param groupName The virtual group name
      */
-    private void addVirtualGroup(ArrayList<ContentProviderOperation> ops, Account account, String groupName) {
+    private void addVirtualGroup(ArrayList<ContentProviderOperation> ops, Account account, String groupName,
+	String systemID) {
 	ContentProviderOperation.Builder builder = ContentProviderOperation
 	    .newInsert(ContactsContract.Groups.CONTENT_URI);
 	builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
 	builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type);
+	if (systemID != null)
+	    builder.withValue(ContactsContract.Groups.SYSTEM_ID, systemID);
 	builder.withValue(ContactsContract.Groups.TITLE, groupName);
 
 	ops.add(builder.build());
--- a/src/com/beem/project/beem/providers/MUCs.java	Fri Jan 27 11:31:23 2012 +0100
+++ b/src/com/beem/project/beem/providers/MUCs.java	Mon Feb 20 18:20:41 2012 +0100
@@ -34,22 +34,23 @@
 
 public class MUCs implements BaseColumns {
 
-	/**
-	 * Constructor.
-	 */
-	public MUCs() {
+    /**
+     * Constructor.
+     */
+    public MUCs() {
 
-	}
+    }
+
+    public static final Uri CONTENT_URI = Uri.parse("content://" + MUCsProvider.AUTHORITY + "/mucs");
+    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.beem.project.beem.provider.mucs";
 
-	public static final Uri CONTENT_URI = Uri.parse("content://"
-			+ MessageProvider.AUTHORITY + "/mucs");
-	public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.beem.project.beem.provider.mucs";
-
-	public static final String _ID = "_id";
-	public static final String NAME = "_NAME";
-	public static final String JID = "_JID";
-	public static final String AUTO_JOIN = "_AUTO_JOIN";
-	public static final String SHARED = "_SHARED";
-	public static final String NICKNAME = "_NICKNAME";
-	public static final String PASSWORD = "_PASSWORD";
+    public static final String _ID = "_id";
+    public static final String NAME = "_NAME";
+    public static final String JID = "_JID";
+    public static final String AUTO_JOIN = "_AUTO_JOIN";
+    public static final String SHARED = "_SHARED";
+    public static final String NICKNAME = "_NICKNAME";
+    public static final String PASSWORD = "_PASSWORD";
+    public static final String ACCOUNT_NAME = "_ACCOUNT_NAME";
+    public static final String ACCOUNT_TYPE = "_ACCOUNT_TYPE";
 }
--- a/src/com/beem/project/beem/providers/MUCsProvider.java	Fri Jan 27 11:31:23 2012 +0100
+++ b/src/com/beem/project/beem/providers/MUCsProvider.java	Mon Feb 20 18:20:41 2012 +0100
@@ -57,7 +57,7 @@
     private static final String MUCS_TABLE_NAME = "mucs";
     private static final UriMatcher sUriMatcher;
 
-    public static final String AUTHORITY = "com.beem.project.beem.providers.mucprovider";
+    public static final String AUTHORITY = "com.beem.project.beem.providers.mucsprovider";
 
     private static HashMap<String, String> mucsProjectionMap;
     private DatabaseHelper mDbHelper;
@@ -90,7 +90,7 @@
 	long rowId = db.insert(MUCS_TABLE_NAME, null, values);
 	if (rowId == -1)
 	    throw new SQLException("Failed to insert row into " + uri);
-	Uri mucUri = ContentUris.withAppendedId(MUCs.CONTENT_URI, rowId);	
+	Uri mucUri = ContentUris.withAppendedId(MUCs.CONTENT_URI, rowId);
 	getContext().getContentResolver().notifyChange(mucUri, null);
 	return mucUri;
 
@@ -151,7 +151,7 @@
     public String getType(Uri uri) {
 	switch (sUriMatcher.match(uri)) {
 	    case MUCS:
-		return Messages.CONTENT_TYPE;
+		return MUCs.CONTENT_TYPE;
 	    default:
 		throw new IllegalArgumentException("Unknown URI " + uri);
 	}
@@ -172,7 +172,9 @@
 	    createDatabase += MUCs.AUTO_JOIN + " BOOLEAN,";
 	    createDatabase += MUCs.SHARED + " BOOLEAN,";
 	    createDatabase += MUCs.NICKNAME + " VARCHAR(255),";
-	    createDatabase += MUCs.PASSWORD + " VARCHAR(255)";
+	    createDatabase += MUCs.PASSWORD + " VARCHAR(255),";
+	    createDatabase += MUCs.ACCOUNT_NAME + " VARCHAR(255),";
+	    createDatabase += MUCs.ACCOUNT_TYPE + " VARCHAR(255)";
 	    createDatabase += ");";
 	    try {
 		db.execSQL(createDatabase);
@@ -202,6 +204,8 @@
 	mucsProjectionMap.put(MUCs.SHARED, MUCs.SHARED);
 	mucsProjectionMap.put(MUCs.NICKNAME, MUCs.NICKNAME);
 	mucsProjectionMap.put(MUCs.PASSWORD, MUCs.PASSWORD);
+	mucsProjectionMap.put(MUCs.ACCOUNT_NAME, MUCs.ACCOUNT_NAME);
+	mucsProjectionMap.put(MUCs.ACCOUNT_TYPE, MUCs.ACCOUNT_TYPE);
     }
 
 }
--- a/src/com/beem/project/beem/ui/ContactList.java	Fri Jan 27 11:31:23 2012 +0100
+++ b/src/com/beem/project/beem/ui/ContactList.java	Mon Feb 20 18:20:41 2012 +0100
@@ -29,8 +29,6 @@
 package com.beem.project.beem.ui;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
 
 import android.app.Activity;
 import android.content.ContentUris;
@@ -47,6 +45,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.provider.ContactsContract;
+import android.provider.ContactsContract.RawContacts;
 import android.util.Log;
 import android.view.ContextMenu;
 import android.view.LayoutInflater;
@@ -59,8 +58,6 @@
 import android.widget.AdapterView;
 import android.widget.AdapterView.AdapterContextMenuInfo;
 import android.widget.AdapterView.OnItemClickListener;
-import android.widget.Filter;
-import android.widget.FilterQueryProvider;
 import android.widget.Filterable;
 import android.widget.Gallery;
 import android.widget.ImageView;
@@ -71,6 +68,7 @@
 import com.beem.project.beem.BeemApplication;
 import com.beem.project.beem.BeemIntent;
 import com.beem.project.beem.R;
+import com.beem.project.beem.providers.MUCs;
 import com.beem.project.beem.service.BeemAvatarCache;
 import com.beem.project.beem.ui.wizard.AccountConfigure;
 
@@ -88,27 +86,29 @@
     private int BANNER_POS_MUC;
 
     private final BeemContactListOnClick mOnContactClick = new BeemContactListOnClick();
+    private final BeemMucListOnClick mOnMucClick = new BeemMucListOnClick();
 
     private SharedPreferences mSettings;
     private BeemBanner mAdapterBanner;
-    private BeemContactList mAdapterContactList;
+    private SimpleCursorAdapter mAdapterContactList;
 
     private String mAccountName;
 
-    private static List<Long> mArrayContactID2Show = new ArrayList<Long>();
-    
     /**
      * Constructor.
      */
     public ContactList() {
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     protected void onCreate(Bundle saveBundle) {
 	super.onCreate(saveBundle);
 
 	setContentView(R.layout.contactlist);
-	
+
 	Bundle b = getIntent().getExtras();
 	if (b == null) {
 	    //TODO: Add toast to advice need to configure at least 1 beem account (Should not happend)
@@ -126,21 +126,15 @@
 	    new String[] { ContactsContract.Groups._ID, ContactsContract.Groups.TITLE },
 	    ContactsContract.Groups.ACCOUNT_NAME + "=?", new String[] { mAccountName }, null);
 
-	mAdapterBanner = new BeemBanner(this, R.layout.contactlist_group, cursorGroup,
-	    new String[] { ContactsContract.Groups.TITLE }, new int[] { R.id.contactlist_group });
+	mAdapterBanner = new BeemBanner(this, R.layout.contactlist_group, cursorGroup, new String[] {
+	    ContactsContract.Groups._ID, ContactsContract.Groups.TITLE }, new int[] { R.id.contactlist_group });
 	cursorGroup.registerContentObserver(new BeemGroupObserver(new Handler()));
 
 	BANNER_POS_MUC = cursorGroup.getCount() - 1;
 	BANNER_POS_NO_GROUP = cursorGroup.getCount() - 2;
 
 	// Get Contacts list
-	final Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon()
-	    .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccountName)
-	    .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, BeemApplication.BEEM_PACKAGE).build();
-	//TODO: change null value for the projection (not efficient)
-	Cursor cursorRawContact = getContentResolver().query(rawContactUri, null,
-	    ContactsContract.RawContacts.DELETED + "= 0", null, null);
-
+	Cursor cursorRawContact = getContacts();
 	mAdapterContactList = new BeemContactList(this, R.layout.contactlistcontact, cursorRawContact, new String[] {
 	    ContactsContract.RawContacts._ID, ContactsContract.RawContacts.CONTACT_ID,
 	    ContactsContract.RawContacts.SOURCE_ID }, new int[] { R.id.avatar, R.id.contactlistpseudo,
@@ -150,17 +144,11 @@
 	listView.setOnItemClickListener(mOnContactClick);
 	registerForContextMenu(listView);
 	listView.setAdapter(mAdapterContactList);
-
-	mAdapterContactList.setFilterQueryProvider(new FilterQueryProvider() {
-	    @Override
-	    public Cursor runQuery(CharSequence constraint) {
-		String s = '%' + constraint.toString() + '%';
-		return getContentResolver().query(rawContactUri, null,
-		    ContactsContract.RawContacts.SOURCE_ID + " LIKE ? ", new String[] { s }, null);
-	    }
-	});
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     protected void onResume() {
 	super.onResume();
@@ -170,6 +158,9 @@
 	    hideGroups();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public final boolean onCreateOptionsMenu(Menu menu) {
 	super.onCreateOptionsMenu(menu);
@@ -178,6 +169,9 @@
 	return true;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public final boolean onOptionsItemSelected(MenuItem item) {
 	switch (item.getItemId()) {
@@ -215,6 +209,9 @@
 	}
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
 	super.onCreateContextMenu(menu, v, menuInfo);
@@ -230,6 +227,9 @@
 	// menu.setHeaderTitle(mSelectedContact.getJID());
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public boolean onContextItemSelected(MenuItem item) {
 	Intent in;
@@ -297,14 +297,12 @@
      * Show the groups view.
      */
     private void showGroups() {
-	Log.e(TAG, "SHOWGROUPS");
 	ViewStub stub = (ViewStub) findViewById(R.id.contactlist_stub);
 	if (stub != null) {
 	    View v = stub.inflate();
 	    Gallery g = (Gallery) v.findViewById(R.id.contactlist_banner);
 	    g.setOnItemClickListener(new OnItemClickGroupName());
 	    g.setAdapter(mAdapterBanner);
-	    Log.e(TAG, "SHOWGROUPS" + mAdapterBanner.getCount());
 	    if (mAdapterBanner.getCount() == 0)
 		v.setVisibility(View.GONE);
 	    else
@@ -316,7 +314,6 @@
      * Hide the groups view.
      */
     private void hideGroups() {
-	Log.e(TAG, "hideGroups");
 	View v = findViewById(R.id.contactlist_groupstub);
 	if (v != null)
 	    v.setVisibility(View.GONE);
@@ -325,14 +322,21 @@
     /**
      * Adapter contact list.
      */
-    private static class BeemContactList extends SimpleCursorAdapter implements Filterable {
+    private static class BeemContactList extends SimpleCursorAdapter {
 
 	private Context mContext;
 	private int mLayout;
 	private BeemAvatarCache mBeemAvatarCache;
-	private final GroupFilter mGroupFilter = new GroupFilter();
 	private Cursor mCursor;
 
+	/**
+	 * Constructor.
+	 * @param context
+	 * @param layout
+	 * @param c
+	 * @param from
+	 * @param to
+	 */
 	public BeemContactList(Context context, int layout, Cursor c, String[] from, int[] to) {
 	    super(context, layout, c, from, to);
 	    mContext = context;
@@ -341,70 +345,74 @@
 	    mCursor = c;
 	}
 
-	@Override 
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public int getCount() {
-	    if (mArrayContactID2Show.size() > 0)
-		return mArrayContactID2Show.size();
 	    return mCursor.getCount();
 	}
-	
+
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
 	public View newView(Context context, Cursor cursor, ViewGroup parent) {
-	    final LayoutInflater inflater = LayoutInflater.from(mContext);
+	    final LayoutInflater inflater = LayoutInflater.from(context);
 	    return inflater.inflate(mLayout, parent, false);
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void changeCursor(Cursor c) {
+	    super.changeCursor(c);
+	    mCursor = c;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
 	public void bindView(View view, Context context, Cursor cursor) {
 
 	    long id = cursor.getLong(cursor.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID));
 
-	    if (mArrayContactID2Show.size() > 0 && !mArrayContactID2Show.contains(id))
-		return;
-
-	    Log.e("BINDVIEWWW", "OOOOOO" + id);
+	    Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, id);
+	    Uri ContactLookupUri = ContactsContract.RawContacts.getContactLookupUri(context.getContentResolver(),
+		rawContactUri);
+	    if (ContactLookupUri != null) {
+		Cursor cursorContact = context.getContentResolver().query(
+		    ContactLookupUri,
+		    new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME,
+			ContactsContract.Contacts.CONTACT_STATUS }, null, null, null);
 
-	    Uri rawContactUri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, id);
-	    Uri entityUri = Uri.withAppendedPath(rawContactUri, ContactsContract.RawContacts.Entity.CONTENT_DIRECTORY);
-	    Cursor cursorContact = mContext.getContentResolver().query(
-		entityUri,
-		new String[] { ContactsContract.RawContacts.SOURCE_ID, ContactsContract.RawContacts.Entity.DATA_ID,
-		    ContactsContract.RawContacts.Entity.MIMETYPE, ContactsContract.RawContacts.Entity.DATA1 }, null,
-		null, null);
- 
-	    try {
-		while (cursorContact.moveToNext()) {
-		    if (!cursorContact.isNull(1)) {
-			String mimeType = cursorContact.getString(2);
-			String data = cursorContact.getString(3);
-			if (mimeType.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)) {
-			    TextView nameText = (TextView) view.findViewById(R.id.contactlistpseudo);
-			    nameText.setText(data);
-			}
-			//else if other mimetype
+		if (cursorContact.moveToFirst()) {
+		    String name = cursorContact.getString(cursorContact
+			.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
+		    String msg = cursorContact.getString(cursorContact
+			.getColumnIndex(ContactsContract.Contacts.CONTACT_STATUS));
+		    TextView nameText = (TextView) view.findViewById(R.id.contactlistpseudo);
+		    nameText.setText(name);
+		    TextView msgperso = (TextView) view.findViewById(R.id.contactlistmsgperso);
+		    msgperso.setText(msg);
 
-		    }
+		    String jid = cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.SOURCE_ID));
+		    view.setTag(jid);
+
+		    ImageView img = (ImageView) view.findViewById(R.id.avatar);
+		    int contactStatus = 1;
+		    //TODO: set the jid instead of null then debug
+		    Drawable avatar = getAvatarStatusDrawable(null);
+		    img.setImageDrawable(avatar);
+		    img.setImageLevel(contactStatus);
 
 		}
-
-		String jid = cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.SOURCE_ID));
-		view.setTag(jid);
-
-		ImageView img = (ImageView) view.findViewById(R.id.avatar);
-		int contactStatus = 1;
-		//TODO: set the jid instead of null then debug
-		Drawable avatar = getAvatarStatusDrawable(null);
-		img.setImageDrawable(avatar);
-		img.setImageLevel(contactStatus);
-	    } finally {
 		cursorContact.close();
 	    }
 	}
 
-	public Filter getGroupFilter() {
-	    return mGroupFilter;
-	}
-
 	/**
 	 * Get a LayerDrawable containing the avatar and the status icon. The status icon will change with the level of
 	 * the drawable.
@@ -428,53 +436,55 @@
 	    ld.setDrawableByLayerId(R.id.avatar, avatarDrawable);
 	    return ld;
 	}
+    }
+
+    /**
+     * Adapter muc list.
+     */
+    private static class BeemMucList extends SimpleCursorAdapter {
+
+	private Context mContext;
+	private int mLayout;
+	private Cursor mCursor;
+
+	public BeemMucList(Context context, int layout, Cursor c, String[] from, int[] to) {
+	    super(context, layout, c, from, to);
+	    mContext = context;
+	    mLayout = layout;
+	    mCursor = c;
+	}
 
 	/**
-	 * A Filter which select Contact to display by searching in ther Jid.
+	 * {@inheritDoc}
 	 */
-	private class GroupFilter extends Filter {
-
-	    /**
-	     * Create a ContactFilter.
-	     */
-	    public GroupFilter() {
-	    }
-
-	    @Override
-	    protected Filter.FilterResults performFiltering(CharSequence constraint) {
-		Log.d(TAG, "performFiltering");
-
-		Cursor cursorContact = mContext.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
-		    new String[] { ContactsContract.Data.RAW_CONTACT_ID }, ContactsContract.Data.MIMETYPE + " =? ",
-		    new String[] { ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE }, null);
+	@Override
+	public int getCount() {
+	    return mCursor.getCount();
+	}
 
-		List<Long> arrayValues = new ArrayList<Long>();
-		try {
-		    while (cursorContact.moveToNext()) {
-			arrayValues.add(cursorContact.getLong(cursorContact
-			    .getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID)));
-		    }
-
-		} finally {
-		    cursorContact.close();
-		}
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public View newView(Context context, Cursor cursor, ViewGroup parent) {
+	    final LayoutInflater inflater = LayoutInflater.from(context);
+	    return inflater.inflate(mLayout, parent, false);
+	}
 
-		Filter.FilterResults fr = new Filter.FilterResults();
-		fr.values = arrayValues;
-		fr.count = arrayValues.size();
-		return fr;
-	    }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void bindView(View view, Context context, Cursor cursor) {
+	    String name = cursor.getString(cursor.getColumnIndex(MUCs.NAME));
+	    String jid = cursor.getString(cursor.getColumnIndex(MUCs.JID));
+	    TextView nameText = (TextView) view.findViewById(R.id.contactlistpseudo);
+	    nameText.setText(name);
+	    TextView msgperso = (TextView) view.findViewById(R.id.contactlistmsgperso);
+	    msgperso.setText(jid);
+	    view.setTag(jid);
+	}
 
-	    @Override
-	    protected void publishResults(CharSequence constraint, Filter.FilterResults results) {
-		Log.d(TAG, "publishResults " + results.count);
-		//Use in the bindview to show only filtered ID
-		mArrayContactID2Show.clear();  
-		mArrayContactID2Show.addAll((ArrayList<Long>) results.values);
-		//mArrayContactID2Show = (List<Integer>) results.values;		
-		notifyDataSetChanged();
-	    }
-	}
     }
 
     /**
@@ -485,18 +495,32 @@
 	private Context mContext;
 	private int mLayout;
 
-	public BeemBanner(Context context, int layout, Cursor c, String[] from, int[] to) {
-	    super(context, layout, c, from, to);
+	/**
+	 * Constructor.
+	 * @param context
+	 * @param layout
+	 * @param c
+	 * @param from
+	 * @param to
+	 */
+	public BeemBanner(Context context, int layout, Cursor cursor, String[] from, int[] to) {
+	    super(context, layout, cursor, from, to);
 	    mContext = context;
 	    mLayout = layout;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
 	public View newView(Context context, Cursor cursor, ViewGroup parent) {
 	    final LayoutInflater inflater = LayoutInflater.from(mContext);
 	    return inflater.inflate(mLayout, parent, false);
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
 	public void bindView(View view, Context context, Cursor cursor) {
 	    String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Groups.TITLE));
@@ -504,6 +528,8 @@
 	    if (nameText != null) {
 		nameText.setText(name);
 	    }
+	    String groupid = cursor.getString(cursor.getColumnIndex(ContactsContract.Groups._ID));
+	    view.setTag(groupid);
 	}
     }
 
@@ -530,6 +556,26 @@
 	}
     }
 
+    private class BeemMucListOnClick implements OnItemClickListener {
+	/**
+	 * Constructor.
+	 */
+	public BeemMucListOnClick() {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void onItemClick(AdapterView<?> arg0, View v, int pos, long lpos) {
+	    String jid = (String) v.getTag();
+	    Log.i(TAG, "OnClick MUC Jid:" + jid);
+	    Intent i = new Intent(ContactList.this, Chat.class);
+	    i.setData(Uri.parse("imto://jabber/" + jid));
+	    startActivity(i);
+	}
+    }
+
     /**
      * Event simple click on middle group name.
      */
@@ -541,39 +587,49 @@
 	public OnItemClickGroupName() {
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
 	public void onItemClick(AdapterView<?> arg0, View v, int i, long l) {
+	    Cursor cursor = null;
+	    ListView listView = (ListView) findViewById(R.id.contactlist);
 	    if (i == BANNER_POS_ALL_CONTACT) {
-		mArrayContactID2Show.clear();
+		cursor = getContacts();
+		listView.setOnItemClickListener(mOnContactClick);
+		mAdapterContactList = new BeemContactList(getBaseContext(), R.layout.contactlistcontact, cursor,
+		    new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.CONTACT_ID,
+			ContactsContract.RawContacts.SOURCE_ID }, new int[] { R.id.avatar, R.id.contactlistpseudo,
+			R.id.contactlistmsgperso });
+	    } else if (i == BANNER_POS_NO_GROUP) {
+		String noGroupID = getNoGroupID();
+		if (noGroupID != null)
+		    cursor = getContactsByGroupID(noGroupID);
+		listView.setOnItemClickListener(mOnContactClick);
+		mAdapterContactList = new BeemContactList(getBaseContext(), R.layout.contactlistcontact, cursor,
+		    new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.CONTACT_ID,
+			ContactsContract.RawContacts.SOURCE_ID }, new int[] { R.id.avatar, R.id.contactlistpseudo,
+			R.id.contactlistmsgperso });
+	    } else if (i == BANNER_POS_MUC) {
+		cursor = getMucs();
+		listView.setOnItemClickListener(mOnMucClick);
+		mAdapterContactList = new BeemMucList(getBaseContext(), R.layout.contactlistcontact, cursor,
+		    new String[] { MUCs._ID, MUCs.NAME, MUCs.JID }, new int[] { R.id.avatar, R.id.contactlistpseudo,
+			R.id.contactlistmsgperso });
+	    } else {
+		String groupid = v.getTag().toString();
+		cursor = getContactsByGroupID(groupid);
+		listView.setOnItemClickListener(mOnContactClick);
+		mAdapterContactList = new BeemContactList(getBaseContext(), R.layout.contactlistcontact, cursor,
+		    new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.CONTACT_ID,
+			ContactsContract.RawContacts.SOURCE_ID }, new int[] { R.id.avatar, R.id.contactlistpseudo,
+			R.id.contactlistmsgperso });
+	    }
+	    if (cursor != null) {	
+		registerForContextMenu(listView);
+		listView.setAdapter(mAdapterContactList);
+		mAdapterContactList.changeCursor(cursor);
 		mAdapterContactList.notifyDataSetChanged();
-	    }  else if (i == BANNER_POS_NO_GROUP) {
-		
-	    } else if (i == BANNER_POS_MUC)
-		Log.e("CONTACTLIST TODO", "MUC");
-	    else {		
-		TextView nameGroup = (TextView) v.findViewById(R.id.contactlist_group);
-		Uri groupUri = ContactsContract.Groups.CONTENT_URI.buildUpon()
-		    .appendQueryParameter(ContactsContract.Groups.ACCOUNT_NAME, mAccountName)
-		    .appendQueryParameter(ContactsContract.Groups.ACCOUNT_TYPE, BeemApplication.BEEM_PACKAGE)
-		    .appendQueryParameter(ContactsContract.Groups.TITLE, nameGroup.toString()).build();
-		Cursor cursorGroup = getContentResolver().query(groupUri, null,
-		    ContactsContract.Groups.DELETED + "= 0", null, null);
-		if (cursorGroup.moveToFirst()) {
-		    String _id = cursorGroup.getString(cursorGroup.getColumnIndex(ContactsContract.Groups._ID));
-		    mAdapterContactList.getGroupFilter().filter(_id);
-
-//		    // Get Contacts list
-//		    final Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon()
-//			.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccountName)
-//			.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, BeemApplication.BEEM_PACKAGE)
-//			.build();
-//		    //TODO: change null value for the projection (not efficient)
-//		    Cursor cursorRawContact = getContentResolver().query(rawContactUri, null,
-//			ContactsContract.RawContacts.DELETED + "= 0", null, null);
-//		    mAdapterContactList.changeCursor(cursorRawContact);		
-//		    cursorRawContact.requery();
-//		    mAdapterContactList.notifyDataSetChanged();
-		}
 	    }
 	}
     }
@@ -583,15 +639,25 @@
      */
     private class BeemGroupObserver extends ContentObserver {
 
+	/**
+	 * Constructor.
+	 * @param handler
+	 */
 	public BeemGroupObserver(Handler handler) {
 	    super(handler);
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
 	public boolean deliverSelfNotifications() {
 	    return true;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
 	public void onChange(boolean selfChange) {
 	    super.onChange(selfChange);
@@ -604,7 +670,56 @@
 		}
 	    }
 	}
+    }
 
+    /**
+     * Retrieve contacts of the current account.
+     * @return a cursor of contacts
+     */
+    public Cursor getContacts() {
+	return getContentResolver().query(
+	    ContactsContract.RawContacts.CONTENT_URI,
+	    new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.CONTACT_ID,
+		ContactsContract.RawContacts.SOURCE_ID },
+	    ContactsContract.RawContacts.ACCOUNT_NAME + "=? AND " + ContactsContract.RawContacts.ACCOUNT_TYPE
+		+ "=? AND " + ContactsContract.RawContacts.DELETED + "= 0",
+	    new String[] { mAccountName, BeemApplication.BEEM_PACKAGE },
+	    ContactsContract.RawContacts.CONTACT_ID + " ASC ");
     }
 
+    /**
+     * Retrieve contacts by groupid.
+     * @param groupid the groupid to select
+     * @return a cursor of contacts
+     */
+    public Cursor getContactsByGroupID(String groupid) {
+	return getContentResolver().query(
+	    ContactsContract.Data.CONTENT_URI,
+	    new String[] { ContactsContract.Data._ID, ContactsContract.RawContacts.CONTACT_ID,
+		ContactsContract.RawContacts.SOURCE_ID },
+	    ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID + "=?", new String[] { groupid }, null);
+    }
+
+    /**
+     * Get the NoGroup ID of the current account.
+     * @return the ID of the NoGroup group
+     */
+    public String getNoGroupID() {
+	final Cursor cursorGroup = getContentResolver().query(
+	    ContactsContract.Groups.CONTENT_URI,
+	    new String[] { ContactsContract.Groups._ID, ContactsContract.Groups.TITLE },
+	    ContactsContract.Groups.ACCOUNT_NAME + "=? AND " + ContactsContract.Groups.ACCOUNT_TYPE + "=? AND "
+		+ ContactsContract.Groups.SYSTEM_ID + "=?",
+	    new String[] { mAccountName, BeemApplication.BEEM_PACKAGE, BeemApplication.NO_GROUP }, null);
+	if (cursorGroup.moveToFirst()) {
+	    return cursorGroup.getString(cursorGroup.getColumnIndex(ContactsContract.Groups._ID));
+	}
+	return null;
+    }
+
+    public Cursor getMucs() {
+	return getContentResolver().query(MUCs.CONTENT_URI, new String[] { MUCs._ID, MUCs.NAME, MUCs.JID },
+	    MUCs.ACCOUNT_NAME + "=? AND " + MUCs.ACCOUNT_TYPE + "=? ",
+	    new String[] { mAccountName, BeemApplication.BEEM_PACKAGE }, null);
+    }
 }