示例#1
0
static void _LoadDataToContact(ClcContact *cont, ClcGroup *group, ClcData *dat, MCONTACT hContact)
{
	if (!cont)
		return;

	cont->type = CLCIT_CONTACT;
	cont->SubAllocated = 0;
	cont->isSubcontact = 0;
	cont->subcontacts = NULL;
	cont->szText[0] = 0;
	cont->lastPaintCounter = 0;
	cont->image_is_special = FALSE;
	cont->hContact = hContact;

	pcli->pfnInvalidateDisplayNameCacheEntry(hContact);

	ClcCacheEntry *cacheEntry = pcli->pfnGetCacheEntry(hContact);
	char *szProto = cacheEntry->m_cache_cszProto;
	cont->proto = szProto;

	if (szProto != NULL && !pcli->pfnIsHiddenMode(dat, pdnce___GetStatus(cacheEntry)))
		cont->flags |= CONTACTF_ONLINE;

	WORD apparentMode = szProto != NULL ? cacheEntry->ApparentMode : 0;

	if (apparentMode)
		switch (apparentMode) {
		case ID_STATUS_OFFLINE:
			cont->flags |= CONTACTF_INVISTO;
			break;
		case ID_STATUS_ONLINE:
			cont->flags |= CONTACTF_VISTO;
			break;
		default:
			cont->flags |= CONTACTF_VISTO | CONTACTF_INVISTO;
	}

	if (cacheEntry->NotOnList)
		cont->flags |= CONTACTF_NOTONLIST;

	DWORD idleMode = szProto != NULL ? cacheEntry->IdleTS : 0;
	if (idleMode)
		cont->flags |= CONTACTF_IDLE;

	// Add subcontacts
	if (szProto)
		if (dat->IsMetaContactsEnabled && mir_strcmp(cont->proto, META_PROTO) == 0)
			AddSubcontacts(dat, cont, CLCItems_IsShowOfflineGroup(group));

	cont->lastPaintCounter = 0;
	cont->avatar_pos = AVATAR_POS_DONT_HAVE;
	Cache_GetAvatar(dat, cont);
	Cache_GetText(dat, cont, 1);
	Cache_GetTimezone(dat, cont->hContact);
	cont->iImage = corecli.pfnGetContactIcon(hContact);
	cont->bContactRate = db_get_b(hContact, "CList", "Rate", 0);
}
示例#2
0
/*
*	Getting Status message (Away message)
*  -1 for XStatus, 1 for Status
*/
int GetStatusMessage(TCHAR *text, int text_size,  PDNCE pdnce, BOOL xstatus_has_priority) 
{
    DBVARIANT dbv={0};
    BOOL noAwayMsg=FALSE;
	WORD wStatus=pdnce___GetStatus( pdnce );
    text[0] = '\0';
	// Hide status text if Offline  /// no offline	
	
	if (wStatus==ID_STATUS_OFFLINE || wStatus==0) noAwayMsg=TRUE;
    // Get XStatusMsg
    if (!noAwayMsg &&xstatus_has_priority && pdnce->m_cache_hContact && pdnce->m_cache_cszProto)
    {
        // Try to get XStatusMsg
        if (!ModernGetSettingTString(pdnce->m_cache_hContact, pdnce->m_cache_cszProto, "XStatusMsg", &dbv)) 
        {
            //lstrcpyn(text, dbv.pszVal, text_size);
            CopySkipUnprintableChars(text, dbv.ptszVal, text_size-1);
            ModernDBFreeVariant(&dbv);

            if (text[0] != '\0')
                return -1;
        }
    }

    // Get StatusMsg
    if (pdnce->m_cache_hContact && text[0] == '\0')
    {
        if (!ModernGetSettingTString(pdnce->m_cache_hContact, "CList", "StatusMsg", &dbv)) 
        {
            //lstrcpyn(text, dbv.pszVal, text_size);
            CopySkipUnprintableChars(text, dbv.ptszVal, text_size-1);
            ModernDBFreeVariant(&dbv);

            if (text[0] != '\0')
                return 1;
        }
    }

    // Get XStatusMsg
    if (!noAwayMsg && !xstatus_has_priority && pdnce->m_cache_hContact && pdnce->m_cache_cszProto && text[0] == '\0')
    {
        // Try to get XStatusMsg
        if (!ModernGetSettingTString(pdnce->m_cache_hContact, pdnce->m_cache_cszProto, "XStatusMsg", &dbv)) 
        {
            //lstrcpyn(text, dbv.pszVal, text_size);
            CopySkipUnprintableChars(text, dbv.ptszVal, text_size-1);
            ModernDBFreeVariant(&dbv);

            if (text[0] != '\0')
                return -1;
        }
    }

    return 1;
}
void GetListeningTo(TCHAR *text, int text_size, ClcCacheEntry *pdnce)
{
	DBVARIANT dbv = { 0 };
	WORD wStatus = pdnce___GetStatus(pdnce);
	text[0] = _T('\0');

	if (wStatus == ID_STATUS_OFFLINE || wStatus == 0)
		return;

	if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "ListeningTo", &dbv)) {
		CopySkipUnprintableChars(text, dbv.ptszVal, text_size - 1);
		db_free(&dbv);
	}
}
示例#4
0
/*
*	Getting Status name
*  -1 for XStatus, 1 for Status
*/
int GetStatusName(TCHAR *text, int text_size, PDNCE pdnce, BOOL xstatus_has_priority) 
{
    BOOL noAwayMsg=FALSE;
    BOOL noXstatus=FALSE;
    // Hide status text if Offline  /// no offline		
	WORD nStatus=pdnce___GetStatus( pdnce );
    if ((nStatus==ID_STATUS_OFFLINE || nStatus==0) && g_CluiData.bRemoveAwayMessageForOffline) noAwayMsg=TRUE;
    if (nStatus==ID_STATUS_OFFLINE || nStatus==0) noXstatus=TRUE;
    text[0] = '\0';
    // Get XStatusName
    if (!noAwayMsg&& !noXstatus&& xstatus_has_priority && pdnce->m_cache_hContact && pdnce->m_cache_cszProto)
    {
        DBVARIANT dbv={0};
        if (!ModernGetSettingTString(pdnce->m_cache_hContact, pdnce->m_cache_cszProto, "XStatusName", &dbv)) 
        {
            //lstrcpyn(text, dbv.pszVal, text_size);
            CopySkipUnprintableChars(text, dbv.ptszVal, text_size-1);
            ModernDBFreeVariant(&dbv);

            if (text[0] != '\0')
                return -1;
        }
    }

    // Get Status name
    {
        TCHAR *tmp = (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)nStatus, GSMDF_TCHAR_MY);
        lstrcpyn(text, tmp, text_size);
        //CopySkipUnprintableChars(text, dbv.pszVal, text_size-1);
        if (text[0] != '\0')
            return 1;
    }

    // Get XStatusName
    if (!noAwayMsg && !noXstatus && !xstatus_has_priority && pdnce->m_cache_hContact && pdnce->m_cache_cszProto)
    {
        DBVARIANT dbv={0};
        if (!ModernGetSettingTString(pdnce->m_cache_hContact, pdnce->m_cache_cszProto, "XStatusName", &dbv)) 
        {
            //lstrcpyn(text, dbv.pszVal, text_size);
            CopySkipUnprintableChars(text, dbv.ptszVal, text_size-1);
            ModernDBFreeVariant(&dbv);

            if (text[0] != '\0')
                return -1;
        }
    }

    return 1;
}
int GetStatusMessage(TCHAR *text, int text_size, ClcCacheEntry *pdnce, BOOL xstatus_has_priority)
{
	DBVARIANT dbv = { 0 };
	BOOL noAwayMsg = FALSE;
	WORD wStatus = pdnce___GetStatus(pdnce);
	text[0] = '\0';
	// Hide status text if Offline  /// no offline

	if (wStatus == ID_STATUS_OFFLINE || wStatus == 0) noAwayMsg = TRUE;
	// Get XStatusMsg
	if (!noAwayMsg  && xstatus_has_priority && pdnce->hContact && pdnce->m_cache_cszProto) {
		// Try to get XStatusMsg
		if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "XStatusMsg", &dbv)) {
			//mir_tstrncpy(text, dbv.pszVal, text_size);
			CopySkipUnprintableChars(text, dbv.ptszVal, text_size - 1);
			db_free(&dbv);

			if (text[0] != '\0')
				return -1;
		}
	}

	// Get StatusMsg
	if (pdnce->hContact && text[0] == '\0') {
		if (!db_get_ts(pdnce->hContact, "CList", "StatusMsg", &dbv)) {
			//mir_tstrncpy(text, dbv.pszVal, text_size);
			CopySkipUnprintableChars(text, dbv.ptszVal, text_size - 1);
			db_free(&dbv);

			if (text[0] != '\0')
				return 1;
		}
	}

	// Get XStatusMsg
	if (!noAwayMsg && !xstatus_has_priority && pdnce->hContact && pdnce->m_cache_cszProto && text[0] == '\0') {
		// Try to get XStatusMsg
		if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "XStatusMsg", &dbv)) {
			//mir_tstrncpy(text, dbv.pszVal, text_size);
			CopySkipUnprintableChars(text, dbv.ptszVal, text_size - 1);
			db_free(&dbv);

			if (text[0] != '\0')
				return -1;
		}
	}

	return 1;
}
示例#6
0
/*
* Get Listening to information
*/
void GetListeningTo(TCHAR *text, int text_size,  PDNCE pdnce)
{
    DBVARIANT dbv={0};
	WORD wStatus=pdnce___GetStatus( pdnce );
    text[0] = _T('\0');
	
    if (wStatus==ID_STATUS_OFFLINE || wStatus==0)
        return;

    if (!ModernGetSettingTString(pdnce->m_cache_hContact, pdnce->m_cache_cszProto, "ListeningTo", &dbv)) 
    {
        CopySkipUnprintableChars(text, dbv.ptszVal, text_size-1);
        ModernDBFreeVariant(&dbv);
    }
}
示例#7
0
/////////// End by FYR ////////
int cli_IconFromStatusMode(const char *szProto,int nStatus, HANDLE hContact)
{
   int result=-1;
   if (hContact && szProto)
   {
       char * szActProto=(char*)szProto;
       char AdvancedService[255]={0};
       int  nActStatus=nStatus;
       HANDLE hActContact=hContact;
       if (!ModernGetSettingByte(NULL,"CLC","Meta",SETTING_USEMETAICON_DEFAULT) && g_szMetaModuleName && !mir_strcmp(szActProto,g_szMetaModuleName))
       {
            // substitute params by mostonline contact datas
           HANDLE hMostOnlineContact=(HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT,(WPARAM)hActContact,0);
           if (hMostOnlineContact)
           {
                pdisplayNameCacheEntry cacheEntry;
                cacheEntry=(pdisplayNameCacheEntry)pcli->pfnGetCacheEntry(hMostOnlineContact);
                if (cacheEntry && cacheEntry->m_cache_cszProto)
                {
                    szActProto=cacheEntry->m_cache_cszProto;
                    nActStatus=pdnce___GetStatus( cacheEntry );
                    hActContact=hMostOnlineContact;
                }
           }
       }
       mir_snprintf(AdvancedService,SIZEOF(AdvancedService),"%s%s",szActProto,"/GetAdvancedStatusIcon");

       if (ServiceExists(AdvancedService))
          result=CallService(AdvancedService,(WPARAM)hActContact, (LPARAM)0);

       if (result==-1 || !(LOWORD(result)))
       {
           //Get normal Icon
           int  basicIcon=corecli.pfnIconFromStatusMode(szActProto,nActStatus,NULL);
           if (result!=-1 && basicIcon!=1) result|=basicIcon;
           else result=basicIcon;
       }
   }
   else
   {
       result=corecli.pfnIconFromStatusMode(szProto,nStatus,NULL);
   }
   return result;
}
/*
*	Getting Status name
*  -1 for XStatus, 1 for Status
*/
int GetStatusName(TCHAR *text, int text_size, ClcCacheEntry *pdnce, BOOL xstatus_has_priority)
{
	BOOL noAwayMsg = FALSE;
	BOOL noXstatus = FALSE;
	// Hide status text if Offline  /// no offline
	WORD nStatus = pdnce___GetStatus(pdnce);
	if ((nStatus == ID_STATUS_OFFLINE || nStatus == 0) && g_CluiData.bRemoveAwayMessageForOffline) noAwayMsg = TRUE;
	if (nStatus == ID_STATUS_OFFLINE || nStatus == 0) noXstatus = TRUE;
	text[0] = '\0';
	// Get XStatusName
	if (!noAwayMsg && !noXstatus &&  xstatus_has_priority && pdnce->hContact && pdnce->m_cache_cszProto) {
		DBVARIANT dbv = { 0 };
		if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "XStatusName", &dbv)) {
			//mir_tstrncpy(text, dbv.pszVal, text_size);
			CopySkipUnprintableChars(text, dbv.ptszVal, text_size - 1);
			db_free(&dbv);

			if (text[0] != '\0')
				return -1;
		}
	}

	// Get Status name
	TCHAR *tmp = pcli->pfnGetStatusModeDescription(nStatus, 0);
	if (tmp && *tmp) {
		mir_tstrncpy(text, tmp, text_size);
		return 1;
	}

	// Get XStatusName
	if (!noAwayMsg && !noXstatus && !xstatus_has_priority && pdnce->hContact && pdnce->m_cache_cszProto) {
		DBVARIANT dbv = { 0 };
		if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "XStatusName", &dbv)) {
			CopySkipUnprintableChars(text, dbv.ptszVal, text_size - 1);
			db_free(&dbv);

			if (text[0] != '\0')
				return -1;
		}
	}

	return 1;
}
示例#9
0
void cliRebuildEntireList(HWND hwnd, ClcData *dat)
{
	DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE);
	ClcGroup *group = NULL;
	static int rebuildCounter = 0;

	BOOL PlaceOfflineToRoot = db_get_b(NULL, "CList", "PlaceOfflineToRoot", SETTING_PLACEOFFLINETOROOT_DEFAULT);
	KillTimer(hwnd, TIMERID_REBUILDAFTER);
	pcli->bAutoRebuild = false;

	ClearRowByIndexCache();
	ImageArray_Clear(&dat->avatar_cache);
	RowHeights_Clear(dat);
	RowHeights_GetMaxRowHeight(dat, hwnd);
	TRACEVAR("Rebuild Entire List %d times\n", ++rebuildCounter);

	dat->list.expanded = 1;
	dat->list.hideOffline = db_get_b(NULL, "CLC", "HideOfflineRoot", SETTING_HIDEOFFLINEATROOT_DEFAULT) && style&CLS_USEGROUPS;
	dat->list.cl.count = dat->list.cl.limit = 0;
	dat->list.cl.increment = 50;
	dat->needsResort = 1;

	MCONTACT hSelected = SaveSelection(dat);
	dat->selection = -1;
	dat->HiLightMode = db_get_b(NULL, "CLC", "HiLightMode", SETTING_HILIGHTMODE_DEFAULT);

	for (int i = 1;; i++) {
		DWORD groupFlags;
		TCHAR *szGroupName = pcli->pfnGetGroupName(i, &groupFlags); //UNICODE
		if (szGroupName == NULL)
			break;
		cli_AddGroup(hwnd, dat, szGroupName, groupFlags, i, 0);
	}

	for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) {
		ClcContact *cont = NULL;
		ClcCacheEntry *cacheEntry = pcli->pfnGetCacheEntry(hContact);

		int nHiddenStatus = CLVM_GetContactHiddenStatus(hContact, NULL, dat);
		if ((style & CLS_SHOWHIDDEN && nHiddenStatus != -1) || !nHiddenStatus) {
			if (mir_tstrlen(cacheEntry->tszGroup) == 0)
				group = &dat->list;
			else
				group = cli_AddGroup(hwnd, dat, cacheEntry->tszGroup, (DWORD)-1, 0, 0);

			if (group != NULL) {
				WORD wStatus = pdnce___GetStatus(cacheEntry);
				if (wStatus == ID_STATUS_OFFLINE && PlaceOfflineToRoot)
					group = &dat->list;

				group->totalMembers++;

				if (!(style & CLS_NOHIDEOFFLINE) && (style & CLS_HIDEOFFLINE || group->hideOffline)) {
					if (cacheEntry->m_cache_cszProto == NULL) {
						if (!pcli->pfnIsHiddenMode(dat, ID_STATUS_OFFLINE) || cacheEntry->m_cache_nNoHiddenOffline || CLCItems_IsShowOfflineGroup(group))
							cont = AddContactToGroup(dat, group, cacheEntry);
					}
					else if (!pcli->pfnIsHiddenMode(dat, wStatus) || cacheEntry->m_cache_nNoHiddenOffline || CLCItems_IsShowOfflineGroup(group))
						cont = AddContactToGroup(dat, group, cacheEntry);
				}
				else cont = AddContactToGroup(dat, group, cacheEntry);
			}
		}
		if (cont) {
			cont->SubAllocated = 0;
			if (cont->proto && dat->IsMetaContactsEnabled  && mir_strcmp(cont->proto, META_PROTO) == 0)
				AddSubcontacts(dat, cont, CLCItems_IsShowOfflineGroup(group));
		}
	}

	if (style & CLS_HIDEEMPTYGROUPS) {
		group = &dat->list;
		group->scanIndex = 0;
		for (;;) {
			if (group->scanIndex == group->cl.count) {
				group = group->parent;
				if (group == NULL)
					break;
			}
			else if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) {
				if (group->cl.items[group->scanIndex]->group->cl.count == 0)
					group = pcli->pfnRemoveItemFromGroup(hwnd, group, group->cl.items[group->scanIndex], 0);
				else {
					group = group->cl.items[group->scanIndex]->group;
					group->scanIndex = 0;
				}
				continue;
			}
			group->scanIndex++;
		}
	}

	pcli->pfnSortCLC(hwnd, dat, 0);

	RestoreSelection(dat, hSelected);
}
示例#10
0
void AddSubcontacts(ClcData *dat, ClcContact *cont, BOOL showOfflineHereGroup)
{
	ClcCacheEntry *cacheEntry = pcli->pfnGetCacheEntry(cont->hContact);
	cont->SubExpanded = (db_get_b(cont->hContact, "CList", "Expanded", 0) && (db_get_b(NULL, "CLC", "MetaExpanding", SETTING_METAEXPANDING_DEFAULT)));
	int subcount = db_mc_getSubCount(cont->hContact);
	if (subcount <= 0) {
		cont->isSubcontact = 0;
		cont->subcontacts = NULL;
		cont->SubAllocated = 0;
		return;
	}

	cont->isSubcontact = 0;
	mir_free(cont->subcontacts);
	cont->subcontacts = (ClcContact *)mir_calloc(sizeof(ClcContact)*subcount);
	cont->SubAllocated = subcount;
	int i = 0;
	int bHideOffline = db_get_b(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT);
	for (int j = 0; j < subcount; j++) {
		MCONTACT hsub = db_mc_getSub(cont->hContact, j);
		cacheEntry = pcli->pfnGetCacheEntry(hsub);
		WORD wStatus = pdnce___GetStatus(cacheEntry);

		if (!showOfflineHereGroup && bHideOffline && !cacheEntry->m_cache_nNoHiddenOffline && wStatus == ID_STATUS_OFFLINE)
			continue;

		ClcContact& p = cont->subcontacts[i];
		p.hContact = cacheEntry->hContact;

		p.avatar_pos = AVATAR_POS_DONT_HAVE;
		Cache_GetAvatar(dat, &p);

		p.iImage = corecli.pfnGetContactIcon(cacheEntry->hContact);
		memset(p.iExtraImage, 0xFF, sizeof(p.iExtraImage));
		p.proto = cacheEntry->m_cache_cszProto;
		p.type = CLCIT_CONTACT;
		p.flags = 0;//CONTACTF_ONLINE;
		p.isSubcontact = i + 1;
		p.lastPaintCounter = 0;
		p.subcontacts = cont;
		p.image_is_special = FALSE;
		//p.status = cacheEntry->status;
		Cache_GetTimezone(dat, (&p)->hContact);
		Cache_GetText(dat, &p, 1);

		char *szProto = cacheEntry->m_cache_cszProto;
		if (szProto != NULL && !pcli->pfnIsHiddenMode(dat, wStatus))
			p.flags |= CONTACTF_ONLINE;
		int apparentMode = szProto != NULL ? cacheEntry->ApparentMode : 0;
		if (apparentMode == ID_STATUS_OFFLINE)	p.flags |= CONTACTF_INVISTO;
		else if (apparentMode == ID_STATUS_ONLINE) p.flags |= CONTACTF_VISTO;
		else if (apparentMode) p.flags |= CONTACTF_VISTO | CONTACTF_INVISTO;
		if (cacheEntry->NotOnList) p.flags |= CONTACTF_NOTONLIST;
		int idleMode = szProto != NULL ? cacheEntry->IdleTS : 0;
		if (idleMode) p.flags |= CONTACTF_IDLE;
		i++;
	}

	cont->SubAllocated = i;
	if (!i && cont->subcontacts != NULL)
		mir_free_and_nil(cont->subcontacts);
}
示例#11
0
int GetContactIconC(pdisplayNameCacheEntry cacheEntry)
{
	return ExtIconFromStatusMode(cacheEntry->m_cache_hContact,cacheEntry->m_cache_cszProto,cacheEntry->m_cache_cszProto==NULL ? ID_STATUS_OFFLINE : pdnce___GetStatus( cacheEntry ));
}
void cliRebuildEntireList(HWND hwnd,struct ClcData *dat)
{
	DWORD style=GetWindowLong(hwnd,GWL_STYLE);
	HANDLE hContact;
	struct ClcContact * cont;
	struct ClcGroup *group;
    static int rebuildCounter=0;

    BOOL PlaceOfflineToRoot=ModernGetSettingByte(NULL,"CList","PlaceOfflineToRoot",SETTING_PLACEOFFLINETOROOT_DEFAULT);
	KillTimer(hwnd,TIMERID_REBUILDAFTER);
	
	ClearRowByIndexCache();
	ImageArray_Clear(&dat->avatar_cache);
	RowHeights_Clear(dat);
	RowHeights_GetMaxRowHeight(dat, hwnd);
    TRACEVAR("Rebuild Entire List %d times\n",++rebuildCounter);
  
	dat->list.expanded=1;
	dat->list.hideOffline=ModernGetSettingByte(NULL,"CLC","HideOfflineRoot",SETTING_HIDEOFFLINEATROOT_DEFAULT) && style&CLS_USEGROUPS;
	dat->list.cl.count = dat->list.cl.limit = 0;
	dat->list.cl.increment = 50;
	dat->NeedResort=1;

	HANDLE hSelected = SaveSelection( dat );
	dat->selection=-1;
	dat->HiLightMode=ModernGetSettingByte(NULL,"CLC","HiLightMode",SETTING_HILIGHTMODE_DEFAULT);
	{
		int i;
		TCHAR *szGroupName;
		DWORD groupFlags;

		for(i=1;;i++) {
			szGroupName=pcli->pfnGetGroupName(i,&groupFlags); //UNICODE
			if(szGroupName==NULL) break;
			cli_AddGroup(hwnd,dat,szGroupName,groupFlags,i,0);
		}
	}

	hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
	while(hContact) 
    {
		pdisplayNameCacheEntry cacheEntry=NULL;
        int nHiddenStatus;
		cont=NULL;
		cacheEntry=(pdisplayNameCacheEntry)pcli->pfnGetCacheEntry(hContact);

		nHiddenStatus=CLVM_GetContactHiddenStatus(hContact, NULL, dat);
		if ( (style&CLS_SHOWHIDDEN && nHiddenStatus!=-1) || !nHiddenStatus)
		{

			if(lstrlen(cacheEntry->m_cache_tcsGroup)==0)
				group=&dat->list;
			else {
				group=cli_AddGroup(hwnd,dat,cacheEntry->m_cache_tcsGroup,(DWORD)-1,0,0);
			}
			if(group!=NULL) 
			{
				WORD wStatus=pdnce___GetStatus( cacheEntry );
				if (wStatus==ID_STATUS_OFFLINE)
					if (PlaceOfflineToRoot)
						group=&dat->list;
				group->totalMembers++;

				if(!(style&CLS_NOHIDEOFFLINE) && (style&CLS_HIDEOFFLINE || group->hideOffline)) 
				{
					if(cacheEntry->m_cache_cszProto==NULL) {
						if(!pcli->pfnIsHiddenMode(dat,ID_STATUS_OFFLINE)||cacheEntry->m_cache_nNoHiddenOffline || CLCItems_IsShowOfflineGroup(group))
							cont=AddContactToGroup(dat,group,cacheEntry);
					}
					else
						if(!pcli->pfnIsHiddenMode(dat,wStatus)||cacheEntry->m_cache_nNoHiddenOffline || CLCItems_IsShowOfflineGroup(group))
							cont=AddContactToGroup(dat,group,cacheEntry);
				}
				else cont=AddContactToGroup(dat,group,cacheEntry);
			}
		}
		if (cont)	
		{	
			cont->SubAllocated=0;
			if (cont->proto && g_szMetaModuleName && dat->IsMetaContactsEnabled  && strcmp(cont->proto,g_szMetaModuleName)==0)
				AddSubcontacts(dat,cont,CLCItems_IsShowOfflineGroup(group));
		}
		hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0);
	}

	if(style&CLS_HIDEEMPTYGROUPS) {
		group=&dat->list;
		group->scanIndex=0;
		for(;;) {
			if(group->scanIndex==group->cl.count) {
				group=group->parent;
				if(group==NULL) break;
			}
			else if(group->cl.items[group->scanIndex]->type==CLCIT_GROUP) {
				if(group->cl.items[group->scanIndex]->group->cl.count==0) {
					group=pcli->pfnRemoveItemFromGroup(hwnd,group,group->cl.items[group->scanIndex],0);
				}
				else {
					group=group->cl.items[group->scanIndex]->group;
					group->scanIndex=0;
				}
				continue;
			}
			group->scanIndex++;
		}
	}

	pcli->pfnSortCLC(hwnd,dat,0);

	RestoreSelection( dat, hSelected );

}
void AddSubcontacts(struct ClcData *dat, struct ClcContact * cont, BOOL showOfflineHereGroup)
{
	int subcount,i,j;
	HANDLE hsub;
	pdisplayNameCacheEntry cacheEntry;
	cacheEntry=(pdisplayNameCacheEntry)pcli->pfnGetCacheEntry(cont->hContact);
	cont->SubExpanded=(ModernGetSettingByte(cont->hContact,"CList","Expanded",0) && (ModernGetSettingByte(NULL,"CLC","MetaExpanding",SETTING_METAEXPANDING_DEFAULT)));
	subcount=(int)CallService(MS_MC_GETNUMCONTACTS,(WPARAM)cont->hContact,0);

	if (subcount <= 0) {
		cont->isSubcontact=0;
		cont->subcontacts=NULL;
		cont->SubAllocated=0;
		return;
	}

	cont->isSubcontact=0;
    mir_free(cont->subcontacts);
	cont->subcontacts=(struct ClcContact *) mir_calloc(sizeof(struct ClcContact)*subcount);
	cont->SubAllocated=subcount;
	i=0;
	for (j=0; j<subcount; j++) {
		WORD wStatus;
		
		hsub=(HANDLE)CallService(MS_MC_GETSUBCONTACT,(WPARAM)cont->hContact,j);
		cacheEntry=(pdisplayNameCacheEntry)pcli->pfnGetCacheEntry(hsub);
		wStatus=pdnce___GetStatus( cacheEntry );
		if (showOfflineHereGroup||(!(ModernGetSettingByte(NULL,"CLC","MetaHideOfflineSub",SETTING_METAHIDEOFFLINESUB_DEFAULT) && ModernGetSettingByte(NULL,"CList","HideOffline",SETTING_HIDEOFFLINE_DEFAULT) ) ||
			wStatus!=ID_STATUS_OFFLINE )
			//&&
			//(!cacheEntry->Hidden || style&CLS_SHOWHIDDEN)
			)

		{
			cont->subcontacts[i].hContact=cacheEntry->m_cache_hContact;

			cont->subcontacts[i].avatar_pos = AVATAR_POS_DONT_HAVE;
			Cache_GetAvatar(dat, &cont->subcontacts[i]);

			cont->subcontacts[i].iImage=CallService(MS_CLIST_GETCONTACTICON,(WPARAM)cacheEntry->m_cache_hContact,1);
			memset(cont->subcontacts[i].iExtraImage,0xFF,sizeof(cont->subcontacts[i].iExtraImage));
			memset((void*)cont->subcontacts[i].iWideExtraImage,0xFF,sizeof(cont->subcontacts[i].iWideExtraImage));
			cont->subcontacts[i].proto=cacheEntry->m_cache_cszProto;		
			cont->subcontacts[i].type=CLCIT_CONTACT;
			cont->subcontacts[i].flags=0;//CONTACTF_ONLINE;
			cont->subcontacts[i].isSubcontact=i+1;
            cont->subcontacts[i].lastPaintCounter=0;
			cont->subcontacts[i].subcontacts=cont;
			cont->subcontacts[i].image_is_special=FALSE;
			//cont->subcontacts[i].status=cacheEntry->status;
			Cache_GetTimezone(dat, (&cont->subcontacts[i])->hContact);
			Cache_GetText(dat, &cont->subcontacts[i],1);

			{
				int apparentMode;
				char *szProto;  
				int idleMode;
				szProto=cacheEntry->m_cache_cszProto;
				if(szProto!=NULL && !pcli->pfnIsHiddenMode(dat,wStatus))
					cont->subcontacts[i].flags|=CONTACTF_ONLINE;
				apparentMode=szProto!=NULL?cacheEntry->ApparentMode:0;
				apparentMode=szProto!=NULL?cacheEntry->ApparentMode:0;
				if(apparentMode==ID_STATUS_OFFLINE)	cont->subcontacts[i].flags|=CONTACTF_INVISTO;
				else if(apparentMode==ID_STATUS_ONLINE) cont->subcontacts[i].flags|=CONTACTF_VISTO;
				else if(apparentMode) cont->subcontacts[i].flags|=CONTACTF_VISTO|CONTACTF_INVISTO;
				if(cacheEntry->NotOnList) cont->subcontacts[i].flags|=CONTACTF_NOTONLIST;
				idleMode=szProto!=NULL?cacheEntry->IdleTS:0;
				if (idleMode) cont->subcontacts[i].flags|=CONTACTF_IDLE;
            }
			i++;
		}	}

	cont->SubAllocated=i;
	if (!i && cont->subcontacts != NULL) mir_free_and_nill(cont->subcontacts);
}
static void _LoadDataToContact(struct ClcContact * cont, struct ClcGroup *group, struct ClcData *dat, HANDLE hContact)
{
	pdisplayNameCacheEntry cacheEntry=NULL;
	WORD apparentMode;
	DWORD idleMode;
	char * szProto;

	if (!cont) return;
	cont->type=CLCIT_CONTACT;
	cont->SubAllocated=0;
	cont->isSubcontact=0;
	cont->subcontacts=NULL;
	cont->szText[0]=0;
	cont->lastPaintCounter=0;
	cont->image_is_special=FALSE;
	cont->hContact=hContact;

	pcli->pfnInvalidateDisplayNameCacheEntry(hContact);	
	cacheEntry=(pdisplayNameCacheEntry)pcli->pfnGetCacheEntry(hContact);	
	
	szProto=cacheEntry->m_cache_cszProto;
	cont->proto=szProto;

	if(szProto!=NULL&&!pcli->pfnIsHiddenMode(dat,pdnce___GetStatus( cacheEntry )))
		cont->flags |= CONTACTF_ONLINE;
	
	apparentMode=szProto!=NULL?cacheEntry->ApparentMode:0;
	
	if (apparentMode)
		switch (apparentMode)
		{
			case ID_STATUS_OFFLINE:
				cont->flags|=CONTACTF_INVISTO;
				break;
			case ID_STATUS_ONLINE:
				cont->flags|=CONTACTF_VISTO;
				break;
			default:
				cont->flags|=CONTACTF_VISTO|CONTACTF_INVISTO;
		}
	
	if(cacheEntry->NotOnList) 
		cont->flags|=CONTACTF_NOTONLIST;
	idleMode=szProto!=NULL?cacheEntry->IdleTS:0;
	
	if (idleMode) 
		cont->flags|=CONTACTF_IDLE;
	

	//Add subcontacts
	if (szProto)
	{	
		if ( g_szMetaModuleName && dat->IsMetaContactsEnabled && mir_strcmp(cont->proto,g_szMetaModuleName)==0) 
			AddSubcontacts(dat,cont,CLCItems_IsShowOfflineGroup(group));
	}
	cont->lastPaintCounter=0;
	cont->avatar_pos=AVATAR_POS_DONT_HAVE;
	Cache_GetAvatar(dat,cont);
	Cache_GetText(dat,cont,1);
	Cache_GetTimezone(dat,cont->hContact);
	cont->iImage=CallService(MS_CLIST_GETCONTACTICON,(WPARAM)hContact,1);
	cont->bContactRate=ModernGetSettingByte(hContact, "CList", "Rate",0);
}