//************************************************************************ // removes a contact from the list //************************************************************************ void CContactList::RemoveContact(MCONTACT hContact) { CListContainer<CContactListEntry*,CContactListGroup*> *pGroup = NULL; ///tstring strGroup = GetContactGroupPath(hContact); CListEntry<CContactListEntry*,CContactListGroup*> *pContactEntry = FindContact(hContact); if(!pContactEntry) { return; } if( !CConfig::GetBoolSetting(CLIST_USEGROUPS)){ if(pContactEntry->GetType() == ITEM) RemoveItem(((CListItem<CContactListEntry*,CContactListGroup*>*)pContactEntry)->GetItemData()); else RemoveGroup(((CListContainer<CContactListEntry*,CContactListGroup*>*)pContactEntry)->GetGroupData()); } else { pGroup = (CListContainer<CContactListEntry*,CContactListGroup*>*)pContactEntry->GetParent(); ASSERT(pGroup != NULL); CContactListEntry *pEntry = GetContactData(pContactEntry); if(!pEntry) { return; } // Update the contacts group if it has one if(pGroup->GetType() != ROOT) { if(!db_mc_isSub(hContact) && pEntry->iStatus != ID_STATUS_OFFLINE) ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,-1); if(!db_mc_isSub(hContact) && pEntry->iMessages > 0) ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,0,-pEntry->iMessages); } if(pContactEntry->GetType() == ITEM) pGroup->RemoveItem(((CListItem<CContactListEntry*,CContactListGroup*>*)pContactEntry)->GetItemData()); else { pGroup->RemoveGroup(((CListContainer<CContactListEntry*,CContactListGroup*>*)pContactEntry)->GetGroupData()); // Reenumerate all subcontacts (maybe MetaContacts was disabled int numContacts = db_mc_getSubCount(hContact); for(int i=0;i<numContacts;i++) { MCONTACT hSubContact = db_mc_getSub(hContact, i); if(!FindContact(hSubContact)) AddContact(hSubContact); } } CListContainer<CContactListEntry*,CContactListGroup*> *pParent = (CListContainer<CContactListEntry*,CContactListGroup*>*)pGroup->GetParent(); while(pParent != NULL && pGroup->IsEmpty() && !pGroup->GetGroupData()->hMetaContact) { pParent->RemoveGroup(pGroup->GetGroupData()); pGroup = pParent; pParent = (CListContainer<CContactListEntry*,CContactListGroup*>*)pGroup->GetParent(); } } }
// This method clears the list and adds contacts again, according to the current filter settings. void RebuildList() { LPSTR pszProto; MTime mtNow; MAnnivDate ad; int i = 0; DWORD age = 0; WORD wDaysBefore = db_get_w(NULL, MODNAME, SET_REMIND_OFFSET, DEFVAL_REMIND_OFFSET); WORD numMale = 0; WORD numFemale = 0; WORD numContacts = 0; WORD numBirthContacts = 0; ShowWindow(_hList, SW_HIDE); DeleteAllItems(); mtNow.GetLocalTime(); // insert the items into the list for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { // ignore meta subcontacts here, as they are not interesting. if (!db_mc_isSub(hContact)) { // filter protocol pszProto = Proto_GetBaseAccountName(hContact); if (pszProto) { numContacts++; switch (GenderOf(hContact, pszProto)) { case 'M': numMale++; break; case 'F': numFemale++; } if (!ad.DBGetBirthDate(hContact, pszProto)) { age += ad.Age(&mtNow); numBirthContacts++; // add birthday if ((_filter.bFilterIndex != FILTER_ANNIV) && (!_filter.pszProto || !_strcmpi(pszProto, _filter.pszProto))) AddRow(hContact, pszProto, ad, mtNow, wDaysBefore); } // add anniversaries if (_filter.bFilterIndex != FILTER_BIRTHDAY && (!_filter.pszProto || !_strcmpi(pszProto, _filter.pszProto))) for (i = 0; !ad.DBGetAnniversaryDate(hContact, i); i++) if (!_filter.pszAnniv || !mir_tstrcmpi(_filter.pszAnniv, ad.Description())) AddRow(hContact, pszProto, ad, mtNow, wDaysBefore); } } } ListView_SortItemsEx(_hList, (CMPPROC)cmpProc, this); ShowWindow(_hList, SW_SHOW); // display statistics SetDlgItemInt(_hDlg, TXT_NUMBIRTH, numBirthContacts, FALSE); SetDlgItemInt(_hDlg, TXT_NUMCONTACT, numContacts, FALSE); SetDlgItemInt(_hDlg, TXT_FEMALE, numFemale, FALSE); SetDlgItemInt(_hDlg, TXT_MALE, numMale, FALSE); SetDlgItemInt(_hDlg, TXT_AGE, numBirthContacts > 0 ? (age - (age % numBirthContacts)) / numBirthContacts : 0, FALSE); }
void setSrmmIcon(MCONTACT h) { MCONTACT hContact = metaIsProtoMetaContacts(h) ? metaGetMostOnline(h) : h; bool enabled = isContactSecured(hContact); MCONTACT hMC = NULL; if(db_mc_isSub(hContact)) hMC = db_mc_getMeta(hContact); else if(metaIsProtoMetaContacts(hContact)) hMC = db_mc_getMeta(hContact); StatusIconData sid = { sizeof(sid) }; sid.szModule = szGPGModuleName; sid.hIcon = IconLibGetIcon("secured"); sid.dwId = 1; sid.flags = enabled ? 0 : MBF_HIDDEN; Srmm_ModifyIcon(hContact, &sid); if(hMC) Srmm_ModifyIcon(hMC, &sid); sid.hIcon = IconLibGetIcon("unsecured"); sid.dwId = 2; sid.flags = enabled ? MBF_HIDDEN : 0; Srmm_ModifyIcon(hContact, &sid); if(hMC) Srmm_ModifyIcon(hMC, &sid); }
//************************************************************************ // 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); }
void setClistIcon(MCONTACT hContact) { bool enabled = isContactSecured(hContact); extern HANDLE g_hCLIcon; MCONTACT hMC = hContact; if(db_mc_isSub(hContact)) hMC = db_mc_getMeta(hContact); else if(metaIsProtoMetaContacts(hContact)) hMC = db_mc_getMeta(hContact); const char *szIconId = (enabled) ? "secured" : NULL; ExtraIcon_SetIcon(g_hCLIcon, hContact, szIconId); if(hMC) ExtraIcon_SetIcon(g_hCLIcon, hMC, szIconId); }
int HookedNewEvent(WPARAM hContact, LPARAM lParam) { //are popups currently enabled? if (pluginOptions.bDisable) return 0; //get DBEVENTINFO without pBlob DBEVENTINFO dbe = { sizeof(dbe) }; db_event_get((HANDLE)lParam, &dbe); //do not show popups for sub-contacts if (hContact && db_mc_isSub(hContact)) return 0; //custom database event types if (ServiceExists(MS_DB_EVENT_GETTYPE)) { DBEVENTTYPEDESCR *pei = (DBEVENTTYPEDESCR*)CallService(MS_DB_EVENT_GETTYPE, (WPARAM)dbe.szModule, (LPARAM)dbe.eventType); // ignore events according to flags if (pei && pei->flags & DETF_NONOTIFY) return 0; } //if event was allready read don't show it if (pluginOptions.bReadCheck && (dbe.flags & DBEF_READ)) return 0; //is it an event sent by the user? -> don't show if (dbe.flags & DBEF_SENT) { // JK, only message event, do not influence others if (pluginOptions.bHideSend && NumberPopupData(hContact, EVENTTYPE_MESSAGE) != -1) { PLUGIN_DATA *pdata = PopupList[NumberPopupData(hContact, EVENTTYPE_MESSAGE)]; PopupAct(pdata->hWnd, MASK_DISMISS, pdata); // JK, only dismiss, i.e. do not kill event (e.g. file transfer) } return 0; } // which status do we have, are we allowed to post popups? // UNDER CONSTRUCTION!!! CallService(MS_CLIST_GETSTATUSMODE, 0, 0); /// TODO: JK: ???? if (dbe.eventType == EVENTTYPE_MESSAGE && (pluginOptions.bMsgWindowCheck && hContact && CheckMsgWnd(hContact))) return 0; //is another popup for this contact already present? -> merge message popups if enabled if (dbe.eventType == EVENTTYPE_MESSAGE && (pluginOptions.bMergePopup && NumberPopupData(hContact, EVENTTYPE_MESSAGE) != -1)) PopupUpdate(hContact, (HANDLE)lParam); else PopupShow(&pluginOptions, hContact, (HANDLE)lParam, (UINT)dbe.eventType); return 0; }
//************************************************************************ // returns the contacts group path //************************************************************************ tstring CContactList::GetContactGroupPath(MCONTACT hContact) { tstring strGroup = _T(""); if(db_get_b(0, "MetaContacts", "Enabled", 1) && db_mc_isSub(hContact)) { MCONTACT hMetaContact = db_mc_getMeta(hContact); if(CConfig::GetBoolSetting(CLIST_USEGROUPS)) strGroup = CAppletManager::GetContactGroup(hMetaContact); tstring strMetaName = CAppletManager::GetContactDisplayname(hMetaContact); strGroup += (strGroup.empty()?_T(""):_T("\\"))+ strMetaName; } else strGroup = CAppletManager::GetContactGroup(hContact); return strGroup; }
//************************************************************************ // called when a contact has been added //************************************************************************ void CContactList::OnContactAdded(MCONTACT hContact) { // Update the list AddContact(hContact); // increase the membercount of the new group, and check if it needs to be created tstring strGroup = GetContactGroupPath(hContact); if(!strGroup.empty()) { CContactListGroup *pGroup = GetGroupObjectByPath(strGroup); if(!pGroup) pGroup = CreateGroupObjectByPath(strGroup); if(!db_mc_isSub(hContact)) ChangeGroupObjectCounters(strGroup,1); } }
//************************************************************************ // returns wether a contact should be listed or not //************************************************************************ bool CContactList::IsVisible(CContactListEntry *pEntry) { if(!pEntry) { return false; } if(pEntry->strProto != _T("MetaContacts")) { if(pEntry->iStatus == ID_STATUS_OFFLINE && CConfig::GetBoolSetting(CLIST_HIDEOFFLINE)) { return false; } } else { if(pEntry->iStatus == ID_STATUS_OFFLINE) { int dwNumContacts = db_mc_getSubCount(pEntry->hHandle); for(int i = 0; i < dwNumContacts; i++) { MCONTACT hSubContact = db_mc_getSub(pEntry->hHandle,i); char *szProto = GetContactProto(hSubContact); if(db_get_w(hSubContact,szProto,"Status",ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) return true; } } } if(pEntry->iMessages > 0) return true; if(CConfig::GetBoolSetting(CLIST_USEIGNORE)) { if(db_get_b(pEntry->hHandle,"CList","Hidden",0)) return false; if(db_mc_isSub(pEntry->hHandle)) { MCONTACT hMetaContact = db_mc_getMeta(pEntry->hHandle); if(db_get_b(hMetaContact,"CList","Hidden",0)) return false; } } if(!CConfig::GetProtocolContactlistFilter(pEntry->strProto)) return false; if(CConfig::GetBoolSetting(CLIST_HIDEOFFLINE) && pEntry->iStatus == ID_STATUS_OFFLINE) return false; return true; }
//************************************************************************ // initializes the group objects //************************************************************************ void CContactList::InitializeGroupObjects() { UninitializeGroupObjects(); int res = 0; CContactListGroup *pGroup = NULL; HANDLE hMetaContact = NULL; char *szProto = NULL; for(MCONTACT hContact = db_find_first();hContact != NULL;hContact = db_find_next(hContact)) { tstring strGroup = GetContactGroupPath(hContact); szProto = GetContactProto(hContact); if(szProto && db_get_b(NULL,META_PROTO,"Enabled",1) && !mir_strcmpi(szProto,META_PROTO)) { tstring strName = CAppletManager::GetContactDisplayname(hContact); tstring strPath = _T(""); if(CConfig::GetBoolSetting(CLIST_USEGROUPS)) strPath += strGroup; strPath += (strPath.empty()?_T(""):_T("\\")) + strName; pGroup = CreateGroupObjectByPath(strPath); pGroup->hMetaContact = hContact; if(!strGroup.empty()) ChangeGroupObjectCounters(strGroup,1); } // If the contact has no group, continue else if(!strGroup.empty() && CConfig::GetBoolSetting(CLIST_USEGROUPS)) { pGroup = GetGroupObjectByPath(strGroup); // create the group if(!pGroup) pGroup = CreateGroupObjectByPath(strGroup); // update it's counters if(!db_mc_isSub(hContact)) ChangeGroupObjectCounters(strGroup,1); } } }
//************************************************************************ // 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); } }
int __fastcall CLVM_GetContactHiddenStatus(MCONTACT hContact, char *szProto, ClcData *dat) { int dbHidden = db_get_b(hContact, "CList", "Hidden", 0); // default hidden state, always respect it. int filterResult = 1; int searchResult = 0; DBVARIANT dbv = { 0 }; char szTemp[64]; TCHAR szGroupMask[256]; DWORD dwLocalMask; ClcCacheEntry *pdnce = pcli->pfnGetCacheEntry(hContact); // always hide subcontacts (but show them on embedded contact lists) if (dat != NULL && dat->IsMetaContactsEnabled && db_mc_isSub(hContact)) return -1; //subcontact if (pdnce && pdnce->isUnknown && dat != NULL && !dat->force_in_dialog) return 1; //'Unknown Contact' if (dat != NULL && dat->filterSearch && pdnce && pdnce->tszName) { // search filtering TCHAR *lowered_name = CharLowerW(NEWTSTR_ALLOCA(pdnce->tszName)); TCHAR *lowered_search = CharLowerW(NEWTSTR_ALLOCA(dat->szQuickSearch)); searchResult = _tcsstr(lowered_name, lowered_search) ? 0 : 1; } if (pdnce && g_CluiData.bFilterEffective && dat != NULL && !dat->force_in_dialog) { if (szProto == NULL) szProto = GetContactProto(hContact); // check stickies first (priority), only if we really have stickies defined (CLVM_STICKY_CONTACTS is set). if (g_CluiData.bFilterEffective & CLVM_STICKY_CONTACTS) { if ((dwLocalMask = db_get_dw(hContact, CLVM_MODULE, g_CluiData.current_viewmode, 0)) != 0) { if (g_CluiData.bFilterEffective & CLVM_FILTER_STICKYSTATUS) { WORD wStatus = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); return !((1 << (wStatus - ID_STATUS_OFFLINE)) & HIWORD(dwLocalMask)) | searchResult; } return 0 | searchResult; } } // check the proto, use it as a base filter result for all further checks if (g_CluiData.bFilterEffective & CLVM_FILTER_PROTOS) { mir_snprintf(szTemp, "%s|", szProto); filterResult = strstr(g_CluiData.protoFilter, szTemp) ? 1 : 0; } if (g_CluiData.bFilterEffective & CLVM_FILTER_GROUPS) { if (!db_get_ts(hContact, "CList", "Group", &dbv)) { mir_sntprintf(szGroupMask, _T("%s|"), &dbv.ptszVal[0]); filterResult = (g_CluiData.filterFlags & CLVM_PROTOGROUP_OP) ? (filterResult | (_tcsstr(g_CluiData.groupFilter, szGroupMask) ? 1 : 0)) : (filterResult & (_tcsstr(g_CluiData.groupFilter, szGroupMask) ? 1 : 0)); mir_free(dbv.ptszVal); } else if (g_CluiData.filterFlags & CLVM_INCLUDED_UNGROUPED) filterResult = (g_CluiData.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 1; else filterResult = (g_CluiData.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 0; } if (g_CluiData.bFilterEffective & CLVM_FILTER_STATUS) { WORD wStatus = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); filterResult = (g_CluiData.filterFlags & CLVM_GROUPSTATUS_OP) ? ((filterResult | ((1 << (wStatus - ID_STATUS_OFFLINE)) & g_CluiData.statusMaskFilter ? 1 : 0))) : (filterResult & ((1 << (wStatus - ID_STATUS_OFFLINE)) & g_CluiData.statusMaskFilter ? 1 : 0)); } if (g_CluiData.bFilterEffective & CLVM_FILTER_LASTMSG) { if (pdnce->dwLastMsgTime != -1) { DWORD now = g_CluiData.t_now; now -= g_CluiData.lastMsgFilter; if (g_CluiData.bFilterEffective & CLVM_FILTER_LASTMSG_OLDERTHAN) filterResult = filterResult & (pdnce->dwLastMsgTime < now); else if (g_CluiData.bFilterEffective & CLVM_FILTER_LASTMSG_NEWERTHAN) filterResult = filterResult & (pdnce->dwLastMsgTime > now); } } return (dbHidden | !filterResult | searchResult); } return dbHidden | searchResult; }
int __fastcall CLVM_GetContactHiddenStatus(MCONTACT hContact, char *szProto, struct ClcData *dat) { int dbHidden = cfg::getByte(hContact, "CList", "Hidden", 0); // default hidden state, always respect it. int filterResult = 1; DBVARIANT dbv = {0}; char szTemp[64]; TCHAR szGroupMask[256]; DWORD dwLocalMask; // always hide subcontacts (but show them on embedded contact lists) if (dat != NULL && dat->bHideSubcontacts && cfg::dat.bMetaEnabled && db_mc_isSub(hContact)) return 1; if ( !cfg::dat.bFilterEffective) return dbHidden; if (szProto == NULL) szProto = GetContactProto(hContact); // check stickies first (priority), only if we really have stickies defined (CLVM_STICKY_CONTACTS is set). if (cfg::dat.bFilterEffective & CLVM_STICKY_CONTACTS) { if ((dwLocalMask = cfg::getDword(hContact, "CLVM", cfg::dat.current_viewmode, 0)) != 0) { if (cfg::dat.bFilterEffective & CLVM_FILTER_STICKYSTATUS) { WORD wStatus = cfg::getWord(hContact, szProto, "Status", ID_STATUS_OFFLINE); return !((1 << (wStatus - ID_STATUS_OFFLINE)) & HIWORD(dwLocalMask)); } return 0; } } // check the proto, use it as a base filter result for all further checks if (cfg::dat.bFilterEffective & CLVM_FILTER_PROTOS) { mir_snprintf(szTemp, sizeof(szTemp), "%s|", szProto); filterResult = strstr(cfg::dat.protoFilter, szTemp) ? 1 : 0; } if (cfg::dat.bFilterEffective & CLVM_FILTER_GROUPS) { if ( !cfg::getTString(hContact, "CList", "Group", &dbv)) { mir_sntprintf(szGroupMask, SIZEOF(szGroupMask), _T("%s|"), &dbv.ptszVal[1]); filterResult = (cfg::dat.filterFlags & CLVM_PROTOGROUP_OP) ? (filterResult | (_tcsstr(cfg::dat.groupFilter, szGroupMask) ? 1 : 0)) : (filterResult & (_tcsstr(cfg::dat.groupFilter, szGroupMask) ? 1 : 0)); mir_free(dbv.ptszVal); } else if (cfg::dat.filterFlags & CLVM_INCLUDED_UNGROUPED) filterResult = (cfg::dat.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 1; else filterResult = (cfg::dat.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 0; } if (cfg::dat.bFilterEffective & CLVM_FILTER_STATUS) { WORD wStatus = cfg::getWord(hContact, szProto, "Status", ID_STATUS_OFFLINE); filterResult = (cfg::dat.filterFlags & CLVM_GROUPSTATUS_OP) ? ((filterResult | ((1 << (wStatus - ID_STATUS_OFFLINE)) & cfg::dat.statusMaskFilter ? 1 : 0))) : (filterResult & ((1 << (wStatus - ID_STATUS_OFFLINE)) & cfg::dat.statusMaskFilter ? 1 : 0)); } if (cfg::dat.bFilterEffective & CLVM_FILTER_LASTMSG) { DWORD now; TExtraCache *p = cfg::getCache(hContact, szProto); if (p) { now = cfg::dat.t_now; now -= cfg::dat.lastMsgFilter; if (cfg::dat.bFilterEffective & CLVM_FILTER_LASTMSG_OLDERTHAN) filterResult = filterResult & (p->dwLastMsgTime < now); else if (cfg::dat.bFilterEffective & CLVM_FILTER_LASTMSG_NEWERTHAN) filterResult = filterResult & (p->dwLastMsgTime > now); } } return (dbHidden | !filterResult); }
//************************************************************************ // 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); }
//************************************************************************ // 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); }