diff options
| author | George Hazan <george.hazan@gmail.com> | 2014-03-03 15:44:40 +0000 | 
|---|---|---|
| committer | George Hazan <george.hazan@gmail.com> | 2014-03-03 15:44:40 +0000 | 
| commit | 914e0b89c4aa13461d4f36fdfcb1b49bb3f00456 (patch) | |
| tree | 82e26a44d5494700d4077295468051fb41dccd85 | |
| parent | 2cbc7f36727cc86800c0866df859a0ab473b678e (diff) | |
- META_PROTO/Default went to cache;
- MIDatabase::MetaSetDefault method added to store the default sub in a database;
- Meta_SettingChanged fixed
git-svn-id: http://svn.miranda-ng.org/main/trunk@8380 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
| -rw-r--r-- | include/m_db_int.h | 7 | ||||
| -rw-r--r-- | plugins/Db3x_mmap/src/dbcontacts.cpp | 9 | ||||
| -rw-r--r-- | plugins/Db3x_mmap/src/dbintf.h | 1 | ||||
| -rw-r--r-- | src/modules/metacontacts/meta_api.cpp | 24 | ||||
| -rw-r--r-- | src/modules/metacontacts/meta_edit.cpp | 22 | ||||
| -rw-r--r-- | src/modules/metacontacts/meta_menu.cpp | 65 | ||||
| -rw-r--r-- | src/modules/metacontacts/meta_services.cpp | 228 | ||||
| -rw-r--r-- | src/modules/metacontacts/meta_utils.cpp | 44 | ||||
| -rw-r--r-- | src/modules/metacontacts/metacontacts.h | 2 | 
9 files changed, 177 insertions, 225 deletions
| diff --git a/include/m_db_int.h b/include/m_db_int.h index 95cd993878..3989424c40 100644 --- a/include/m_db_int.h +++ b/include/m_db_int.h @@ -52,10 +52,10 @@ struct DBCachedContact  	DBCachedContactValue *first, *last;
  	// metacontacts
 -	int       nSubs;    // == -1 -> not a metacontact at all
 +	int       nSubs;    // == -1 -> not a metacontact
  	MCONTACT *pSubs;
 -	MCONTACT  parentID, // == 0 -> not a subcontact
 -		       activeID; // manually chosen active sub
 +	MCONTACT  parentID; // == 0 -> not a subcontact
 +	int       nDefault; // default sub number
  };
  interface MIDatabaseCache : public MZeroedObject
 @@ -113,6 +113,7 @@ interface MIDatabase  	STDMETHOD_(BOOL, IsSettingEncrypted)(LPCSTR szModule, LPCSTR szSetting) PURE;
  	STDMETHOD_(BOOL, MetaDetouchSub)(DBCachedContact*, int nSub) PURE;
 +	STDMETHOD_(BOOL, MetaSetDefault)(DBCachedContact*) PURE;
  };
  ///////////////////////////////////////////////////////////////////////////////
 diff --git a/plugins/Db3x_mmap/src/dbcontacts.cpp b/plugins/Db3x_mmap/src/dbcontacts.cpp index ebdc9c6cfd..d05dac5555 100644 --- a/plugins/Db3x_mmap/src/dbcontacts.cpp +++ b/plugins/Db3x_mmap/src/dbcontacts.cpp @@ -208,6 +208,11 @@ BOOL CDb3Mmap::MetaDetouchSub(DBCachedContact *cc, int nSub)  	return 0;
  }
 +BOOL CDb3Mmap::MetaSetDefault(DBCachedContact *cc)
 +{
 +	return db_set_dw(cc->contactID, META_PROTO, "Default", cc->nDefault);
 +}
 +
  /////////////////////////////////////////////////////////////////////////////////////////
  // contacts convertor
 @@ -279,8 +284,8 @@ void CDb3Mmap::FillContacts()  				cc->pSubs[i] = hSub;
  			}
  		}
 -		cc->activeID = (0 != GetContactSetting(dwContactID, META_PROTO, "Default", &dbv)) ? NULL : dbv.dVal;
 -		cc->parentID = (0 != GetContactSetting(dwContactID, META_PROTO, "Handle", &dbv)) ? NULL : dbv.dVal;
 +		cc->nDefault = (0 != GetContactSetting(dwContactID, META_PROTO, "Default", &dbv)) ? -1 : dbv.dVal;
 +		cc->parentID = (0 != GetContactSetting(dwContactID, META_PROTO, "ParentMeta", &dbv)) ? NULL : dbv.dVal;
  		// whether we need conversion or not
  		if (!GetContactSetting(dwContactID, META_PROTO, "MetaID", &dbv))
 diff --git a/plugins/Db3x_mmap/src/dbintf.h b/plugins/Db3x_mmap/src/dbintf.h index 986ac700d0..50821b6204 100644 --- a/plugins/Db3x_mmap/src/dbintf.h +++ b/plugins/Db3x_mmap/src/dbintf.h @@ -235,6 +235,7 @@ public:  	STDMETHODIMP_(BOOL)     IsSettingEncrypted(LPCSTR szModule, LPCSTR szSetting);
  	STDMETHODIMP_(BOOL)     MetaDetouchSub(DBCachedContact *cc, int nSub);
 +	STDMETHODIMP_(BOOL)     MetaSetDefault(DBCachedContact *cc);
  protected:
  	STDMETHODIMP_(BOOL)     Start(DBCHeckCallback *callback);
 diff --git a/src/modules/metacontacts/meta_api.cpp b/src/modules/metacontacts/meta_api.cpp index af114f4bd3..d7448d74ef 100644 --- a/src/modules/metacontacts/meta_api.cpp +++ b/src/modules/metacontacts/meta_api.cpp @@ -34,9 +34,8 @@ INT_PTR MetaAPI_GetDefault(WPARAM hMetaContact, LPARAM)  	if (cc == NULL)
  		return 1;
 -	DWORD default_contact_number = db_get_dw(hMetaContact, META_PROTO, "Default", -1);
 -	if (default_contact_number != -1)
 -		return (INT_PTR)Meta_GetContactHandle(cc, default_contact_number);
 +	if (cc->nDefault != -1)
 +		return Meta_GetContactHandle(cc, cc->nDefault);
  	return 0;
  }
 @@ -48,12 +47,7 @@ INT_PTR MetaAPI_GetDefault(WPARAM hMetaContact, LPARAM)  INT_PTR MetaAPI_GetDefaultNum(WPARAM hMetaContact, LPARAM)
  {
  	DBCachedContact *cc = CheckMeta(hMetaContact);
 -	if (cc == NULL)
 -		return 1;
 -
 -	// !!!!!!!!!!!!!!!!!!!!!!!
 -	// return db_get_dw(hMetaContact, META_PROTO, "Default", -1);
 -	return -1;
 +	return (cc == NULL) ? -1 : cc->nDefault;
  }
  //gets the handle for the 'most online' contact
 @@ -100,8 +94,9 @@ INT_PTR MetaAPI_SetDefaultContactNum(WPARAM hMetaContact, LPARAM lParam)  		return 1;
  	if ((int)lParam >= cc->nSubs || (int)lParam < 0)
  		return 1;
 -	if (db_set_dw(hMetaContact, META_PROTO, "Default", (DWORD)lParam))
 -		return 1;
 +
 +	cc->nDefault = lParam;
 +	currDb->MetaSetDefault(cc);
  	NotifyEventHooks(hEventDefaultChanged, hMetaContact, Meta_GetContactHandle(cc, (int)lParam));
  	return 0;
 @@ -121,9 +116,8 @@ INT_PTR MetaAPI_SetDefaultContact(WPARAM hMetaContact, LPARAM lParam)  	if (contact_number == -1) 
  		return 1;
 -	// currDb->Meta_SetDefaultSub(cc, lParam); !!!!!!!!!!!!!!!!!!!!
 -	if (db_set_dw(cc->contactID, META_PROTO, "Default", contact_number))
 -		return 1;
 +	cc->nDefault = contact_number;
 +	currDb->MetaSetDefault(cc);
  	NotifyEventHooks(hEventDefaultChanged, hMetaContact, lParam);
  	return 0;
 @@ -213,7 +207,7 @@ INT_PTR MetaAPI_GetForceState(WPARAM hMetaContact, LPARAM lParam)  		return 0;
  	if (db_get_b(hMetaContact, META_PROTO, "ForceDefault", 0)) {
 -		if (lParam) *(DWORD *)lParam = db_get_dw(hMetaContact, META_PROTO, "Default", -1);
 +		if (lParam) *(DWORD *)lParam = cc->nDefault;
  		return 1;
  	}
 diff --git a/src/modules/metacontacts/meta_edit.cpp b/src/modules/metacontacts/meta_edit.cpp index 98c877a5ac..87929eedf4 100644 --- a/src/modules/metacontacts/meta_edit.cpp +++ b/src/modules/metacontacts/meta_edit.cpp @@ -152,10 +152,8 @@ void ApplyChanges(CHANGES *chg)  	NotifyEventHooks(hSubcontactsChanged, chg->hMeta, chg->hDefaultContact);
  	// set default
 -	if (chg->hDefaultContact)
 -		db_set_dw(chg->hMeta, META_PROTO, "Default", Meta_GetContactNumber(chg->cc, chg->hDefaultContact));
 -	else
 -		db_set_dw(chg->hMeta, META_PROTO, "Default", 0);
 +	chg->cc->nDefault = (chg->hDefaultContact) ? Meta_GetContactNumber(chg->cc, chg->hDefaultContact) : 0;
 +	currDb->MetaSetDefault(chg->cc);
  	NotifyEventHooks(hEventDefaultChanged, chg->hMeta, chg->hDefaultContact);
  	// set offline
 @@ -231,6 +229,12 @@ INT_PTR CALLBACK Meta_EditDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPAR  		TranslateDialogDefault( hwndDlg );
  		SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIconEx(I_EDIT));
  		{	
 +			DBCachedContact *cc = currDb->m_cache->GetCachedContact(lParam);
 +			if (cc == NULL) {
 +				DestroyWindow(hwndDlg);
 +				return FALSE;
 +			}
 +
  			// Disable the 'Apply' button.
  			EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),FALSE);
 @@ -268,17 +272,15 @@ INT_PTR CALLBACK Meta_EditDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPAR  			EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UP), FALSE);
  			EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_DOWN), FALSE);
 -			int nb_contacts = db_get_dw(lParam, META_PROTO, "NumContacts", 0);
 -			int default_contact_number = db_get_dw(lParam, META_PROTO, "Default", INVALID_CONTACT_ID);
  			int offline_contact_number = db_get_dw(lParam, META_PROTO, "OfflineSend", INVALID_CONTACT_ID);
 +			changes.cc = cc;
  			changes.hMeta = lParam;
 -			changes.cc = currDb->m_cache->GetCachedContact(lParam);
 -			changes.num_contacts = nb_contacts;
 +			changes.num_contacts = cc->nSubs;
  			changes.num_deleted = 0;
 -			changes.hDefaultContact = Meta_GetContactHandle(changes.cc, default_contact_number);
 +			changes.hDefaultContact = Meta_GetContactHandle(changes.cc, cc->nDefault);
  			changes.hOfflineContact = Meta_GetContactHandle(changes.cc, offline_contact_number);
 -			for (i = 0; i < nb_contacts; i++)
 +			for (i = 0; i < cc->nSubs; i++)
  				changes.hContact[i] = Meta_GetContactHandle(changes.cc, i);
  			changes.force_default = MetaAPI_GetForceState((WPARAM)lParam, 0);
 diff --git a/src/modules/metacontacts/meta_menu.cpp b/src/modules/metacontacts/meta_menu.cpp index acdb6d3dd7..5cc3777495 100644 --- a/src/modules/metacontacts/meta_menu.cpp +++ b/src/modules/metacontacts/meta_menu.cpp @@ -115,20 +115,17 @@ INT_PTR Meta_Edit(WPARAM wParam, LPARAM lParam)  	return 0;
  }
 -void Meta_RemoveContactNumber(DBCachedContact *cc, int number)
 +void Meta_RemoveContactNumber(DBCachedContact *ccMeta, int number)
  {
 -	if (cc == NULL)
 +	if (ccMeta == NULL)
  		return;
 -	if (number < 0 && number >= cc->nSubs)
 +	if (number < 0 && number >= ccMeta->nSubs)
  		return;
 -	// get the handle
 -	MCONTACT hContact = Meta_GetContactHandle(cc, number);
 -	int default_contact = db_get_dw(cc->contactID, META_PROTO, "Default", -1);
 -
  	// make sure this contact thinks it's part of this metacontact
 -	if (hContact == cc->contactID) {
 +	MCONTACT hContact = Meta_GetContactHandle(ccMeta, number);
 +	if (hContact == ccMeta->contactID) {
  		// stop ignoring, if we were
  		if (options.suppress_status)
  			CallService(MS_IGNORE_UNIGNORE, hContact, IGNOREEVENT_USERONLINE);
 @@ -136,59 +133,59 @@ void Meta_RemoveContactNumber(DBCachedContact *cc, int number)  	// each contact from 'number' upwards will be moved down one
  	// and the last one will be deleted
 -	for (int i = number + 1; i < cc->nSubs; i++)
 -		Meta_SwapContacts(cc, i, i - 1);
 +	for (int i = number + 1; i < ccMeta->nSubs; i++)
 +		Meta_SwapContacts(ccMeta, i, i - 1);
  	// remove the last one
  	char buffer[512], idStr[20];
 -	_itoa(cc->nSubs - 1, idStr, 10);
 +	_itoa(ccMeta->nSubs - 1, idStr, 10);
  	strcpy(buffer, "Protocol"); strcat(buffer, idStr);
 -	db_unset(cc->contactID, META_PROTO, buffer);
 +	db_unset(ccMeta->contactID, META_PROTO, buffer);
  	strcpy(buffer, "Status"); strcat(buffer, idStr);
 -	db_unset(cc->contactID, META_PROTO, buffer);
 +	db_unset(ccMeta->contactID, META_PROTO, buffer);
  	strcpy(buffer, "StatusString"); strcat(buffer, idStr);
 -	db_unset(cc->contactID, META_PROTO, buffer);
 +	db_unset(ccMeta->contactID, META_PROTO, buffer);
  	strcpy(buffer, "Login"); strcat(buffer, idStr);
 -	db_unset(cc->contactID, META_PROTO, buffer);
 +	db_unset(ccMeta->contactID, META_PROTO, buffer);
  	strcpy(buffer, "Nick"); strcat(buffer, idStr);
 -	db_unset(cc->contactID, META_PROTO, buffer);
 +	db_unset(ccMeta->contactID, META_PROTO, buffer);
  	strcpy(buffer, "CListName"); strcat(buffer, idStr);
 -	db_unset(cc->contactID, META_PROTO, buffer);
 +	db_unset(ccMeta->contactID, 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;
 +	if (ccMeta->nDefault >= number) {
 +		ccMeta->nDefault--;
 +		if (ccMeta->nDefault < 0)
 +			ccMeta->nDefault = 0;
 -		db_set_dw(cc->contactID, META_PROTO, "Default", default_contact);
 -		NotifyEventHooks(hEventDefaultChanged, cc->contactID, Meta_GetContactHandle(cc, default_contact));
 +		currDb->MetaSetDefault(ccMeta);
 +		NotifyEventHooks(hEventDefaultChanged, ccMeta->contactID, Meta_GetContactHandle(ccMeta, ccMeta->nDefault));
  	}
 -	cc->nSubs--;
 -	db_set_dw(cc->contactID, META_PROTO, "NumContacts", cc->nSubs);
 +	ccMeta->nSubs--;
 +	db_set_dw(ccMeta->contactID, META_PROTO, "NumContacts", ccMeta->nSubs);
  	// fix nick
 -	hContact = Meta_GetMostOnline(cc);
 -	Meta_CopyContactNick(cc, hContact);
 +	hContact = Meta_GetMostOnline(ccMeta);
 +	Meta_CopyContactNick(ccMeta, hContact);
  	// fix status
 -	Meta_FixStatus(cc);
 +	Meta_FixStatus(ccMeta);
  	// fix avatar
 -	hContact = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS);
 +	hContact = Meta_GetMostOnlineSupporting(ccMeta, PFLAGNUM_4, PF4_AVATARS);
  	if (hContact) {
  		PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) };
 -		AI.hContact = cc->contactID;
 +		AI.hContact = ccMeta->contactID;
  		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(cc->contactID, "ContactPhoto", "File", AI.filename);
 +			db_set_ts(ccMeta->contactID, "ContactPhoto", "File", AI.filename);
  	}
  }
 @@ -248,11 +245,13 @@ INT_PTR Meta_Delete(WPARAM hContact, LPARAM bSkipQuestion)  * @param lParam :	HWND to the clist window
  (This means the function has been called via the contact menu).
  */
 +
  INT_PTR Meta_Default(WPARAM hMeta, LPARAM wParam)
  {
  	DBCachedContact *cc = CheckMeta(hMeta);
  	if (cc) {
 -		db_set_dw(hMeta, META_PROTO, "Default", Meta_GetContactNumber(cc, wParam));
 +		cc->nDefault = Meta_GetContactNumber(cc, wParam);
 +		currDb->MetaSetDefault(cc);
  		NotifyEventHooks(hEventDefaultChanged, hMeta, wParam);
  	}
  	return 0;
 @@ -279,7 +278,7 @@ INT_PTR Meta_ForceDefault(WPARAM hMeta, LPARAM)  		db_set_dw(hMeta, META_PROTO, "ForceSend", 0);
  		if (current)
 -			NotifyEventHooks(hEventForceSend, hMeta, Meta_GetContactHandle(cc, db_get_dw(hMeta, META_PROTO, "Default", -1)));
 +			NotifyEventHooks(hEventForceSend, hMeta, Meta_GetContactHandle(cc, cc->nDefault));
  		else
  			NotifyEventHooks(hEventUnforceSend, hMeta, 0);
  	}
 diff --git a/src/modules/metacontacts/meta_services.cpp b/src/modules/metacontacts/meta_services.cpp index 8bad53d5df..d9131c9461 100644 --- a/src/modules/metacontacts/meta_services.cpp +++ b/src/modules/metacontacts/meta_services.cpp @@ -257,19 +257,14 @@ INT_PTR Meta_SendNudge(WPARAM wParam, LPARAM lParam)  INT_PTR Meta_SendMessage(WPARAM wParam,LPARAM lParam)
  {
  	CCSDATA *ccs = (CCSDATA*)lParam;
 -	char *proto = 0;
 -	DWORD default_contact_number;
 -	if ((default_contact_number = db_get_dw(ccs->hContact, META_PROTO, "Default",INVALID_CONTACT_ID)) == INVALID_CONTACT_ID) {
 +	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);
  	}
 -	DBCachedContact *cc = CheckMeta(ccs->hContact);
 -	if (cc == NULL)
 -		return 1;
 -
  	MCONTACT most_online = Meta_GetMostOnline(cc);
  	if (!most_online) {
  		// send failure to notify user of reason
 @@ -290,7 +285,7 @@ INT_PTR Meta_SendMessage(WPARAM wParam,LPARAM lParam)  	Meta_CopyContactNick(cc, most_online);
  	ccs->hContact = most_online;
 -	proto = GetContactProto(most_online);
 +	char *proto = GetContactProto(most_online);
  	Meta_SetNick(proto);	// (no matter what was there before)
  	// don't bypass filters etc
 @@ -341,7 +336,8 @@ INT_PTR MetaFilter_RecvMessage(WPARAM wParam,LPARAM lParam)  		return CallService(MS_PROTO_CHAINRECV, wParam, (LPARAM)ccs);
  	if (options.set_default_on_recv) {
 -		db_set_dw(cc->parentID, META_PROTO, "Default", ccs->hContact);
 +		cc->nDefault = Meta_GetContactNumber(cc, ccs->hContact);
 +		currDb->MetaSetDefault(cc);
  		NotifyEventHooks(hEventDefaultChanged, cc->parentID, ccs->hContact); // nick set in event handler
  	}
 @@ -536,58 +532,61 @@ static DWORD sttHideContacts(BOOL param)  * @param lParam Reference to a structure that contains the setting that has changed (not used)
  */
 -int Meta_SettingChanged(WPARAM wParam, LPARAM lParam)
 +int Meta_SettingChanged(WPARAM hContact, LPARAM lParam)
  {
  	DBCONTACTWRITESETTING *dcws = (DBCONTACTWRITESETTING *)lParam;
  	char buffer[512], szId[40];
 -	int contact_number;
  	// hide metacontacts when groups disabled
 -	if (wParam == 0
 -		 && ((strcmp(dcws->szModule, "CList") == 0 && strcmp(dcws->szSetting, "UseGroups") == 0)
 -		 || (strcmp(dcws->szModule, META_PROTO) == 0 && strcmp(dcws->szSetting, "Enabled") == 0))) {
 -		sttHideContacts(!Meta_IsEnabled());
 +	if (hContact == 0)
 +		if ((!strcmp(dcws->szModule, "CList") && !strcmp(dcws->szSetting, "UseGroups")) ||
 +			 (!strcmp(dcws->szModule, META_PROTO) && !strcmp(dcws->szSetting, "Enabled"))) {
 +			sttHideContacts(!Meta_IsEnabled());
 +			return 0;
 +		}
 +
 +	// from here on, we're just interested in subcontact settings
 +	if (hContact == 0)
  		return 0;
 -	}
 -	// from here on, we're just interested in contact settings
 -	if (wParam == 0)
 +	DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact);
 +	if (cc == NULL || !IsSub(cc))
  		return 0;
 -	DBCachedContact *cc = CheckMeta(wParam);
 -	if (cc == NULL)
 +	DBCachedContact *ccMeta = currDb->m_cache->GetCachedContact(cc->parentID);
 +	if (ccMeta == NULL || !IsMeta(ccMeta))
  		return 0;
  	// This contact is attached to a MetaContact.
 -	contact_number = Meta_GetContactNumber(cc, wParam);
 +	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(cc->contactID, META_PROTO, "IP", dcws->value.dVal);
 +			db_set_dw(ccMeta->contactID, META_PROTO, "IP", dcws->value.dVal);
  		else
 -			db_unset(cc->contactID, META_PROTO, "IP");
 +			db_unset(ccMeta->contactID, META_PROTO, "IP");
  	}
  	else if (!strcmp(dcws->szSetting, "RealIP")) {
  		if (dcws->value.type == DBVT_DWORD)
 -			db_set_dw(cc->contactID, META_PROTO, "RealIP", dcws->value.dVal);
 +			db_set_dw(ccMeta->contactID, META_PROTO, "RealIP", dcws->value.dVal);
  		else
 -			db_unset(cc->contactID, META_PROTO, "RealIP");
 +			db_unset(ccMeta->contactID, META_PROTO, "RealIP");
  	}
  	else if (!strcmp(dcws->szSetting, "ListeningTo")) {
  		switch (dcws->value.type) {
  		case DBVT_ASCIIZ:
 -			db_set_s(cc->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal);
 +			db_set_s(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal);
  			break;
  		case DBVT_UTF8:
 -			db_set_utf(cc->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal);
 +			db_set_utf(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal);
  			break;
  		case DBVT_WCHAR:
 -			db_set_ws(cc->contactID, META_PROTO, "ListeningTo", dcws->value.pwszVal);
 +			db_set_ws(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pwszVal);
  			break;
  		case DBVT_DELETED:
 -			db_unset(cc->contactID, META_PROTO, "ListeningTo");
 +			db_unset(ccMeta->contactID, META_PROTO, "ListeningTo");
  			break;
  		}
  	}
 @@ -595,57 +594,57 @@ int Meta_SettingChanged(WPARAM wParam, LPARAM lParam)  		// subcontact nick has changed - update metacontact
  		strcpy(buffer, "Nick");
  		strcat(buffer, _itoa(contact_number, szId, 10));
 -		db_set(cc->contactID, META_PROTO, buffer, &dcws->value);
 +		db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value);
  		DBVARIANT dbv;
 -		if (Mydb_get(wParam, "CList", "MyHandle", &dbv)) {
 +		if (Mydb_get(hContact, "CList", "MyHandle", &dbv)) {
  			strcpy(buffer, "CListName");
  			strcat(buffer, _itoa(contact_number, szId, 10));
 -			db_set(cc->contactID, META_PROTO, buffer, &dcws->value);
 +			db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value);
  		}
  		else db_free(&dbv);
  		// copy nick to metacontact, if it's the most online
 -		MCONTACT most_online = Meta_GetMostOnline(cc);
 -		Meta_CopyContactNick(cc, most_online);
 +		MCONTACT most_online = Meta_GetMostOnline(ccMeta);
 +		Meta_CopyContactNick(ccMeta, most_online);
  		return 0;
  	}
  	else if (!strcmp(dcws->szSetting, "IdleTS")) {
  		if (dcws->value.type == DBVT_DWORD)
 -			db_set_dw(cc->contactID, META_PROTO, "IdleTS", dcws->value.dVal);
 +			db_set_dw(ccMeta->contactID, META_PROTO, "IdleTS", dcws->value.dVal);
  		else if (dcws->value.type == DBVT_DELETED)
 -			db_set_dw(cc->contactID, META_PROTO, "IdleTS", 0);
 +			db_set_dw(ccMeta->contactID, META_PROTO, "IdleTS", 0);
  	}
  	else if (!strcmp(dcws->szSetting, "LogonTS")) {
  		if (dcws->value.type == DBVT_DWORD)
 -			db_set_dw(cc->contactID, META_PROTO, "LogonTS", dcws->value.dVal);
 +			db_set_dw(ccMeta->contactID, META_PROTO, "LogonTS", dcws->value.dVal);
  		else if (dcws->value.type == DBVT_DELETED)
 -			db_set_dw(cc->contactID, META_PROTO, "LogonTS", 0);
 +			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(wParam);
 +			char *proto = GetContactProto(hContact);
  			strcpy(buffer, "CListName");
  			strcat(buffer, _itoa(contact_number, szId, 10));
  			DBVARIANT dbv;
 -			if (proto && !Mydb_get(wParam, proto, "Nick", &dbv)) {
 -				db_set(cc->contactID, META_PROTO, buffer, &dbv);
 +			if (proto && !Mydb_get(hContact, proto, "Nick", &dbv)) {
 +				db_set(ccMeta->contactID, META_PROTO, buffer, &dbv);
  				db_free(&dbv);
  			}
 -			else db_unset(cc->contactID, META_PROTO, buffer);
 +			else db_unset(ccMeta->contactID, META_PROTO, buffer);
  		}
  		else {
  			// subcontact clist displayname has changed - update metacontact
  			strcpy(buffer, "CListName");
  			strcat(buffer, _itoa(contact_number, szId, 10));
 -			db_set(cc->contactID, META_PROTO, buffer, &dcws->value);
 +			db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value);
  		}
  		// copy nick to metacontact, if it's the most online
 -		MCONTACT most_online = Meta_GetMostOnline(cc);
 -		Meta_CopyContactNick(cc, most_online);
 +		MCONTACT most_online = Meta_GetMostOnline(ccMeta);
 +		Meta_CopyContactNick(ccMeta, most_online);
  		return 0;
  	}
  	else if (!strcmp(dcws->szSetting, "Status") && !dcws->value.type == DBVT_DELETED) {
 @@ -654,39 +653,39 @@ int Meta_SettingChanged(WPARAM wParam, LPARAM lParam)  		// update subcontact status setting
  		strcpy(buffer, "Status");
  		strcat(buffer, _itoa(contact_number, szId, 10));
 -		db_set_w(cc->contactID, META_PROTO, buffer, dcws->value.wVal);
 +		db_set_w(ccMeta->contactID, META_PROTO, buffer, dcws->value.wVal);
  		strcpy(buffer, "StatusString");
  		strcat(buffer, _itoa(contact_number, szId, 10));
 -		db_set_ts(cc->contactID, META_PROTO, buffer, cli.pfnGetStatusModeDescription(dcws->value.wVal, 0));
 +		db_set_ts(ccMeta->contactID, META_PROTO, buffer, cli.pfnGetStatusModeDescription(dcws->value.wVal, 0));
  		// if the contact was forced, unforce it (which updates status)
 -		if ((HANDLE)db_get_dw(cc->contactID, META_PROTO, "ForceSend", 0) == (HANDLE)wParam)
 -			MetaAPI_UnforceSendContact((WPARAM)cc->contactID, 0);
 +		if (db_get_dw(ccMeta->contactID, META_PROTO, "ForceSend", 0) == hContact)
 +			MetaAPI_UnforceSendContact((WPARAM)ccMeta->contactID, 0);
  		else {
  			// set status to that of most online contact
 -			Meta_CopyContactNick(cc, Meta_GetMostOnline(cc));
 +			Meta_CopyContactNick(ccMeta, Meta_GetMostOnline(ccMeta));
 -			Meta_FixStatus(cc);
 -			Meta_CopyData(cc);
 +			Meta_FixStatus(ccMeta);
 +			Meta_CopyData(ccMeta);
  		}
  		// most online contact with avatar support might have changed - update avatar
 -		MCONTACT most_online = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS);
 +		MCONTACT most_online = Meta_GetMostOnlineSupporting(ccMeta, PFLAGNUM_4, PF4_AVATARS);
  		if (most_online) {
  			PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) };
 -			AI.hContact = cc->contactID;
 +			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(cc->contactID, "ContactPhoto", "File", AI.filename);
 +				db_set_ts(ccMeta->contactID, "ContactPhoto", "File", AI.filename);
  		}
  	}
  	else if (strcmp(dcws->szSetting, "XStatusId") == 0 || strcmp(dcws->szSetting, "XStatusMsg") == 0 || strcmp(dcws->szSetting, "XStatusName") == 0 || strcmp(dcws->szSetting, "StatusMsg") == 0) {
 -		Meta_CopyData(cc);
 +		Meta_CopyData(ccMeta);
  	}
  	else if (strcmp(dcws->szSetting, "MirVer") == 0)
 -		Meta_CopyData(cc);
 +		Meta_CopyData(ccMeta);
  	return 0;
  }
 @@ -779,14 +778,10 @@ int Meta_ContactIsTyping(WPARAM hMeta, LPARAM lParam)  int Meta_UserInfo(WPARAM wParam, LPARAM hMeta)
  {
  	DBCachedContact *cc = CheckMeta(hMeta);
 -	if (cc == NULL)
 -		return 0;
 -
 -	DWORD default_contact_number = db_get_dw(hMeta, META_PROTO, "Default", INVALID_CONTACT_ID);
 -	if (default_contact_number == -1) // not a meta contact
 +	if (cc == NULL || cc->nDefault == -1)
  		return 0;
 -	CallService(MS_USERINFO_SHOWDIALOG, Meta_GetContactHandle(cc, default_contact_number), 0);
 +	CallService(MS_USERINFO_SHOWDIALOG, Meta_GetContactHandle(cc, cc->nDefault), 0);
  	return 1;
  }
 @@ -806,7 +801,7 @@ int Meta_MessageWindowEvent(WPARAM wParam, LPARAM lParam)  			db_set_b(mwed->hContact, META_PROTO, "WindowOpen", 1);
  			if (IsSub(cc))  // subcontact window opened - remove clist events we added for metacontact
 -			while (!CallService(MS_CLIST_REMOVEEVENT, cc->contactID, mwed->hContact));
 +			while (!CallService(MS_CLIST_REMOVEEVENT, cc->parentID, mwed->hContact));
  		}
  		else if (mwed->uType == MSG_WINDOW_EVT_CLOSE || mwed->uType == MSG_WINDOW_EVT_CLOSING)
  			db_set_b(mwed->hContact, META_PROTO, "WindowOpen", 0);
 @@ -818,10 +813,7 @@ int Meta_MessageWindowEvent(WPARAM wParam, LPARAM lParam)  int Meta_ClistDoubleClicked(WPARAM hMeta, LPARAM lParam)
  {
  	DBCachedContact *cc = CheckMeta(hMeta);
 -	if (cc == NULL)
 -		return 0;
 -
 -	if (db_get_dw(hMeta, META_PROTO, "Default", (WORD)-1) == (WORD)-1)
 +	if (cc == NULL || cc->nDefault == -1)
  		return 0;
  	// -1 indicates  no specific capability but respect 'ForceDefault'
 @@ -930,7 +922,8 @@ INT_PTR Meta_ContactMenuFunc(WPARAM hMeta, LPARAM lParam)  			int caps = CallService(buffer, (WPARAM)PFLAGNUM_1, 0);
  			if ((caps & PF1_IMSEND) || (caps & PF1_CHAT) || (proto && strcmp(proto, "IRC") == 0)) {
  				// set default contact for sending/status and open message window
 -				db_set_dw(hMeta, META_PROTO, "Default", (DWORD)(int)lParam);
 +				cc->nDefault = (int)lParam;
 +				currDb->MetaSetDefault(cc);
  				NotifyEventHooks(hEventDefaultChanged, hMeta, (LPARAM)hContact);
  				CallService(MS_MSG_SENDMESSAGE, hMeta, 0);
  			}
 @@ -955,95 +948,64 @@ INT_PTR Meta_ContactMenuFunc(WPARAM hMeta, LPARAM lParam)  INT_PTR Meta_FileSend(WPARAM wParam, LPARAM lParam)
  {
  	CCSDATA *ccs = (CCSDATA*)lParam;
 -	char *proto = 0;
 -
  	DBCachedContact *cc = CheckMeta(ccs->hContact);
 -	if (cc == NULL)
 +	if (cc == NULL || cc->nDefault == -1)
  		return 0;
 -	DWORD default_contact_number;
 -	if ((default_contact_number = db_get_dw(ccs->hContact, META_PROTO, "Default", INVALID_CONTACT_ID)) == INVALID_CONTACT_ID) {
 -		// This is a simple contact
 -		// (this should normally not happen, since linked contacts do not appear on the list.)
 -		//PUShowMessage("meta has no default", SM_NOTIFY);
 +	MCONTACT most_online = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_FILESEND);
 +	if (!most_online)
  		return 0;
 -	}
 -	else {
 -		MCONTACT most_online = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_FILESEND);
 -		if (!most_online) {
 -			//PUShowMessage("no most online for ft", SM_NOTIFY);
 -			return 0;
 -		}
 -		proto = GetContactProto(most_online);
 -		if (proto)
 -			return (int)(CallContactService(most_online, PSS_FILE, ccs->wParam, ccs->lParam));
 -	}
 +	char *proto = GetContactProto(most_online);
 +	if (proto)
 +		return (int)(CallContactService(most_online, PSS_FILE, ccs->wParam, ccs->lParam));
 +
  	return 0; // fail
  }
  INT_PTR Meta_GetAwayMsg(WPARAM wParam, LPARAM lParam)
  {
  	CCSDATA *ccs = (CCSDATA*)lParam;
 -	char *proto = 0;
 -
  	DBCachedContact *cc = CheckMeta(ccs->hContact);
 -	if (cc == NULL)
 +	if (cc == NULL || cc->nDefault == -1)
  		return 0;
 -	DWORD default_contact_number;
 -	if ((default_contact_number = db_get_dw(ccs->hContact, META_PROTO, "Default", INVALID_CONTACT_ID)) == INVALID_CONTACT_ID) {
 -		// This is a simple contact
 -		// (this should normally not happen, since linked contacts do not appear on the list.)
 +	MCONTACT most_online = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_MODEMSGRECV);
 +	if (!most_online)
  		return 0;
 -	}
 -	else {
 -		MCONTACT most_online = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_MODEMSGRECV);
 -		if (!most_online)
 -			return 0;
 -
 -		proto = GetContactProto(most_online);
 -		if (!proto) return 0;
 -		//Meta_CopyContactNick(ccs->hContact, most_online, proto);
 -
 -		ccs->hContact = most_online;
 -		//Meta_SetNick(proto);
 +	char *proto = GetContactProto(most_online);
 +	if (!proto)
 +		return 0;
 -		return (int)(CallContactService(ccs->hContact, PSS_GETAWAYMSG, ccs->wParam, ccs->lParam));
 -	}
 -	return 0; // fail
 +	ccs->hContact = most_online;
 +	return (int)(CallContactService(ccs->hContact, PSS_GETAWAYMSG, ccs->wParam, ccs->lParam));
  }
  INT_PTR Meta_GetAvatarInfo(WPARAM wParam, LPARAM lParam)
  {
  	PROTO_AVATAR_INFORMATIONT *AI = (PROTO_AVATAR_INFORMATIONT *)lParam;
 -	DWORD default_contact_number;
 +	DBCachedContact *cc = CheckMeta(AI->hContact);
 +	if (cc == NULL)
 +		return GAIR_NOAVATAR;
 -	if ((default_contact_number = db_get_dw(AI->hContact, META_PROTO, "Default", INVALID_CONTACT_ID)) == INVALID_CONTACT_ID) {
 -		// This is a simple contact
 -		// (this should normally not happen, since linked contacts do not appear on the list.)
 +	if (cc->nDefault == -1)
  		return 0;
 -	}
 -	else {
 -		DBCachedContact *cc = CheckMeta(AI->hContact);
 -		if (cc == NULL)
 -			return GAIR_NOAVATAR;
 -		MCONTACT hSub = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS);
 -		if (!hSub)
 -			return GAIR_NOAVATAR;
 +	MCONTACT hSub = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS);
 +	if (!hSub)
 +		return GAIR_NOAVATAR;
 -		char *proto = GetContactProto(hSub);
 -		if (!proto) return GAIR_NOAVATAR;
 +	char *proto = GetContactProto(hSub);
 +	if (!proto)
 +		return GAIR_NOAVATAR;
 -		AI->hContact = hSub;
 +	AI->hContact = hSub;
 +	INT_PTR result = ProtoCallService(proto, PS_GETAVATARINFOT, wParam, lParam);
 +	AI->hContact = cc->contactID;
 +	if (result != CALLSERVICE_NOTFOUND)
 +		return result;
 -		INT_PTR result = ProtoCallService(proto, PS_GETAVATARINFOT, wParam, lParam);
 -		AI->hContact = cc->contactID;
 -		if (result != CALLSERVICE_NOTFOUND)
 -			return result;
 -	}
  	return GAIR_NOAVATAR; // fail
  }
 @@ -1054,11 +1016,7 @@ INT_PTR Meta_GetInfo(WPARAM wParam, LPARAM 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)
 -		return 0;
 -
 -	MCONTACT default_contact_number = db_get_dw(ccs->hContact, META_PROTO, "Default", INVALID_CONTACT_ID);
 -	if (default_contact_number == INVALID_CONTACT_ID)
 +	if (cc == NULL || cc->nDefault == -1)
  		return 0;
  	MCONTACT most_online = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS);
 diff --git a/src/modules/metacontacts/meta_utils.cpp b/src/modules/metacontacts/meta_utils.cpp index c0d03bde65..28e915784b 100644 --- a/src/modules/metacontacts/meta_utils.cpp +++ b/src/modules/metacontacts/meta_utils.cpp @@ -321,7 +321,8 @@ BOOL Meta_Assign(MCONTACT src, MCONTACT dest, BOOL set_as_default)  	db_set_dw(dest, META_PROTO, "NumContacts", num_contacts);
  	if (set_as_default) {
 -		db_set_dw(dest, META_PROTO, "Default", (WORD)(num_contacts - 1));
 +		ccDest->nDefault = num_contacts - 1;
 +		currDb->MetaSetDefault(ccDest);
  		NotifyEventHooks(hEventDefaultChanged, (WPARAM)dest, (LPARAM)src);
  	}
 @@ -379,25 +380,18 @@ MCONTACT Meta_GetMostOnline(DBCachedContact *cc)  MCONTACT Meta_GetMostOnlineSupporting(DBCachedContact *cc, int pflagnum, unsigned long capability)
  {
 -	if (cc == NULL)
 +	if (cc == NULL || cc->nDefault == -1)
  		return 0;
  	int most_online_status = ID_STATUS_OFFLINE;
  	MCONTACT hContact;
 -	int i, default_contact_number, num_contacts;
 -
 -	// you can't get more online than having the default contact ONLINE - so check that first
 -	if ((default_contact_number = db_get_dw(cc->contactID, META_PROTO, "Default", INVALID_CONTACT_ID)) == INVALID_CONTACT_ID) {
 -		// This is a simple contact - return NULL to signify error.
 -		// (this should normally not happen, since all meta contacts have a default contact)
 -		return NULL;
 -	}
 +	int i;
  	// if the default is beyond the end of the list (eek!) return null
 -	if (default_contact_number >= (num_contacts = db_get_dw(cc->contactID, META_PROTO, "NumContacts", 0)))
 +	if (cc->nDefault >= cc->nSubs)
  		return NULL;
 -	MCONTACT most_online_contact = Meta_GetContactHandle(cc, default_contact_number);
 +	MCONTACT most_online_contact = Meta_GetContactHandle(cc, cc->nDefault);
  	char *szProto = GetContactProto(most_online_contact);
  	DWORD caps = szProto ? CallProtoService(szProto, PS_GETCAPS, (WPARAM)pflagnum, 0) : 0;
  	if (szProto && strcmp(szProto, "IRC") == 0) caps |= PF1_IM;
 @@ -413,7 +407,7 @@ MCONTACT Meta_GetMostOnlineSupporting(DBCachedContact *cc, int pflagnum, unsigne  			return most_online_contact;
  	}
 -	most_online_contact = Meta_GetContactHandle(cc, default_contact_number);
 +	most_online_contact = Meta_GetContactHandle(cc, cc->nDefault);
  	szProto = GetContactProto(most_online_contact);
  	if (szProto && CallProtoService(szProto, PS_GETSTATUS, 0, 0) >= ID_STATUS_ONLINE) {
  		caps = szProto ? CallProtoService(szProto, PS_GETCAPS, (WPARAM)pflagnum, 0) : 0;
 @@ -432,8 +426,8 @@ MCONTACT Meta_GetMostOnlineSupporting(DBCachedContact *cc, int pflagnum, unsigne  	char *most_online_proto = szProto;
  	// otherwise, check all the subcontacts for the one closest to the ONLINE state which supports the required capability
 -	for (i = 0; i < num_contacts; i++) {
 -		if (i == default_contact_number) // already checked that (i.e. initial value of most_online_contact and most_online_status are those of the default contact)
 +	for (i = 0; i < cc->nSubs; i++) {
 +		if (i == cc->nDefault) // already checked that (i.e. initial value of most_online_contact and most_online_status are those of the default contact)
  			continue;
  		hContact = Meta_GetContactHandle(cc, i);
 @@ -510,18 +504,16 @@ BOOL dbv_same(DBVARIANT *dbv1, DBVARIANT *dbv2)  void copy_settings_array(DBCachedContact *ccMeta, char *module, const char *settings[], int num_settings)
  {
 -	int num_contacts = db_get_dw(ccMeta->contactID, META_PROTO, "NumContacts", INVALID_CONTACT_ID),
 -		default_contact = db_get_dw(ccMeta->contactID, META_PROTO, "Default", INVALID_CONTACT_ID),
 -		most_online = Meta_GetContactNumber(ccMeta, Meta_GetMostOnline(ccMeta));
 +	int most_online = Meta_GetContactNumber(ccMeta, Meta_GetMostOnline(ccMeta));
  	BOOL use_default = FALSE;
 -	int source_contact = (use_default ? default_contact : most_online);
 -	if (source_contact < 0 || source_contact >= num_contacts)
 +	int source_contact = (use_default ? ccMeta->nDefault : most_online);
 +	if (source_contact < 0 || source_contact >= ccMeta->nSubs)
  		return;
  	for (int i = 0; i < num_settings; i++) {
  		BOOL bDataWritten = FALSE;
 -		for (int j = 0; j < num_contacts && !bDataWritten; j++) {
 +		for (int j = 0; j < ccMeta->nSubs && !bDataWritten; j++) {
  			// do source (most online) first
  			MCONTACT hContact;
  			if (j == 0)
 @@ -1008,18 +1000,18 @@ INT_PTR CALLBACK DlgProcNull(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPara  	return FALSE;
  }
 -void Meta_FixStatus(DBCachedContact *cc)
 +void Meta_FixStatus(DBCachedContact *ccMeta)
  {
 -	MCONTACT most_online = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, 0);
 +	MCONTACT most_online = Meta_GetMostOnlineSupporting(ccMeta, PFLAGNUM_1, 0);
  	if (most_online) {
  		char *szProto = GetContactProto(most_online);
  		if (szProto) {
  			WORD status = db_get_w(most_online, szProto, "Status", ID_STATUS_OFFLINE);
 -			db_set_w(cc->contactID, META_PROTO, "Status", status);
 +			db_set_w(ccMeta->contactID, META_PROTO, "Status", status);
  		}
 -		else db_set_w(cc->contactID, META_PROTO, "Status", ID_STATUS_OFFLINE);
 +		else db_set_w(ccMeta->contactID, META_PROTO, "Status", ID_STATUS_OFFLINE);
  	}
 -	else db_set_w(cc->contactID, META_PROTO, "Status", ID_STATUS_OFFLINE);
 +	else db_set_w(ccMeta->contactID, META_PROTO, "Status", ID_STATUS_OFFLINE);
  }
  INT_PTR Meta_IsEnabled()
 diff --git a/src/modules/metacontacts/metacontacts.h b/src/modules/metacontacts/metacontacts.h index 2dcc6497f6..bba360fdd5 100644 --- a/src/modules/metacontacts/metacontacts.h +++ b/src/modules/metacontacts/metacontacts.h @@ -69,7 +69,7 @@ MCONTACT Meta_GetContactHandle(DBCachedContact *cc, int contact_number);  DBCachedContact* CheckMeta(MCONTACT hMeta);
  // function to copy history from one contact to another - courtesy JdGordon with mods (thx)
 -void Meta_FixStatus(DBCachedContact *cc);
 +void Meta_FixStatus(DBCachedContact *ccMeta);
  char *Meta_GetUniqueIdentifier(MCONTACT hContact, DWORD *pused);
 | 
