コード例 #1
0
void
on_del_button_clicked                  (GtkToolButton   *toolbutton,
                                        gpointer         user_data)
{
	GtkTreeSelection *select;
	GtkTreeIter iter;
        GtkTreeModel *model;
	gchar *nick;
	GtkTreeView *tree_view;
	
	tree_view = (GtkTreeView*)lookup_widget(main_window, "msg_list");
	select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
	if (gtk_tree_selection_get_selected (select, &model, &iter))
	{
		gtk_tree_model_get (model, &iter, 0, &nick, -1);
		GtkWidget *dialog = gtk_message_dialog_new (NULL,
                                  GTK_DIALOG_DESTROY_WITH_PARENT,
                                  GTK_MESSAGE_ERROR,
                                  GTK_BUTTONS_YES_NO,
                                  "Are you sure you want to delete the user %s ?", nick
                                  );
			gint result = gtk_dialog_run (GTK_DIALOG (dialog));
			gtk_widget_destroy (dialog);
			if(result == GTK_RESPONSE_YES)
				RemoveContact(nick);
	}
}
コード例 #2
0
//--------------------------------------------------------------------------------------------------
void q3ContactManager::RemoveContactsFromBody( q3Body *body )
{
	q3ContactEdge* edge = body->m_contactList;

	while( edge )
	{
		q3ContactEdge* next = edge->next;
		RemoveContact( edge->constraint );
		edge = next;
	}
}
コード例 #3
0
ファイル: CContactList.cpp プロジェクト: kmdtukl/miranda-ng
//************************************************************************
// called when a contacts hidden flag has changed
//************************************************************************
void CContactList::OnContactHiddenChanged(MCONTACT hContact, bool bHidden)
{
	CListEntry<CContactListEntry*,CContactListGroup*> *pContactEntry =  FindContact(hContact);

	if(!pContactEntry && !bHidden)
	{
		AddContact(hContact);
		return;
	}
	else if(!pContactEntry)
		return;

	if(!IsVisible(GetContactData(pContactEntry)))
		RemoveContact(hContact);
}
コード例 #4
0
ファイル: CContactList.cpp プロジェクト: kmdtukl/miranda-ng
//************************************************************************
// called when the contacts message count has changed
//************************************************************************
void CContactList::OnMessageCountChanged(MCONTACT hContact)
{
	CListEntry<CContactListEntry *,CContactListGroup*> *pContactEntry = FindContact(hContact);
	if(!pContactEntry)
	{
		AddContact(hContact);
		return;
	}

	UpdateMessageCounter(pContactEntry);

	if(!IsVisible(GetContactData(pContactEntry)))
		RemoveContact(hContact);
	((CListContainer<CContactListEntry*,CContactListGroup*>*)pContactEntry->GetParent())->sort(CContactList::CompareEntries);

}
コード例 #5
0
ファイル: CContactList.cpp プロジェクト: kmdtukl/miranda-ng
//************************************************************************
// called when a contacts status has changed
//************************************************************************
void CContactList::OnStatusChange(MCONTACT hContact,int iStatus)
{
	// find the entry in the list
	CListEntry<CContactListEntry *,CContactListGroup*> *pContactEntry = FindContact(hContact);
	if(!pContactEntry)
	{
		AddContact(hContact);
		return;
	}
	
	
	CContactListEntry *pItemData = GetContactData(pContactEntry);
	if(!pItemData) {
		return;
	}
	// get the old status
	int iOldStatus = pItemData->iStatus;
		
	// Update the list entry
	TCHAR *szStatus = pcli->pfnGetStatusModeDescription(iStatus, 0);
	if(szStatus != NULL)
		pItemData->strStatus =toTstring(szStatus);
	
	pItemData->iStatus = iStatus;
	
	// update the contacts group
	CListContainer<CContactListEntry*,CContactListGroup*>* pGroup = ((CListContainer<CContactListEntry*,CContactListGroup*>*)pContactEntry->GetParent());
	if(pGroup->GetType() != ROOT)
	{
		if(!db_mc_isSub(hContact) && iStatus == ID_STATUS_OFFLINE && iOldStatus != ID_STATUS_OFFLINE)
			ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,-1);

		else if(!db_mc_isSub(hContact) && iStatus != ID_STATUS_OFFLINE && iOldStatus == ID_STATUS_OFFLINE)
			ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,1);
	}
	
	// check if the entry is still visible
	if(!IsVisible(pItemData))
	{
		RemoveContact(hContact);
		return;
	}

	// sort the list
	pGroup->sort(CContactList::CompareEntries);

}
コード例 #6
0
//************************************************************************
// called when a contacts status has changed
//************************************************************************
void CContactList::OnStatusChange(HANDLE hContact,int iStatus)
{
	// find the entry in the list
	CListEntry<CContactListEntry *,CContactListGroup*> *pContactEntry = FindContact(hContact);
	if(!pContactEntry)
	{
		AddContact(hContact);
		return;
	}
	
	
	CContactListEntry *pItemData = GetContactData(pContactEntry);
	if(!pItemData) {
		return;
	}
	// get the old status
	int iOldStatus = pItemData->iStatus;
		
	// Update the list entry
	char *szStatus = (char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iStatus, 0);
	if(szStatus != NULL)
		pItemData->strStatus =toTstring(szStatus);
	
	pItemData->iStatus = iStatus;
	
	// update the contacts group
	CListContainer<CContactListEntry*,CContactListGroup*>* pGroup = ((CListContainer<CContactListEntry*,CContactListGroup*>*)pContactEntry->GetParent());
	if(pGroup->GetType() != ROOT)
	{
		if(!CAppletManager::IsSubContact(hContact) && iStatus == ID_STATUS_OFFLINE && iOldStatus != ID_STATUS_OFFLINE)
			ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,-1);

		else if(!CAppletManager::IsSubContact(hContact) && iStatus != ID_STATUS_OFFLINE && iOldStatus == ID_STATUS_OFFLINE)
			ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,1);
	}
	
	// check if the entry is still visible
	if(!IsVisible(pItemData))
	{
		RemoveContact(hContact);
		return;
	}

	// sort the list
	pGroup->sort(CContactList::CompareEntries);

}
コード例 #7
0
ファイル: CContactList.cpp プロジェクト: kmdtukl/miranda-ng
//************************************************************************
// called when a contact has been deleted
//************************************************************************
void CContactList::OnContactDeleted(MCONTACT hContact)
{
	// Update the list
	RemoveContact(hContact);

	// Decrease the membercount of the old group, and check if it needs to be deleted
	int res = 0;
	tstring strGroup = GetContactGroupPath(hContact);
	if(!strGroup.empty())
	{
		CContactListGroup *pGroup = GetGroupObjectByPath(strGroup);
		
		
		if(!db_mc_isSub(hContact))
			ChangeGroupObjectCounters(strGroup,-1);
		
		if(pGroup->iMembers <= 0)
			DeleteGroupObjectByPath(pGroup->strPath);
	}
}
コード例 #8
0
ファイル: CContactList.cpp プロジェクト: kmdtukl/miranda-ng
//************************************************************************
// refreshes the list
//************************************************************************
void CContactList::RefreshList()
{
	if((db_get_b(NULL,"MetaContacts","Enabled",1) != 0) != m_bUseMetaContacts ||
		CConfig::GetBoolSetting(CLIST_USEGROUPS) != m_bUseGroups)
	{
		InitializeGroupObjects();
		Clear();
	}
	m_bUseGroups = CConfig::GetBoolSetting(CLIST_USEGROUPS);
	m_bUseMetaContacts = db_get_b(NULL,"MetaContacts","Enabled",1) != 0;

	CListEntry<CContactListEntry*,CContactListGroup*> *pContactEntry = NULL;
	MCONTACT hContact = db_find_first();
    while(hContact != NULL)
	{
		pContactEntry = FindContact(hContact);
		if(!pContactEntry)
			AddContact(hContact);
		else if(pContactEntry && !IsVisible(GetContactData(pContactEntry)))
			RemoveContact(hContact);
        hContact = db_find_next(hContact);
    }
}
コード例 #9
0
//--------------------------------------------------------------------------------------------------
void q3ContactManager::TestCollisions( void )
{
	q3ContactConstraint* constraint = m_contactList;

	while( constraint )
	{
		q3Box *A = constraint->A;
		q3Box *B = constraint->B;
		q3Body *bodyA = A->body;
		q3Body *bodyB = B->body;

		constraint->m_flags &= ~q3ContactConstraint::eIsland;

		if( !bodyA->IsAwake( ) && !bodyB->IsAwake( ) )
		{
			constraint = constraint->next;
			continue;
		}

		if ( !bodyA->CanCollide( bodyB ) )
		{
			q3ContactConstraint* next = constraint->next;
			RemoveContact( constraint );
			constraint = next;
			continue;
		}

		// Check if contact should persist
		if ( !m_broadphase.TestOverlap( A->broadPhaseIndex, B->broadPhaseIndex ) )
		{
			q3ContactConstraint* next = constraint->next;
			RemoveContact( constraint );
			constraint = next;
			continue;
		}
		q3Manifold* manifold = &constraint->manifold;
		q3Manifold oldManifold = constraint->manifold;
		q3Vec3 ot0 = oldManifold.tangentVectors[ 0 ];
		q3Vec3 ot1 = oldManifold.tangentVectors[ 1 ];
		constraint->SolveCollision( );
		q3ComputeBasis( manifold->normal, manifold->tangentVectors, manifold->tangentVectors + 1 );

		for ( i32 i = 0; i < manifold->contactCount; ++i )
		{
			q3Contact *c = manifold->contacts + i;
			c->tangentImpulse[ 0 ] = c->tangentImpulse[ 1 ] = c->normalImpulse = r32( 0.0 );
			u8 oldWarmStart = c->warmStarted;
			c->warmStarted = u8( 0 );

			for ( i32 j = 0; j < oldManifold.contactCount; ++j )
			{
				q3Contact *oc = oldManifold.contacts + j;
				if ( c->fp.key == oc->fp.key )
				{
					c->normalImpulse = oc->normalImpulse;

					// Attempt to re-project old friction solutions
					q3Vec3 friction = ot0 * oc->tangentImpulse[ 0 ] + ot1 * oc->tangentImpulse[ 1 ];
					c->tangentImpulse[ 0 ] = q3Dot( friction, manifold->tangentVectors[ 0 ] );
					c->tangentImpulse[ 1 ] = q3Dot( friction, manifold->tangentVectors[ 1 ] );
					c->warmStarted = q3Max( oldWarmStart, u8( oldWarmStart + 1 ) );
					break;
				}
			}
		}

		if ( m_contactListener )
		{
			i32 now_colliding = constraint->m_flags & q3ContactConstraint::eColliding;
			i32 was_colliding = constraint->m_flags & q3ContactConstraint::eWasColliding;

			if ( now_colliding && !was_colliding )
				m_contactListener->BeginContact( constraint );

			else if ( !now_colliding && was_colliding )
				m_contactListener->EndContact( constraint );
		}

		constraint = constraint->next;
	}
}
コード例 #10
0
ファイル: Jabber.cpp プロジェクト: HaikuArchives/IMKit
status_t
Jabber::Process( BMessage * msg )
{
	switch ( msg->what )
	{
		case IM::MESSAGE:
		{
			int32 im_what = 0;
			
			msg->FindInt32("im_what", &im_what );
						
			switch ( im_what )
			{
				case IM::SET_STATUS:
				{
					const char *status = msg->FindString("status");
					LOG(kProtocolName, liMedium, "Set status to %s", status);
					
					if (strcmp(status, OFFLINE_TEXT) == 0) 
					{
							
						SetStatus(S_OFFLINE,OFFLINE_TEXT); //do the log-out?
					} 
					else 
					if (strcmp(status, AWAY_TEXT) == 0) 
					{
						if(IsAuthorized()){
						
						 //const char *away_msg;	
						 BString away_msg;					 
						 if(msg->FindString("away_msg",&away_msg) == B_OK)
						 {
						 	// quick and dirty way to use advanced away status:
						 	// add 'DND: ' for Do not Disturb
						 	// or  'XA: ' for Extended Away
						 	
						 	if(away_msg.Compare("DND: ",4) == 0)
						 		SetStatus(S_DND,away_msg); 
						 	else
						 	if(away_msg.Compare("XA: ",4) == 0)
						 		SetStatus(S_XA,away_msg); 
						 	else	
						 		SetStatus(S_AWAY,away_msg); 
						 }
						 	 else
						 		 SetStatus(S_AWAY,AWAY_TEXT); 
						 
						 			
						 SetAway(true);
						} 
					} 
					else 
					if (strcmp(status, ONLINE_TEXT) == 0) 
					{
							if(!IsAuthorized())
							{
								if(fUsername == "")
									Error("Empty Username!",NULL);
								if(fServer == "")
									Error("Empty Server!",NULL);
								if(fPassword == "")
									Error("Empty Password!",NULL);
								
								Progress("Jabber Login", "Jabber: Connecting..", 0.0);
										
							}
							
							SetStatus(S_ONLINE,ONLINE_TEXT); //do the login!
							if(IsAuthorized()) SetAway(false); 
					} 
					else
					{
						Error("Invalid",NULL);
						LOG(kProtocolName, liHigh, "Invalid status when setting status: '%s'", status);
					}
				}	break;
				
				case IM::SEND_MESSAGE:
				{
						const char * buddy=msg->FindString("id");
						const char * sms=msg->FindString("message");
						JabberMessage jm;
						jm.SetTo(buddy);
						jm.SetFrom(GetJid());
						jm.SetBody(sms);
						TimeStamp(jm);
						
						//not the right place.. see Jabber::Message
						JabberContact *contact=getContact(buddy);
						
						//tmp: new mess id!
						BString messid("imkit_");
						messid << idsms;
						idsms++;
						
						if(contact)
							jm.SetID(messid);
												
						SendMessage(jm);
						
						MessageSent(buddy,sms);
				} 
				break;
				case IM::REGISTER_CONTACTS:
					
					{
					
					//debugger("REGISTER");
					type_code garbage;
					int32 count = 0;
					msg->GetInfo("id", &garbage, &count);
					
										
					if (count > 0 ) {
						
						for ( int i=0; msg->FindString("id",i); i++ )
						{
							const char * id = msg->FindString("id",i);
							JabberContact* contact=getContact(id);
							if(contact)
								  BuddyStatusChanged(contact);
							else
							{
							 
								//Are we on-line?
								// send auth req?
								if(fFullLogged)
								{ 			
									AddContact(id,id,"");
									BuddyStatusChanged(id,OFFLINE_TEXT);
								}
								
								else
								{
								 // we add to a temp list.
								 // when logged in we will register the new buddy..
									 fLaterBuddyList->push_back(BString(id));
								}							 
							} 
						};
						
					} 
					else 
						return B_ERROR;
					} 	
					break;
				case IM::UNREGISTER_CONTACTS:
				
				{
						
					
						const char * buddy=NULL;
						
						for ( int i=0; msg->FindString("id", i, &buddy) == B_OK; i++ )
						{
							LOG(kProtocolName, liDebug, "Unregister Contact: '%s'", buddy);
							
							if(!fFullLogged)
							BuddyStatusChanged(buddy,OFFLINE_TEXT);
							else
							{
								LOG(kProtocolName, liDebug, "Unregister Contact DOING IT");
							 	JabberContact* contact=getContact(buddy);
							 	if(contact)
									RemoveContact(contact);
							}
						}
				} 
					
					break;
				case IM::USER_STARTED_TYPING: 
				{
						const char * id=NULL;
						
						if( msg->FindString("id", &id) == B_OK )
						{
						 JabberContact* contact=getContact(id);
						 if(contact)
							StartComposingMessage(contact);
						}
				} 
				break;
				case IM::USER_STOPPED_TYPING: 
				{
						const char * id=NULL;
						
						if( msg->FindString("id", &id) == B_OK )
						{
						 JabberContact* contact=getContact(id);
						 if(contact && (contact->GetLastMessageID().ICompare("")!=0)){
							StopComposingMessage(contact);
							contact->SetLastMessageID("");
							
							}
						}
				} 
				break;
				
				case IM::GET_CONTACT_INFO:
					//debugger("Get Contact Info! ;)");
					SendContactInfo(msg->FindString("id"));
				break;
								
				case IM::SEND_AUTH_ACK:
				{
					if(!IsAuthorized())
						return B_ERROR;
					
					const char * id = msg->FindString("id");
					int32 button = msg->FindInt32("which");
					
					if (button == 0) {
						
						//Authorization granted
						AcceptSubscription(id);
						BMessage im_msg(IM::MESSAGE);
						im_msg.AddInt32("im_what", IM::CONTACT_AUTHORIZED);
						im_msg.AddString("protocol", kProtocolName);
						im_msg.AddString("id", id);
						im_msg.AddString("message", "");
						fServerMsgr.SendMessage(&im_msg);
						
						//now we want to see you! ;)
						AddContact(id,id,"");
														
					} 
					else 
					{
						//Authorization rejected
						Error("Authorization rejected!",id);
					}
						
					
				}
				break;
				default:
					// we don't handle this im_what code
					msg->PrintToStream();	
					return B_ERROR;
			}
		}	break;
		
		default:
			// we don't handle this what code
			return B_ERROR;
	}
	
	return B_OK;
}
コード例 #11
0
ファイル: CContactList.cpp プロジェクト: kmdtukl/miranda-ng
//************************************************************************
// called when a contacts group has changed
//************************************************************************
void CContactList::OnContactGroupChanged(MCONTACT hContact,tstring strGroup)
{
	bool bMetaContact = false;
	

	strGroup = GetContactGroupPath(hContact);

	// Decrease the membercount of the old group
	CListEntry<CContactListEntry *,CContactListGroup*> *pContactEntry = FindContact(hContact);
	CContactListGroup *pOldGroup = NULL;
	// If the contactentry was not found, try adding the contact (metacontacts fix)
	if(!pContactEntry) {
		return;
	}
	if(pContactEntry->GetType() == CONTAINER)
		bMetaContact = true;


	CListContainer<CContactListEntry*,CContactListGroup*>* pContainer = ((CListContainer<CContactListEntry*,CContactListGroup*>*)pContactEntry->GetParent());
	// Update the contacts group if it has one
	if(pContainer->GetType() != ROOT)
	{
		pOldGroup = pContainer->GetGroupData();
		if(!db_mc_isSub(hContact))
			ChangeGroupObjectCounters(pOldGroup->strPath,-1);
	}
	
	// increase the membercount of the new group, and check if it needs to be created
	if(!strGroup.empty())
	{
		CContactListGroup *pGroup = GetGroupObjectByPath(strGroup);
		if(!pGroup)
			pGroup = CreateGroupObjectByPath(strGroup);
		if(!db_mc_isSub(hContact))
			ChangeGroupObjectCounters(strGroup,1);
	}

	// move subcontacts
	if(pContactEntry->GetType() == CONTAINER)
	{
		CListContainer<CContactListEntry*,CContactListGroup*> *pGroup = (CListContainer<CContactListEntry*,CContactListGroup*>*)pContactEntry;
		CListContainer<CContactListEntry*,CContactListGroup*>::iterator iter = pGroup->begin();
		while(!pGroup->empty())
		{
			iter = pGroup->begin();
			if((*iter)->GetType() == ITEM)
				OnContactGroupChanged(GetContactData(*iter)->hHandle,_T(""));
			Sleep(1);
		}
	}

	// update the list
	RemoveContact(hContact);
	AddContact(hContact);

	if(bMetaContact)
	{
		tstring strName = CAppletManager::GetContactDisplayname(hContact);
		tstring strPath = _T("");
		if(pOldGroup)
			strPath += pOldGroup->strPath;
		strPath += (strPath.empty()?_T(""):_T("\\")) + strName;
		DeleteGroupObjectByPath(strPath);
	}

	// check if the old group ( if it exists ) needs to be deleted
	if(pOldGroup && !pOldGroup->hMetaContact && pOldGroup->iMembers <= 0 && pOldGroup->iGroups <= 0)
		DeleteGroupObjectByPath(pOldGroup->strPath);
}
コード例 #12
0
ファイル: CContactList.cpp プロジェクト: kmdtukl/miranda-ng
//************************************************************************
// adds a contact to the list
//************************************************************************
void CContactList::AddContact(MCONTACT hContact)
{
	CListContainer<CContactListEntry*,CContactListGroup*> *pGroup = NULL;

	tstring strName = CAppletManager::GetContactDisplayname(hContact);
	char *szProto = GetContactProto(hContact);
	
	tstring strGroup = GetContactGroupPath(hContact);
	// ignore contacts without a valid protocoll
	if(szProto == NULL)
		return;

	int iStatus = db_get_w(hContact,szProto,"Status",ID_STATUS_OFFLINE);
	TCHAR *szStatus = pcli->pfnGetStatusModeDescription(iStatus, 0);

	CContactListEntry *psContact = new CContactListEntry();

	psContact->strName = strName;
	psContact->iMessages = 0;
	psContact->hHandle = hContact;
	
	psContact->iStatus = iStatus;
	
	if(szStatus != NULL)
		psContact->strStatus =toTstring(szStatus);
	psContact->strProto = toTstring(szProto);

	// check wether the contact should be listed
	if(!IsVisible(psContact)) {
		delete psContact;
		return;
	}

	// Don't add metacontacts as contacts
	if(!mir_strcmpi(szProto,"MetaContacts"))
	{
		if(!CConfig::GetBoolSetting(CLIST_USEGROUPS))
			strGroup = _T("");
		strGroup += (strGroup.empty()?_T(""):_T("\\"))+psContact->strName;
		pGroup = GetGroupByString(strGroup);
		if(pGroup == NULL)
			pGroup = AddGroupByString(strGroup);
		pGroup->GetGroupData()->hMetaContact = hContact;
		pGroup->GetGroupData()->pContactListEntry = psContact;

		pGroup = (CListContainer<CContactListEntry*,CContactListGroup*>*)pGroup->GetParent();
		if(pGroup->GetType() != ROOT && iStatus != ID_STATUS_OFFLINE)
			ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,1);

		pGroup->sort(CContactList::CompareEntries);

		// check that all subcontacts exist
		int numContacts = db_mc_getSubCount(hContact);
		MCONTACT hSubContact = NULL;
		for(int i=0;i<numContacts;i++) {
			hSubContact = db_mc_getSub(hContact, i);
			RemoveContact(hSubContact);
			AddContact(hSubContact);
		}
		return;
	}
	else if(db_mc_isSub(hContact)) {
		MCONTACT hMetaContact = db_mc_getMeta(hContact);
		// check that the metacontact exists
		if(!FindContact(hMetaContact))
			AddContact(hMetaContact);
	}

	CListItem<CContactListEntry*,CContactListGroup*> *pItem = NULL;
	if((!db_mc_isSub(hContact) && !CConfig::GetBoolSetting(CLIST_USEGROUPS)) || strGroup.empty())
	{
		pItem = AddItem(psContact);
		((CListContainer<CContactListEntry*,CContactListGroup*>*)this)->sort(CContactList::CompareEntries);
	}
	else
	{
		pGroup = GetGroupByString(strGroup);
		if(pGroup == NULL) {
			pGroup = AddGroupByString(strGroup);
		}
		pItem = pGroup->AddItem(psContact);
	
		if(!db_mc_isSub(hContact) && iStatus != ID_STATUS_OFFLINE)
			ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,1);

		pGroup->sort(CContactList::CompareEntries);
	}

	UpdateMessageCounter((CListEntry<CContactListEntry*,CContactListGroup*>*)pItem);
}
コード例 #13
0
//************************************************************************
// adds a contact to the list
//************************************************************************
void CContactList::AddContact(HANDLE hContact)
{
	CListContainer<CContactListEntry*,CContactListGroup*> *pGroup = NULL;

	tstring strName = CAppletManager::GetContactDisplayname(hContact);
	char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(UINT)hContact,0);
	
	tstring strGroup = GetContactGroupPath(hContact);
	// ignore contacts without a valid protocoll
	if(szProto == NULL)
		return;

	int iStatus = db_get_w(hContact,szProto,"Status",ID_STATUS_OFFLINE);
	char *szStatus = (char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iStatus, 0);

	CContactListEntry *psContact = new CContactListEntry();

	psContact->strName = strName;
	psContact->iMessages = 0;
	psContact->hHandle = hContact;
	
	psContact->iStatus = iStatus;
	
	if(szStatus != NULL)
		psContact->strStatus =toTstring(szStatus);
	psContact->strProto = toTstring(szProto);

	// check wether the contact should be listed
	if(!IsVisible(psContact)) {
		delete psContact;
		return;
	}

	// Don't add metacontacts as contacts
	if(!stricmp(szProto,"MetaContacts"))
	{
		if(!CConfig::GetBoolSetting(CLIST_USEGROUPS))
			strGroup = _T("");
		strGroup += (strGroup.empty()?_T(""):_T("\\"))+psContact->strName;
		pGroup = GetGroupByString(strGroup);
		if(pGroup == NULL)
			pGroup = AddGroupByString(strGroup);
		pGroup->GetGroupData()->hMetaContact = hContact;
		pGroup->GetGroupData()->pContactListEntry = psContact;

		pGroup = (CListContainer<CContactListEntry*,CContactListGroup*>*)pGroup->GetParent();
		if(pGroup->GetType() != ROOT && iStatus != ID_STATUS_OFFLINE)
			ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,1);

		pGroup->sort(CContactList::CompareEntries);

		// check that all subcontacts exist
		int numContacts = CallService(MS_MC_GETNUMCONTACTS,(WPARAM)hContact,0);
		HANDLE hSubContact = NULL;
		for(int i=0;i<numContacts;i++) {
			hSubContact = (HANDLE *) CallService(MS_MC_GETSUBCONTACT, (WPARAM)hContact, (LPARAM)i);
			RemoveContact(hSubContact);
			AddContact(hSubContact);
		}
		return;
	} else if(CAppletManager::IsSubContact(hContact)) {
		HANDLE hMetaContact = (HANDLE *) CallService(MS_MC_GETMETACONTACT, (WPARAM)hContact, 0);
		// check that the metacontact exists
		if(!FindContact(hMetaContact)) {
			AddContact(hMetaContact);
		}
	}

	CListItem<CContactListEntry*,CContactListGroup*> *pItem = NULL;
	if((!CAppletManager::IsSubContact(hContact) && !CConfig::GetBoolSetting(CLIST_USEGROUPS)) || strGroup.empty())
	{
		pItem = AddItem(psContact);
		((CListContainer<CContactListEntry*,CContactListGroup*>*)this)->sort(CContactList::CompareEntries);
	}
	else
	{
		pGroup = GetGroupByString(strGroup);
		if(pGroup == NULL) {
			pGroup = AddGroupByString(strGroup);
		}
		pItem = pGroup->AddItem(psContact);
	
		if(!CAppletManager::IsSubContact(hContact) && iStatus != ID_STATUS_OFFLINE)
			ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,1);

		pGroup->sort(CContactList::CompareEntries);
	}

	UpdateMessageCounter((CListEntry<CContactListEntry*,CContactListGroup*>*)pItem);
}