Пример #1
0
int Meta_ContactDeleted(WPARAM hContact, LPARAM lParam)
{
	DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact);
	if (cc == NULL)
		return 0;

	// is a subcontact - update meta contact
	if (cc->IsSub()) {
		DBCachedContact *ccMeta = CheckMeta(cc->parentID);
		if (ccMeta) {
			Meta_RemoveContactNumber(ccMeta, Meta_GetContactNumber(ccMeta, hContact), true);
			NotifyEventHooks(hSubcontactsChanged, ccMeta->contactID, 0);
		}
		return 0;
	}

	// not a subcontact - is it a metacontact?
	if (!cc->IsMeta())
		return 0;

	if (cc->nSubs > 0)
		NotifyEventHooks(hSubcontactsChanged, hContact, 0);

	// remove & restore all subcontacts
	for (int i = 0; i < cc->nSubs; i++) {
		currDb->MetaDetouchSub(cc, i);

		// stop ignoring, if we were
		if (options.bSuppressStatus)
			CallService(MS_IGNORE_UNIGNORE, cc->pSubs[i], IGNOREEVENT_USERONLINE);
	}
	return 0;
}
Пример #2
0
INT_PTR Meta_ContactMenuFunc(WPARAM hMeta, LPARAM lParam)
{
	DBCachedContact *cc = CheckMeta(hMeta);
	if (cc == NULL)
		return 0;

	MCONTACT hContact = Meta_GetContactHandle(cc, (int)lParam);

	if (options.menu_function == FT_MSG) {
		// open message window if protocol supports message sending or chat, else simulate double click
		char *proto = GetContactProto(hContact);
		if (proto) {
			INT_PTR caps = CallProtoService(proto, PS_GETCAPS, PFLAGNUM_1, 0);
			if ((caps & PF1_IMSEND) || (caps & PF1_CHAT)) {
				// set default contact for sending/status and open message window
				Meta_SetSrmmSub(hMeta, hContact);				
				db_mc_setDefaultNum(hMeta, lParam, false);
				CallService(MS_MSG_SENDMESSAGET, hMeta, 0);
			}
			else // protocol does not support messaging - simulate double click
				CallService(MS_CLIST_CONTACTDOUBLECLICKED, hContact, 0);
		}
		else // protocol does not support messaging - simulate double click
			CallService(MS_CLIST_CONTACTDOUBLECLICKED, hContact, 0);
	}
	else if (options.menu_function == FT_MENU) // show contact's context menu
		CallFunctionAsync(sttMenuThread, (void*)hContact);
	else if (options.menu_function == FT_INFO) // show user info for subcontact
		CallService(MS_USERINFO_SHOWDIALOG, hContact, 0);

	return 0;
}
Пример #3
0
INT_PTR Meta_GetAvatarInfo(WPARAM wParam, LPARAM lParam)
{
	PROTO_AVATAR_INFORMATIONT *AI = (PROTO_AVATAR_INFORMATIONT*)lParam;
	DBCachedContact *cc = CheckMeta(AI->hContact);
	if (cc == NULL)
		return GAIR_NOAVATAR;

	if (cc->nDefault == -1)
		return 0;

	MCONTACT hSub = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS);
	if (!hSub)
		return GAIR_NOAVATAR;

	char *proto = GetContactProto(hSub);
	if (!proto)
		return GAIR_NOAVATAR;

	AI->hContact = hSub;
	INT_PTR result = ProtoCallService(proto, PS_GETAVATARINFOT, wParam, lParam);
	AI->hContact = cc->contactID;
	if (result != CALLSERVICE_NOTFOUND)
		return result;

	return GAIR_NOAVATAR; // fail
}
Пример #4
0
static int FillList(HWND list, BOOL sort)
{
	int i = 0;

	// The DB is searched through, to get all the metacontacts
	for (MCONTACT hMetaUser = db_find_first(); hMetaUser; hMetaUser = db_find_next(hMetaUser)) {
		// if it's not a MetaContact, go to the next
		DBCachedContact *cc = CheckMeta(hMetaUser);
		if (cc == NULL)
			continue;

		// get contact display name from clist
		TCHAR *swzContactDisplayName = cli.pfnGetContactDisplayName(hMetaUser, 0);
		// don't insert huge strings that we have to compare with later
		if (_tcslen(swzContactDisplayName) > 1023)
			swzContactDisplayName[1024] = 0;

		int pos = -1;
		if (sort) {
			for (pos = 0; pos < i; pos++) {
				TCHAR buff[1024];
				SendMessage(list, LB_GETTEXT, pos, (LPARAM)buff);
				if (_tcscmp(buff, swzContactDisplayName) > 0)
					break;
			}
		}

		int index = SendMessage(list, LB_INSERTSTRING, pos, (LPARAM)swzContactDisplayName);
		SendMessage(list, LB_SETITEMDATA, index, hMetaUser);
		i++;
	}
	return i;
}
Пример #5
0
//returns a handle to the default contact, or null on failure
MIR_CORE_DLL(MCONTACT) db_mc_getDefault(MCONTACT hMetaContact)
{
	DBCachedContact *cc = CheckMeta(hMetaContact);
	if (cc == NULL)
		return 0;

	return (cc->nDefault != -1) ? Meta_GetContactHandle(cc, cc->nDefault) : 0;
}
Пример #6
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);
}
Пример #7
0
static int Meta_UserInfo(WPARAM wParam, LPARAM hMeta)
{
	DBCachedContact *cc = CheckMeta(hMeta);
	if (cc == NULL || cc->nDefault == -1)
		return 0;

	CallService(MS_USERINFO_SHOWDIALOG, Meta_GetContactHandle(cc, cc->nDefault), 0);
	return 1;
}
Пример #8
0
int Meta_CallMostOnline(WPARAM hContact, LPARAM lParam)
{
	DBCachedContact *cc = CheckMeta(hContact);
	if (cc == NULL)
		return 0;

	Meta_CopyContactNick(cc, db_mc_getSrmmSub(cc->contactID));
	Meta_FixStatus(cc);
	return 0;
}
Пример #9
0
static rc_t fix_run_stat(const XmlMeta* xml) {
    rc_t rc = 0;
    bool found = false;
    const SRATable *tbl = NULL;
    SDbMeta db;
    memset(&db, 0, sizeof db);
    rc = CheckMeta(xml, &db, &found);
    RELEASE(SRATable, tbl);
    return rc;
}
Пример #10
0
// we assume that it could be called only for the metacontacts
static int Meta_SrmmIconClicked(WPARAM hMeta, LPARAM lParam)
{
	StatusIconClickData *sicd = (StatusIconClickData*)lParam;
	if (lstrcmpA(sicd->szModule, META_PROTO))
		return 0;

	DBCachedContact *cc = CheckMeta(hMeta);
	if (cc == NULL)
		return 0;

	HMENU hMenu = CreatePopupMenu();
	int iDefault = Meta_GetContactNumber(cc, db_mc_getSrmmSub(cc->contactID));

	MENUITEMINFO mii = { sizeof(mii) };
	mii.fMask = MIIM_ID | MIIM_STATE | MIIM_STRING;
	for (int i = 0; i < cc->nSubs; i++)	{
		char *szProto = GetContactProto(cc->pSubs[i]);
		if (szProto == NULL) continue;

		PROTOACCOUNT *pa = ProtoGetAccount(szProto);
		if (pa == NULL)
			continue;

		CMString tszNick;
		if (options.menu_contact_label == DNT_DID)
			tszNick = cli.pfnGetContactDisplayName(cc->pSubs[i], 0);
		else
			Meta_GetSubNick(hMeta, i, tszNick);
		tszNick.AppendFormat(_T(" [%s]"), pa->tszAccountName);

		mii.wID = i + 1;
		mii.fState = (i == iDefault) ? MFS_CHECKED : MFS_ENABLED;
		mii.dwTypeData = tszNick.GetBuffer();
		mii.cch = tszNick.GetLength();
		InsertMenuItem(hMenu, i, TRUE, &mii);
	}

	UINT res = TrackPopupMenu(hMenu, TPM_NONOTIFY | TPM_RETURNCMD | TPM_BOTTOMALIGN | TPM_LEFTALIGN, sicd->clickLocation.x, sicd->clickLocation.y, 0, cli.hwndContactTree, NULL);
	if (res > 0) {
		MCONTACT hChosen = Meta_GetContactHandle(cc, res - 1);

		MetaSrmmData tmp = { cc->contactID };
		if (MetaSrmmData *p = arMetaWindows.find(&tmp))
			p->m_hSub = hChosen;

		db_mc_setDefault(cc->contactID, hChosen, true);
	}
	return 0;
}
Пример #11
0
int Meta_HandleACK(WPARAM, LPARAM lParam)
{
	ACKDATA *ack = (ACKDATA*)lParam;
	DBCachedContact *cc = CheckMeta(ack->hContact);
	if (cc == NULL)
		return 0;

	if (!strcmp(ack->szModule, META_PROTO))
		return 0; // don't rebroadcast our own acks

	// if it's for something we don't support, ignore
	if (ack->type != ACKTYPE_MESSAGE && ack->type != ACKTYPE_CHAT && ack->type != ACKTYPE_FILE && ack->type != ACKTYPE_AWAYMSG && ack->type != ACKTYPE_AVATAR && ack->type != ACKTYPE_GETINFO)
		return 0;

	// change the hContact in the avatar info struct, if it's the avatar we're using - else drop it
	if (ack->type == ACKTYPE_AVATAR) {
		if (ack->result == ACKRESULT_SUCCESS || ack->result == ACKRESULT_FAILED || ack->result == ACKRESULT_STATUS) {
			DBVARIANT dbv;

			// change avatar if the most online supporting avatars changes, or if we don't have one
			MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS);
			//if (AI.hContact == 0 || AI.hContact != hMostOnline) {
			if (ack->hContact == 0 || ack->hContact != hMostOnline) {
				return 0;
			}

			if (!db_get(ack->hContact, "ContactPhoto", "File", &dbv)) {
				db_set_ts(cc->contactID, "ContactPhoto", "File", dbv.ptszVal);
				db_free(&dbv);
			}

			if (ack->hProcess) {
				PROTO_AVATAR_INFORMATIONT AI;
				memcpy(&AI, (PROTO_AVATAR_INFORMATIONT *)ack->hProcess, sizeof(PROTO_AVATAR_INFORMATIONT));
				if (AI.hContact)
					AI.hContact = cc->contactID;

				return ProtoBroadcastAck(META_PROTO, cc->contactID, ack->type, ack->result, (HANDLE)&AI, ack->lParam);
			}

			return ProtoBroadcastAck(META_PROTO, cc->contactID, ack->type, ack->result, 0, ack->lParam);
		}
	}

	return ProtoBroadcastAck(META_PROTO, cc->contactID, ack->type, ack->result, ack->hProcess, ack->lParam);
}
Пример #12
0
INT_PTR Meta_FileSend(WPARAM wParam, LPARAM lParam)
{
	CCSDATA *ccs = (CCSDATA*)lParam;
	DBCachedContact *cc = CheckMeta(ccs->hContact);
	if (cc == NULL || cc->nDefault == -1)
		return 0;

	MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_FILESEND);
	if (!hMostOnline)
		return 0;

	char *proto = GetContactProto(hMostOnline);
	if (proto)
		return CallContactService(hMostOnline, PSS_FILE, ccs->wParam, ccs->lParam);

	return 0; // fail
}
Пример #13
0
//sets the default contact, using the subcontact's number
MIR_CORE_DLL(int) db_mc_setDefaultNum(MCONTACT hMetaContact, int iNum, BOOL bWriteDb)
{
	DBCachedContact *cc = CheckMeta(hMetaContact);
	if (cc == NULL)
		return 1;
	if (iNum >= cc->nSubs || iNum < 0)
		return 1;

	if (cc->nDefault != iNum) {
		cc->nDefault = iNum;
		if (bWriteDb)
			currDb->MetaSetDefault(cc);

		NotifyEventHooks(hEventDefaultChanged, hMetaContact, Meta_GetContactHandle(cc, iNum));
	}
	return 0;
}
Пример #14
0
INT_PTR Meta_GetAwayMsg(WPARAM wParam, LPARAM lParam)
{
	CCSDATA *ccs = (CCSDATA*)lParam;
	DBCachedContact *cc = CheckMeta(ccs->hContact);
	if (cc == NULL || cc->nDefault == -1)
		return 0;

	MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_MODEMSGRECV);
	if (!hMostOnline)
		return 0;

	char *proto = GetContactProto(hMostOnline);
	if (!proto)
		return 0;

	ccs->hContact = hMostOnline;
	return CallContactService(ccs->hContact, PSS_GETAWAYMSG, ccs->wParam, ccs->lParam);
}
Пример #15
0
/** 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;
}
Пример #16
0
//sets the default contact, using the subcontact's handle
MIR_CORE_DLL(int) db_mc_setDefault(MCONTACT hMetaContact, MCONTACT hSub, BOOL bWriteDb)
{
	DBCachedContact *cc = CheckMeta(hMetaContact);
	if (cc == NULL)
		return 1;

	int contact_number = Meta_GetContactNumber(cc, hSub);
	if (contact_number == -1) 
		return 1;

	if (cc->nDefault != contact_number) {
		cc->nDefault = contact_number;
		if (bWriteDb)
			currDb->MetaSetDefault(cc);

		NotifyEventHooks(hEventDefaultChanged, hMetaContact, hSub);
	}
	return 0;
}
Пример #17
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);
}
Пример #18
0
INT_PTR Meta_SendMessage(WPARAM wParam,LPARAM lParam)
{
	CCSDATA *ccs = (CCSDATA*)lParam;

	DBCachedContact *cc = CheckMeta(ccs->hContact);
	if (cc == NULL || cc->nDefault == -1) {
		// This is a simple contact, let through the stack of protocols
		// (this should normally not happen, since linked contacts do not appear on the list.)
		return CallService(MS_PROTO_CHAINSEND, wParam, lParam);
	}

	MCONTACT hMostOnline = db_mc_getSrmmSub(cc->contactID);
	if (!hMostOnline) {
		// send failure to notify user of reason
		HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

		TFakeAckParams *tfap = (TFakeAckParams *)mir_alloc(sizeof(TFakeAckParams));
		tfap->hContact = ccs->hContact;
		tfap->hEvent = hEvent;
		tfap->id = 10;
		strcpy(tfap->msg, Translate("No online contacts found."));

		DWORD dwThreadId;
		CloseHandle(CreateThread(NULL, 0, sttFakeAckFail, tfap, 0, &dwThreadId));
		SetEvent(hEvent);
		return 10;
	}

	Meta_CopyContactNick(cc, hMostOnline);

	ccs->hContact = hMostOnline;
	char *proto = GetContactProto(hMostOnline);
	Meta_SetNick(proto);	// (no matter what was there before)

	return CallContactService(ccs->hContact, PSS_MESSAGE, ccs->wParam, ccs->lParam);
}
Пример #19
0
//returns the default contact number, or -1 on failure
MIR_CORE_DLL(int) db_mc_getDefaultNum(MCONTACT hMetaContact)
{
	DBCachedContact *cc = CheckMeta(hMetaContact);
	return (cc == NULL) ? -1 : cc->nDefault;
}
Пример #20
0
//returns the number of subcontacts, or -1 on failure
MIR_CORE_DLL(int) db_mc_getSubCount(MCONTACT hMetaContact)
{
	DBCachedContact *cc = CheckMeta(hMetaContact);
	return (cc == NULL) ? -1 : cc->nSubs;
}
Пример #21
0
// returns a subcontact with the given index
MIR_CORE_DLL(MCONTACT) db_mc_getSub(MCONTACT hMetaContact, int iNum)
{
	DBCachedContact *cc = CheckMeta(hMetaContact);
	return (cc == NULL) ? 0 : Meta_GetContactHandle(cc, iNum);
}