/** Scans the \c CHANGES and call the appropriate function for each change. * * @param chg : Structure holding all the change info (See CHANGES). */ void ApplyChanges(CHANGES *chg) { HANDLE most_online; int i; // remove removed contacts for(i = 0; i < chg->num_deleted; i++) { Meta_Delete((WPARAM)chg->hDeletedContacts[i], 0); if(chg->hDeletedContacts[i] == chg->hDefaultContact) chg->hDefaultContact = 0; if(chg->hDeletedContacts[i] == chg->hOfflineContact) chg->hOfflineContact = 0; } // set contact positions for(i = 0; i < chg->num_contacts; i++) { if(Meta_GetContactNumber(chg->hContact[i]) != i) Meta_SwapContacts(chg->hMeta, Meta_GetContactNumber(chg->hContact[i]), i); } NotifyEventHooks(hSubcontactsChanged, (WPARAM)chg->hMeta, (LPARAM)chg->hDefaultContact); // set default if(chg->hDefaultContact) DBWriteContactSettingDword(chg->hMeta, META_PROTO, "Default", Meta_GetContactNumber(chg->hDefaultContact)); else DBWriteContactSettingDword(chg->hMeta, META_PROTO, "Default", 0); NotifyEventHooks(hEventDefaultChanged, (WPARAM)chg->hMeta, (LPARAM)chg->hDefaultContact); // set offline if(chg->hOfflineContact) DBWriteContactSettingDword(chg->hMeta, META_PROTO, "OfflineSend", Meta_GetContactNumber(chg->hOfflineContact)); else DBWriteContactSettingDword(chg->hMeta, META_PROTO, "OfflineSend", (DWORD)-1); // fix nick most_online = Meta_GetMostOnline(chg->hMeta); Meta_CopyContactNick(chg->hMeta, most_online); // fix status Meta_FixStatus(chg->hMeta); // fix avatar most_online = Meta_GetMostOnlineSupporting(chg->hMeta, PFLAGNUM_4, PF4_AVATARS); if(most_online) { PROTO_AVATAR_INFORMATION AI; AI.cbSize = sizeof(AI); AI.hContact = chg->hMeta; AI.format = PA_FORMAT_UNKNOWN; strcpy(AI.filename, "X"); if((int)CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&AI) == GAIR_SUCCESS) DBWriteContactSettingString(chg->hMeta, "ContactPhoto", "File",AI.filename); } if(MetaAPI_GetForceState((WPARAM)chg->hMeta, 0) != chg->force_default) MetaAPI_ForceDefault((WPARAM)chg->hMeta, 0); }
INT_PTR Meta_SendNudge(WPARAM wParam, LPARAM lParam) { DBCachedContact *cc = CheckMeta(wParam); if (cc == NULL) return 1; MCONTACT hSubContact = Meta_GetMostOnline(cc); return ProtoCallService(GetContactProto(hSubContact), PS_SEND_NUDGE, hSubContact, lParam); }
HANDLE Meta_GetActive(HANDLE hMeta) { HANDLE hActive = 0; if(DBGetContactSettingByte(hMeta, MODULE, "ForceDefault", 0)) hActive = (HANDLE)MetaAPI_GetDefault((WPARAM)hMeta, 0); if(!hActive) { if((hActive = (HANDLE)DBGetContactSettingDword(hMeta, MODULE, "ForceSend", 0)) == 0) { if((hActive = (HANDLE)DBGetContactSettingDword(hMeta, MODULE, "TempDefault", 0)) == 0) { hActive = Meta_GetMostOnline(hMeta); if(ContactStatus(hActive, ContactProto(hActive)) == ID_STATUS_OFFLINE) { hActive = Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_4, PF4_IMSENDOFFLINE); } } } } return hActive; }
/** Call when we want to send a user is typing message * * @param wParam HANDLE to the contact that we are typing to * @param lParam either PROTOTYPE_SELFTYPING_ON or PROTOTYPE_SELFTYPING_OFF */ static INT_PTR Meta_UserIsTyping(WPARAM hMeta, LPARAM lParam) { DBCachedContact *cc = CheckMeta(hMeta); if (cc == NULL) return 0; // forward to sending protocol, if supported MCONTACT hMostOnline = Meta_GetMostOnline(cc); Meta_CopyContactNick(cc, hMostOnline); if (!hMostOnline) return 0; char *proto = GetContactProto(hMostOnline); if (proto) if (ProtoServiceExists(proto, PSS_USERISTYPING)) ProtoCallService(proto, PSS_USERISTYPING, hMostOnline, lParam); return 0; }
INT_PTR Meta_GetInfo(WPARAM wParam, LPARAM lParam) { CCSDATA *ccs = (CCSDATA*)lParam; // This is a simple contact // (this should normally not happen, since linked contacts do not appear on the list.) DBCachedContact *cc = CheckMeta(ccs->hContact); if (cc == NULL || cc->nDefault == -1) return 0; MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS); if (!hMostOnline) return 0; char *proto = GetContactProto(hMostOnline); if (!proto) return 0; PROTO_AVATAR_INFORMATIONT AI; AI.cbSize = sizeof(AI); AI.hContact = ccs->hContact; AI.format = PA_FORMAT_UNKNOWN; _tcscpy(AI.filename, _T("X")); if (CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) db_set_ts(ccs->hContact, "ContactPhoto", "File", AI.filename); hMostOnline = Meta_GetMostOnline(cc); Meta_CopyContactNick(cc, hMostOnline); if (!hMostOnline) return 0; ccs->hContact = hMostOnline; if (!ProtoServiceExists(proto, PSS_GETINFO)) return 0; // fail return CallContactService(ccs->hContact, PSS_GETINFO, ccs->wParam, ccs->lParam); }
int Meta_SettingChanged(WPARAM hContact, LPARAM lParam) { DBCONTACTWRITESETTING *dcws = (DBCONTACTWRITESETTING *)lParam; char buffer[512]; // the only global options we're interested in if (hContact == 0) return 0; DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact); if (cc == NULL || !cc->IsSub()) return 0; DBCachedContact *ccMeta = currDb->m_cache->GetCachedContact(cc->parentID); if (ccMeta == NULL || !ccMeta->IsMeta()) return 0; // This contact is attached to a MetaContact. int contact_number = Meta_GetContactNumber(ccMeta, hContact); if (contact_number == -1) return 0; // exit - db corruption if (!strcmp(dcws->szSetting, "IP")) { if (dcws->value.type == DBVT_DWORD) db_set_dw(ccMeta->contactID, META_PROTO, "IP", dcws->value.dVal); else db_unset(ccMeta->contactID, META_PROTO, "IP"); } else if (!strcmp(dcws->szSetting, "RealIP")) { if (dcws->value.type == DBVT_DWORD) db_set_dw(ccMeta->contactID, META_PROTO, "RealIP", dcws->value.dVal); else db_unset(ccMeta->contactID, META_PROTO, "RealIP"); } else if (!strcmp(dcws->szSetting, "ListeningTo")) { switch (dcws->value.type) { case DBVT_ASCIIZ: db_set_s(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal); break; case DBVT_UTF8: db_set_utf(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal); break; case DBVT_WCHAR: db_set_ws(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pwszVal); break; case DBVT_DELETED: db_unset(ccMeta->contactID, META_PROTO, "ListeningTo"); break; } } else if (!strcmp(dcws->szSetting, "Nick") && dcws->value.type != DBVT_DELETED) { // subcontact nick has changed - update metacontact mir_snprintf(buffer, SIZEOF(buffer), "Nick%d", contact_number); db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value); ptrT tszMyhandle(db_get_tsa(hContact, "CList", "MyHandle")); if (tszMyhandle == NULL) { mir_snprintf(buffer, SIZEOF(buffer), "CListName%d", contact_number); db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value); } // copy nick to metacontact, if it's the most online MCONTACT hMostOnline = Meta_GetMostOnline(ccMeta); Meta_CopyContactNick(ccMeta, hMostOnline); } else if (!strcmp(dcws->szSetting, "IdleTS")) { if (dcws->value.type == DBVT_DWORD) db_set_dw(ccMeta->contactID, META_PROTO, "IdleTS", dcws->value.dVal); else if (dcws->value.type == DBVT_DELETED) db_set_dw(ccMeta->contactID, META_PROTO, "IdleTS", 0); } else if (!strcmp(dcws->szSetting, "LogonTS")) { if (dcws->value.type == DBVT_DWORD) db_set_dw(ccMeta->contactID, META_PROTO, "LogonTS", dcws->value.dVal); else if (dcws->value.type == DBVT_DELETED) db_set_dw(ccMeta->contactID, META_PROTO, "LogonTS", 0); } else if (!strcmp(dcws->szModule, "CList") && !strcmp(dcws->szSetting, "MyHandle")) { if (dcws->value.type == DBVT_DELETED) { char *proto = GetContactProto(hContact); mir_snprintf(buffer, SIZEOF(buffer), "CListName%d", contact_number); DBVARIANT dbv; if (proto && !db_get_ts(hContact, proto, "Nick", &dbv)) { db_set_ts(ccMeta->contactID, META_PROTO, buffer, dbv.ptszVal); db_free(&dbv); } else db_unset(ccMeta->contactID, META_PROTO, buffer); } else { // subcontact clist displayname has changed - update metacontact mir_snprintf(buffer, SIZEOF(buffer), "CListName%d", contact_number); db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value); } // copy nick to metacontact, if it's the most online Meta_CopyContactNick(ccMeta, Meta_GetMostOnline(ccMeta)); } // subcontact changing status else if (!strcmp(dcws->szSetting, "Status") && dcws->value.type != DBVT_DELETED) { // update subcontact status setting mir_snprintf(buffer, SIZEOF(buffer), "Status%d", contact_number); db_set_w(ccMeta->contactID, META_PROTO, buffer, dcws->value.wVal); mir_snprintf(buffer, SIZEOF(buffer), "StatusString%d", contact_number); db_set_ts(ccMeta->contactID, META_PROTO, buffer, cli.pfnGetStatusModeDescription(dcws->value.wVal, 0)); // set status to that of most online contact MCONTACT hMostOnline = Meta_GetMostOnline(ccMeta); if (hMostOnline != db_mc_getDefault(ccMeta->contactID)) db_mc_notifyDefChange(ccMeta->contactID, hMostOnline); Meta_CopyContactNick(ccMeta, hMostOnline); Meta_FixStatus(ccMeta); // most online contact with avatar support might have changed - update avatar hMostOnline = Meta_GetMostOnlineSupporting(ccMeta, PFLAGNUM_4, PF4_AVATARS); if (hMostOnline) { PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) }; AI.hContact = ccMeta->contactID; AI.format = PA_FORMAT_UNKNOWN; _tcscpy(AI.filename, _T("X")); if (CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) db_set_ts(ccMeta->contactID, "ContactPhoto", "File", AI.filename); } } return 0; }
void Meta_RemoveContactNumber(HANDLE hMeta, int number) { int i, num_contacts, default_contact; HANDLE hContact;//, handle; char buffer[512], buffer2[512]; num_contacts = DBGetContactSettingDword(hMeta, META_PROTO, "NumContacts", 0); default_contact = DBGetContactSettingDword(hMeta, META_PROTO, "Default", -1); if(number >= 0 && number < num_contacts) { // get the handle hContact = Meta_GetContactHandle(hMeta, number); // make sure this contact thinks it's part of this metacontact if((HANDLE)DBGetContactSettingDword(hContact,META_PROTO,"Handle", 0) == hMeta) { // remove link to meta contact DBDeleteContactSetting(hContact,META_PROTO,"IsSubcontact"); DBDeleteContactSetting(hContact,META_PROTO,META_LINK); DBDeleteContactSetting(hContact,META_PROTO,"Handle"); DBDeleteContactSetting(hContact,META_PROTO,"ContactNumber"); // unhide - must be done after removing link (see meta_services.c:Meta_ChangeStatus) Meta_RestoreGroup(hContact); DBDeleteContactSetting(hContact,META_PROTO,"OldCListGroup"); //CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)hContact,(LPARAM)META_PROTO); CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)hContact,(LPARAM)META_FILTER); // stop ignoring, if we were if(options.suppress_status) CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, (WPARAM)IGNOREEVENT_USERONLINE); } // remove history from metacontact //Meta_RemoveHistory(hMeta, hContact); // each contact from 'number' upwards will be moved down one // and the last one will be deleted for(i = number + 1; i < num_contacts; i++) { Meta_SwapContacts(hMeta, i, i-1); } // remove the last one strcpy(buffer, "Protocol"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); strcpy(buffer, "Status"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); strcpy(buffer, "Handle"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); strcpy(buffer, "StatusString"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); strcpy(buffer, "Login"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); strcpy(buffer, "Nick"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); strcpy(buffer, "CListName"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); // if the default contact was equal to or greater than 'number', decrement it (and deal with ends) if(default_contact >= number) { default_contact--; if(default_contact < 0) default_contact = 0; DBWriteContactSettingDword(hMeta, META_PROTO, "Default", (DWORD)default_contact); NotifyEventHooks(hEventDefaultChanged, (WPARAM)hMeta, (LPARAM)Meta_GetContactHandle(hMeta, default_contact)); } num_contacts--; DBWriteContactSettingDword(hMeta, META_PROTO, "NumContacts", (DWORD)num_contacts); // fix nick hContact = Meta_GetMostOnline(hMeta); Meta_CopyContactNick(hMeta, hContact); // fix status Meta_FixStatus(hMeta); // fix avatar hContact = Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_4, PF4_AVATARS); if(hContact) { PROTO_AVATAR_INFORMATION AI; AI.cbSize = sizeof(AI); AI.hContact = hMeta; AI.format = PA_FORMAT_UNKNOWN; strcpy(AI.filename, "X"); if((int)CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&AI) == GAIR_SUCCESS) DBWriteContactSettingString(hMeta, "ContactPhoto", "File",AI.filename); } } }
/** Called when the context-menu of a contact is about to be displayed * * This will test which of the 4 menu item should be displayed, depending * on which contact triggered the event * * @param wParam : \c HANDLE to the contact that triggered the event * @param lParam : Always set to 0; */ int Meta_ModifyMenu(WPARAM wParam, LPARAM lParam) { CLISTMENUITEM mi; DBVARIANT dbv; HANDLE hContact; char *proto; char buf[512], buffer2[512]; int i, iconIndex; WORD status; mi.flags = CMIM_FLAGS; mi.cbSize = sizeof(CLISTMENUITEM); if(DBGetContactSettingDword((HANDLE)wParam,META_PROTO,META_ID,-1) != (DWORD)-1) { int num_contacts, i; // save the mouse pos in case they open a subcontact menu GetCursorPos(&menuMousePoint); // This is a MetaContact, show the edit, force default, and the delete menu, and hide the others CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&mi); //mi.flags |= CMIM_NAME; //if(DBGetContactSettingByte((HANDLE)wParam, META_PROTO, "ForceDefault", 0)) // mi.pszName = Translate("Unforce Default"); //else // mi.pszName = Translate("Force Default"); //CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuForceDefault, (LPARAM)&mi); mi.flags = CMIM_FLAGS | CMIF_HIDDEN; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); mi.flags = CMIM_FLAGS | CMIM_NAME | CMIF_HIDDEN; // we don't need delete - already in contact menu mi.pszName = Translate("Delete MetaContact"); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&mi); //show subcontact menu items num_contacts = DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "NumContacts", 0); for(i = 0; i < MAX_CONTACTS; i++) { if(i < num_contacts) { hContact = Meta_GetContactHandle((HANDLE)wParam, i); proto = _strdup((char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)); if(!proto) status = ID_STATUS_OFFLINE; else status = DBGetContactSettingWord(hContact, proto, "Status", ID_STATUS_OFFLINE); if(options.menu_contact_label == DNT_UID) { strcpy(buf, "Login"); strcat(buf, _itoa(i, buffer2, 10)); DBGetContactSetting((HANDLE)wParam,META_PROTO,buf,&dbv); switch(dbv.type) { case DBVT_ASCIIZ: mir_snprintf(buf,512,"%s",dbv.pszVal); break; case DBVT_BYTE: mir_snprintf(buf,512,"%d",dbv.bVal); break; case DBVT_WORD: mir_snprintf(buf,512,"%d",dbv.wVal); break; case DBVT_DWORD: mir_snprintf(buf,512,"%d",dbv.dVal); break; default: buf[0] = 0; } DBFreeVariant(&dbv); mi.pszName = buf; mi.flags = 0; } else { char *name = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0); char *wname = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_UNICODE); if(wname && strncmp(name, wname, strlen(name)) != 0) { mi.pszName = wname; mi.flags = CMIF_UNICODE; } else { mi.pszName = name; mi.flags = 0; } } mi.flags |= CMIM_FLAGS | CMIM_NAME | CMIM_ICON; //mi.hIcon = LoadSkinnedProtoIcon(proto, status); iconIndex = (int)CallService(MS_CLIST_GETCONTACTICON, (WPARAM)hContact, 0); mi.hIcon = ImageList_GetIcon((HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), iconIndex, 0);; free(proto); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); DestroyIcon(mi.hIcon); //CallService(MS_SKIN2_RELEASEICON, (WPARAM)mi.hIcon, 0); } else { mi.flags = CMIM_FLAGS | CMIF_HIDDEN; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); } } // show hide nudge menu item #define MS_NUDGE_SHOWMENU "NudgeShowMenu" // wParam = char *szProto // lParam = BOOL show { char serviceFunc[256]; hContact = Meta_GetMostOnline((HANDLE)wParam); mir_snprintf(serviceFunc, 256, "%s/SendNudge", (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)); CallService(MS_NUDGE_SHOWMENU, (WPARAM)META_PROTO, (LPARAM)ServiceExists(serviceFunc)); } } else {// This is a simple contact if(!Meta_IsEnabled()) { // groups disabled - all meta menu options hidden mi.flags = CMIM_FLAGS | CMIF_HIDDEN; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&mi); for(i = 0; i < MAX_CONTACTS; i++) { mi.flags = CMIM_FLAGS | CMIF_HIDDEN; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); } } else if(DBGetContactSettingDword((HANDLE)wParam,META_PROTO,META_LINK,(DWORD)-1)!=(DWORD)-1) { // The contact is affected to a metacontact. CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); mi.flags |= CMIM_NAME; mi.pszName = (char *)Translate("Remove from MetaContact"); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&mi); mi.flags = CMIM_FLAGS | CMIF_HIDDEN; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&mi); for(i = 0; i < MAX_CONTACTS; i++) { mi.flags = CMIM_FLAGS | CMIF_HIDDEN; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); } } else { // The contact is neutral CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); mi.flags |= CMIF_HIDDEN; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); for(i = 0; i < MAX_CONTACTS; i++) { mi.flags = CMIM_FLAGS | CMIF_HIDDEN; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); } } } return 0; }
//gets the handle for the 'most online' contact //wParam=(HANDLE)hMetaContact //lParam=0 //returns a handle to the 'most online' contact INT_PTR MetaAPI_GetMostOnline(WPARAM wParam, LPARAM lParam) { return (INT_PTR)Meta_GetMostOnline((HANDLE)wParam); }
void Meta_RemoveContactNumber(DBCachedContact *ccMeta, int number, bool bUpdateInfo) { if (ccMeta == NULL) return; // make sure this contact thinks it's part of this metacontact DBCachedContact *ccSub = currDb->m_cache->GetCachedContact(Meta_GetContactHandle(ccMeta, number)); if (ccSub != NULL) { if (ccSub->parentID == ccMeta->contactID) { db_unset(ccSub->contactID, "CList", "Hidden"); // stop ignoring, if we were if (options.bSuppressStatus) CallService(MS_IGNORE_UNIGNORE, ccSub->contactID, IGNOREEVENT_USERONLINE); } } // each contact from 'number' upwards will be moved down one // and the last one will be deleted for (int i = number+1; i < ccMeta->nSubs; i++) Meta_SwapContacts(ccMeta, i, i - 1); // remove the last one int id = ccMeta->nSubs - 1; char buffer[512]; mir_snprintf(buffer, "Handle%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); mir_snprintf(buffer, "Protocol%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); mir_snprintf(buffer, "Status%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); mir_snprintf(buffer, "StatusString%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); mir_snprintf(buffer, "Login%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); mir_snprintf(buffer, "Nick%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); mir_snprintf(buffer, "CListName%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); if (ccSub != NULL) { ccSub->parentID = 0; currDb->MetaDetouchSub(ccMeta, ccMeta->nSubs - 1); currDb->MetaSplitHistory(ccMeta, ccSub); } // if the default contact was equal to or greater than 'number', decrement it (and deal with ends) if (ccMeta->nDefault >= number) { int iNumber = ccMeta->nDefault-1; if (iNumber < 0) iNumber = 0; db_mc_setDefaultNum(ccMeta->contactID, iNumber, true); } ccMeta->nSubs--; db_set_dw(ccMeta->contactID, META_PROTO, "NumContacts", ccMeta->nSubs); if (bUpdateInfo) { // fix nick Meta_CopyContactNick(ccMeta, Meta_GetMostOnline(ccMeta)); // fix status Meta_FixStatus(ccMeta); // fix avatar MCONTACT hContact = Meta_GetMostOnlineSupporting(ccMeta, PFLAGNUM_4, PF4_AVATARS); if (hContact) { PROTO_AVATAR_INFORMATION ai = { 0 }; ai.hContact = ccMeta->contactID; ai.format = PA_FORMAT_UNKNOWN; _tcsncpy_s(ai.filename, _T("X"), _TRUNCATE); if (CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&ai) == GAIR_SUCCESS) db_set_ts(ccMeta->contactID, "ContactPhoto", "File", ai.filename); } } }
int Meta_ModifyMenu(WPARAM hMeta, LPARAM) { DBCachedContact *cc = currDb->m_cache->GetCachedContact(hMeta); if (cc == NULL) return 0; Menu_ShowItem(hMenuRoot, false); if (cc->IsMeta()) { // save the mouse pos in case they open a subcontact menu GetCursorPos(&menuMousePoint); // This is a MetaContact, show the edit, force default, and the delete menu, and hide the others Menu_ShowItem(hMenuEdit, true); Menu_ShowItem(hMenuAdd, false); Menu_ShowItem(hMenuConvert, false); Menu_ShowItem(hMenuDefault, false); Menu_ShowItem(hMenuDelete, false); Menu_ModifyItem(hMenuDelete, LPGENT("Remove from metacontact")); // show subcontact menu items CMString tszNick; for (int i = 0; i < MAX_CONTACTS; i++) { if (i >= cc->nSubs) { Menu_ShowItem(hMenuContact[i], false); continue; } MCONTACT hContact = Meta_GetContactHandle(cc, i); LPCTSTR ptszName; if (options.menu_contact_label == DNT_UID) { Meta_GetSubNick(hMeta, i, tszNick); ptszName = tszNick.GetBuffer(); } else ptszName = cli.pfnGetContactDisplayName(hContact, 0); int iconIndex = CallService(MS_CLIST_GETCONTACTICON, hContact, 0); HICON hIcon = ImageList_GetIcon((HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), iconIndex, 0); Menu_ModifyItem(hMenuContact[i], ptszName, hIcon, 0); DestroyIcon(hIcon); Menu_ShowItem(hMenuRoot, true); } // show hide nudge menu item char serviceFunc[256]; mir_snprintf(serviceFunc, _countof(serviceFunc), "%s%s", GetContactProto(Meta_GetMostOnline(cc)), PS_SEND_NUDGE); CallService(MS_NUDGE_SHOWMENU, (WPARAM)META_PROTO, ServiceExists(serviceFunc)); return 0; } PROTOACCOUNT *pa = Proto_GetAccount(cc->szProto); if (!db_mc_isEnabled() || !pa || pa->bIsVirtual) { // groups disabled - all meta menu options hidden Menu_ShowItem(hMenuDefault, false); Menu_ShowItem(hMenuDelete, false); Menu_ShowItem(hMenuAdd, false); Menu_ShowItem(hMenuConvert, false); Menu_ShowItem(hMenuEdit, false); return 0; } // the contact is affected to a metacontact if (cc->IsSub()) { Menu_ShowItem(hMenuDefault, true); Menu_ModifyItem(hMenuDelete, LPGENT("Remove from metacontact")); Menu_ShowItem(hMenuDelete, true); Menu_ShowItem(hMenuAdd, false); Menu_ShowItem(hMenuConvert, false); Menu_ShowItem(hMenuEdit, false); } else { // The contact is neutral bool bHideChat = db_get_b(hMeta, cc->szProto, "ChatRoom", 0) == 0; Menu_ShowItem(hMenuAdd, bHideChat); Menu_ShowItem(hMenuConvert, bHideChat); Menu_ShowItem(hMenuEdit, false); Menu_ShowItem(hMenuDelete, false); Menu_ShowItem(hMenuDefault, false); } for (int i = 0; i < MAX_CONTACTS; i++) Menu_ShowItem(hMenuContact[i], false); return 0; }
int Meta_ModifyMenu(WPARAM wParam, LPARAM lParam) { DBVARIANT dbv; char buf[512], idStr[512]; WORD status; CLISTMENUITEM mi = { sizeof(mi) }; if (db_get_dw((HANDLE)wParam, META_PROTO, META_ID,-1) != (DWORD)-1) { // save the mouse pos in case they open a subcontact menu GetCursorPos(&menuMousePoint); // This is a MetaContact, show the edit, force default, and the delete menu, and hide the others Menu_ShowItem(hMenuEdit, true); Menu_ShowItem(hMenuAdd, false); Menu_ShowItem(hMenuConvert, false); Menu_ShowItem(hMenuDefault, false); Menu_ShowItem(hMenuDelete, false); mi.flags = CMIM_NAME | CMIF_TCHAR; mi.ptszName = (TCHAR*)TranslateT("Remove from MetaContact"); Menu_ModifyItem(hMenuDelete, &mi); //show subcontact menu items int num_contacts = db_get_dw((HANDLE)wParam, META_PROTO, "NumContacts", 0); for (int i = 0; i < MAX_CONTACTS; i++) { if (i >= num_contacts) { Menu_ShowItem(hMenuContact[i], false); continue; } HANDLE hContact = Meta_GetContactHandle((HANDLE)wParam, i); char *szProto = GetContactProto(hContact); if ( !szProto) status = ID_STATUS_OFFLINE; else status = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); if (options.menu_contact_label == DNT_UID) { strcpy(buf, "Login"); strcat(buf, _itoa(i, idStr, 10)); db_get((HANDLE)wParam, META_PROTO, buf, &dbv); switch(dbv.type) { case DBVT_ASCIIZ: mir_snprintf(buf,512,"%s",dbv.pszVal); break; case DBVT_BYTE: mir_snprintf(buf,512,"%d",dbv.bVal); break; case DBVT_WORD: mir_snprintf(buf,512,"%d",dbv.wVal); break; case DBVT_DWORD: mir_snprintf(buf,512,"%d",dbv.dVal); break; default: buf[0] = 0; } db_free(&dbv); mi.pszName = buf; mi.flags = 0; } else { mi.ptszName = pcli->pfnGetContactDisplayName(hContact, GCDNF_TCHAR); mi.flags = CMIF_TCHAR; } mi.flags |= CMIM_FLAGS | CMIM_NAME | CMIM_ICON; int iconIndex = CallService(MS_CLIST_GETCONTACTICON, (WPARAM)hContact, 0); mi.hIcon = ImageList_GetIcon((HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), iconIndex, 0); Menu_ModifyItem(hMenuContact[i], &mi); DestroyIcon(mi.hIcon); } // show hide nudge menu item #define MS_NUDGE_SHOWMENU "NudgeShowMenu" // wParam = char *szProto // lParam = BOOL show char serviceFunc[256]; mir_snprintf(serviceFunc, 256, "%s%s", GetContactProto( Meta_GetMostOnline((HANDLE)wParam)), PS_SEND_NUDGE); CallService(MS_NUDGE_SHOWMENU, (WPARAM)META_PROTO, (LPARAM)ServiceExists(serviceFunc)); } else { // This is a simple contact if ( !Meta_IsEnabled()) { // groups disabled - all meta menu options hidden Menu_ShowItem(hMenuDefault, false); Menu_ShowItem(hMenuDelete, false); Menu_ShowItem(hMenuAdd, false); Menu_ShowItem(hMenuConvert, false); Menu_ShowItem(hMenuEdit, false); } else if (db_get_dw((HANDLE)wParam, META_PROTO, META_LINK,(DWORD)-1)!=(DWORD)-1) { // The contact is affected to a metacontact. Menu_ShowItem(hMenuDefault, true); mi.flags = CMIM_NAME | CMIF_TCHAR; mi.ptszName = (TCHAR*)TranslateT("Remove from MetaContact"); Menu_ModifyItem(hMenuDelete, &mi); Menu_ShowItem(hMenuAdd, false); Menu_ShowItem(hMenuConvert, false); Menu_ShowItem(hMenuEdit, false); } else { // The contact is neutral Menu_ShowItem(hMenuAdd, true); Menu_ShowItem(hMenuConvert, true); Menu_ShowItem(hMenuEdit, false); Menu_ShowItem(hMenuDelete, false); Menu_ShowItem(hMenuDefault, false); } for (int i = 0; i < MAX_CONTACTS; i++) Menu_ShowItem(hMenuContact[i], false); } return 0; }
void Meta_RemoveContactNumber(HANDLE hMeta, int number) { int num_contacts = db_get_dw(hMeta, META_PROTO, "NumContacts", 0); int default_contact = db_get_dw(hMeta, META_PROTO, "Default", -1); if (number < 0 && number >= num_contacts) return; // get the handle HANDLE hContact = Meta_GetContactHandle(hMeta, number); // make sure this contact thinks it's part of this metacontact if ((HANDLE)db_get_dw(hContact, META_PROTO, "Handle", 0) == hMeta) { // remove link to meta contact db_unset(hContact, META_PROTO, "IsSubcontact"); db_unset(hContact, META_PROTO, META_LINK); db_unset(hContact, META_PROTO, "Handle"); db_unset(hContact, META_PROTO, "ContactNumber"); // unhide - must be done after removing link (see meta_services.c:Meta_ChangeStatus) Meta_RestoreGroup(hContact); db_unset(hContact, META_PROTO, "OldCListGroup"); // stop ignoring, if we were if (options.suppress_status) CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, (WPARAM)IGNOREEVENT_USERONLINE); } // each contact from 'number' upwards will be moved down one // and the last one will be deleted for (int i = number + 1; i < num_contacts; i++) Meta_SwapContacts(hMeta, i, i-1); // remove the last one char buffer[512], idStr[20]; _itoa(num_contacts-1, idStr, 10); strcpy(buffer, "Protocol"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); strcpy(buffer, "Status"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); strcpy(buffer, "Handle"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); strcpy(buffer, "StatusString"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); strcpy(buffer, "Login"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); strcpy(buffer, "Nick"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); strcpy(buffer, "CListName"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); // if the default contact was equal to or greater than 'number', decrement it (and deal with ends) if (default_contact >= number) { default_contact--; if (default_contact < 0) default_contact = 0; db_set_dw(hMeta, META_PROTO, "Default", (DWORD)default_contact); NotifyEventHooks(hEventDefaultChanged, (WPARAM)hMeta, (LPARAM)Meta_GetContactHandle(hMeta, default_contact)); } num_contacts--; db_set_dw(hMeta, META_PROTO, "NumContacts", (DWORD)num_contacts); // fix nick hContact = Meta_GetMostOnline(hMeta); Meta_CopyContactNick(hMeta, hContact); // fix status Meta_FixStatus(hMeta); // fix avatar hContact = Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_4, PF4_AVATARS); if (hContact) { PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) }; AI.hContact = hMeta; AI.format = PA_FORMAT_UNKNOWN; _tcscpy(AI.filename, _T("X")); if ((int)CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) db_set_ts(hMeta, "ContactPhoto", "File",AI.filename); } }