Merge
authorDa Risk <darisk972@gmail.com>
Fri, 22 May 2009 22:30:28 +0200
changeset 220 2b8bebb95bbd
parent 206 e707f2adc40a (diff)
parent 219 79ccbe331695 (current diff)
child 221 d2c030543834
Merge
src/com/beem/project/beem/ui/SendIM.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/layout/contactdialog.xml	Fri May 22 22:30:28 2009 +0200
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:orientation="vertical" android:layout_width="fill_parent"
+	android:layout_height="fill_parent">
+
+	<Button android:id="@+id/CDChat" android:layout_width="fill_parent"
+		android:layout_height="wrap_content" android:text="Chat" />
+
+	<Button android:id="@+id/CDAlias" android:layout_width="fill_parent"
+		android:layout_height="wrap_content" android:text="Alias" />
+
+	<Button android:id="@+id/CDGroup" android:layout_width="fill_parent"
+		android:layout_height="wrap_content" android:text="Change group" />
+
+	<Button android:id="@+id/CDResend" android:layout_width="fill_parent"
+		android:layout_height="wrap_content" android:text="Resend suscription" />
+
+	<Button android:id="@+id/CDInfos" android:layout_width="fill_parent"
+		android:layout_height="wrap_content" android:text="User infos" />
+
+</LinearLayout>
\ No newline at end of file
--- a/res/layout/contactlistgroup.xml	Fri May 22 22:29:14 2009 +0200
+++ b/res/layout/contactlistgroup.xml	Fri May 22 22:30:28 2009 +0200
@@ -9,10 +9,7 @@
         <TextView android:id="@+id/textgroup"
         	android:layout_width="fill_parent"
             android:layout_height="wrap_content"
+            android:minHeight="30sp"
             android:paddingLeft="40sp" />
 
-        <TextView android:id="@+id/rowText2"
-			android:layout_width="fill_parent"
-            android:layout_height="wrap_content" />
-
 </LinearLayout> 
\ No newline at end of file
--- a/res/layout/contactlistsettings.xml	Fri May 22 22:29:14 2009 +0200
+++ b/res/layout/contactlistsettings.xml	Fri May 22 22:30:28 2009 +0200
@@ -8,9 +8,8 @@
 		<TextView android:layout_width="fill_parent"
 			android:layout_height="wrap_content" android:text="@string/CLSServerConnection"
 			android:textSize="18sp" />
-		<LinearLayout
-			android:orientation="horizontal" android:layout_width="fill_parent"
-			android:layout_height="wrap_content">
+		<LinearLayout android:orientation="horizontal"
+			android:layout_width="fill_parent" android:layout_height="wrap_content">
 			<TextView android:layout_width="wrap_content"
 				android:layout_height="wrap_content" android:text="@string/CLSUserid"
 				android:minWidth="90dp" android:textSize="14sp" />
@@ -20,33 +19,8 @@
 				android:scrollHorizontally="true" />
 		</LinearLayout>
 
-		<LinearLayout
-			android:orientation="horizontal" android:layout_width="fill_parent"
-			android:layout_height="wrap_content">
-			<TextView android:layout_width="wrap_content"
-				android:layout_height="wrap_content" android:text="@string/CLSPassword"
-				android:minWidth="90dp" android:textSize="14sp" />
-			<EditText android:id="@+id/password" android:layout_width="fill_parent"
-				android:layout_height="wrap_content" android:singleLine="true"
-				android:password="true" android:textSize="14sp" android:autoText="false"
-				android:capitalize="none" android:scrollHorizontally="true" />
-		</LinearLayout>
-
-		<LinearLayout
-			android:orientation="horizontal" android:layout_width="fill_parent"
-			android:layout_height="wrap_content">
-			<TextView android:layout_width="wrap_content"
-				android:layout_height="wrap_content" android:text="@string/CLSService"
-				android:minWidth="90dp" android:textSize="14sp" />
-			<EditText android:id="@+id/service" android:layout_width="fill_parent"
-				android:layout_height="wrap_content" android:singleLine="true"
-				android:textSize="14sp" android:autoText="false" android:capitalize="none"
-				android:scrollHorizontally="true" />
-		</LinearLayout>
-
-		<LinearLayout
-			android:orientation="horizontal" android:layout_width="fill_parent"
-			android:layout_height="wrap_content">
+		<LinearLayout android:orientation="horizontal"
+			android:layout_width="fill_parent" android:layout_height="wrap_content">
 			<TextView android:layout_width="wrap_content"
 				android:layout_height="wrap_content" android:text="@string/CLSHostPort"
 				android:minWidth="90dp" android:textSize="14sp" />
@@ -60,6 +34,17 @@
 				android:layout_weight="3" android:scrollHorizontally="true" />
 		</LinearLayout>
 
+		<LinearLayout android:orientation="horizontal"
+			android:layout_width="fill_parent" android:layout_height="wrap_content">
+			<TextView android:layout_width="wrap_content"
+				android:layout_height="wrap_content" android:text="@string/CLSPassword"
+				android:minWidth="90dp" android:textSize="14sp" />
+			<EditText android:id="@+id/password" android:layout_width="fill_parent"
+				android:layout_height="wrap_content" android:singleLine="true"
+				android:password="true" android:textSize="14sp" android:autoText="false"
+				android:capitalize="none" android:scrollHorizontally="true" />
+		</LinearLayout>
+
 		<TextView android:layout_width="fill_parent"
 			android:layout_height="wrap_content" android:text=""
 			android:textSize="18sp" />
@@ -92,9 +77,8 @@
 					android:scrollHorizontally="true" />
 			</LinearLayout>
 
-			<LinearLayout
-				android:orientation="horizontal" android:layout_width="fill_parent"
-				android:layout_height="wrap_content">
+			<LinearLayout android:orientation="horizontal"
+				android:layout_width="fill_parent" android:layout_height="wrap_content">
 				<TextView android:layout_width="wrap_content"
 					android:layout_height="wrap_content" android:text="@string/CLSLogin"
 					android:minWidth="90dp" android:textSize="14sp" />
@@ -104,9 +88,8 @@
 					android:capitalize="none" android:scrollHorizontally="true" />
 			</LinearLayout>
 
-			<LinearLayout
-				android:orientation="horizontal" android:layout_width="fill_parent"
-				android:layout_height="wrap_content">
+			<LinearLayout android:orientation="horizontal"
+				android:layout_width="fill_parent" android:layout_height="wrap_content">
 				<TextView android:layout_width="wrap_content"
 					android:layout_height="wrap_content" android:text="@string/CLSPassword"
 					android:minWidth="90dp" android:textSize="14sp" />
--- a/src/com/beem/project/beem/BeemApplication.java	Fri May 22 22:29:14 2009 +0200
+++ b/src/com/beem/project/beem/BeemApplication.java	Fri May 22 22:30:28 2009 +0200
@@ -99,9 +99,12 @@
 	mBeemApp.mProgressDialog.setTitle("Beem");
 	mBeemApp.mProgressDialog.setIcon(R.drawable.signal);
 	mBeemApp.mProgressDialog.setMessage("Connecting...");
+	mBeemApp.mProgressDialog.setCancelable(true);
+	
 	mBeemApp.mApplicationContext = activity.getApplication();
 	activity.getResources();
 	mBeemApp.onCreate();
+	//mBeemApp.mProgressDialog.show();
 	return mBeemApp;
     }
 
@@ -110,8 +113,8 @@
      */
     public synchronized void startBeemService() {
 	if (!mIsConnected) {
-	    mProgressDialog.setMessage("Connecting...");
-	    mProgressDialog.show();
+	    ConnectionRunnable cRun = new ConnectionRunnable("Connecting...");
+	    mBeemApp.mActivity.runOnUiThread(cRun);
 	    // the connection will be made on service connect
 	    mApplicationContext.bindService(BeemApplication.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
 	}
--- a/src/com/beem/project/beem/BeemService.java	Fri May 22 22:29:14 2009 +0200
+++ b/src/com/beem/project/beem/BeemService.java	Fri May 22 22:30:28 2009 +0200
@@ -27,8 +27,7 @@
 import com.beem.project.beem.ui.Subscription;
 
 /**
- * This class is for the Beem service.
- * The connection to the xmpp server will be made asynchronously when the service
+ * This class is for the Beem service. The connection to the xmpp server will be made asynchronously when the service
  * will start.
  * @author darisk
  */
@@ -80,10 +79,10 @@
 	mPassword = mSettings.getString(getString(R.string.PreferencePasswordKey), "");
 	mHost = mSettings.getString(getString(R.string.PreferenceHostKey), "");
 	mPort = mSettings.getInt(getString(R.string.PreferencePortKey), 5222);
-	mService = mSettings.getString(getString(R.string.PreferenceService), "");
-	
-	// TODO penser a commenter
-	// mHost = "10.0.2.2";
+	if (mHost.equals("talk.google.com"))
+	    mService = "gmail.com";
+	else
+	    mService = null;
 	initConnectionConfig();
 	mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
 	mConnection = new XmppConnectionAdapter(mConnectionConfiguration, mLogin, mPassword, this);
@@ -115,8 +114,8 @@
 
     /**
      * Show a notification.
-     * @param id 	the id of the notification.
-     * @param notif	the notification to show
+     * @param id the id of the notification.
+     * @param notif the notification to show
      */
     public void sendNotification(int id, Notification notif) {
 	mNotificationManager.notify(id, notif);
@@ -126,7 +125,7 @@
      * Initialise la configuration de la connexion.
      */
     private void initConnectionConfig() {
-	//TODO mettre a false par defaut et remplacer les valeurs par defaut
+	// TODO mettre a false par defaut et remplacer les valeurs par defaut
 	mUseProxy = mSettings.getBoolean(getString(R.string.PreferenceUseProxy), false);
 	if (mUseProxy) {
 	    String stype = mSettings.getString(getString(R.string.PreferenceProxyType),
@@ -134,12 +133,18 @@
 	    String phost = mSettings.getString(getString(R.string.PreferenceProxyHost), "");
 	    String puser = mSettings.getString(getString(R.string.PreferenceProxyUser), "");
 	    String ppass = mSettings.getString(getString(R.string.PreferenceProxyPassword), "");
-	    int pport =  mSettings.getInt(getString(R.string.PreferenceProxyPort), 1080);
+	    int pport = mSettings.getInt(getString(R.string.PreferenceProxyPort), 1080);
 	    ProxyInfo.ProxyType type = ProxyType.valueOf(stype);
 	    mProxyInfo = new ProxyInfo(type, phost, pport, puser, ppass);
-	    mConnectionConfiguration = new ConnectionConfiguration(mHost, mPort, mService, mProxyInfo);
+	    if (mService != null)
+		mConnectionConfiguration = new ConnectionConfiguration(mHost, mPort, mService, mProxyInfo);
+	    else
+		mConnectionConfiguration = new ConnectionConfiguration(mHost, mPort, mProxyInfo);
 	} else {
-	    mConnectionConfiguration = new ConnectionConfiguration(mHost, mPort);
+	    if (mService != null)
+		mConnectionConfiguration = new ConnectionConfiguration(mHost, mPort, mService);
+	    else
+		mConnectionConfiguration = new ConnectionConfiguration(mHost, mPort);
 	}
 	mConnectionConfiguration.setDebuggerEnabled(false);
 	mConnectionConfiguration.setSendPresence(true);
@@ -147,7 +152,7 @@
 
     private void initRosterRequestListener() {
 	Roster.setDefaultSubscriptionMode(SubscriptionMode.manual);
-	final XMPPConnection con =  mConnection.getAdaptee();
+	final XMPPConnection con = mConnection.getAdaptee();
 	try {
 	    // l'ajout d'un packet listener ne peut etre effectuer que lorsqu'on est connecte au serveur
 	    mConnection.addConnectionListener(new IBeemConnectionListener.Stub() {
@@ -189,10 +194,9 @@
 
 		}
 
-
 		@Override
 		public void onConnect() throws RemoteException {
-		    
+
 		    PacketFilter filter = new PacketFilter() {
 
 			@Override
@@ -210,14 +214,14 @@
 			@Override
 			public void processPacket(Packet packet) {
 			    String from = packet.getFrom();
-			    Notification notif = new Notification(com.beem.project.beem.R.drawable.signal, "Demande d'ajout", System
-				.currentTimeMillis());
+			    Notification notif = new Notification(com.beem.project.beem.R.drawable.signal,
+				"Demande d'ajout", System.currentTimeMillis());
 			    notif.defaults = Notification.DEFAULT_ALL;
 			    notif.flags = Notification.FLAG_AUTO_CANCEL;
 			    Intent intent = new Intent(BeemService.this, Subscription.class);
 			    intent.putExtra("from", from);
-			    notif.setLatestEventInfo(BeemService.this, from, "demande d'ajout de " + from, PendingIntent.getActivity(BeemService.this, 0,
-				intent, PendingIntent.FLAG_ONE_SHOT));
+			    notif.setLatestEventInfo(BeemService.this, from, "demande d'ajout de " + from,
+				PendingIntent.getActivity(BeemService.this, 0, intent, PendingIntent.FLAG_ONE_SHOT));
 			    int id = packet.hashCode();
 			    sendNotification(id, notif);
 			}
@@ -237,7 +241,6 @@
 
 		}
 
-
 		@Override
 		public void connectionFailed(String errorMsg) throws RemoteException {
 		    // TODO Auto-generated method stub
@@ -258,5 +261,4 @@
 	    mConnection.disconnect();
     }
 
-
 }
--- a/src/com/beem/project/beem/service/Contact.java	Fri May 22 22:29:14 2009 +0200
+++ b/src/com/beem/project/beem/service/Contact.java	Fri May 22 22:30:28 2009 +0200
@@ -140,10 +140,15 @@
      * @param presence the presence containing status
      */
     public void setStatus(Presence presence) {
-	Log.i(TAG,"PRESENCE");
 	mStatus = Status.getStatusFromPresence(presence);
 	mMsgState = presence.getStatus();
     }
+    
+    public void setStatus(PresenceAdapter presence) {
+	mStatus = presence.getStatus();
+	mMsgState = presence.getStatusText();
+	
+    }
 
     /**
      * Get the message status of the contact.
@@ -220,6 +225,10 @@
 	    mGroups.add(rosterGroup.getName());
 	}
     }
+    
+    public void addGroup(String group) {
+	mGroups.add(group);
+    }
 
     /**
      * @param mGroups the mGroups to set
@@ -227,11 +236,11 @@
     public void setGroups(List<String> mGroups) {
 	this.mGroups = mGroups;
     }
-
+    
     /**
      * @return the mGroups
      */
     public List<String> getGroups() {
 	return mGroups;
-    }
+    }    
 }
--- a/src/com/beem/project/beem/service/PresenceAdapter.java	Fri May 22 22:29:14 2009 +0200
+++ b/src/com/beem/project/beem/service/PresenceAdapter.java	Fri May 22 22:30:28 2009 +0200
@@ -14,6 +14,7 @@
 	private int mStatus;
 	private String mTo;
 	private String mFrom;
+	private String mStatusText;
 	
 	/**
 	 * Parcelable.Creator needs by Android.
@@ -36,6 +37,7 @@
 		mStatus = Status.getStatusFromPresence(presence);
 		mTo = presence.getTo();
 		mFrom = presence.getFrom();
+		mStatusText = presence.getStatus();
 	}
 	
 	
@@ -44,6 +46,7 @@
 		mStatus = source.readInt();
 		mTo = source.readString();
 		mFrom = source.readString();
+		mStatusText = source.readString();
 	}
 
 	@Override
@@ -58,6 +61,7 @@
 		dest.writeInt(mStatus);
 		dest.writeString(mTo);
 		dest.writeString(mFrom);
+		dest.writeString(mStatusText);
 	}
 
 
@@ -122,4 +126,20 @@
 	public String getFrom() {
 	    return mFrom;
 	}
+
+
+	/**
+	 * @param mStatusText the mStatusText to set
+	 */
+	public void setStatusText(String mStatusText) {
+	    this.mStatusText = mStatusText;
+	}
+
+
+	/**
+	 * @return the mStatusText
+	 */
+	public String getStatusText() {
+	    return mStatusText;
+	}
 }
--- a/src/com/beem/project/beem/service/RosterAdapter.java	Fri May 22 22:29:14 2009 +0200
+++ b/src/com/beem/project/beem/service/RosterAdapter.java	Fri May 22 22:30:28 2009 +0200
@@ -71,6 +71,10 @@
 	    mAdaptee.createEntry(user, name, groups);
 	    Contact res = new Contact(user);
 	    mContacts.put(user, res);
+	    for (String group : groups) {
+		//mAdaptee.createGroup(group);
+		res.addGroup(group);
+	    }
 	    return res;
 	} catch (XMPPException e) {
 	    Log.e(TAG, "Error while adding new contact", e);
--- a/src/com/beem/project/beem/ui/AccountCreation.java	Fri May 22 22:29:14 2009 +0200
+++ b/src/com/beem/project/beem/ui/AccountCreation.java	Fri May 22 22:30:28 2009 +0200
@@ -58,7 +58,7 @@
 		valid = false;
 		
 	    } else {
-		mAttributes.put("password", getWidgetText(R.id.password));
+		mAttributes.put("password", getWidgetText(R.id.ac_password));
 	    }
 	    if (getWidgetText(R.id.ac_email).length() == 0) {
 		valid = false;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/ui/ContactDialog.java	Fri May 22 22:30:28 2009 +0200
@@ -0,0 +1,91 @@
+package com.beem.project.beem.ui;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.beem.project.beem.R;
+import com.beem.project.beem.service.Contact;
+
+public class ContactDialog extends Dialog {
+
+    private Contact mContact;
+    private Context mContext;
+
+    public ContactDialog(final Context context, Contact curContact) {
+	super(context);
+	mContext = context;
+	setContentView(R.layout.contactdialog);
+	mContact = curContact;
+	setTitle(curContact.getJID());
+
+	Button chat = (Button) findViewById(R.id.CDChat);
+	chat.setOnClickListener(new chatListener());
+	Button alias= (Button) findViewById(R.id.CDAlias);
+	alias.setOnClickListener(new aliasListener());
+	Button group = (Button) findViewById(R.id.CDGroup);
+	group.setOnClickListener(new groupListener());
+	Button resend = (Button) findViewById(R.id.CDResend);
+	resend.setOnClickListener(new resendListener());
+	Button infos = (Button) findViewById(R.id.CDInfos);
+	infos.setOnClickListener(new infosListener());
+    }
+
+    class chatListener implements View.OnClickListener {
+
+	@Override
+	public void onClick(View v) {
+	    Activity a = ContactDialog.this.getOwnerActivity();
+	    Intent i = new Intent(mContext, SendIM.class);
+	    i.putExtra("contact", mContact);
+	    a.startActivity(i);
+	    dismiss();
+	}
+
+    }
+
+    class aliasListener implements View.OnClickListener {
+
+	@Override
+	public void onClick(View v) {
+	    // TODO Auto-generated method stub
+	    dismiss();
+	}
+	
+    }
+    
+    class groupListener implements View.OnClickListener {
+
+	@Override
+	public void onClick(View v) {
+	    // TODO Auto-generated method stub
+	    dismiss();
+	}
+	
+    }
+    
+    class resendListener implements View.OnClickListener {
+
+	@Override
+	public void onClick(View v) {
+	    // TODO Auto-generated method stub
+	    dismiss();
+	}
+	
+    }
+    
+    class infosListener implements View.OnClickListener {
+
+	@Override
+	public void onClick(View v) {
+	    // TODO Auto-generated method stub
+	    dismiss();
+	}
+	
+    }
+
+}
--- a/src/com/beem/project/beem/ui/ContactList.java	Fri May 22 22:29:14 2009 +0200
+++ b/src/com/beem/project/beem/ui/ContactList.java	Fri May 22 22:30:28 2009 +0200
@@ -5,26 +5,33 @@
 import java.util.List;
 import java.util.Map;
 
+import org.jivesoftware.smack.util.StringUtils;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
 import android.app.ExpandableListActivity;
-import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.database.DataSetObserver;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
 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.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
 import android.widget.ExpandableListAdapter;
-import android.widget.ExpandableListView;
 import android.widget.ImageView;
-import android.widget.SimpleExpandableListAdapter;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import com.beem.project.beem.BeemApplication;
 import com.beem.project.beem.R;
@@ -39,52 +46,35 @@
 
     private static final String TAG = "CONTACTLIST_ACT";
     private static final int PREFERENCECHANGED = 0;
-    private static final String CHILD = "CHILD";
-    private static final String GROUP = "GROUP";
+    private static final String DEFAULT_GROUP = "Default";
     private IXmppFacade mService = null;
-    private ExpandableListAdapter mAdapter;
+    private MyExpandableListAdapter mAdapter;
     private BeemApplication mBeemApplication;
     private BeemRosterListener mRosterListener;
     private SharedPreferences mSettings;
     private IRoster mRoster;
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
-	Map<String, Contact> child = (HashMap<String, Contact>) parent.getExpandableListAdapter().getChild(
-	    groupPosition, childPosition);
-	Intent i = new Intent(this, SendIM.class);
-	i.putExtra("contact", child.get(CHILD));
-	startActivity(i);
-	return true;
-    }
+    private Map<String, List<Contact>> groupMap;
+    private List<String> groupName;
+    private List<Contact> mListContact;
+    private Handler mHandler;
 
     @Override
     protected void onCreate(Bundle saveBundle) {
 	super.onCreate(saveBundle);
+	mHandler = new Handler();
 	mRosterListener = new BeemRosterListener();
 	mSettings = getSharedPreferences(getString(R.string.PreferenceFileName), MODE_PRIVATE);
 	mBeemApplication = BeemApplication.getApplication(this);
-	if (mSettings.getString(getString(R.string.PreferenceHostKey), "").equals(""))
-	    startActivityForResult(new Intent(this, ContactListSettings.class), PREFERENCECHANGED);
-    }
-
-    @Override
-    protected void onResume() {
-	super.onResume();
-
-	if (!mBeemApplication.isConnected()) {
-	    mBeemApplication = BeemApplication.getApplication(this);
-	    mBeemApplication.startBeemService();
-	}
-	mBeemApplication.callWhenConnectedToServer(new Handler(), new Runnable() {
+	groupMap = new HashMap<String, List<Contact>>();
+	groupName = new ArrayList<String>();
+	mBeemApplication.callWhenConnectedToServer(mHandler, new Runnable() {
 	    @Override
 	    public void run() {
 		mService = mBeemApplication.getXmppFacade();
 		try {
 		    mRoster = mService.getRoster();
 		} catch (RemoteException e1) {
-		    e1.printStackTrace();
+		    Log.e(TAG, "Get roster failed", e1);
 		}
 		if (mRoster != null) {
 		    try {
@@ -93,29 +83,25 @@
 			e.printStackTrace();
 		    }
 		}
-		if (mAdapter == null)
-		    callbackShowContactList();
+		callbackShowContactList();
 	    }
-	});
-    }
+	});	
+    }    
 
     @Override
     protected void onDestroy() {
-	// TODO Auto-generated method stub
-	super.onDestroy();
 	mBeemApplication.unbindBeemService();
+	super.onDestroy();	
     }
 
     private void callbackShowContactList() {
-	/*
-	 * @TODO: A ameliorer apres listener de nikita
-	 */
-	if (mRoster != null)
+	if (mRoster != null) {
 	    try {
-		showContactList(mRoster.getGroupsNames(), mRoster.getContactList());
+		buildContactList(mRoster.getContactList());
 	    } catch (RemoteException e) {
 		e.printStackTrace();
 	    }
+	}
     }
 
     /**
@@ -140,109 +126,247 @@
     public final boolean onOptionsItemSelected(MenuItem item) {
 	switch (item.getItemId()) {
 	    case R.id.account_edit:
-		startActivityForResult(new Intent(this, ContactListSettings.class), PREFERENCECHANGED);
+		startActivityForResult(new Intent(ContactList.this, ContactListSettings.class), PREFERENCECHANGED);
 		return true;
 	    case R.id.account_about:
 		Intent t = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.beem-project.com"));
 		startActivity(t);
 		return true;
 	    case R.id.account_create:
-		startActivity(new Intent(this, AccountCreation.class));
+		startActivity(new Intent(ContactList.this, AccountCreation.class));
 		return true;
 	    case R.id.add_contact:
-		startActivity(new Intent(this, AddContact.class));
+		startActivity(new Intent(ContactList.this, AddContact.class));
 		return true;
 	    default:
 		return false;
 	}
     }
 
+    /*
+     * @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition,
+     * long id) { try { } catch (NullPointerException e) { Log.e(TAG, "Child not found", e); return false; } }
+     */
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 	if (requestCode == PREFERENCECHANGED) {
 	    if (resultCode == RESULT_OK) {
-		mAdapter = null;
-		setListAdapter(mAdapter);
+		if (!groupMap.isEmpty())
+		    groupMap.clear();
 		mBeemApplication.stopBeemService();
 	    }
 	}
     }
 
-    private void showContactList(List<String> listGroup, List<Contact> listContact) {
-	List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
-	List<List<Map<String, Contact>>> childData = new ArrayList<List<Map<String, Contact>>>();
-	int groupSize = listGroup.size();
-	if (groupSize == 0)
-	    listGroup.add("Default");
-	for (int i = 0; i < listGroup.size(); i++) {
-	    Map<String, String> curGroupMap = new HashMap<String, String>();
-
-	    groupData.add(curGroupMap);
-	    curGroupMap.put("GROUP", listGroup.get(i));
-
-	    List<Map<String, Contact>> children = new ArrayList<Map<String, Contact>>();
-	    for (int j = 0; j < listContact.size(); ++j) {
-		Contact c = listContact.get(j);
-		if (groupSize == 0 || c.getGroups().contains(listGroup.get(i))) {
-		    Log.i(TAG, c.getID() + " " + c.getJID());
-		    Map<String, Contact> curChildMap = new HashMap<String, Contact>();
-		    children.add(curChildMap);
-		    curChildMap.put(CHILD, c);
+    private void buildContactList(List<Contact> listContact) {
+	mListContact = listContact;	
+	for (Contact contact : listContact) {
+	    for (String group : contact.getGroups()) {
+		if (!groupMap.containsKey(group)) {
+		    groupMap.put(group, new ArrayList<Contact>());
+		    groupName.add(group);
+		}
+		try {
+		    if (!groupMap.get(group).contains(contact))
+			groupMap.get(group).add(contact);
+		} catch (NullPointerException e) {
+		    Log.e(TAG, "Failed to find group in groupMap", e);
 		}
 	    }
-	    childData.add(children);
+	    if (contact.getGroups().isEmpty()) {
+		if (!groupMap.containsKey(DEFAULT_GROUP)) {
+		    groupMap.put(DEFAULT_GROUP, new ArrayList<Contact>());
+		    groupName.add(DEFAULT_GROUP);
+		}
+		groupMap.get(DEFAULT_GROUP).add(contact);
+	    }
 	}
-
-	mAdapter = new ContactExpandableListAdapter(this, groupData, R.layout.contactlistgroup, new String[] { GROUP },
-	    new int[] { R.id.textgroup }, childData, R.layout.contactlistcontact, new String[] { CHILD }, new int[] {
-		R.id.contactliststatus, R.id.contactlistpseudo, R.id.contactlistmsgperso, R.id.contactlistavatar });
+	mAdapter = new MyExpandableListAdapter();
 	setListAdapter(mAdapter);
     }
 
-    /**
-     * A simple adapter which allows you to bind data to specific Views defined within the layout of an Expandable Lists
-     * children (Implement getGroupView() to define the layout of parents)
-     */
-    private class ContactExpandableListAdapter extends SimpleExpandableListAdapter {
+    private class MyExpandableListAdapter implements ExpandableListAdapter {
+
+	private List<DataSetObserver> observers;
+
+	public MyExpandableListAdapter() {
+	    observers = new ArrayList<DataSetObserver>();
+	}
+
+	public void changed() {
+	    for (DataSetObserver obs : observers) {
+		obs.onChanged();
+	    }
+	}
+
+	@Override
+	public boolean areAllItemsEnabled() {
+	    return true;
+	}
+
+	@Override
+	public Object getChild(int groupPosition, int childPosition) {
+	    try {
+		return groupMap.get(groupName.get(groupPosition)).get(childPosition);
+	    } catch (NullPointerException e) {
+		Log.e(TAG, "Child not found", e);
+		return null;
+	    }
+	}
 
-	private List<? extends List<? extends Map<String, ?>>> mChildData;
-	private String[] mChildFrom;
-	private int[] mChildTo;
+	@Override
+	public long getChildId(int groupPosition, int childPosition) {
+	    try {
+		groupMap.get(groupName.get(groupPosition)).get(childPosition);
+	    } catch (NullPointerException e) {
+		Log.e(TAG, "Child not found", e);
+		return 0;
+	    }
+	    return childPosition;
+	}
+
+	void createDialog(Contact contact) {
+	    Dialog dialogContact= new ContactDialog(ContactList.this, contact);
+	    dialogContact.setOwnerActivity(ContactList.this);
+	    dialogContact.show();
+	}
 
-	public ContactExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int groupLayout,
-	    String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData,
-	    int childLayout, String[] childFrom, int[] childTo) {
-	    super(context, groupData, groupLayout, groupFrom, groupTo, childData, childLayout, childFrom, childTo);
+	class MyOnLongClickListener implements OnLongClickListener {
+	    @Override
+	    public boolean onLongClick(View v) {
+		TextView jidTextView = (TextView) v.findViewById(R.id.contactlistpseudo);
+		String jid = jidTextView.getText().toString();
+		for (Contact curContact : mListContact) {
+		    if (jid.equals(curContact.getJID())) {
+			createDialog(curContact);
+			break;
+		    }
+		}
+		return true;
+	    }
+	}
 
-	    mChildData = childData;
-	    mChildFrom = childFrom;
-	    mChildTo = childTo;
+	class MyOnClickListener implements OnClickListener {
+	    @Override
+	    public void onClick(View v) {
+		TextView jidTextView = (TextView) v.findViewById(R.id.contactlistpseudo);
+		String jid = jidTextView.getText().toString();
+		for (Contact curContact : mListContact) {
+		    if (jid.equals(curContact.getJID())) {
+			Intent i = new Intent(ContactList.this, SendIM.class);
+			i.putExtra("contact", curContact);
+			startActivity(i);
+			break;
+		    }
+		}
+	    }
 
 	}
 
 	@Override
 	public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
 	    ViewGroup parent) {
-
 	    View v;
 	    if (convertView == null) {
-		v = newChildView(isLastChild, parent);
+		v = LayoutInflater.from(ContactList.this).inflate(R.layout.contactlistcontact, null);
 	    } else {
 		v = convertView;
 	    }
-	    bindView(v, mChildData.get(groupPosition).get(childPosition), mChildFrom, mChildTo, groupPosition,
-		childPosition);
+	    bindView(v, groupMap.get(groupName.get(groupPosition)).get(childPosition));
+
+	    v.setOnLongClickListener(new MyOnLongClickListener());
+	    v.setOnClickListener(new MyOnClickListener());
 	    return v;
 	}
 
-	private void bindView(View view, Map<String, ?> data, String[] from, int[] to, int groupPosition,
-	    int childPosition) {
-	    Contact c = (Contact) data.get(from[0]);
+	@Override
+	public int getChildrenCount(int groupPosition) {
+	    try {
+		return groupMap.get(groupName.get(groupPosition)).size();
+	    } catch (NullPointerException e) {
+		Log.e(TAG, "Child not found", e);
+		return 0;
+	    }
+	}
+
+	@Override
+	public long getCombinedChildId(long groupId, long childId) {
+	    return 1000 * groupId + childId;
+	}
+
+	@Override
+	public long getCombinedGroupId(long groupId) {
+	    return 1000 * groupId;
+	}
+
+	@Override
+	public Object getGroup(int groupPosition) {
+	    try {
+		return groupMap.get(groupName.get(groupPosition));
+	    } catch (NullPointerException e) {
+		Log.e(TAG, "Group not found", e);
+		return null;
+	    }
+	}
+
+	@Override
+	public int getGroupCount() {
+	    return groupMap.size();
+	}
+
+	@Override
+	public long getGroupId(int groupPosition) {
+	    return groupPosition;
+	}
 
-	    if (c != null) {
+	@Override
+	public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
+	    if (convertView == null) {
+		convertView = LayoutInflater.from(ContactList.this).inflate(R.layout.contactlistgroup, null);
+	    }
+	    TextView groupTextView = (TextView) convertView.findViewById(R.id.textgroup);
+	    groupTextView.setText(groupName.get(groupPosition));
+	    return convertView;
+	}
+
+	@Override
+	public boolean hasStableIds() {
+	    return false;
+	}
+
+	@Override
+	public boolean isChildSelectable(int groupPosition, int childPosition) {
+	    return true;
+	}
+
+	@Override
+	public boolean isEmpty() {
+	    return groupMap.isEmpty();
+	}
 
-		ImageView imgV = (ImageView) view.findViewById(to[0]);
+	@Override
+	public void onGroupCollapsed(int groupPosition) {
+	}
+
+	@Override
+	public void onGroupExpanded(int groupPosition) {
+	}
+
+	@Override
+	public void registerDataSetObserver(DataSetObserver observer) {
+	    observers.add(observer);
+	}
+
+	@Override
+	public void unregisterDataSetObserver(DataSetObserver observer) {
+	    observers.remove(observer);
+	}
+
+	private void bindView(View view, Contact curContact) {
+
+	    if (curContact != null) {
+		ImageView imgV = (ImageView) view.findViewById(R.id.contactliststatus);
 		Drawable imageDrawable = null;
-		switch (c.getStatus()) {
+		switch (curContact.getStatus()) {
 		    case Status.CONTACT_STATUS_AVAILABLE:
 			imageDrawable = (Drawable) getResources().getDrawable(R.drawable.online);
 			break;
@@ -267,20 +391,18 @@
 		}
 		imgV.setImageDrawable(imageDrawable);
 
-		TextView v = (TextView) view.findViewById(to[1]);
+		TextView v = (TextView) view.findViewById(R.id.contactlistpseudo);
 		if (v != null) {
-		    v.setText(c.getJID());
+		    v.setText(curContact.getJID());
 		}
 
-		v = (TextView) view.findViewById(to[2]);
+		v = (TextView) view.findViewById(R.id.contactlistmsgperso);
 		if (v != null) {
-		    v.setText(c.getMsgState());
+		    v.setText(curContact.getMsgState());
 		}
 
-		/*
-		 * TODO: Rajouter l'avatar du contact getAvatar() dans la classe
-		 */
-		imgV = (ImageView) view.findViewById(to[3]);
+		// TODO: Rajouter l'avatar du contact getAvatar() dans la classe
+		imgV = (ImageView) view.findViewById(R.id.contactlistavatar);
 		if (imgV != null) {
 		    imageDrawable = (Drawable) getResources().getDrawable(R.drawable.avatar);
 		    imgV.setImageDrawable(imageDrawable);
@@ -293,26 +415,96 @@
 
 	@Override
 	public void onEntriesAdded(List<String> addresses) throws RemoteException {
-	    Log.i(TAG, "ENTRIES ADDED");
-
+	    for (String str: addresses) {
+		Contact curContact = mRoster.getContact(str);
+		for (String group: curContact.getGroups()) {
+		    if (!groupMap.containsKey(group)) {
+			groupMap.put(group, new ArrayList<Contact>());
+			groupName.add(group);
+		    }
+		    try {
+			groupMap.get(group).add(curContact);
+		    } catch (NullPointerException e) {
+			Log.e(TAG, "Failed to find group in groupMap", e);
+		    }
+		}
+	    }
+	    mHandler.post(new Runnable() {
+		@Override
+		public void run() {
+		    mAdapter.changed();
+		}
+	    });
 	}
 
 	@Override
 	public void onEntriesDeleted(List<String> addresses) throws RemoteException {
-	    Log.i(TAG, "ENTRIES DEL");
-
+	    for (List<Contact> cList : groupMap.values()) {
+		for (Contact curContact:cList) {
+		    for (String addr:addresses) {
+			if (addr.equals(curContact.getJID())) {
+			    cList.remove(curContact);
+			    if (cList.isEmpty()) {
+				groupMap.values().remove(cList);
+				}
+			}
+		    }
+		}
+	    }
+	    mHandler.post(new Runnable() {
+		@Override
+		public void run() {
+		    mAdapter.changed();
+		}
+	    });
 	}
 
 	@Override
 	public void onEntriesUpdated(List<String> addresses) throws RemoteException {
-	    Log.i(TAG, "ENTRIES UPD");
-
+	    for (String str: addresses) {
+		Contact curContact = mRoster.getContact(str);
+		for (String group: curContact.getGroups()) {
+		    if (!groupMap.containsKey(group)) {
+			groupMap.put(group, new ArrayList<Contact>());
+			groupName.add(group);
+			groupMap.get(group).add(curContact);
+		    } else {
+			boolean found = false;
+			for (Contact tempContact:groupMap.get(group)) {
+			    if (tempContact.getJID() == str) {
+				curContact = tempContact;
+				found = true;
+				break ;
+			    }
+			}
+			if (!found) {
+			    groupMap.get(group).add(curContact);
+			}
+		    }
+		}
+	    }
+	    mHandler.post(new Runnable() {
+		@Override
+		public void run() {
+		    mAdapter.changed();
+		}
+	    });
 	}
 
 	@Override
 	public void onPresenceChanged(PresenceAdapter presence) throws RemoteException {
-	    Log.i(TAG, "PRESENCE CHANGED");
-
+	    for (Contact curContact : mListContact) {
+		if (curContact.getJID().equals(StringUtils.parseBareAddress(presence.getFrom()))) {
+		    curContact.setStatus(presence);
+		    mHandler.post(new Runnable() {
+			@Override
+			public void run() {
+			    mAdapter.changed();
+			}
+		    });
+		    return;
+		}
+	    }
 	}
 
     }
--- a/src/com/beem/project/beem/ui/ContactListSettings.java	Fri May 22 22:29:14 2009 +0200
+++ b/src/com/beem/project/beem/ui/ContactListSettings.java	Fri May 22 22:30:28 2009 +0200
@@ -46,9 +46,10 @@
 		sp.setSelection(i);
 	sp.setOnItemSelectedListener(mProxyType);
 
-	showSettings();
 	Button ok = (Button) findViewById(R.id.ok);
 	ok.setOnClickListener(mOkListener);
+
+	showSettings();
     }
 
     private OnItemSelectedListener mProxyType = new OnItemSelectedListener() {
@@ -104,10 +105,6 @@
 		editor.putString(getString(R.string.PreferencePasswordKey), getWidgetText(R.id.password));
 		mIsChanged = true;
 	    }
-	    if (isChanged(R.id.service, R.string.PreferenceService)) {
-		editor.putString(getString(R.string.PreferenceService), getWidgetText(R.id.service));
-		mIsChanged = true;
-	    }
 
 	    if (isChanged(R.id.proxy_host, R.string.PreferenceProxyHost)) {
 		editor.putString(getString(R.string.PreferenceProxyHost), getWidgetText(R.id.proxy_host));
@@ -149,8 +146,6 @@
 	e.setText(getPreferenceString(R.string.PreferenceLoginKey));
 	e = (EditText) findViewById(R.id.password);
 	e.setText(getPreferenceString(R.string.PreferencePasswordKey));
-	e = (EditText) findViewById(R.id.service);
-	e.setText(getPreferenceString(R.string.PreferenceService));
 
 	e = (EditText) findViewById(R.id.proxy_host);
 	e.setText(getPreferenceString(R.string.PreferenceProxyHost));
--- a/src/com/beem/project/beem/ui/SendIM.java	Fri May 22 22:29:14 2009 +0200
+++ b/src/com/beem/project/beem/ui/SendIM.java	Fri May 22 22:30:28 2009 +0200
@@ -140,11 +140,12 @@
 	    Log.d(TAG, "mchat open false", e);
 	}
 	super.onPause();
+	finish();
     }
 
     @Override
     protected void onStop() {
-	super.onStop();
+	
 	Log.d(TAG, "onStop");
 	try {
 	    mChat.setOpen(false);
@@ -152,11 +153,12 @@
 	    Log.d(TAG, "mchat open false", e);
 	}
 	mBeemApplication.unbindBeemService();
+	super.onStop();
     }
 
     @Override
     protected void onDestroy() {
-	super.onDestroy();
+	
 	if (mChatManager != null) {
 	    try {
 		mChatManager.removeChatCreationListener(mChatManagerListener);
@@ -166,6 +168,7 @@
 		Log.e(TAG, "mchat manager and SendIM destroy", e);
 	    }
 	}
+	super.onDestroy();
     }
 
     /**
--- a/src/com/beem/project/beem/ui/SendIMDialogSmiley.java	Fri May 22 22:29:14 2009 +0200
+++ b/src/com/beem/project/beem/ui/SendIMDialogSmiley.java	Fri May 22 22:30:28 2009 +0200
@@ -6,19 +6,19 @@
 import android.content.SharedPreferences;
 
 public class SendIMDialogSmiley extends Dialog {
-   private SendIM	mSendIM;
-    private SharedPreferences	mSet;
-    
+    private SendIM mSendIM;
+    private SharedPreferences mSet;
+
     public SendIMDialogSmiley(SendIM sendim, SharedPreferences settings) {
-        super(sendim);
-        this.mSendIM = sendim;
-        this.mSet = settings;
+	super(sendim);
+	this.mSendIM = sendim;
+	this.mSet = settings;
     }
-    
+
     @Override
     protected void onStart() {
-        super.onStart();
-        setContentView(R.layout.sendimdialogsmiley);
-        setTitle("Select a smiley");
+	super.onStart();
+	setContentView(R.layout.sendimdialogsmiley);
+	setTitle("Select a smiley");
     }
 }