From f04d64869f3b1de54fb343f28f955584780001b8 Mon Sep 17 00:00:00 2001 From: mataes2007 Date: Sat, 26 Nov 2011 15:41:10 +0000 Subject: Project folders rename part 3 git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@215 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- UserInfoEx/ex_import/classExImContactBase.cpp | 581 ++++++++++++++++++++++++++ 1 file changed, 581 insertions(+) create mode 100644 UserInfoEx/ex_import/classExImContactBase.cpp (limited to 'UserInfoEx/ex_import/classExImContactBase.cpp') diff --git a/UserInfoEx/ex_import/classExImContactBase.cpp b/UserInfoEx/ex_import/classExImContactBase.cpp new file mode 100644 index 0000000..c0e0bc0 --- /dev/null +++ b/UserInfoEx/ex_import/classExImContactBase.cpp @@ -0,0 +1,581 @@ +/* +UserinfoEx plugin for Miranda IM + +Copyright: +© 2006-2010 DeathAxe, Yasnovidyashii, Merlin, K. Romanov, Kreol + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +=============================================================================== + +File name : $HeadURL: https://userinfoex.googlecode.com/svn/trunk/ex_import/classExImContactBase.cpp $ +Revision : $Revision: 210 $ +Last change on : $Date: 2010-10-02 22:27:36 +0400 (Сб, 02 окт 2010) $ +Last change by : $Author: ing.u.horn $ + +=============================================================================== +*/ +#include "commonheaders.h" +#include "..\svc_contactinfo.h" +#include "classExImContactBase.h" +#include "mir_rfcCodecs.h" + +HANDLE CListFindGroup(LPCSTR pszGroup) +{ + CHAR buf[4]; + BYTE i; + DBVARIANT dbv; + + for (i = 0; i < 255; i++) { + _itoa(i, buf, 10); + if (DB::Setting::GetUString(NULL, "CListGroups", buf, &dbv)) + break; + if (dbv.pszVal && pszGroup && !_stricmp(dbv.pszVal + 1, pszGroup)) { + DB::Variant::Free(&dbv); + return (HANDLE)(INT_PTR)(i+1); + } + DB::Variant::Free(&dbv); + } + return INVALID_HANDLE_VALUE; +} + +/** + * name: CExImContactBase + * class: CExImContactBase + * desc: default constructor + * param: none + * return: nothing + **/ +CExImContactBase::CExImContactBase() +{ + _pszNick = NULL; + _pszDisp = NULL; + _pszGroup = NULL; + _pszProto = NULL; + _pszProtoOld = NULL; + _pszAMPro = NULL; + _pszUIDKey = NULL; + _dbvUIDHash = NULL; + ZeroMemory(&_dbvUID, sizeof(DBVARIANT)); + _hContact = INVALID_HANDLE_VALUE; + _isNewContact = FALSE; +} + +/** + * name: ~CExImContactBase + * class: CExImContactBase + * desc: default denstructor + * param: none + * return: nothing + **/ +CExImContactBase::~CExImContactBase() +{ + MIR_FREE(_pszNick); + MIR_FREE(_pszDisp); + MIR_FREE(_pszGroup); + MIR_FREE(_pszProtoOld); + MIR_FREE(_pszProto); + MIR_FREE(_pszAMPro); + MIR_FREE(_pszUIDKey); + DB::Variant::Free(&_dbvUID); +} + +/** + * name: fromDB + * class: CExImContactBase + * desc: get contact information from database + * param: hContact - handle to contact whose information to read + * return: TRUE if successful or FALSE otherwise + **/ +BOOLEAN CExImContactBase::fromDB(HANDLE hContact) +{ + BOOLEAN ret = FALSE; + BOOLEAN isChatRoom = FALSE; + LPSTR pszProto; + LPCSTR uidSetting; + DBVARIANT dbv; + + _hContact = hContact; + _dbvUIDHash = 0; + MIR_FREE(_pszProtoOld); + MIR_FREE(_pszProto); + MIR_FREE(_pszAMPro); + MIR_FREE(_pszNick); + MIR_FREE(_pszDisp); + MIR_FREE(_pszGroup); + MIR_FREE(_pszUIDKey); + DB::Variant::Free(&_dbvUID); + ZeroMemory(&_dbvUID, sizeof(DBVARIANT)); + + // OWNER + if (!_hContact) return TRUE; + + // Proto + if (!(pszProto = DB::Contact::Proto(_hContact))) return FALSE; + _pszProto = mir_strdup(pszProto); + + // AM_BaseProto + if (!DB::Setting::GetUString(NULL, pszProto, "AM_BaseProto", &dbv )) { + _pszAMPro = mir_strdup(dbv.pszVal); + DB::Variant::Free(&dbv); + } + + // unique id (for ChatRoom) + if (isChatRoom = DB::Setting::GetByte(_hContact, pszProto, "ChatRoom", 0)) { + uidSetting = "ChatRoomID"; + _pszUIDKey = mir_strdup(uidSetting); + if (!DB::Setting::GetAsIs(_hContact, pszProto, uidSetting, &_dbvUID)) { + ret = TRUE; + } + } + // unique id (normal) + else { + uidSetting = (LPCSTR)CallProtoService(pszProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); + // valid + if (uidSetting != NULL && (INT_PTR)uidSetting != CALLSERVICE_NOTFOUND) { + _pszUIDKey = mir_strdup(uidSetting); + if (!DB::Setting::GetAsIs(_hContact, pszProto, uidSetting, &_dbvUID)) { + ret = TRUE; + } + } + // fails because the protocol is no longer installed + else { + // assert(ret == TRUE); + ret = TRUE; + } + } + + // nickname + if (!DB::Setting::GetUString(_hContact, pszProto, SET_CONTACT_NICK, &dbv)) { + _pszNick = mir_strdup(dbv.pszVal); + DB::Variant::Free(&dbv); + } + + if (_hContact && ret) { + // Clist Group + if (!DB::Setting::GetUString(_hContact, MOD_CLIST, "Group", &dbv)) { + _pszGroup = mir_strdup(dbv.pszVal); + DB::Variant::Free(&dbv); + } + // Clist DisplayName + if (!DB::Setting::GetUString(_hContact, MOD_CLIST, SET_CONTACT_MYHANDLE, &dbv)) { + _pszDisp = mir_strdup(dbv.pszVal); + DB::Variant::Free(&dbv); + } + } + return ret; +} + +/** + * name: fromIni + * class: CExImContactBase + * desc: get contact information from a row of a ini file + * param: row - the rows data + * return: TRUE if successful or FALSE otherwise + **/ +BOOLEAN CExImContactBase::fromIni(LPSTR& row) +{ + LPSTR p1, p2 = NULL; + LPSTR pszUIDValue, pszUIDSetting, pszProto = NULL; + LPSTR pszBuf = &row[0]; + size_t cchBuf = strlen(row); + + MIR_FREE(_pszProtoOld); + MIR_FREE(_pszProto); + MIR_FREE(_pszAMPro); + MIR_FREE(_pszNick); + MIR_FREE(_pszDisp); + MIR_FREE(_pszGroup); + MIR_FREE(_pszUIDKey); + DB::Variant::Free(&_dbvUID); + ZeroMemory(&_dbvUID, sizeof(DBVARIANT)); + _dbvUIDHash = 0; + + // read uid value + if (cchBuf > 10 && (p1 = mir_strrchr(pszBuf, '*{')) && (p2 = mir_strchr(p1, '}*')) && p1 + 2 < p2) { + pszUIDValue = p1 + 1; + *p1 = *(p2 - 1) = 0; + + // insulate the uid setting from buffer pointer + if (cchBuf > 0 && (p1 = mir_strrchr(pszBuf, '*<')) && (p2 = mir_strchr(p1, '>*')) && p1 + 2 < p2) { + pszUIDSetting = p1 + 1; + *p1 = *(p2 - 1) = 0; + + // insulate the protocol name from buffer pointer + if (cchBuf > 0 && (p1 = mir_strrchr(pszBuf, '*(')) && (p2 = mir_strchr(p1, ')*')) && p1 + 2 < p2) { + pszProto = p1 + 1; + *(--p1) = *(p2 - 1) = 0; + + // DBVT_DWORD + if (strspn(pszUIDValue, "0123456789") == mir_strlen(pszUIDValue)) { + _dbvUID.dVal = _atoi64(pszUIDValue); + _dbvUID.type = DBVT_DWORD; + } + else { + // DBVT_UTF8 + _dbvUID.pszVal = mir_strdup(pszUIDValue); + _dbvUID.type = DBVT_UTF8; + } + _pszUIDKey = mir_strdup(pszUIDSetting); + _pszProto = mir_strdup(pszProto); + } //end insulate the protocol name from buffer pointer + } //end insulate the uid setting from buffer pointer + } //end read uid value + + // create valid nickname + _pszNick = mir_strdup(pszBuf); + size_t i = strlen(_pszNick)-1; + while (i > 0 && (_pszNick[i] == ' ' || _pszNick[i] == '\t')) { + _pszNick[i] = 0; + i--; + } + // finally try to find contact in contact list + findHandle(); + return FALSE; +} + +/** + * name: toDB + * class: CExImContactBase + * desc: searches the database for a contact representing the one + * identified by this class or creates a new one if it was not found + * param: hMetaContact - a meta contact to add this contact to + * return: handle of the contact if successful + **/ +HANDLE CExImContactBase::toDB() +{ + DBCONTACTWRITESETTING cws; + + // create new contact if none exists + if (_hContact == INVALID_HANDLE_VALUE && _pszProto && _pszUIDKey && _dbvUID.type != DBVT_DELETED) { + PROTOACCOUNT* pszAccount = 0; + if(NULL == (pszAccount = ProtoGetAccount( _pszProto ))) { + //account does not exist + _hContact = INVALID_HANDLE_VALUE; + return INVALID_HANDLE_VALUE; + } + if(!IsAccountEnabled(pszAccount)) { + ; + } + // create new contact + _hContact = DB::Contact::Add(); + if (!_hContact) { + _hContact = INVALID_HANDLE_VALUE; + return INVALID_HANDLE_VALUE; + } + // Add the protocol to the new contact + if (CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)_hContact, (LPARAM)_pszProto)) { + DB::Contact::Delete(_hContact); + _hContact = INVALID_HANDLE_VALUE; + return INVALID_HANDLE_VALUE; + } + // write uid to protocol module + cws.szModule = _pszProto; + cws.szSetting = _pszUIDKey; + cws.value = _dbvUID; + if (CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)_hContact, (LPARAM)&cws)) { + DB::Contact::Delete(_hContact); + _hContact = INVALID_HANDLE_VALUE; + return INVALID_HANDLE_VALUE; + } + // write nick and display name + if (_pszNick) DB::Setting::WriteUString(_hContact, _pszProto, SET_CONTACT_NICK, _pszNick); + if (_pszDisp) DB::Setting::WriteUString(_hContact, MOD_CLIST, SET_CONTACT_MYHANDLE, _pszDisp); + + // add group + if (_pszGroup) { + DB::Setting::WriteUString(_hContact, MOD_CLIST, "Group", _pszGroup); + if (CListFindGroup(_pszGroup) == INVALID_HANDLE_VALUE) { + WPARAM hGroup = (WPARAM)CallService(MS_CLIST_GROUPCREATE, 0, 0); + if (hGroup) { + // renaming twice is stupid but the only way to avoid error dialog telling shit like + // a group with that name does exist + CallService(MS_CLIST_GROUPRENAME, (WPARAM)hGroup, (LPARAM)_pszGroup); + } + } + } + } + return _hContact; +} + +/** + * name: toIni + * class: CExImContactBase + * desc: writes the line to an opened ini file which identifies the contact + * whose information are stored in this class + * param: file - pointer to the opened file + * return: nothing + **/ +VOID CExImContactBase::toIni(FILE* file, int modCount) +{ + // getting dbeditor++ NickFromHContact(hContact) + static char name[512] = ""; + char* ret = 0; + + if (_hContact){ + int loaded = _pszUIDKey ? 1 : 0; + if (_pszProto == NULL || !loaded) { + if (_pszProto){ + if (_pszNick) + mir_snprintf(name, sizeof(name),"%s (%s)", _pszNick, _pszProto); + else + mir_snprintf(name, sizeof(name),"(UNKNOWN) (%s)", _pszProto); + } + else + mir_snprintf(name, sizeof(name),"(UNKNOWN)"); + } + else { + // Proto loadet - GetContactName(hContact,pszProto,0) + LPSTR pszCI = NULL; + CONTACTINFO ci; + ZeroMemory(&ci, sizeof(ci)); + + ci.cbSize = sizeof(ci); + ci.hContact = _hContact; + ci.szProto = _pszProto; + ci.dwFlag = CNF_DISPLAY; + + if (!GetContactInfo(NULL, (LPARAM) &ci)){ + // CNF_DISPLAY always returns a string type + pszCI = (LPSTR)ci.pszVal; + } + LPSTR pszUID = uid2String(FALSE); + if (_pszUIDKey && pszUID) + mir_snprintf(name, sizeof(name), "%s *(%s)*<%s>*{%s}*", pszCI, _pszProto, _pszUIDKey, pszUID); + else + mir_snprintf(name, sizeof(name), "%s (%s)", pszCI, _pszProto); + + mir_free(pszCI); + mir_free(pszUID); + } // end else (Proto loadet) + + // it is not the best solution (but still works if only basic modules export) - need rework + if (modCount > 3) + fprintf(file, "CONTACT: %s\n", name); + else + fprintf(file, "FROM CONTACT: %s\n", name); + + } // end *if (_hContact) + else { + fprintf(file, "SETTINGS:\n"); + } +} + +BOOLEAN CExImContactBase::compareUID(DBVARIANT *dbv) +{ + DWORD hash = 0; + switch (dbv->type) { + case DBVT_BYTE: + if (dbv->bVal == _dbvUID.bVal) { + _dbvUID.type = dbv->type; + return TRUE; + } + break; + case DBVT_WORD: + if (dbv->wVal == _dbvUID.wVal) { + _dbvUID.type = dbv->type; + return TRUE; + } + break; + case DBVT_DWORD: + if (dbv->dVal == _dbvUID.dVal) { + _dbvUID.type = dbv->type; + return TRUE; + } + break; + case DBVT_ASCIIZ: + hash = hashSetting_M2(dbv->pszVal); + case DBVT_WCHAR: + if(!hash) hash = hashSettingW_M2((const char *)dbv->pwszVal); + case DBVT_UTF8: + if(!hash) { + LPWSTR tmp = mir_utf8decodeW(dbv->pszVal); + hash = hashSettingW_M2((const char *)tmp); + mir_free(tmp); + } + if(hash == _dbvUIDHash) return TRUE; + break; + case DBVT_BLOB: //'n' cpbVal and pbVal are valid + if (_dbvUID.type == dbv->type && + _dbvUID.cpbVal == dbv->cpbVal && + memcmp(_dbvUID.pbVal, dbv->pbVal, dbv->cpbVal) == 0) { + return TRUE; + } + break; + default: + return FALSE; + } + return FALSE; +} + +LPSTR CExImContactBase::uid2String(BOOLEAN bPrependType) +{ + CHAR szUID[MAX_PATH]; + LPSTR ptr = szUID; + + switch (_dbvUID.type) { + case DBVT_BYTE: //'b' bVal and cVal are valid + if (bPrependType) *ptr++ = 'b'; + _itoa(_dbvUID.bVal, ptr, 10); + break; + case DBVT_WORD: //'w' wVal and sVal are valid + if (bPrependType) *ptr++ = 'w'; + _itoa(_dbvUID.wVal, ptr, 10); + break; + case DBVT_DWORD: //'d' dVal and lVal are valid + if (bPrependType) *ptr++ = 'd'; + _itoa(_dbvUID.dVal, ptr, 10); + break; + case DBVT_WCHAR: //'u' pwszVal is valid + { + LPSTR r = mir_utf8encodeW(_dbvUID.pwszVal); + if (bPrependType) { + LPSTR t = (LPSTR)mir_alloc(strlen(r)+2); + t[0] = 'u'; + strcpy(t+1, r); + mir_free(r); + r = t; + } + return r; + } + case DBVT_UTF8: //'u' pszVal is valid + { + if (bPrependType) *ptr++ = 'u'; + mir_strncpy(ptr, _dbvUID.pszVal, SIZEOF(szUID)-1); + } + break; + case DBVT_ASCIIZ: { + LPSTR r = mir_utf8encode(_dbvUID.pszVal); + if (bPrependType) { + LPSTR t = (LPSTR)mir_alloc(strlen(r)+2); + t[0] = 's'; + strcpy(t+1, r); + mir_free(r); + r = t; + } + return r; + } + case DBVT_BLOB: //'n' cpbVal and pbVal are valid + { + if (bPrependType) { //True = XML + INT_PTR baselen = Base64EncodeGetRequiredLength(_dbvUID.cpbVal, BASE64_FLAG_NOCRLF); + LPSTR t = (LPSTR)mir_alloc(baselen + 5 + bPrependType); + assert(t != NULL); + if (Base64Encode(_dbvUID.pbVal, _dbvUID.cpbVal, t + bPrependType, &baselen, BASE64_FLAG_NOCRLF)){ + if (baselen){ + t[baselen + bPrependType] = 0; + if (bPrependType) t[0] = 'n'; + return t; + } + } + mir_free(t); + return NULL; + } + else { //FALSE = INI + WORD j; + INT_PTR baselen = (_dbvUID.cpbVal * 3); + LPSTR t = (LPSTR)mir_alloc(3 + baselen); + ZeroMemory(t, (3 + baselen)); + for (j = 0; j < _dbvUID.cpbVal; j++) { + mir_snprintf((t + bPrependType + (j * 3)), 4,"%02X ", (BYTE)_dbvUID.pbVal[j]); + } + if (t){ + if (bPrependType) t[0] = 'n'; + return t; + } + else { + mir_free(t); + return NULL; + } + } + break; + } + default: + return NULL; + } + return mir_strdup(szUID); +} + +BOOLEAN CExImContactBase::isMeta() const +{ + return DB::Module::IsMeta(_pszProto); +} + +BOOLEAN CExImContactBase::isHandle(HANDLE hContact) +{ + LPCSTR pszProto; + DBVARIANT dbv; + BOOLEAN isEqual = FALSE; + + // owner contact ? + if (!_pszProto) return hContact == NULL; + + // compare protocols + pszProto = DB::Contact::Proto(hContact); + if (pszProto == NULL || (INT_PTR)pszProto == CALLSERVICE_NOTFOUND || mir_stricmp(pszProto, _pszProto)) + return FALSE; + + // compare uids + if (_pszUIDKey) { + // get uid + if (DB::Setting::GetAsIs(hContact, pszProto,_pszUIDKey, &dbv)) + return FALSE; + + isEqual = compareUID (&dbv); + DB::Variant::Free(&dbv); + } + // compare nicknames if no UID + else if (!DB::Setting::GetUString(hContact, _pszProto, SET_CONTACT_NICK, &dbv)) { + if (dbv.type == DBVT_UTF8 && dbv.pszVal && !mir_stricmp(dbv.pszVal,_pszNick)) { + LPTSTR ptszNick = mir_utf8decodeT(_pszNick); + LPTSTR ptszProto = mir_a2t(_pszProto); + INT ans = MsgBox(NULL, MB_ICONQUESTION|MB_YESNO, LPGENT("Question"), LPGENT("contact identificaion"), + LPGENT("The contact %s(%s) has no unique id in the vCard,\nbut there is a contact in your clist with the same nick and protocol.\nDo you wish to use this contact?"), + ptszNick, ptszProto); + MIR_FREE(ptszNick); + MIR_FREE(ptszProto); + isEqual = ans == IDYES; + } + DB::Variant::Free(&dbv); + } + return isEqual; +} + +/** + * name: handle + * class: CExImContactBase + * desc: return the handle of the contact + * whose information are stored in this class + * param: none + * return: handle if successful, INVALID_HANDLE_VALUE otherwise + **/ +HANDLE CExImContactBase::findHandle() +{ + HANDLE hContact; + + for (hContact = DB::Contact::FindFirst(); + hContact != NULL; + hContact = DB::Contact::FindNext(hContact)) + { + if (isHandle(hContact)) { + _hContact = hContact; + _isNewContact = FALSE; + return hContact; + } + } + _isNewContact = TRUE; + _hContact = INVALID_HANDLE_VALUE; + return INVALID_HANDLE_VALUE; +} -- cgit v1.2.3