# HG changeset patch # User Jean-Manuel ¨dasilvj¨ Da Silva # Date 1257905134 -3600 # Node ID 4da77df8f9508a743ccfe0dfba09356f18e048c8 # Parent 973f28f405bc1730de4d0e8d6fcc861b03c93d5c Intégration de l´activité Chat à la place de l´activité SendIM Amélioration de l´activité Chat: - Skin - Meilleure gestion des URL et des messages de status Modifications très légères de skin sur les activités ContactList et ChangeStatus. diff -r 973f28f405bc -r 4da77df8f950 AndroidManifest.xml --- a/AndroidManifest.xml Sun Nov 08 02:01:19 2009 +0100 +++ b/AndroidManifest.xml Wed Nov 11 03:05:34 2009 +0100 @@ -23,13 +23,6 @@ android:name="com.beem.project.beem.service.XmppConnectionAdapter.CONNECTION_CLOSED" /> - - - - - diff -r 973f28f405bc -r 4da77df8f950 res/layout/changestatus.xml --- a/res/layout/changestatus.xml Sun Nov 08 02:01:19 2009 +0100 +++ b/res/layout/changestatus.xml Wed Nov 11 03:05:34 2009 +0100 @@ -1,8 +1,7 @@ - + android:layout_height="fill_parent" android:padding="6px"> + android:inputType="textShortMessage|textAutoCorrect" + android:imeOptions="actionDone" android:layout_width="fill_parent" + android:layout_height="wrap_content" /> diff -r 973f28f405bc -r 4da77df8f950 res/layout/chat.xml --- a/res/layout/chat.xml Sun Nov 08 02:01:19 2009 +0100 +++ b/res/layout/chat.xml Wed Nov 11 03:05:34 2009 +0100 @@ -1,10 +1,11 @@ - + @@ -13,22 +14,24 @@ android:paddingLeft="15sp"> + android:autoLink="all" android:textSize="12sp" android:textColor="#FFFFFF" + android:textColorLink="#FFFFFF" /> - - - + android:layout_width="fill_parent" + android:layout_height="0px" android:layout_weight="1" + android:transcriptMode="normal" android:fastScrollEnabled="true" + android:smoothScrollbar="false" android:layout_marginBottom="20sp" + android:padding="4px" /> + diff -r 973f28f405bc -r 4da77df8f950 res/layout/contactlistcontact.xml --- a/res/layout/contactlistcontact.xml Sun Nov 08 02:01:19 2009 +0100 +++ b/res/layout/contactlistcontact.xml Wed Nov 11 03:05:34 2009 +0100 @@ -23,6 +23,6 @@ android:paddingLeft="16px" android:singleLine="true" android:maxLines="1" android:linksClickable="false" android:autoLink="all" android:scrollHorizontally="true" android:textColor="@color/white" - android:textSize="12px" /> + android:textColorLink="@color/white" android:textSize="12px" /> diff -r 973f28f405bc -r 4da77df8f950 res/values-fr/arrays.xml --- a/res/values-fr/arrays.xml Sun Nov 08 02:01:19 2009 +0100 +++ b/res/values-fr/arrays.xml Wed Nov 11 03:05:34 2009 +0100 @@ -6,7 +6,7 @@ SOCKS5 - Disponible pour chatter + Disponible pour clavarder Disponible Occupé(e) Parti(e) diff -r 973f28f405bc -r 4da77df8f950 res/values-fr/strings.xml --- a/res/values-fr/strings.xml Sun Nov 08 02:01:19 2009 +0100 +++ b/res/values-fr/strings.xml Wed Nov 11 03:05:34 2009 +0100 @@ -264,6 +264,14 @@ Oui Non Etes vous sûr de vouloir renvoyer l\'invitation ? -Saisissez votre message -Beem - Chat + + Saisissez votre message + Beem - Chat + Moi + Disponible + Disponible pour clavarder + Occupé(e) + Parti(e) + Indisponible + Hors ligne diff -r 973f28f405bc -r 4da77df8f950 res/values/arrays.xml --- a/res/values/arrays.xml Sun Nov 08 02:01:19 2009 +0100 +++ b/res/values/arrays.xml Wed Nov 11 03:05:34 2009 +0100 @@ -6,7 +6,7 @@ SOCKS5 - Available for chat + Available to chat Available Busy Away diff -r 973f28f405bc -r 4da77df8f950 res/values/strings.xml --- a/res/values/strings.xml Sun Nov 08 02:01:19 2009 +0100 +++ b/res/values/strings.xml Wed Nov 11 03:05:34 2009 +0100 @@ -245,6 +245,14 @@ No Are you sure you want to resend invit ? -Beem - Chat -Type your message + Beem - Chat + Type your message + Me + Available + Available to chat + Do not disturb + Away + Unavailable + Disconnected + diff -r 973f28f405bc -r 4da77df8f950 src/com/beem/project/beem/service/BeemChatManager.java --- a/src/com/beem/project/beem/service/BeemChatManager.java Sun Nov 08 02:01:19 2009 +0100 +++ b/src/com/beem/project/beem/service/BeemChatManager.java Wed Nov 11 03:05:34 2009 +0100 @@ -25,7 +25,6 @@ import com.beem.project.beem.service.aidl.IChatManager; import com.beem.project.beem.service.aidl.IChatManagerListener; import com.beem.project.beem.service.aidl.IMessageListener; -import com.beem.project.beem.ui.SendIM; /** * An adapter for smack's ChatManager. This class provides functionnality to handle chats. @@ -78,7 +77,7 @@ .currentTimeMillis()); notif.defaults = Notification.DEFAULT_ALL; notif.flags = Notification.FLAG_AUTO_CANCEL; - Intent intent = new Intent(mService, SendIM.class); + Intent intent = new Intent(mService, Chat.class); intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.setData(chat.getParticipant().toUri()); notif.setLatestEventInfo(mService, text, mService.getString(R.string.BeemChatManagerNewMessage), diff -r 973f28f405bc -r 4da77df8f950 src/com/beem/project/beem/ui/Chat.java --- a/src/com/beem/project/beem/ui/Chat.java Sun Nov 08 02:01:19 2009 +0100 +++ b/src/com/beem/project/beem/ui/Chat.java Wed Nov 11 03:05:34 2009 +0100 @@ -1,12 +1,13 @@ package com.beem.project.beem.ui; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.util.StringUtils; -import org.jivesoftware.smackx.ChatState; import android.app.Activity; import android.content.ComponentName; @@ -16,14 +17,18 @@ import android.content.ServiceConnection; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.Typeface; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.text.util.Linkify; import android.util.Log; +import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; +import android.view.View.OnKeyListener; import android.widget.BaseAdapter; import android.widget.EditText; import android.widget.ImageView; @@ -46,444 +51,619 @@ import com.beem.project.beem.utils.BeemBroadcastReceiver; import com.beem.project.beem.utils.Status; -public class Chat extends Activity { - - private static final String TAG = "Chat"; - private static final Intent SERVICE_INTENT = new Intent(); - static { - SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService")); - } - - private Handler mHandler = new Handler(); - - private IRoster mRoster; - private Contact mContact; - - private TextView mContactNameTextView; - private TextView mContactStatusMsgTextView; - private ImageView mContactStatusIcon; - private ListView mMessagesListView; - private EditText mInputField; - private Map mStatusIconsMap = new HashMap(); - - private List mListMessages = new ArrayList(); - - private IChat mChat; - private IChatManager mChatManager; - private IChatManagerListener mChatManagerListener; - private IMessageListener mMessageListener; - private MessagesListAdapter mMessagesListAdapter; - - private final ServiceConnection mConn = new BeemServiceConnection(); - private BeemBroadcastReceiver mBroadcastReceiver; - - - /** - * Constructor. - */ - public Chat() { - super(); - } - - /** - * {@inheritDoc}. - */ - protected void onCreate(Bundle savedBundle) { - super.onCreate(savedBundle); - - Log.v(TAG, "BEGIN onCreate."); - setContentView(R.layout.chat); - mMessagesListAdapter = new MessagesListAdapter(this); - - mHandler = new Handler(); - - // Listeners - mMessageListener = new OnMessageListener(); - mChatManagerListener = new OnChatManagerListener(); +public class Chat extends Activity implements OnKeyListener { - mBroadcastReceiver = new BeemBroadcastReceiver(mConn); - this.registerReceiver(mBroadcastReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED)); - - // UI - mContactNameTextView = (TextView) findViewById(R.id.chat_contact_name); - mContactStatusMsgTextView = (TextView) findViewById(R.id.chat_contact_status_msg); - mContactStatusIcon = (ImageView) findViewById(R.id.chat_contact_status_icon); - mMessagesListView = (ListView) findViewById(R.id.chat_messages); - mMessagesListView.setAdapter(mMessagesListAdapter); - mInputField = (EditText) findViewById(R.id.chat_input); - - prepareIconsStatus(); - - Log.v(TAG, "END onCreate."); - } - - /** - * {@inheritDoc}. - */ - protected void onDestroy() { - super.onDestroy(); - - Log.v(TAG, "BEGIN onDestroy."); - this.unregisterReceiver(mBroadcastReceiver); - if (mChatManager != null) { - try { - mChatManager.removeChatCreationListener(mChatManagerListener); - } catch (RemoteException e) { - Log.e(TAG, e.getMessage()); - } - } - Log.v(TAG, "END onDestroy."); - } - - /** - * {@inheritDoc}. - */ - protected void onStart() { - super.onStart(); - - Log.v(TAG, "BEGIN onStart."); - bindService(new Intent(this, BeemService.class), mConn, BIND_AUTO_CREATE); - Log.v(TAG, "END onStart."); - } - - /** - * {@inheritDoc}. - */ - protected void onStop() { - super.onStop(); - - Log.v(TAG, "BEGIN onStop."); - if (mChat != null) { - try { - mChat.setOpen(false); - } catch (RemoteException e) { - Log.e(TAG, e.getMessage()); - } - } - if (mBroadcastReceiver.isBinded()) { - unbindService(mConn); + private static final String TAG = "Chat"; + private static final Intent SERVICE_INTENT = new Intent(); + static { + SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService")); } - Log.v(TAG, "END onStop."); - } - - /** - * {@inheritDoc}. - */ - protected void onResume() { - super.onResume(); - } - - /** - * {@inheritDoc}. - */ - protected void onPause() { - super.onPause(); - } - - /** - * {@inheritDoc}. - */ - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - - Log.v(TAG, "BEGIN onNewIntent."); - mContact = new Contact(intent.getData()); - updateContactInformations(); - Log.v(TAG, "END onNewIntent."); - } - - /** - * - * @author Jamu - * - */ - private final class BeemServiceConnection implements ServiceConnection { - - private IXmppFacade mXmppFacade; - private final BeemRosterListener mBeemRosterListener = new BeemRosterListener(); + private Map mDefaultStatusMessages; - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - Log.v(TAG, "BEGIN onServiceConnected."); - mXmppFacade = IXmppFacade.Stub.asInterface(service); - mBroadcastReceiver.setBinded(true); - try { - mChatManager = mXmppFacade.getChatManager(); - - mRoster = mXmppFacade.getRoster(); - mRoster.addRosterListener(mBeemRosterListener); - - mChat = mChatManager.createChat((mContact = new Contact(getIntent().getData())), mMessageListener); - mChat.setOpen(true); - mChatManager.deleteChatNotification(mChat); - - updateContactInformations(); - updateContactStatusIcon(); - } catch (RemoteException e) { - Log.e(TAG, e.getMessage()); - } - Log.v(TAG, "END onServiceConnected."); - } - - @Override - public void onServiceDisconnected(ComponentName name) { - Log.v(TAG, "BEGIN onServiceDisconnected."); - mXmppFacade = null; - mBroadcastReceiver.setBinded(false); - try { - mRoster.removeRosterListener(mBeemRosterListener); - } catch (RemoteException e) { - Log.e(TAG, e.getMessage()); - } - Log.v(TAG, "END onServiceDisconnected."); - } - } - + private Handler mHandler = new Handler(); + + private IRoster mRoster; + private Contact mContact; - /** - * - * @author Jamu - * - */ - private class BeemRosterListener extends IBeemRosterListener.Stub { - - @Override - public void onEntriesAdded(List addresses) throws RemoteException { - // Nothing to do - } + private TextView mContactNameTextView; + private TextView mContactStatusMsgTextView; + private ImageView mContactStatusIcon; + private ListView mMessagesListView; + private EditText mInputField; + private Map mStatusIconsMap = new HashMap(); - @Override - public void onEntriesDeleted(List addresses) throws RemoteException { - // Nothing to do - } - - @Override - public void onEntriesUpdated(List addresses) throws RemoteException { - // Nothing to do - } - - @Override - public void onEntryDeleteFromGroup(String group, String jid) throws RemoteException { - // Nothing to do - } + private List mListMessages = new ArrayList(); - @Override - public void onPresenceChanged(PresenceAdapter presence) throws RemoteException { - Log.v(TAG, "BEGIN onPresenceChanged."); - if (mContact.getJID().equals(StringUtils.parseBareAddress(presence.getFrom()))) { - mHandler.post(new Runnable() { - @Override - public void run() { - updateContactInformations(); - updateContactStatusIcon(); - } - }); - } - Log.v(TAG, "END onPresenceChanged."); - } - } - - /** - * - * @author Jamu - * - */ - private class OnMessageListener extends IMessageListener.Stub { - - @Override - public void processMessage(IChat chat, final Message msg) throws RemoteException { - Log.v(TAG, "BEGIN processMessage."); - mHandler.post(new Runnable() { + private IChat mChat; + private IChatManager mChatManager; + private IChatManagerListener mChatManagerListener; + private IMessageListener mMessageListener; + private MessagesListAdapter mMessagesListAdapter; - @Override - public void run() { - if (msg.getBody() != null && msg.getType() != Message.MSG_TYPE_ERROR) { - mListMessages.add(new MessageText(msg.getFrom(), msg.getBody())); - mMessagesListAdapter.notifyDataSetChanged(); - } - } - }); - Log.v(TAG, "END processMessage."); - } + private final ServiceConnection mConn = new BeemServiceConnection(); + private BeemBroadcastReceiver mBroadcastReceiver; - @Override - public void stateChanged(IChat chat) throws RemoteException { - Log.v(TAG, "BEGIN stateChanged."); - mHandler.post(new Runnable() { - - @Override - public void run() { - } - }); - Log.v(TAG, "END stateChanged."); - } - - } - - /** - * - * @author Jamu - * - */ - private class OnChatManagerListener extends IChatManagerListener.Stub { /** * Constructor. */ - public OnChatManagerListener() { - Log.v(TAG, "OnChatManagerListener constructor."); + public Chat() { + super(); + } + + /** + * {@inheritDoc}. + */ + protected void onCreate(Bundle savedBundle) { + super.onCreate(savedBundle); + + Log.v(TAG, "BEGIN onCreate."); + setContentView(R.layout.chat); + mMessagesListAdapter = new MessagesListAdapter(this); + + mHandler = new Handler(); + + // Listeners + mMessageListener = new OnMessageListener(); + mChatManagerListener = new OnChatManagerListener(); + + mBroadcastReceiver = new BeemBroadcastReceiver(mConn); + this.registerReceiver(mBroadcastReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED)); + + // UI + mContactNameTextView = (TextView) findViewById(R.id.chat_contact_name); + mContactStatusMsgTextView = (TextView) findViewById(R.id.chat_contact_status_msg); + mContactStatusIcon = (ImageView) findViewById(R.id.chat_contact_status_icon); + mMessagesListView = (ListView) findViewById(R.id.chat_messages); + mMessagesListView.setAdapter(mMessagesListAdapter); + mInputField = (EditText) findViewById(R.id.chat_input); + mInputField.setOnKeyListener(this); + + mDefaultStatusMessages = createDefaultStatusMessagesMap(); + prepareIconsStatus(); + + Log.v(TAG, "END onCreate."); + } + + /** + * {@inheritDoc}. + */ + protected void onDestroy() { + super.onDestroy(); + + Log.v(TAG, "BEGIN onDestroy."); + this.unregisterReceiver(mBroadcastReceiver); + if (mChatManager != null) { + try { + mChatManager.removeChatCreationListener(mChatManagerListener); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + } + Log.v(TAG, "END onDestroy."); + } + + /** + * {@inheritDoc}. + */ + protected void onStart() { + super.onStart(); + + Log.v(TAG, "BEGIN onStart."); + bindService(new Intent(this, BeemService.class), mConn, BIND_AUTO_CREATE); + Log.v(TAG, "END onStart."); + } + + /** + * {@inheritDoc}. + */ + protected void onStop() { + super.onStop(); + + Log.v(TAG, "BEGIN onStop."); + if (mChat != null) { + try { + mChat.setOpen(false); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + } + if (mBroadcastReceiver.isBinded()) { + unbindService(mConn); + } + Log.v(TAG, "END onStop."); + } + + /** + * {@inheritDoc}. + */ + protected void onResume() { + super.onResume(); + } + + /** + * {@inheritDoc}. + */ + protected void onPause() { + super.onPause(); + } + + /** + * {@inheritDoc}. + */ + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + + Log.v(TAG, "BEGIN onNewIntent."); + mContact = new Contact(intent.getData()); + if (mRoster != null) { + try { + mContact = mRoster.getContact(mContact.getJID()); + if (mContact.getMsgState() == null) + mContact.setMsgState(mDefaultStatusMessages.get(mContact.getStatus())); + + updateContactInformations(); + updateContactStatusIcon(); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + } + Log.v(TAG, "END onNewIntent."); + } + + /** + * {@inheritDoc}. + */ + @Override + protected void onSaveInstanceState(Bundle savedInstanceState) { + // TODO + super.onSaveInstanceState(savedInstanceState); } + /** + * {@inheritDoc}. + */ @Override - public void chatCreated(IChat chat, boolean locally) throws RemoteException { - Log.i(TAG, "Chat has been created."); + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + // TODO } - } - - /** - * Update the contact informations. - * - */ - private void updateContactInformations() { - Log.v(TAG, "BEGIN updateContactInformations."); - // Check for a contact name update - if (!(mContactNameTextView.getText().toString().equals(mContact.getName()))) - mContactNameTextView.setText(mContact.getName()); - - // Check for a contact status message update - if (!(mContactStatusMsgTextView.getText().toString().equals(mContact.getMsgState()))) { - Log.d(TAG, "Setting status message - " + mContact.getMsgState()); - if (mContact.getMsgState() == null) - mContactStatusMsgTextView.setText("Message de status de test de la mort tres tres long, voir meme trop long!"); - else - mContactStatusMsgTextView.setText(mContact.getMsgState()); - Linkify.addLinks(mContactStatusMsgTextView, Linkify.WEB_URLS); + + /** + * + * @author Jamu + * + */ + private final class BeemServiceConnection implements ServiceConnection { + + private IXmppFacade mXmppFacade; + private final BeemRosterListener mBeemRosterListener = new BeemRosterListener(); + + /** + * {@inheritDoc}. + */ + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + Log.v(TAG, "BEGIN onServiceConnected."); + mXmppFacade = IXmppFacade.Stub.asInterface(service); + mBroadcastReceiver.setBinded(true); + try { + mChatManager = mXmppFacade.getChatManager(); + + mRoster = mXmppFacade.getRoster(); + mRoster.addRosterListener(mBeemRosterListener); + + mChat = mChatManager.createChat((mContact = new Contact(getIntent().getData())), mMessageListener); + mChat.setOpen(true); + mChatManager.deleteChatNotification(mChat); + + mContact = mRoster.getContact(mContact.getJID()); + if (mContact.getMsgState() == null) + mContact.setMsgState(mDefaultStatusMessages.get(mContact.getStatus())); + + updateContactInformations(); + updateContactStatusIcon(); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + Log.v(TAG, "END onServiceConnected."); + } + + /** + * {@inheritDoc}. + */ + @Override + public void onServiceDisconnected(ComponentName name) { + Log.v(TAG, "BEGIN onServiceDisconnected."); + mXmppFacade = null; + mBroadcastReceiver.setBinded(false); + try { + mRoster.removeRosterListener(mBeemRosterListener); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + Log.v(TAG, "END onServiceDisconnected."); + } } - Log.v(TAG, "END updateContactInformations."); - } - - /** - * Update the contact status icon. - */ - private void updateContactStatusIcon() { - Log.v(TAG, "BEGIN updateContactStatusIcon."); - mContactStatusIcon.setImageBitmap(mStatusIconsMap.get(mContact.getStatus())); - Log.v(TAG, "END updateContactStatusIcon."); - } - - /** - * Prepare the status icons map. - */ - private void prepareIconsStatus() { - mStatusIconsMap.put(Status.CONTACT_STATUS_AVAILABLE, BitmapFactory.decodeResource(getResources(), R.drawable.status_available)); - mStatusIconsMap.put(Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT, BitmapFactory.decodeResource(getResources(), R.drawable.status_available)); - mStatusIconsMap.put(Status.CONTACT_STATUS_AWAY, BitmapFactory.decodeResource(getResources(), R.drawable.status_away)); - mStatusIconsMap.put(Status.CONTACT_STATUS_BUSY, BitmapFactory.decodeResource(getResources(), R.drawable.status_dnd)); - mStatusIconsMap.put(Status.CONTACT_STATUS_DISCONNECT, BitmapFactory.decodeResource(getResources(), R.drawable.status_offline)); - mStatusIconsMap.put(Status.CONTACT_STATUS_UNAVAILABLE, BitmapFactory.decodeResource(getResources(), R.drawable.status_requested)); - } - - private class MessagesListAdapter extends BaseAdapter { + + /** + * + * @author Jamu + * + */ + private class BeemRosterListener extends IBeemRosterListener.Stub { + + /** + * {@inheritDoc}. + */ + @Override + public void onEntriesAdded(List addresses) throws RemoteException { + Log.v(TAG, "BEGIN onEntriesAdded."); + Log.v(TAG, "END onEntriesAdded."); + } + + /** + * {@inheritDoc}. + */ + @Override + public void onEntriesDeleted(List addresses) throws RemoteException { + Log.v(TAG, "BEGIN onEntriesDeleted."); + Log.v(TAG, "END onEntriesDeleted."); + } + + /** + * {@inheritDoc}. + */ + @Override + public void onEntriesUpdated(List addresses) throws RemoteException { + Log.v(TAG, "BEGIN onEntriesUpdated."); + Log.v(TAG, "END onEntriesUpdated."); + } + + /** + * {@inheritDoc}. + */ + @Override + public void onEntryDeleteFromGroup(String group, String jid) throws RemoteException { + Log.v(TAG, "BEGIN onEntryDeleteFromGroup."); + Log.v(TAG, "END onEntryDeleteFromGroup."); + } + + /** + * {@inheritDoc}. + */ + @Override + public void onPresenceChanged(final PresenceAdapter presence) throws RemoteException { + Log.v(TAG, "BEGIN onPresenceChanged."); + if (mContact.getJID().equals(StringUtils.parseBareAddress(presence.getFrom()))) { + mHandler.post(new Runnable() { + @Override + public void run() { + mContact.setStatus(presence.getStatus()); + if (presence.getStatusText() == null) + mContact.setMsgState(mDefaultStatusMessages.get(presence.getStatus())); + else + mContact.setMsgState(presence.getStatusText()); + + updateContactInformations(); + updateContactStatusIcon(); + } + }); + } + Log.v(TAG, "END onPresenceChanged."); + } + } - private Context mContext; - - public MessagesListAdapter(Context context) { - mContext = context; - } + /** + * + * @author Jamu + * + */ + private class OnMessageListener extends IMessageListener.Stub { + + /** + * {@inheritDoc}. + */ + @Override + public void processMessage(IChat chat, final Message msg) throws RemoteException { + Log.v(TAG, "BEGIN processMessage."); + + final String fromBareJid = StringUtils.parseBareAddress(msg.getFrom()); + + if (mContact.getJID().equals(fromBareJid)) { + mHandler.post(new Runnable() { + + /** + * {@inheritDoc}. + */ + @Override + public void run() { + if (msg.getBody() != null && msg.getType() != Message.MSG_TYPE_ERROR) { + MessageText lastMessage = mListMessages.size() != 0 ? mListMessages.get(mListMessages + .size() - 1) : null; + + if (lastMessage != null && lastMessage.getBareJid().equals(fromBareJid)) { + lastMessage.setMessage(lastMessage.getMessage().concat("\n" + msg.getBody())); + mListMessages.set(mListMessages.size() - 1, lastMessage); + } else + mListMessages.add(new MessageText(fromBareJid, mContact.getName(), msg.getBody())); + mMessagesListAdapter.notifyDataSetChanged(); + } + } + }); + } + Log.v(TAG, "END processMessage."); + } - public int getCount() { - return mListMessages.size(); - } + /** + * {@inheritDoc}. + */ + @Override + public void stateChanged(IChat chat) throws RemoteException { + Log.v(TAG, "BEGIN stateChanged."); + mHandler.post(new Runnable() { + + /** + * {@inheritDoc}. + */ + @Override + public void run() { + } + }); + Log.v(TAG, "END stateChanged."); + } + } - public Object getItem(int position) { - return position; - } + /** + * + * @author Jamu + * + */ + private class OnChatManagerListener extends IChatManagerListener.Stub { + /** + * Constructor. + */ + public OnChatManagerListener() { + Log.v(TAG, "OnChatManagerListener constructor."); + } - public long getItemId(int position) { - return position; - } + /** + * {@inheritDoc}. + */ + @Override + public void chatCreated(IChat chat, boolean locally) throws RemoteException { + Log.i(TAG, "Chat has been created."); + } + } - public View getView(int position, View convertView, ViewGroup parent) { - MessageView sv; - if (convertView == null) { - sv = new MessageView(mContext, mListMessages.get(position).getName(), - mListMessages.get(position).getMessage()); - } else { - sv = (MessageView) convertView; - sv.setName(mListMessages.get(position).getName()); - sv.setMessage(mListMessages.get(position).getMessage()); - } + /** + * Update the contact informations. + * + */ + private void updateContactInformations() { + Log.v(TAG, "BEGIN updateContactInformations."); + // Check for a contact name update + if (!(mContactNameTextView.getText().toString().equals(mContact.getName()))) + mContactNameTextView.setText(mContact.getName()); + + // Check for a contact status message update + if (!(mContactStatusMsgTextView.getText().toString().equals(mContact.getMsgState()))) { + Log.d(TAG, "Setting status message - " + mContact.getMsgState()); + mContactStatusMsgTextView.setText(mContact.getMsgState()); + Linkify.addLinks(mContactStatusMsgTextView, Linkify.WEB_URLS); + } + Log.v(TAG, "END updateContactInformations."); + } + + /** + * Update the contact status icon. + */ + private void updateContactStatusIcon() { + Log.v(TAG, "BEGIN updateContactStatusIcon."); + mContactStatusIcon.setImageBitmap(mStatusIconsMap.get(mContact.getStatus())); + Log.v(TAG, "END updateContactStatusIcon."); + } - return sv; - } - } - - private class MessageText { - private String mName; - private String mMessage; - - public MessageText(String name, String message) { - mName = name; - mMessage = message; + /** + * Prepare the status icons map. + */ + private void prepareIconsStatus() { + mStatusIconsMap.put(Status.CONTACT_STATUS_AVAILABLE, BitmapFactory.decodeResource(getResources(), + R.drawable.status_available)); + mStatusIconsMap.put(Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT, BitmapFactory.decodeResource(getResources(), + R.drawable.status_available)); + mStatusIconsMap.put(Status.CONTACT_STATUS_AWAY, BitmapFactory.decodeResource(getResources(), + R.drawable.status_away)); + mStatusIconsMap.put(Status.CONTACT_STATUS_BUSY, BitmapFactory.decodeResource(getResources(), + R.drawable.status_dnd)); + mStatusIconsMap.put(Status.CONTACT_STATUS_DISCONNECT, BitmapFactory.decodeResource(getResources(), + R.drawable.status_offline)); + mStatusIconsMap.put(Status.CONTACT_STATUS_UNAVAILABLE, BitmapFactory.decodeResource(getResources(), + R.drawable.status_requested)); } - - public String getName() { - return mName; - } - - public String getMessage() { - return mMessage; - } - - public void setName(String name) { - mName = name; - } - - public void setMessage(String message) { - mMessage = message; + + private class MessagesListAdapter extends BaseAdapter { + + private Context mContext; + + public MessagesListAdapter(Context context) { + mContext = context; + } + + public int getCount() { + return mListMessages.size(); + } + + public Object getItem(int position) { + return position; + } + + public long getItemId(int position) { + return position; + } + + public View getView(int position, View convertView, ViewGroup parent) { + MessageView sv; + if (convertView == null) { + sv = new MessageView(mContext, mListMessages.get(position).getName(), mListMessages.get(position) + .getMessage()); + } else { + sv = (MessageView) convertView; + sv.setName(mListMessages.get(position).getName()); + sv.setMessage(mListMessages.get(position).getMessage()); + } + + sv.setPadding(2, 2, 2, 4); + + sv.mName.setTextSize(16); + sv.mName.setTextColor(Color.WHITE); + sv.mName.setTypeface(Typeface.DEFAULT_BOLD); + + sv.mMessage.setLinkTextColor(Color.WHITE); + sv.mMessage.setPadding(0, 4, 0, 4); + Linkify.addLinks(sv.mMessage, Linkify.WEB_URLS); + + return sv; + } } - } - - /** - * We will use a MessageView to display each message. - */ - private class MessageView extends LinearLayout { - private TextView mName; - private TextView mMessage; - - /** - * Constructor. - * @param context - * @param name - * @param message - */ - public MessageView(Context context, String name, String message) { - super(context); + + private class MessageText { + private String mBareJid; + private String mName; + private String mMessage; + + public MessageText(String bareJid, String name, String message) { + mBareJid = bareJid; + mName = name; + mMessage = message; + } + + public String getBareJid() { + return mBareJid; + } + + public String getName() { + return mName; + } + + public String getMessage() { + return mMessage; + } + + public void setBareJid(String bareJid) { + mBareJid = bareJid; + } + + public void setName(String name) { + mName = name; + } - this.setOrientation(VERTICAL); + public void setMessage(String message) { + mMessage = message; + } + } + + /** + * We will use a MessageView to display each message. + */ + private class MessageView extends LinearLayout { + private TextView mName; + private TextView mMessage; + + /** + * Constructor. + * + * @param context + * @param name + * @param message + */ + public MessageView(Context context, String name, String message) { + super(context); + + this.setOrientation(VERTICAL); + + mName = new TextView(context); + mName.setText(name); + addView(mName, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); + + mMessage = new TextView(context); + mMessage.setText(message); + addView(mMessage, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); + } - mName = new TextView(context); - mName.setText(name); - addView(mName, new LinearLayout.LayoutParams( - LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); + /** + * Convenience method to set the title of a MessageView + */ + public void setName(String name) { + mName.setText(name); + } + + /** + * Convenience method to set the dialogue of a MessageView + */ + public void setMessage(String message) { + mMessage.setText(message); + } + } - mMessage = new TextView(context); - mMessage.setText(message); - addView(mMessage, new LinearLayout.LayoutParams( - LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); - } + /** + * {@inheritDoc}. + */ + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + Log.d(TAG, "KeyEvent = " + event.getAction()); + if (event.getAction() == KeyEvent.ACTION_DOWN) { + switch (keyCode) { + case KeyEvent.KEYCODE_ENTER: + sendMessage(); + return true; + default: + return false; + } + } + return false; + } + + /** + * Send an xmpp message. + */ + private void sendMessage() { + final String inputContent = mInputField.getText().toString(); - /** - * Convenience method to set the title of a MessageView - */ - public void setName(String name) { - mName.setText(name); - } + Log.v(TAG, "BEGIN sendMessage."); + if (!inputContent.equals("")) { + Message msgToSend = new Message(mContact.getJID(), Message.MSG_TYPE_CHAT); + msgToSend.setBody(inputContent); + + try { + mChat.sendMessage(msgToSend); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + + final String self = getString(R.string.chat_self); + MessageText lastMessage = mListMessages.size() != 0 ? mListMessages.get(mListMessages.size() - 1) : null; - /** - * Convenience method to set the dialogue of a MessageView - */ - public void setMessage(String message) { - mMessage.setText(message); - } - } + if (lastMessage != null && lastMessage.getName().equals(self)) { + lastMessage.setMessage(lastMessage.getMessage().concat("\n" + inputContent)); + mListMessages.set(mListMessages.size() - 1, lastMessage); + } else + mListMessages.add(new MessageText(self, self, inputContent)); + mMessagesListAdapter.notifyDataSetChanged(); + mInputField.setText(null); + } + Log.v(TAG, "END sendMessage."); + } + + private Map createDefaultStatusMessagesMap() { + Map defaultStatusMessages = new HashMap(); + defaultStatusMessages.put(Status.CONTACT_STATUS_AVAILABLE, getString(R.string.contact_status_msg_available)); + defaultStatusMessages.put(Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT, + getString(R.string.contact_status_msg_available_chat)); + defaultStatusMessages.put(Status.CONTACT_STATUS_AWAY, getString(R.string.contact_status_msg_away)); + defaultStatusMessages.put(Status.CONTACT_STATUS_BUSY, getString(R.string.contact_status_msg_dnd)); + defaultStatusMessages.put(Status.CONTACT_STATUS_DISCONNECT, getString(R.string.contact_status_msg_offline)); + defaultStatusMessages.put(Status.CONTACT_STATUS_UNAVAILABLE, getString(R.string.contact_status_msg_xa)); + + return (defaultStatusMessages); + } } diff -r 973f28f405bc -r 4da77df8f950 src/com/beem/project/beem/ui/ContactDialog.java --- a/src/com/beem/project/beem/ui/ContactDialog.java Sun Nov 08 02:01:19 2009 +0100 +++ b/src/com/beem/project/beem/ui/ContactDialog.java Wed Nov 11 03:05:34 2009 +0100 @@ -98,7 +98,7 @@ @Override public void onClick(View v) { Activity a = ContactDialog.this.getOwnerActivity(); - Intent i = new Intent(mContext, SendIM.class); + Intent i = new Intent(mContext, Chat.class); i.setData(mContact.toUri()); a.startActivity(i); dismiss(); diff -r 973f28f405bc -r 4da77df8f950 src/com/beem/project/beem/ui/ContactList.java --- a/src/com/beem/project/beem/ui/ContactList.java Sun Nov 08 02:01:19 2009 +0100 +++ b/src/com/beem/project/beem/ui/ContactList.java Wed Nov 11 03:05:34 2009 +0100 @@ -52,222 +52,32 @@ */ public class ContactList extends Activity { - //private static final String TAG = "CONTACTLIST_ACT"; - private static final Intent SERVICE_INTENT = new Intent(); - private static final int REQUEST_CODE = 1; - private BeemContactList mAdapterContactList; - private BeemBanner mAdapterBanner; - private IRoster mRoster; - private List mListContact = new ArrayList(); - private final List mListGroup = new ArrayList(); - private final Map> mContactOnGroup = new HashMap>(); - private String mCurGroup; - private Handler mHandler; - private IXmppFacade mXmppFacade; - private SharedPreferences mSettings; - private final ServiceConnection mServConn = new BeemServiceConnection(); - private BeemBroadcastReceiver mReceiver; - private Map mIconsMap = new HashMap(); - private LayoutInflater mInflater; - - static { - SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService")); - } - - /** - * Constructor. - */ - public ContactList() { - - } - - /** - * {@inheritDoc} - */ - @Override - protected void onCreate(Bundle saveBundle) { - super.onCreate(saveBundle); - mSettings = PreferenceManager.getDefaultSharedPreferences(this); - setContentView(R.layout.contactlist); - mAdapterContactList = new BeemContactList(this); - mAdapterBanner = new BeemBanner(this); - mHandler = new Handler(); - mReceiver = new BeemBroadcastReceiver(mServConn); - this.registerReceiver(mReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED)); - mInflater = LayoutInflater.from(this); - prepareIconsStatus(); - } - - /** - * Callback for menu creation. - * @param menu the menu created - * @return true on success, false otherwise - */ - @Override - public final boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.contact_list, menu); - return true; - } + // private static final String TAG = "CONTACTLIST_ACT"; + private static final Intent SERVICE_INTENT = new Intent(); + private static final int REQUEST_CODE = 1; + private BeemContactList mAdapterContactList; + private BeemBanner mAdapterBanner; + private IRoster mRoster; + private List mListContact = new ArrayList(); + private final List mListGroup = new ArrayList(); + private final Map> mContactOnGroup = new HashMap>(); + private String mCurGroup; + private Handler mHandler; + private IXmppFacade mXmppFacade; + private SharedPreferences mSettings; + private final ServiceConnection mServConn = new BeemServiceConnection(); + private BeemBroadcastReceiver mReceiver; + private Map mIconsMap = new HashMap(); + private LayoutInflater mInflater; - /** - * Callback for menu item selected. - * @param item the item selected - * @return true on success, false otherwise - */ - @Override - public final boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.contact_list_menu_settings: - startActivityForResult(new Intent(this, Settings.class), REQUEST_CODE); - return true; - case R.id.contact_list_menu_add_contact: - startActivity(new Intent(ContactList.this, AddContact.class)); - return true; - default: - return false; - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == REQUEST_CODE) { - if (resultCode == RESULT_OK) { - mListContact.clear(); - stopService(SERVICE_INTENT); - finish(); - startActivity(new Intent(this, Login.class)); - } + static { + SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService")); } - } - /** - * {@inheritDoc} - */ - @Override - protected void onStart() { - super.onStart(); - bindService(SERVICE_INTENT, mServConn, BIND_AUTO_CREATE); - } - - /** - * {@inheritDoc} - */ - @Override - protected void onStop() { - super.onStop(); - if (mReceiver.isBinded()) - unbindService(mServConn); - mReceiver.setBinded(false); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - this.unregisterReceiver(mReceiver); - } - - /** - * Comparator Contact by Name. - */ - class ComparatorContactListByName implements Comparator { /** * Constructor. */ - public ComparatorContactListByName() { - - } - - /** - * {@inheritDoc} - */ - @Override - public int compare(T c1, T c2) { - return ((Contact) c1).getName().compareToIgnoreCase(((Contact) c2).getName()); - } - } - - /** - * Comparator Contact by status and name. - */ - class ComparatorContactListByStatusAndName implements Comparator { - /** - * Constructor. - */ - public ComparatorContactListByStatusAndName() { - - } - - /** - * {@inheritDoc} - */ - @Override - public int compare(T c1, T c2) { - if (((Contact) c1).getStatus() < ((Contact) c2).getStatus()) { - return 1; - } else if (((Contact) c1).getStatus() > ((Contact) c2).getStatus()) { - return -1; - } else - return ((Contact) c1).getName().compareToIgnoreCase(((Contact) c2).getName()); - } - } - - /** - * Contact List construction. - */ - private void buildContactList() { - if (mCurGroup != null) { - mListContact = mContactOnGroup.get(mCurGroup); - } - sortBeemContactList(); - ListView listView = (ListView) findViewById(R.id.contactlist); - listView.setOnItemClickListener(new BeemContactListOnClick()); - listView.setOnItemLongClickListener(new BeemContactListOnLongClick()); - listView.setAdapter(mAdapterContactList); - } - - /** - * buildBanner. - */ - private void buildBanner() { - Gallery g = (Gallery) findViewById(R.id.contactlist_banner); - g.setOnItemClickListener(new OnItemClickGroupName()); - g.setAdapter(mAdapterBanner); - } - - /** - * Event simple click on item of the contact list. - */ - public class BeemContactListOnClick implements OnItemClickListener { - /** - * Constructor. - */ - public BeemContactListOnClick() { - - } - - /** - * {@inheritDoc} - */ - @Override - public void onItemClick(AdapterView arg0, View v, int pos, long lpos) { - Contact c = mListContact.get(pos); - Intent i = new Intent(ContactList.this, SendIM.class); - i.setData(c.toUri()); - startActivity(i); - } - } - - /** - * Event long click on item of the contact list. - */ - public class BeemContactListOnLongClick implements OnItemLongClickListener { - /** - * Constructor. - */ - public BeemContactListOnLongClick() { + public ContactList() { } @@ -275,420 +85,625 @@ * {@inheritDoc} */ @Override - public boolean onItemLongClick(AdapterView arg0, View v, int pos, long lpos) { - Contact c = mListContact.get(pos); - ContactDialog dialogContact = new ContactDialog(ContactList.this, c); - dialogContact.setOwnerActivity(ContactList.this); - dialogContact.show(); - return true; + protected void onCreate(Bundle saveBundle) { + super.onCreate(saveBundle); + mSettings = PreferenceManager.getDefaultSharedPreferences(this); + setContentView(R.layout.contactlist); + mAdapterContactList = new BeemContactList(this); + mAdapterBanner = new BeemBanner(this); + mHandler = new Handler(); + mReceiver = new BeemBroadcastReceiver(mServConn); + this.registerReceiver(mReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED)); + mInflater = LayoutInflater.from(this); + prepareIconsStatus(); } - } - - /** - * Event simple click on middle groupe name. - */ - private class OnItemClickGroupName implements OnItemClickListener { /** - * Constructor. + * Callback for menu creation. + * + * @param menu + * the menu created + * @return true on success, false otherwise */ - public OnItemClickGroupName() { + @Override + public final boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.contact_list, menu); + return true; + } + + /** + * Callback for menu item selected. + * + * @param item + * the item selected + * @return true on success, false otherwise + */ + @Override + public final boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.contact_list_menu_settings: + startActivityForResult(new Intent(this, Settings.class), REQUEST_CODE); + return true; + case R.id.contact_list_menu_add_contact: + startActivity(new Intent(ContactList.this, AddContact.class)); + return true; + default: + return false; + } } @Override - public void onItemClick(AdapterView arg0, View v, int i, long l) { - mCurGroup = mListGroup.get(i); - buildContactList(); - } - } - - /** - * Prepare Bitmap Map. - */ - private void prepareIconsStatus(){ - mIconsMap.put(Status.CONTACT_STATUS_AVAILABLE, BitmapFactory.decodeResource(getResources(), R.drawable.status_available)); - mIconsMap.put(Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT, BitmapFactory.decodeResource(getResources(), R.drawable.status_available)); - mIconsMap.put(Status.CONTACT_STATUS_AWAY, BitmapFactory.decodeResource(getResources(), R.drawable.status_away)); - mIconsMap.put(Status.CONTACT_STATUS_BUSY, BitmapFactory.decodeResource(getResources(), R.drawable.status_dnd)); - mIconsMap.put(Status.CONTACT_STATUS_DISCONNECT, BitmapFactory.decodeResource(getResources(), R.drawable.status_offline)); - mIconsMap.put(Status.CONTACT_STATUS_UNAVAILABLE, BitmapFactory.decodeResource(getResources(), R.drawable.status_requested)); - } - - /** - * Sort the contact list. - */ - private void sortBeemContactList() { - Collections.sort(mListContact, new ComparatorContactListByStatusAndName()); - } - - /** - * Listener on service event. - */ - private class BeemRosterListener extends IBeemRosterListener.Stub { - /** - * Constructor. - */ - public BeemRosterListener() { - - } - - /** - * Refresh the contact list. - */ - private class RunnableChange implements Runnable { - /** - * Constructor. - */ - public RunnableChange() { - - } - - /** - * {@inheritDoc} - */ - @Override - public void run() { - sortBeemContactList(); - mAdapterContactList.notifyDataSetChanged(); - mAdapterBanner.notifyDataSetChanged(); - } + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == REQUEST_CODE) { + if (resultCode == RESULT_OK) { + mListContact.clear(); + stopService(SERVICE_INTENT); + finish(); + startActivity(new Intent(this, Login.class)); + } + } } /** * {@inheritDoc} */ @Override - public void onEntriesAdded(List addresses) throws RemoteException { - for (String newName : addresses) { - Contact c = mRoster.getContact(newName); - mContactOnGroup.get(getString(R.string.contact_list_all_contact)).add(c); - if (c.getGroups().size() == 0) - mContactOnGroup.get(getString(R.string.contact_list_no_group)).add(c); - else { - for (String group : c.getGroups()) { - if (!mListGroup.contains(group)) { - mListGroup.add(mListGroup.size() - 1, group); - List tmplist = new ArrayList(); - mContactOnGroup.put(group, tmplist); - } - mContactOnGroup.get(group).add(c); - if (group.equals(mCurGroup) && !mListContact.contains(c)) - mListContact.add(c); - } - } - } - mHandler.post(new RunnableChange()); - } - - /** - * {@inheritDoc} - */ - @Override - public void onEntriesDeleted(List addresses) throws RemoteException { - for (String cToDelete : addresses) { - for (Contact c : mListContact) { - if (c.getJID().equals(cToDelete)) { - mListContact.remove(c); - for (String group : mListGroup) { - mContactOnGroup.get(group).remove(c); - if (mContactOnGroup.get(group).size() == 0) { - mListGroup.remove(group); - mListContact = mContactOnGroup.get(getString(R.string.contact_list_all_contact)); - } - } - break; - } - } - } - mHandler.post(new RunnableChange()); - } - - /** - * {@inheritDoc} - */ - @Override - public void onEntriesUpdated(List addresses) throws RemoteException { - for (String adr : addresses) { - Contact c = mRoster.getContact(adr); - if (c.getGroups() != null) { - if (mContactOnGroup.get(getString(R.string.contact_list_no_group)).contains(c)) { - mContactOnGroup.get(getString(R.string.contact_list_no_group)).remove(c); - } - } - } - mHandler.post(new RunnableChange()); - } - - @Override - public void onEntryDeleteFromGroup(String group, String jid) throws RemoteException { - List tmpContactList = mContactOnGroup.get(group); - Contact curContact = null; - for (Contact c : tmpContactList) { - if (jid.equals(c.getJID())) { - curContact = c; - tmpContactList.remove(c); - c.getGroups().remove(group); - if (mContactOnGroup.get(group).size() == 0) { - mContactOnGroup.remove(group); - mListGroup.remove(group); - mListContact = mContactOnGroup.get(getString(R.string.contact_list_all_contact)); - } - break; - } - } - if (curContact != null && curContact.getGroups().size() == 0) { - mContactOnGroup.get(getString(R.string.contact_list_no_group)).add(curContact); - } - mHandler.post(new RunnableChange()); + protected void onStart() { + super.onStart(); + bindService(SERVICE_INTENT, mServConn, BIND_AUTO_CREATE); } /** * {@inheritDoc} */ @Override - public void onPresenceChanged(PresenceAdapter presence) throws RemoteException { - String from = presence.getFrom(); - boolean resfound = false; - for (Contact curContact : mListContact) { - if (curContact.getJID().equals(StringUtils.parseBareAddress(from))) { - String pres = StringUtils.parseResource(from); - for (String res : curContact.getMRes()) { - if (res.equals(pres)) { - resfound = true; - break; - } - } - curContact.setStatus(mRoster.getPresence(StringUtils.parseBareAddress(presence.getFrom()))); - int status = presence.getStatus(); - if (!resfound && !Status.statusOnline(status)) - curContact.addRes(pres); - else if (resfound && Status.statusOnline(status)) - curContact.delRes(pres); - mHandler.post(new RunnableChange()); - return; + protected void onStop() { + super.onStop(); + if (mReceiver.isBinded()) + unbindService(mServConn); + mReceiver.setBinded(false); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + this.unregisterReceiver(mReceiver); + } + + /** + * Comparator Contact by Name. + */ + class ComparatorContactListByName implements Comparator { + /** + * Constructor. + */ + public ComparatorContactListByName() { + } - } + + /** + * {@inheritDoc} + */ + @Override + public int compare(T c1, T c2) { + return ((Contact) c1).getName().compareToIgnoreCase(((Contact) c2).getName()); + } } - } - - /** - * Adapter contact list. - */ - private class BeemContactList extends BaseAdapter { /** - * Constructor. - * @param context context activity. + * Comparator Contact by status and name. */ - public BeemContactList(final Context context) { + class ComparatorContactListByStatusAndName implements Comparator { + /** + * Constructor. + */ + public ComparatorContactListByStatusAndName() { + + } + + /** + * {@inheritDoc} + */ + @Override + public int compare(T c1, T c2) { + if (((Contact) c1).getStatus() < ((Contact) c2).getStatus()) { + return 1; + } else if (((Contact) c1).getStatus() > ((Contact) c2).getStatus()) { + return -1; + } else + return ((Contact) c1).getName().compareToIgnoreCase(((Contact) c2).getName()); + } + } + + /** + * Contact List construction. + */ + private void buildContactList() { + if (mCurGroup != null) { + mListContact = mContactOnGroup.get(mCurGroup); + } + sortBeemContactList(); + ListView listView = (ListView) findViewById(R.id.contactlist); + listView.setOnItemClickListener(new BeemContactListOnClick()); + listView.setOnItemLongClickListener(new BeemContactListOnLongClick()); + listView.setAdapter(mAdapterContactList); + } + + /** + * buildBanner. + */ + private void buildBanner() { + Gallery g = (Gallery) findViewById(R.id.contactlist_banner); + g.setOnItemClickListener(new OnItemClickGroupName()); + g.setAdapter(mAdapterBanner); } /** - * {@inheritDoc} + * Event simple click on item of the contact list. */ - @Override - public int getCount() { - if (mSettings.getBoolean("settings_key_hidden_contact", false)) { - int res = 0; - for (Contact c : mListContact) { - if (Status.statusOnline(c.getStatus())) - res++; + public class BeemContactListOnClick implements OnItemClickListener { + /** + * Constructor. + */ + public BeemContactListOnClick() { + } - return res; - } else { - return mListContact.size(); - } - } - /** - * {@inheritDoc} - */ - @Override - public Object getItem(int position) { - return position; - } - - /** - * {@inheritDoc} - */ - @Override - public long getItemId(int position) { - return position; + /** + * {@inheritDoc} + */ + @Override + public void onItemClick(AdapterView arg0, View v, int pos, long lpos) { + Contact c = mListContact.get(pos); + Intent i = new Intent(ContactList.this, Chat.class); + i.setData(c.toUri()); + startActivity(i); + } } /** - * {@inheritDoc} + * Event long click on item of the contact list. + */ + public class BeemContactListOnLongClick implements OnItemLongClickListener { + /** + * Constructor. + */ + public BeemContactListOnLongClick() { + + } + + /** + * {@inheritDoc} + */ + @Override + public boolean onItemLongClick(AdapterView arg0, View v, int pos, long lpos) { + Contact c = mListContact.get(pos); + ContactDialog dialogContact = new ContactDialog(ContactList.this, c); + dialogContact.setOwnerActivity(ContactList.this); + dialogContact.show(); + return true; + } + } + + /** + * Event simple click on middle groupe name. */ - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - if (convertView == null) { - v = mInflater.inflate(R.layout.contactlistcontact, null); - } - Contact c = null; - if (mSettings.getBoolean("settings_key_hidden_contact", false)) { - int res = 0; - for (Contact cur : mListContact) { - if (res == position) { - c = cur; - break; - } - if (Status.statusOnline(cur.getStatus())) - res++; + private class OnItemClickGroupName implements OnItemClickListener { + + /** + * Constructor. + */ + public OnItemClickGroupName() { + } + + @Override + public void onItemClick(AdapterView arg0, View v, int i, long l) { + mCurGroup = mListGroup.get(i); + buildContactList(); } - } else - c = mListContact.get(position); - if (mRoster != null) { - try { - c = mRoster.getContact(c.getJID()); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - if (mSettings.getBoolean("settings_key_hidden_contact", false) && !Status.statusOnline(c.getStatus())) { - v.setVisibility(View.GONE); - } else { - bindView(v, c); - } - return v; + } + + /** + * Prepare Bitmap Map. + */ + private void prepareIconsStatus() { + mIconsMap.put(Status.CONTACT_STATUS_AVAILABLE, BitmapFactory.decodeResource(getResources(), + R.drawable.status_available)); + mIconsMap.put(Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT, BitmapFactory.decodeResource(getResources(), + R.drawable.status_available)); + mIconsMap.put(Status.CONTACT_STATUS_AWAY, BitmapFactory.decodeResource(getResources(), R.drawable.status_away)); + mIconsMap.put(Status.CONTACT_STATUS_BUSY, BitmapFactory.decodeResource(getResources(), R.drawable.status_dnd)); + mIconsMap.put(Status.CONTACT_STATUS_DISCONNECT, BitmapFactory.decodeResource(getResources(), + R.drawable.status_offline)); + mIconsMap.put(Status.CONTACT_STATUS_UNAVAILABLE, BitmapFactory.decodeResource(getResources(), + R.drawable.status_requested)); + } + + /** + * Sort the contact list. + */ + private void sortBeemContactList() { + Collections.sort(mListContact, new ComparatorContactListByStatusAndName()); } /** - * Adapte curContact to the view. - * @param view the row view. - * @param curContact the current contact. - */ - private void bindView(View view, Contact curContact) { - - if (curContact != null) { - ImageView imgV = (ImageView) view.findViewById(R.id.contactliststatus); - TextView v = (TextView) view.findViewById(R.id.contactlistpseudo); - imgV.setImageBitmap(mIconsMap.get(curContact.getStatus())); - v.setText(curContact.getName()); - v = (TextView) view.findViewById(R.id.contactlistmsgperso); - v.setText(curContact.getMsgState()); - } - } - } - - /** - * Adapter banner list. - */ - public class BeemBanner extends BaseAdapter { - /** - * Constructor. - * @param c context activity. + * Listener on service event. */ - public BeemBanner(final Context c) { - } + private class BeemRosterListener extends IBeemRosterListener.Stub { + /** + * Constructor. + */ + public BeemRosterListener() { + + } + + /** + * Refresh the contact list. + */ + private class RunnableChange implements Runnable { + /** + * Constructor. + */ + public RunnableChange() { + + } - /** - * {@inheritDoc} - */ - @Override - public int getCount() { - return mListGroup.size(); - } + /** + * {@inheritDoc} + */ + @Override + public void run() { + sortBeemContactList(); + mAdapterContactList.notifyDataSetChanged(); + mAdapterBanner.notifyDataSetChanged(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void onEntriesAdded(List addresses) throws RemoteException { + for (String newName : addresses) { + Contact c = mRoster.getContact(newName); + mContactOnGroup.get(getString(R.string.contact_list_all_contact)).add(c); + if (c.getGroups().size() == 0) + mContactOnGroup.get(getString(R.string.contact_list_no_group)).add(c); + else { + for (String group : c.getGroups()) { + if (!mListGroup.contains(group)) { + mListGroup.add(mListGroup.size() - 1, group); + List tmplist = new ArrayList(); + mContactOnGroup.put(group, tmplist); + } + mContactOnGroup.get(group).add(c); + if (group.equals(mCurGroup) && !mListContact.contains(c)) + mListContact.add(c); + } + } + } + mHandler.post(new RunnableChange()); + } - /** - * {@inheritDoc} - */ - @Override - public Object getItem(int position) { - return position; - } + /** + * {@inheritDoc} + */ + @Override + public void onEntriesDeleted(List addresses) throws RemoteException { + for (String cToDelete : addresses) { + for (Contact c : mListContact) { + if (c.getJID().equals(cToDelete)) { + mListContact.remove(c); + for (String group : mListGroup) { + mContactOnGroup.get(group).remove(c); + if (mContactOnGroup.get(group).size() == 0) { + mListGroup.remove(group); + mListContact = mContactOnGroup.get(getString(R.string.contact_list_all_contact)); + } + } + break; + } + } + } + mHandler.post(new RunnableChange()); + } + + /** + * {@inheritDoc} + */ + @Override + public void onEntriesUpdated(List addresses) throws RemoteException { + for (String adr : addresses) { + Contact c = mRoster.getContact(adr); + if (c.getGroups() != null) { + if (mContactOnGroup.get(getString(R.string.contact_list_no_group)).contains(c)) { + mContactOnGroup.get(getString(R.string.contact_list_no_group)).remove(c); + } + } + } + mHandler.post(new RunnableChange()); + } - /** - * {@inheritDoc} - */ - @Override - public long getItemId(int position) { - return position; + @Override + public void onEntryDeleteFromGroup(String group, String jid) throws RemoteException { + List tmpContactList = mContactOnGroup.get(group); + Contact curContact = null; + for (Contact c : tmpContactList) { + if (jid.equals(c.getJID())) { + curContact = c; + tmpContactList.remove(c); + c.getGroups().remove(group); + if (mContactOnGroup.get(group).size() == 0) { + mContactOnGroup.remove(group); + mListGroup.remove(group); + mListContact = mContactOnGroup.get(getString(R.string.contact_list_all_contact)); + } + break; + } + } + if (curContact != null && curContact.getGroups().size() == 0) { + mContactOnGroup.get(getString(R.string.contact_list_no_group)).add(curContact); + } + mHandler.post(new RunnableChange()); + } + + /** + * {@inheritDoc} + */ + @Override + public void onPresenceChanged(PresenceAdapter presence) throws RemoteException { + String from = presence.getFrom(); + boolean resfound = false; + for (Contact curContact : mListContact) { + if (curContact.getJID().equals(StringUtils.parseBareAddress(from))) { + String pres = StringUtils.parseResource(from); + for (String res : curContact.getMRes()) { + if (res.equals(pres)) { + resfound = true; + break; + } + } + curContact.setStatus(mRoster.getPresence(StringUtils.parseBareAddress(presence.getFrom()))); + int status = presence.getStatus(); + if (!resfound && !Status.statusOnline(status)) + curContact.addRes(pres); + else if (resfound && Status.statusOnline(status)) + curContact.delRes(pres); + mHandler.post(new RunnableChange()); + return; + } + } + } } /** - * {@inheritDoc} + * Adapter contact list. */ - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - if (convertView == null) { - v = mInflater.inflate(R.layout.contactlist_group, null); - } - ((TextView) v).setText(mListGroup.get(position)); - return v; - } + private class BeemContactList extends BaseAdapter { + + /** + * Constructor. + * + * @param context + * context activity. + */ + public BeemContactList(final Context context) { + } + + /** + * {@inheritDoc} + */ + @Override + public int getCount() { + if (mSettings.getBoolean("settings_key_hidden_contact", false)) { + int res = 0; + for (Contact c : mListContact) { + if (Status.statusOnline(c.getStatus())) + res++; + } + return res; + } else { + return mListContact.size(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Object getItem(int position) { + return position; + } + + /** + * {@inheritDoc} + */ + @Override + public long getItemId(int position) { + return position; + } - } + /** + * {@inheritDoc} + */ + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (convertView == null) { + v = mInflater.inflate(R.layout.contactlistcontact, null); + } + Contact c = null; + if (mSettings.getBoolean("settings_key_hidden_contact", false)) { + int res = 0; + for (Contact cur : mListContact) { + if (res == position) { + c = cur; + break; + } + if (Status.statusOnline(cur.getStatus())) + res++; + } + } else + c = mListContact.get(position); + if (mRoster != null) { + try { + c = mRoster.getContact(c.getJID()); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + if (mSettings.getBoolean("settings_key_hidden_contact", false) && !Status.statusOnline(c.getStatus())) { + v.setVisibility(View.GONE); + } else { + bindView(v, c); + } + return v; + } - /** - * The service connection used to connect to the Beem service. - */ - private class BeemServiceConnection implements ServiceConnection { - private final BeemRosterListener mBeemRosterListener = new BeemRosterListener(); + /** + * Adapte curContact to the view. + * + * @param view + * the row view. + * @param curContact + * the current contact. + */ + private void bindView(View view, Contact curContact) { - /** - * Constructor. - */ - public BeemServiceConnection() { + if (curContact != null) { + ImageView imgV = (ImageView) view.findViewById(R.id.contactliststatus); + TextView v = (TextView) view.findViewById(R.id.contactlistpseudo); + imgV.setImageBitmap(mIconsMap.get(curContact.getStatus())); + v.setText(curContact.getName()); + v = (TextView) view.findViewById(R.id.contactlistmsgperso); + v.setText(curContact.getMsgState()); + } + } } - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - mXmppFacade = IXmppFacade.Stub.asInterface(service); - mReceiver.setBinded(true); - try { - mRoster = mXmppFacade.getRoster(); - if (mRoster != null) { - mRoster.addRosterListener(mBeemRosterListener); - List tmpContactList = mRoster.getContactList(); - List tmpGroupList = mRoster.getGroupsNames(); - Collections.sort(tmpGroupList); - if (mListGroup.size() > 0) - mListGroup.clear(); - mListGroup.add(getString(R.string.contact_list_all_contact)); - mListGroup.addAll(tmpGroupList); - mListGroup.add(getString(R.string.contact_list_no_group)); - if (tmpGroupList.size() > 0) { - List tmpNoGroup = new ArrayList(); - for (String s : tmpGroupList) { - List tmpList = new ArrayList(); - for (Contact c : tmpContactList) { - if (c.getGroups().size() == 0 && !tmpNoGroup.contains(c)) - tmpNoGroup.add(c); - else if (c.getGroups().contains(s)) - tmpList.add(c); - } - mContactOnGroup.put(s, tmpList); + /** + * Adapter banner list. + */ + public class BeemBanner extends BaseAdapter { + /** + * Constructor. + * + * @param c + * context activity. + */ + public BeemBanner(final Context c) { + } + + /** + * {@inheritDoc} + */ + @Override + public int getCount() { + return mListGroup.size(); + } + + /** + * {@inheritDoc} + */ + @Override + public Object getItem(int position) { + return position; + } + + /** + * {@inheritDoc} + */ + @Override + public long getItemId(int position) { + return position; + } + + /** + * {@inheritDoc} + */ + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (convertView == null) { + v = mInflater.inflate(R.layout.contactlist_group, null); } - mContactOnGroup.put(getString(R.string.contact_list_no_group), tmpNoGroup); - } else { - mContactOnGroup.put(getString(R.string.contact_list_no_group), tmpContactList); - } - mContactOnGroup.put(getString(R.string.contact_list_all_contact), tmpContactList); - mCurGroup = getString(R.string.contact_list_all_contact); - buildBanner(); - buildContactList(); + ((TextView) v).setText(mListGroup.get(position)); + return v; } - } catch (RemoteException e) { - e.printStackTrace(); - } } - @Override - public void onServiceDisconnected(ComponentName name) { - try { - mRoster.removeRosterListener(mBeemRosterListener); - } catch (RemoteException e) { - e.printStackTrace(); - } - mXmppFacade = null; - mRoster = null; - mListContact.clear(); - mListGroup.clear(); - mContactOnGroup.clear(); - mReceiver.setBinded(false); + /** + * The service connection used to connect to the Beem service. + */ + private class BeemServiceConnection implements ServiceConnection { + private final BeemRosterListener mBeemRosterListener = new BeemRosterListener(); + + /** + * Constructor. + */ + public BeemServiceConnection() { + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + mXmppFacade = IXmppFacade.Stub.asInterface(service); + mReceiver.setBinded(true); + try { + mRoster = mXmppFacade.getRoster(); + if (mRoster != null) { + mRoster.addRosterListener(mBeemRosterListener); + List tmpContactList = mRoster.getContactList(); + List tmpGroupList = mRoster.getGroupsNames(); + Collections.sort(tmpGroupList); + if (mListGroup.size() > 0) + mListGroup.clear(); + mListGroup.add(getString(R.string.contact_list_all_contact)); + mListGroup.addAll(tmpGroupList); + mListGroup.add(getString(R.string.contact_list_no_group)); + if (tmpGroupList.size() > 0) { + List tmpNoGroup = new ArrayList(); + for (String s : tmpGroupList) { + List tmpList = new ArrayList(); + for (Contact c : tmpContactList) { + if (c.getGroups().size() == 0 && !tmpNoGroup.contains(c)) + tmpNoGroup.add(c); + else if (c.getGroups().contains(s)) + tmpList.add(c); + } + mContactOnGroup.put(s, tmpList); + } + mContactOnGroup.put(getString(R.string.contact_list_no_group), tmpNoGroup); + } else { + mContactOnGroup.put(getString(R.string.contact_list_no_group), tmpContactList); + } + mContactOnGroup.put(getString(R.string.contact_list_all_contact), tmpContactList); + mCurGroup = getString(R.string.contact_list_all_contact); + buildBanner(); + buildContactList(); + } + } catch (RemoteException e) { + e.printStackTrace(); + } + + } + + @Override + public void onServiceDisconnected(ComponentName name) { + try { + mRoster.removeRosterListener(mBeemRosterListener); + } catch (RemoteException e) { + e.printStackTrace(); + } + mXmppFacade = null; + mRoster = null; + mListContact.clear(); + mListGroup.clear(); + mContactOnGroup.clear(); + mReceiver.setBinded(false); + } } - } }