From fe7d09b9df2514c587376b924379ae1ccb1ff7a6 Mon Sep 17 00:00:00 2001 From: Rozhuk Ivan Date: Thu, 27 Nov 2014 18:39:28 +0000 Subject: Tlen: code cleanup git-svn-id: http://svn.miranda-ng.org/main/trunk@11119 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Tlen/src/tlen_avatar.cpp | 881 +++++++++++------------ protocols/Tlen/src/tlen_opt.cpp | 1343 ++++++++++++++++++------------------ protocols/Tlen/src/tlen_xml.cpp | 1141 +++++++++++++++--------------- 3 files changed, 1691 insertions(+), 1674 deletions(-) (limited to 'protocols/Tlen/src') diff --git a/protocols/Tlen/src/tlen_avatar.cpp b/protocols/Tlen/src/tlen_avatar.cpp index e6b1673ce0..6d468591bf 100644 --- a/protocols/Tlen/src/tlen_avatar.cpp +++ b/protocols/Tlen/src/tlen_avatar.cpp @@ -1,440 +1,441 @@ -/* - -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2004-2007 Piotr Piastucki - -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. - -*/ - - -#include "tlen.h" -#include "tlen_list.h" -#include "tlen_avatar.h" -#include -#include -#include -#include -#include - -/* TlenGetAvatarFileName() - gets a file name for the avatar image */ - -void TlenGetAvatarFileName(TlenProtocol *proto, TLEN_LIST_ITEM *item, TCHAR* ptszDest, int cbLen) -{ - - int tPathLen = mir_sntprintf(ptszDest, cbLen, TEXT("%s\\%S"), VARST( TEXT("%miranda_avatarcache%")), proto->m_szModuleName); - if (_taccess(ptszDest, 0)) { - int ret = CreateDirectoryTreeT(ptszDest); - if (ret == 0) - proto->debugLog(_T("getAvatarFilename(): Created new directory for avatar cache: %s."), ptszDest); - else { - proto->debugLog(_T("getAvatarFilename(): Can not create directory for avatar cache: %s. errno=%d: %s"), ptszDest, errno, strerror(errno)); - TCHAR buffer[512]; - mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("Cannot create avatars cache directory. ERROR: %d: %s\n%s"), errno, _tcserror(errno), ptszDest); - PUShowMessageT(buffer, SM_WARNING); - } - } - - int format = PA_FORMAT_PNG; - - ptszDest[ tPathLen++ ] = '\\'; - if (item != NULL) - format = item->avatarFormat; - else if (proto->threadData != NULL) - format = proto->threadData->avatarFormat; - else - format = db_get_dw(NULL, proto->m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); - - const TCHAR *tszFileType = ProtoGetAvatarExtension(format); - if ( item != NULL ) - mir_sntprintf(ptszDest + tPathLen, MAX_PATH - tPathLen, TEXT("%S%s"), ptrA( TlenSha1(item->jid)), tszFileType); - else - mir_sntprintf(ptszDest + tPathLen, MAX_PATH - tPathLen, TEXT("%S_avatar%s"), proto->m_szModuleName, tszFileType); -} - -static void RemoveAvatar(TlenProtocol *proto, MCONTACT hContact) { - TCHAR tFileName[ MAX_PATH ]; - if (hContact == NULL) { - proto->threadData->avatarHash[0] = '\0'; - } - TlenGetAvatarFileName( proto, NULL, tFileName, sizeof tFileName ); - DeleteFile(tFileName); - db_unset(hContact, "ContactPhoto", "File"); - db_unset(hContact, proto->m_szModuleName, "AvatarHash"); - db_unset(hContact, proto->m_szModuleName, "AvatarFormat"); - ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL, 0); -} - -static void SetAvatar(TlenProtocol *proto, MCONTACT hContact, TLEN_LIST_ITEM *item, char *data, int len, DWORD format) { - TCHAR filename[MAX_PATH]; - char md5[33]; - mir_md5_state_t ctx; - DWORD digest[4]; - - if (format == PA_FORMAT_UNKNOWN && len > 4) - format = ProtoGetBufferFormat(data); - - mir_md5_init( &ctx ); - mir_md5_append( &ctx, ( BYTE* )data, len); - mir_md5_finish( &ctx, ( BYTE* )digest ); - - sprintf( md5, "%08x%08x%08x%08x", (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3])); //!!!!!!!!!!!!!! - if (item != NULL) { - char *hash = item->avatarHash; - item->avatarFormat = format; - item->avatarHash = mir_strdup(md5); - mir_free(hash); - } else { - proto->threadData->avatarFormat = format; - strcpy(proto->threadData->avatarHash, md5); - } - TlenGetAvatarFileName(proto, item, filename, sizeof filename ); - DeleteFile(filename); - FILE *out = _tfopen(filename, TEXT("wb") ); - if (out != NULL) { - fwrite(data, len, 1, out); - fclose(out); - db_set_ts(hContact, "ContactPhoto", "File", filename ); - db_set_s(hContact, proto->m_szModuleName, "AvatarHash", md5); - db_set_dw(hContact, proto->m_szModuleName, "AvatarFormat", format); - } else { - TCHAR buffer[128]; - mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("Cannot save new avatar file \"%s\" Error:\n\t%s (Error: %d)"), filename, _tcserror(errno), errno); - PUShowMessageT(buffer, SM_WARNING); - proto->debugLog(buffer); - return; - } - ProtoBroadcastAck( proto->m_szModuleName, hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL , 0); -} - -int TlenProcessAvatarNode(TlenProtocol *proto, XmlNode *avatarNode, TLEN_LIST_ITEM *item) { - XmlNode *aNode; - char *oldHash = NULL; - char *md5 = NULL, *type = NULL; - MCONTACT hContact; - hContact = NULL; - if (item != NULL) { - if ((hContact=TlenHContactFromJID(proto, item->jid)) == NULL) return 0; - } - if (item == NULL) { - oldHash = proto->threadData->avatarHash; - } else { - oldHash = item->avatarHash; - } - if (avatarNode != NULL) { - aNode = TlenXmlGetChild(avatarNode, "a"); - if (aNode != NULL) { - type = TlenXmlGetAttrValue(aNode, "type"); - md5 = TlenXmlGetAttrValue(aNode, "md5"); - } - } - if (md5 != NULL) { - /* check contact's avatar hash - md5 */ - if (oldHash == NULL || strcmp(oldHash, md5)) { - if (item != NULL) { - item->newAvatarDownloading = TRUE; - } - TlenGetAvatar(proto, hContact); - return 1; - } - } else { - /* remove avatar */ - if (oldHash != NULL) { - if (item != NULL) { - item->avatarHash = NULL; - mir_free(oldHash); - item->newAvatarDownloading = FALSE; - } - RemoveAvatar(proto, hContact); - return 1; - } - } - return 0; -} - -void TlenProcessPresenceAvatar(TlenProtocol *proto, XmlNode *node, TLEN_LIST_ITEM *item) { - MCONTACT hContact; - if ((hContact=TlenHContactFromJID(proto, item->jid)) == NULL) return; - TlenProcessAvatarNode(proto, TlenXmlGetChild(node, "avatar"), item); -} - - -static char *replaceTokens(const char *base, const char *uri, const char *login, const char* token, int type, int access) { - char *result; - int i, l, size; - l = (int)strlen(uri); - size = (int)strlen(base); - for (i = 0; i < l; ) { - if (!strncmp(uri + i, "^login^", 7)) { - size += (int)strlen(login); - i += 7; - } else if (!strncmp(uri + i, "^type^", 6)) { - size++; - i += 6; - } else if (!strncmp(uri + i, "^token^", 7)) { - size += (int)strlen(token); - i += 7; - } else if (!strncmp(uri + i, "^access^", 8)) { - size++; - i += 8; - } else { - size++; - i++; - } - } - result = (char *)mir_alloc(size +1); - strcpy(result, base); - size = (int)strlen(base); - for (i = 0; i < l; ) { - if (!strncmp(uri + i, "^login^", 7)) { - strcpy(result + size, login); - size += (int)strlen(login); - i += 7; - } else if (!strncmp(uri + i, "^type^", 6)) { - result[size++] = '0' + type; - i += 6; - } else if (!strncmp(uri + i, "^token^", 7)) { - strcpy(result + size, token); - size += (int)strlen(token); - i += 7; - } else if (!strncmp(uri + i, "^access^", 8)) { - result[size++] = '0' + access; - i += 8; - } else { - result[size++] = uri[i++]; - } - } - result[size] = '\0'; - return result; -} - - -static int getAvatarMutex = 0; - -typedef struct { - TlenProtocol *proto; - MCONTACT hContact; -} TLENGETAVATARTHREADDATA; - -static void TlenGetAvatarThread(void *ptr) { - - TLEN_LIST_ITEM *item = NULL; - NETLIBHTTPREQUEST req; - NETLIBHTTPREQUEST *resp; - TLENGETAVATARTHREADDATA *data = (TLENGETAVATARTHREADDATA *)ptr; - MCONTACT hContact = data->hContact; - char *request; - char *login = NULL; - if (hContact != NULL) { - char *jid = TlenJIDFromHContact(data->proto, hContact); - login = TlenNickFromJID(jid); - item = TlenListGetItemPtr(data->proto, LIST_ROSTER, jid); - mir_free(jid); - } else { - login = mir_strdup(data->proto->threadData->username); - } - if ((data->proto->threadData != NULL && hContact == NULL) || item != NULL) { - DWORD format = PA_FORMAT_UNKNOWN; - if (item != NULL) { - item->newAvatarDownloading = TRUE; - } - request = replaceTokens(data->proto->threadData->tlenConfig.mailBase, data->proto->threadData->tlenConfig.avatarGet, login, data->proto->threadData->avatarToken, 0, 0); - ZeroMemory(&req, sizeof(req)); - req.cbSize = sizeof(req); - req.requestType = data->proto->threadData->tlenConfig.avatarGetMthd; - req.flags = 0; - req.headersCount = 0; - req.headers = NULL; - req.dataLength = 0; - req.szUrl = request; - resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->m_hNetlibUser, (LPARAM)&req); - if (item != NULL) { - item->newAvatarDownloading = FALSE; - } - if (resp != NULL) { - if (resp->resultCode/100 == 2) { - if (resp->dataLength > 0) { - int i; - for (i=0; iheadersCount; i++ ) { - if (!strcmpi(resp->headers[i].szName, "Content-Type")) { - if (!strcmpi(resp->headers[i].szValue, "image/png")) - format = PA_FORMAT_PNG; - else if (!strcmpi(resp->headers[i].szValue, "image/x-png")) - format = PA_FORMAT_PNG; - else if (!strcmpi(resp->headers[i].szValue, "image/jpeg")) - format = PA_FORMAT_JPEG; - else if (!strcmpi(resp->headers[i].szValue, "image/jpg")) - format = PA_FORMAT_JPEG; - else if (!strcmpi(resp->headers[i].szValue, "image/gif")) - format = PA_FORMAT_GIF; - else if (!strcmpi(resp->headers[i].szValue, "image/bmp")) - format = PA_FORMAT_BMP; - - break; - } - } - SetAvatar(data->proto, hContact, item, resp->pData, resp->dataLength, format); - } else { - RemoveAvatar(data->proto, hContact); - } - } - CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); - } - mir_free(request); - mir_free(login); - } - if (hContact == NULL) { - getAvatarMutex = 0; - } - mir_free(data); -} - -void TlenGetAvatar(TlenProtocol *proto, MCONTACT hContact) { - if (hContact == NULL) { - if (getAvatarMutex != 0) { - return; - } - getAvatarMutex = 1; - } - { - TLENGETAVATARTHREADDATA *data = (TLENGETAVATARTHREADDATA *)mir_alloc(sizeof(TLENGETAVATARTHREADDATA)); - data->proto = proto; - data->hContact = hContact; - forkthread(TlenGetAvatarThread, 0, data); - } -} - -typedef struct { - TlenProtocol *proto; - NETLIBHTTPREQUEST *req; -} TLENREMOVEAVATARTHREADDATA; - -static void TlenRemoveAvatarRequestThread(void *ptr) { - NETLIBHTTPREQUEST *resp; - TLENREMOVEAVATARTHREADDATA *data = (TLENREMOVEAVATARTHREADDATA*)ptr; - NETLIBHTTPREQUEST *req = (NETLIBHTTPREQUEST *)data->req; - resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->m_hNetlibUser, (LPARAM)req); - mir_free(req->szUrl); - mir_free(req->headers); - mir_free(req->pData); - mir_free(req); - if (resp != NULL) { - CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); - RemoveAvatar(data->proto, NULL); - } - mir_free(data); - -} - -typedef struct { - TlenProtocol *proto; - NETLIBHTTPREQUEST *req; - char *data; - int length; -} TLENUPLOADAVATARTHREADDATA; - -boolean checkUploadAvatarResponse(TlenProtocol *proto, NETLIBHTTPREQUEST *resp){ - if (resp == NULL){ - proto->debugLogA("Error while setting avatar on Tlen account (no response)"); - PUShowMessageT(TranslateT("Error while setting avatar on Tlen account (no response)"), SM_WARNING); - return false; - } - if (resp->resultCode != 200 || !resp->dataLength || !resp->pData) { - proto->debugLogA("Error while setting avatar on Tlen account (invalid response) resultCode=%d, dataLength=%d", resp->resultCode, resp->dataLength); - PUShowMessageT(TranslateT("Error while setting avatar on Tlen account (invalid response)"), SM_WARNING); - return false; - } - if (strncmp(resp->pData, "debugLogA("Error while setting avatar on Tlen account: %s", resp->pData); - PUShowMessageT(TranslateT("Error while setting avatar on Tlen account"), SM_WARNING); - return false; - } - return true; -} - -static void TlenUploadAvatarRequestThread(void *ptr) { - NETLIBHTTPREQUEST *resp; - TLENUPLOADAVATARTHREADDATA * data = (TLENUPLOADAVATARTHREADDATA *) ptr; - NETLIBHTTPREQUEST *req = data->req; - resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->m_hNetlibUser, (LPARAM)req); - if (checkUploadAvatarResponse(data->proto, resp)) { - CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); - SetAvatar(data->proto, NULL, NULL, data->data, data->length, PA_FORMAT_PNG); - } - mir_free(req->szUrl); - mir_free(req->headers); - mir_free(req->pData); - mir_free(req); - mir_free(data->data); - mir_free(data); -} - -void TlenRemoveAvatar(TlenProtocol *proto) { - NETLIBHTTPREQUEST *req; - char *request; - if (proto->threadData != NULL) { - TLENREMOVEAVATARTHREADDATA *data = (TLENREMOVEAVATARTHREADDATA *)mir_alloc(sizeof(TLENREMOVEAVATARTHREADDATA)); - req = (NETLIBHTTPREQUEST *)mir_alloc(sizeof(NETLIBHTTPREQUEST)); - data->proto =proto; - data->req = req; - request = replaceTokens(proto->threadData->tlenConfig.mailBase, proto->threadData->tlenConfig.avatarRemove, "", proto->threadData->avatarToken, 0, 0); - ZeroMemory(req, sizeof(NETLIBHTTPREQUEST)); - req->cbSize = sizeof(NETLIBHTTPREQUEST); - req->requestType = proto->threadData->tlenConfig.avatarGetMthd; - req->szUrl = request; - forkthread(TlenRemoveAvatarRequestThread, 0, data); - } -} - - -void TlenUploadAvatar(TlenProtocol *proto, unsigned char *data, int dataLen, int access) { - NETLIBHTTPREQUEST *req; - NETLIBHTTPHEADER *headers; - TLENUPLOADAVATARTHREADDATA *threadData; - char *request; - unsigned char *buffer; - if (proto->threadData != NULL && dataLen > 0 && data != NULL) { - char *mpartHead = "--AaB03x\r\nContent-Disposition: form-data; name=\"filename\"; filename=\"plik.png\"\r\nContent-Type: image/png\r\n\r\n"; - char *mpartTail = "\r\n--AaB03x--\r\n"; - int size, sizeHead = (int)strlen(mpartHead), sizeTail = (int)strlen(mpartTail); - request = replaceTokens(proto->threadData->tlenConfig.mailBase, proto->threadData->tlenConfig.avatarUpload, "", proto->threadData->avatarToken, 0, access); - threadData = (TLENUPLOADAVATARTHREADDATA *)mir_alloc(sizeof(TLENUPLOADAVATARTHREADDATA)); - threadData->proto = proto; - req = (NETLIBHTTPREQUEST *)mir_alloc(sizeof(NETLIBHTTPREQUEST)); - headers = (NETLIBHTTPHEADER *)mir_alloc(sizeof(NETLIBHTTPHEADER)); - ZeroMemory(req, sizeof(NETLIBHTTPREQUEST)); - req->cbSize = sizeof(NETLIBHTTPREQUEST); - req->requestType = proto->threadData->tlenConfig.avatarUploadMthd; - req->szUrl = request; - req->flags = 0; - headers[0].szName = "Content-Type"; - headers[0].szValue = "multipart/form-data; boundary=AaB03x"; - req->headersCount = 1; - req->headers = headers; - size = dataLen + sizeHead + sizeTail; - buffer = (unsigned char *)mir_alloc(size); - memcpy(buffer, mpartHead, sizeHead); - memcpy(buffer + sizeHead, data, dataLen); - memcpy(buffer + sizeHead + dataLen, mpartTail, sizeTail); - req->dataLength = size; - req->pData = (char*)buffer; - threadData->req = req; - threadData->data = (char *) mir_alloc(dataLen); - memcpy(threadData->data, data, dataLen); - threadData->length = dataLen; - forkthread(TlenUploadAvatarRequestThread, 0, threadData); - } -} - +/* + +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2004-2007 Piotr Piastucki + +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. + +*/ + + +#include "tlen.h" +#include "tlen_list.h" +#include "tlen_avatar.h" +#include +#include +#include +#include +#include + +/* TlenGetAvatarFileName() - gets a file name for the avatar image */ + +void TlenGetAvatarFileName(TlenProtocol *proto, TLEN_LIST_ITEM *item, TCHAR* ptszDest, int cbLen) +{ + + int tPathLen = mir_sntprintf(ptszDest, cbLen, TEXT("%s\\%S"), VARST( TEXT("%miranda_avatarcache%")), proto->m_szModuleName); + if (_taccess(ptszDest, 0)) { + int ret = CreateDirectoryTreeT(ptszDest); + if (ret == 0) + proto->debugLog(_T("getAvatarFilename(): Created new directory for avatar cache: %s."), ptszDest); + else { + proto->debugLog(_T("getAvatarFilename(): Can not create directory for avatar cache: %s. errno=%d: %s"), ptszDest, errno, strerror(errno)); + TCHAR buffer[512]; + mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("Cannot create avatars cache directory. ERROR: %d: %s\n%s"), errno, _tcserror(errno), ptszDest); + PUShowMessageT(buffer, SM_WARNING); + } + } + + int format = PA_FORMAT_PNG; + + ptszDest[ tPathLen++ ] = '\\'; + if (item != NULL) + format = item->avatarFormat; + else if (proto->threadData != NULL) + format = proto->threadData->avatarFormat; + else + format = db_get_dw(NULL, proto->m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); + + const TCHAR *tszFileType = ProtoGetAvatarExtension(format); + if ( item != NULL ) + mir_sntprintf(ptszDest + tPathLen, MAX_PATH - tPathLen, TEXT("%S%s"), ptrA( TlenSha1(item->jid)), tszFileType); + else + mir_sntprintf(ptszDest + tPathLen, MAX_PATH - tPathLen, TEXT("%S_avatar%s"), proto->m_szModuleName, tszFileType); +} + +static void RemoveAvatar(TlenProtocol *proto, MCONTACT hContact) { + TCHAR tFileName[ MAX_PATH ]; + if (hContact == NULL) { + proto->threadData->avatarHash[0] = '\0'; + } + TlenGetAvatarFileName( proto, NULL, tFileName, sizeof tFileName ); + DeleteFile(tFileName); + db_unset(hContact, "ContactPhoto", "File"); + db_unset(hContact, proto->m_szModuleName, "AvatarHash"); + db_unset(hContact, proto->m_szModuleName, "AvatarFormat"); + ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL, 0); +} + +static void SetAvatar(TlenProtocol *proto, MCONTACT hContact, TLEN_LIST_ITEM *item, char *data, int len, DWORD format) { + TCHAR filename[MAX_PATH]; + char md5[33]; + mir_md5_state_t ctx; + DWORD digest[4]; + + if (format == PA_FORMAT_UNKNOWN && len > 4) + format = ProtoGetBufferFormat(data); + + mir_md5_init( &ctx ); + mir_md5_append( &ctx, ( BYTE* )data, len); + mir_md5_finish( &ctx, ( BYTE* )digest ); + + sprintf( md5, "%08x%08x%08x%08x", (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3])); //!!!!!!!!!!!!!! + if (item != NULL) { + char *hash = item->avatarHash; + item->avatarFormat = format; + item->avatarHash = mir_strdup(md5); + mir_free(hash); + } else { + proto->threadData->avatarFormat = format; + strcpy(proto->threadData->avatarHash, md5); + } + TlenGetAvatarFileName(proto, item, filename, sizeof filename ); + DeleteFile(filename); + FILE *out = _tfopen(filename, TEXT("wb") ); + if (out != NULL) { + fwrite(data, len, 1, out); + fclose(out); + db_set_ts(hContact, "ContactPhoto", "File", filename ); + db_set_s(hContact, proto->m_szModuleName, "AvatarHash", md5); + db_set_dw(hContact, proto->m_szModuleName, "AvatarFormat", format); + } else { + TCHAR buffer[128]; + mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("Cannot save new avatar file \"%s\" Error:\n\t%s (Error: %d)"), filename, _tcserror(errno), errno); + PUShowMessageT(buffer, SM_WARNING); + proto->debugLog(buffer); + return; + } + ProtoBroadcastAck( proto->m_szModuleName, hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL , 0); +} + +int TlenProcessAvatarNode(TlenProtocol *proto, XmlNode *avatarNode, TLEN_LIST_ITEM *item) { + XmlNode *aNode; + char *oldHash = NULL; + char *md5 = NULL, *type = NULL; + MCONTACT hContact; + hContact = NULL; + if (item != NULL) { + if ((hContact=TlenHContactFromJID(proto, item->jid)) == NULL) return 0; + } + if (item == NULL) { + oldHash = proto->threadData->avatarHash; + } else { + oldHash = item->avatarHash; + } + if (avatarNode != NULL) { + aNode = TlenXmlGetChild(avatarNode, "a"); + if (aNode != NULL) { + type = TlenXmlGetAttrValue(aNode, "type"); + md5 = TlenXmlGetAttrValue(aNode, "md5"); + } + } + if (md5 != NULL) { + /* check contact's avatar hash - md5 */ + if (oldHash == NULL || strcmp(oldHash, md5)) { + if (item != NULL) { + item->newAvatarDownloading = TRUE; + } + TlenGetAvatar(proto, hContact); + return 1; + } + } else { + /* remove avatar */ + if (oldHash != NULL) { + if (item != NULL) { + item->avatarHash = NULL; + mir_free(oldHash); + item->newAvatarDownloading = FALSE; + } + RemoveAvatar(proto, hContact); + return 1; + } + } + return 0; +} + +void TlenProcessPresenceAvatar(TlenProtocol *proto, XmlNode *node, TLEN_LIST_ITEM *item) { + MCONTACT hContact; + if ((hContact=TlenHContactFromJID(proto, item->jid)) == NULL) return; + TlenProcessAvatarNode(proto, TlenXmlGetChild(node, "avatar"), item); +} + + +static char *replaceTokens(const char *base, const char *uri, const char *login, const char* token, int type, int access) { + char *result; + int i, l, size; + l = (int)strlen(uri); + size = (int)strlen(base); + for (i = 0; i < l; ) { + if (!strncmp(uri + i, "^login^", 7)) { + size += (int)strlen(login); + i += 7; + } else if (!strncmp(uri + i, "^type^", 6)) { + size++; + i += 6; + } else if (!strncmp(uri + i, "^token^", 7)) { + size += (int)strlen(token); + i += 7; + } else if (!strncmp(uri + i, "^access^", 8)) { + size++; + i += 8; + } else { + size++; + i++; + } + } + result = (char *)mir_alloc(size +1); + strcpy(result, base); + size = (int)strlen(base); + for (i = 0; i < l; ) { + if (!strncmp(uri + i, "^login^", 7)) { + strcpy(result + size, login); + size += (int)strlen(login); + i += 7; + } else if (!strncmp(uri + i, "^type^", 6)) { + result[size++] = '0' + type; + i += 6; + } else if (!strncmp(uri + i, "^token^", 7)) { + strcpy(result + size, token); + size += (int)strlen(token); + i += 7; + } else if (!strncmp(uri + i, "^access^", 8)) { + result[size++] = '0' + access; + i += 8; + } else { + result[size++] = uri[i++]; + } + } + result[size] = '\0'; + return result; +} + + +static int getAvatarMutex = 0; + +typedef struct { + TlenProtocol *proto; + MCONTACT hContact; +} TLENGETAVATARTHREADDATA; + +static void TlenGetAvatarThread(void *ptr) { + + TLEN_LIST_ITEM *item = NULL; + NETLIBHTTPREQUEST req; + NETLIBHTTPREQUEST *resp; + TLENGETAVATARTHREADDATA *data = (TLENGETAVATARTHREADDATA *)ptr; + MCONTACT hContact = data->hContact; + char *request; + char *login = NULL; + if (hContact != NULL) { + char *jid = TlenJIDFromHContact(data->proto, hContact); + login = TlenNickFromJID(jid); + item = TlenListGetItemPtr(data->proto, LIST_ROSTER, jid); + mir_free(jid); + } else { + if (data->proto->threadData != NULL) + login = mir_strdup(data->proto->threadData->username); + } + if ((data->proto->threadData != NULL && hContact == NULL) || item != NULL) { + DWORD format = PA_FORMAT_UNKNOWN; + if (item != NULL) { + item->newAvatarDownloading = TRUE; + } + request = replaceTokens(data->proto->threadData->tlenConfig.mailBase, data->proto->threadData->tlenConfig.avatarGet, login, data->proto->threadData->avatarToken, 0, 0); + ZeroMemory(&req, sizeof(req)); + req.cbSize = sizeof(req); + req.requestType = data->proto->threadData->tlenConfig.avatarGetMthd; + req.flags = 0; + req.headersCount = 0; + req.headers = NULL; + req.dataLength = 0; + req.szUrl = request; + resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->m_hNetlibUser, (LPARAM)&req); + if (item != NULL) { + item->newAvatarDownloading = FALSE; + } + if (resp != NULL) { + if (resp->resultCode/100 == 2) { + if (resp->dataLength > 0) { + int i; + for (i=0; iheadersCount; i++ ) { + if (!strcmpi(resp->headers[i].szName, "Content-Type")) { + if (!strcmpi(resp->headers[i].szValue, "image/png")) + format = PA_FORMAT_PNG; + else if (!strcmpi(resp->headers[i].szValue, "image/x-png")) + format = PA_FORMAT_PNG; + else if (!strcmpi(resp->headers[i].szValue, "image/jpeg")) + format = PA_FORMAT_JPEG; + else if (!strcmpi(resp->headers[i].szValue, "image/jpg")) + format = PA_FORMAT_JPEG; + else if (!strcmpi(resp->headers[i].szValue, "image/gif")) + format = PA_FORMAT_GIF; + else if (!strcmpi(resp->headers[i].szValue, "image/bmp")) + format = PA_FORMAT_BMP; + + break; + } + } + SetAvatar(data->proto, hContact, item, resp->pData, resp->dataLength, format); + } else { + RemoveAvatar(data->proto, hContact); + } + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + } + mir_free(request); + mir_free(login); + } + if (hContact == NULL) { + getAvatarMutex = 0; + } + mir_free(data); +} + +void TlenGetAvatar(TlenProtocol *proto, MCONTACT hContact) { + if (hContact == NULL) { + if (getAvatarMutex != 0) { + return; + } + getAvatarMutex = 1; + } + { + TLENGETAVATARTHREADDATA *data = (TLENGETAVATARTHREADDATA *)mir_alloc(sizeof(TLENGETAVATARTHREADDATA)); + data->proto = proto; + data->hContact = hContact; + forkthread(TlenGetAvatarThread, 0, data); + } +} + +typedef struct { + TlenProtocol *proto; + NETLIBHTTPREQUEST *req; +} TLENREMOVEAVATARTHREADDATA; + +static void TlenRemoveAvatarRequestThread(void *ptr) { + NETLIBHTTPREQUEST *resp; + TLENREMOVEAVATARTHREADDATA *data = (TLENREMOVEAVATARTHREADDATA*)ptr; + NETLIBHTTPREQUEST *req = (NETLIBHTTPREQUEST *)data->req; + resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->m_hNetlibUser, (LPARAM)req); + mir_free(req->szUrl); + mir_free(req->headers); + mir_free(req->pData); + mir_free(req); + if (resp != NULL) { + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + RemoveAvatar(data->proto, NULL); + } + mir_free(data); + +} + +typedef struct { + TlenProtocol *proto; + NETLIBHTTPREQUEST *req; + char *data; + int length; +} TLENUPLOADAVATARTHREADDATA; + +boolean checkUploadAvatarResponse(TlenProtocol *proto, NETLIBHTTPREQUEST *resp){ + if (resp == NULL){ + proto->debugLogA("Error while setting avatar on Tlen account (no response)"); + PUShowMessageT(TranslateT("Error while setting avatar on Tlen account (no response)"), SM_WARNING); + return false; + } + if (resp->resultCode != 200 || !resp->dataLength || !resp->pData) { + proto->debugLogA("Error while setting avatar on Tlen account (invalid response) resultCode=%d, dataLength=%d", resp->resultCode, resp->dataLength); + PUShowMessageT(TranslateT("Error while setting avatar on Tlen account (invalid response)"), SM_WARNING); + return false; + } + if (strncmp(resp->pData, "debugLogA("Error while setting avatar on Tlen account: %s", resp->pData); + PUShowMessageT(TranslateT("Error while setting avatar on Tlen account"), SM_WARNING); + return false; + } + return true; +} + +static void TlenUploadAvatarRequestThread(void *ptr) { + NETLIBHTTPREQUEST *resp; + TLENUPLOADAVATARTHREADDATA * data = (TLENUPLOADAVATARTHREADDATA *) ptr; + NETLIBHTTPREQUEST *req = data->req; + resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->m_hNetlibUser, (LPARAM)req); + if (checkUploadAvatarResponse(data->proto, resp)) { + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + SetAvatar(data->proto, NULL, NULL, data->data, data->length, PA_FORMAT_PNG); + } + mir_free(req->szUrl); + mir_free(req->headers); + mir_free(req->pData); + mir_free(req); + mir_free(data->data); + mir_free(data); +} + +void TlenRemoveAvatar(TlenProtocol *proto) { + NETLIBHTTPREQUEST *req; + char *request; + if (proto->threadData != NULL) { + TLENREMOVEAVATARTHREADDATA *data = (TLENREMOVEAVATARTHREADDATA *)mir_alloc(sizeof(TLENREMOVEAVATARTHREADDATA)); + req = (NETLIBHTTPREQUEST *)mir_alloc(sizeof(NETLIBHTTPREQUEST)); + data->proto =proto; + data->req = req; + request = replaceTokens(proto->threadData->tlenConfig.mailBase, proto->threadData->tlenConfig.avatarRemove, "", proto->threadData->avatarToken, 0, 0); + ZeroMemory(req, sizeof(NETLIBHTTPREQUEST)); + req->cbSize = sizeof(NETLIBHTTPREQUEST); + req->requestType = proto->threadData->tlenConfig.avatarGetMthd; + req->szUrl = request; + forkthread(TlenRemoveAvatarRequestThread, 0, data); + } +} + + +void TlenUploadAvatar(TlenProtocol *proto, unsigned char *data, int dataLen, int access) { + NETLIBHTTPREQUEST *req; + NETLIBHTTPHEADER *headers; + TLENUPLOADAVATARTHREADDATA *threadData; + char *request; + unsigned char *buffer; + if (proto->threadData != NULL && dataLen > 0 && data != NULL) { + char *mpartHead = "--AaB03x\r\nContent-Disposition: form-data; name=\"filename\"; filename=\"plik.png\"\r\nContent-Type: image/png\r\n\r\n"; + char *mpartTail = "\r\n--AaB03x--\r\n"; + int size, sizeHead = (int)strlen(mpartHead), sizeTail = (int)strlen(mpartTail); + request = replaceTokens(proto->threadData->tlenConfig.mailBase, proto->threadData->tlenConfig.avatarUpload, "", proto->threadData->avatarToken, 0, access); + threadData = (TLENUPLOADAVATARTHREADDATA *)mir_alloc(sizeof(TLENUPLOADAVATARTHREADDATA)); + threadData->proto = proto; + req = (NETLIBHTTPREQUEST *)mir_alloc(sizeof(NETLIBHTTPREQUEST)); + headers = (NETLIBHTTPHEADER *)mir_alloc(sizeof(NETLIBHTTPHEADER)); + ZeroMemory(req, sizeof(NETLIBHTTPREQUEST)); + req->cbSize = sizeof(NETLIBHTTPREQUEST); + req->requestType = proto->threadData->tlenConfig.avatarUploadMthd; + req->szUrl = request; + req->flags = 0; + headers[0].szName = "Content-Type"; + headers[0].szValue = "multipart/form-data; boundary=AaB03x"; + req->headersCount = 1; + req->headers = headers; + size = dataLen + sizeHead + sizeTail; + buffer = (unsigned char *)mir_alloc(size); + memcpy(buffer, mpartHead, sizeHead); + memcpy(buffer + sizeHead, data, dataLen); + memcpy(buffer + sizeHead + dataLen, mpartTail, sizeTail); + req->dataLength = size; + req->pData = (char*)buffer; + threadData->req = req; + threadData->data = (char *) mir_alloc(dataLen); + memcpy(threadData->data, data, dataLen); + threadData->length = dataLen; + forkthread(TlenUploadAvatarRequestThread, 0, threadData); + } +} + diff --git a/protocols/Tlen/src/tlen_opt.cpp b/protocols/Tlen/src/tlen_opt.cpp index 5e6d26ebd3..110124bced 100644 --- a/protocols/Tlen/src/tlen_opt.cpp +++ b/protocols/Tlen/src/tlen_opt.cpp @@ -1,665 +1,678 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -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. - -*/ - -#include "tlen.h" -#include "tlen_list.h" -#include "tlen_voice.h" -#include -#include "resource.h" - -static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -typedef struct TabDefStruct { - DLGPROC dlgProc; - DWORD dlgId; - TCHAR *tabName; -} TabDef; - -static TabDef tabPages[] = { - {TlenBasicOptDlgProc, IDD_OPTIONS_BASIC, LPGENT("General")}, - {TlenVoiceOptDlgProc, IDD_OPTIONS_VOICE, LPGENT("Voice Chats")}, - {TlenAdvOptDlgProc, IDD_OPTIONS_ADVANCED, LPGENT("Advanced")}, - {TlenPopupsDlgProc, IDD_OPTIONS_POPUPS, LPGENT("Notifications")} - }; - -void TlenLoadOptions(TlenProtocol *proto) -{ - proto->tlenOptions.savePassword = db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE); - proto->tlenOptions.useEncryption = db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE); - proto->tlenOptions.reconnect = db_get_b(NULL, proto->m_szModuleName, "Reconnect", TRUE); - proto->tlenOptions.alertPolicy = db_get_w(NULL, proto->m_szModuleName, "AlertPolicy", TLEN_ALERTS_IGNORE_NIR); - proto->tlenOptions.rosterSync = db_get_b(NULL, proto->m_szModuleName, "RosterSync", FALSE); - proto->tlenOptions.offlineAsInvisible = db_get_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", FALSE); - proto->tlenOptions.leaveOfflineMessage = db_get_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", TRUE); - proto->tlenOptions.offlineMessageOption = db_get_w(NULL, proto->m_szModuleName, "OfflineMessageOption", 0); - proto->tlenOptions.ignoreAdvertisements = db_get_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", TRUE); - proto->tlenOptions.groupChatPolicy = db_get_w(NULL, proto->m_szModuleName, "GroupChatPolicy", TLEN_MUC_ASK); - proto->tlenOptions.voiceChatPolicy = db_get_w(NULL, proto->m_szModuleName, "VoiceChatPolicy", TLEN_MUC_ASK); - proto->tlenOptions.imagePolicy = db_get_w(NULL, proto->m_szModuleName, "ImagePolicy",TLEN_IMAGES_IGNORE_NIR); - proto->tlenOptions.enableAvatars = db_get_b(NULL, proto->m_szModuleName, "EnableAvatars", TRUE); - proto->tlenOptions.enableVersion = db_get_b(NULL, proto->m_szModuleName, "EnableVersion", TRUE); - proto->tlenOptions.useNudge = db_get_b(NULL, proto->m_szModuleName, "UseNudge", FALSE); - proto->tlenOptions.logAlerts = db_get_b(NULL, proto->m_szModuleName, "LogAlerts", TRUE); - proto->tlenOptions.sendKeepAlive = db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE); - proto->tlenOptions.useNewP2P = TRUE; -} - -static int changed = 0; - -static void ApplyChanges(TlenProtocol *proto, int i) { - changed &= ~i; - if (changed == 0) { - TlenLoadOptions(proto); - } -} - -static void MarkChanges(int i, HWND hWnd) { - SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); - changed |= i; -} - - -int TlenProtocol::OptionsInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { sizeof(odp) }; - odp.hInstance = hInst; - odp.ptszGroup = LPGENT("Network"); - odp.ptszTitle = m_tszUserName; - odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; - odp.dwInitParam = (LPARAM)this; - for (int i = 0; i < SIZEOF(tabPages); i++) { - odp.pszTemplate = MAKEINTRESOURCEA(tabPages[i].dlgId); - odp.pfnDlgProc = tabPages[i].dlgProc; - odp.ptszTab = tabPages[i].tabName; - Options_AddPage(wParam, &odp); - } - return 0; -} - -static LRESULT CALLBACK TlenValidateUsernameWndProc(HWND hwndEdit, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_CHAR: - if (strchr("\"&'/:<>@", wParam&0xff) != NULL) - return 0; - break; - } - return mir_callNextSubclass(hwndEdit, TlenValidateUsernameWndProc, msg, wParam, lParam); -} - -INT_PTR CALLBACK TlenAccMgrUIDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char text[256]; - - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - DBVARIANT dbv; - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - TranslateDialogDefault(hwndDlg); - if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) { - SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); - db_free(&dbv); - } - if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) { - SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); - db_free(&dbv); - } - CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE)); - - mir_subclassWindow(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), TlenValidateUsernameWndProc); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_EDIT_USERNAME: - case IDC_EDIT_PASSWORD: - if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_SAVEPASSWORD: - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_REGISTERACCOUNT: - CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); - break; - } - break; - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - BOOL reconnectRequired = FALSE; - DBVARIANT dbv; - - GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); - if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) db_free(&dbv); - db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text)); - - if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { - GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); - if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) db_free(&dbv); - db_set_s(NULL, proto->m_szModuleName, "Password", text); - } - else - db_unset(NULL, proto->m_szModuleName, "Password"); - - db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); - if (reconnectRequired && proto->isConnected) - MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); - TlenLoadOptions(proto); - return TRUE; - } - } - break; - } - return FALSE; -} - -static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char text[256]; - - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - DBVARIANT dbv; - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - TranslateDialogDefault(hwndDlg); - if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) { - SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); - db_free(&dbv); - } - if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) { - SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); - db_free(&dbv); - } - CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE)); - - CheckDlgButton(hwndDlg, IDC_RECONNECT, proto->tlenOptions.reconnect); - CheckDlgButton(hwndDlg, IDC_ROSTER_SYNC, proto->tlenOptions.rosterSync); - CheckDlgButton(hwndDlg, IDC_SHOW_OFFLINE, proto->tlenOptions.offlineAsInvisible); - CheckDlgButton(hwndDlg, IDC_OFFLINE_MESSAGE, proto->tlenOptions.leaveOfflineMessage); - CheckDlgButton(hwndDlg, IDC_IGNORE_ADVERTISEMENTS, proto->tlenOptions.ignoreAdvertisements); - CheckDlgButton(hwndDlg, IDC_AVATARS, proto->tlenOptions.enableAvatars); - CheckDlgButton(hwndDlg, IDC_VERSIONINFO, proto->tlenOptions.enableVersion); - CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, proto->tlenOptions.useNudge); - CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, proto->tlenOptions.logAlerts); - - SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all alerts")); - SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore alerts from unauthorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all alerts")); - SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_SETCURSEL, proto->tlenOptions.alertPolicy, 0); - - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_SETCURSEL, proto->tlenOptions.groupChatPolicy, 0); - - SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all images")); - SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore images from unauthorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all images")); - SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_SETCURSEL, proto->tlenOptions.imagePolicy, 0); - - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("")); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_ONLINE, 0)); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_AWAY, 0)); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_NA, 0)); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_DND, 0)); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_FREECHAT, 0)); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_INVISIBLE, 0)); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_SETCURSEL, proto->tlenOptions.offlineMessageOption, 0); - - mir_subclassWindow(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), TlenValidateUsernameWndProc); - return TRUE; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_EDIT_USERNAME: - case IDC_EDIT_PASSWORD: - if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - // Fall through - case IDC_SAVEPASSWORD: - case IDC_RECONNECT: - case IDC_ROSTER_SYNC: - case IDC_IGNORE_ADVERTISEMENTS: - case IDC_SHOW_OFFLINE: - case IDC_OFFLINE_MESSAGE: - MarkChanges(1, hwndDlg); - break; - case IDC_LOG_ALERTS: - CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, BST_UNCHECKED); - MarkChanges(1, hwndDlg); - break; - case IDC_NUDGE_SUPPORT: - CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, BST_UNCHECKED); - MarkChanges(1, hwndDlg); - break; - case IDC_REGISTERACCOUNT: - CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); - break; - case IDC_OFFLINE_MESSAGE_OPTION: - case IDC_ALERT_POLICY: - case IDC_MUC_POLICY: - if (HIWORD(wParam) == CBN_SELCHANGE) - MarkChanges(1, hwndDlg); - break; - default: - MarkChanges(1, hwndDlg); - break; - } - break; - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - BOOL reconnectRequired = FALSE; - DBVARIANT dbv; - - GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); - if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) db_free(&dbv); - db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text)); - - if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { - GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); - if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) db_free(&dbv); - db_set_s(NULL, proto->m_szModuleName, "Password", text); - } - else - db_unset(NULL, proto->m_szModuleName, "Password"); - - db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); - db_set_b(NULL, proto->m_szModuleName, "Reconnect", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_RECONNECT)); - db_set_b(NULL, proto->m_szModuleName, "RosterSync", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ROSTER_SYNC)); - db_set_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOW_OFFLINE)); - db_set_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IGNORE_ADVERTISEMENTS)); - db_set_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_OFFLINE_MESSAGE)); - db_set_w(NULL, proto->m_szModuleName, "OfflineMessageOption", (WORD) SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_GETCURSEL, 0, 0)); - db_set_w(NULL, proto->m_szModuleName, "AlertPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_GETCURSEL, 0, 0)); - db_set_w(NULL, proto->m_szModuleName, "GroupChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_GETCURSEL, 0, 0)); - db_set_w(NULL, proto->m_szModuleName, "ImagePolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_GETCURSEL, 0, 0)); - db_set_b(NULL, proto->m_szModuleName, "EnableAvatars", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AVATARS)); - db_set_b(NULL, proto->m_szModuleName, "EnableVersion", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VERSIONINFO)); - db_set_b(NULL, proto->m_szModuleName, "UseNudge", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_NUDGE_SUPPORT)); - db_set_b(NULL, proto->m_szModuleName, "LogAlerts", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LOG_ALERTS)); - if (reconnectRequired && proto->isConnected) - MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); - ApplyChanges(proto, 1); - return TRUE; - } - } - break; - } - return FALSE; -} - -static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_SETCURSEL, proto->tlenOptions.voiceChatPolicy, 0); - TlenVoiceBuildInDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_IN)); - TlenVoiceBuildOutDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_OUT)); - return TRUE; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_VOICE_POLICY: - case IDC_VOICE_DEVICE_IN: - case IDC_VOICE_DEVICE_OUT: - if (HIWORD(wParam) == CBN_SELCHANGE) - MarkChanges(2, hwndDlg); - break; - } - break; - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - db_set_w(NULL, proto->m_szModuleName, "VoiceChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_GETCURSEL, 0, 0)); - db_set_w(NULL, proto->m_szModuleName, "VoiceDeviceIn", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_IN, CB_GETCURSEL, 0, 0)); - db_set_w(NULL, proto->m_szModuleName, "VoiceDeviceOut", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_OUT, CB_GETCURSEL, 0, 0)); - ApplyChanges(proto, 2); - return TRUE; - } - } - break; - } - - return FALSE; -} - -static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char text[256]; - BOOL bChecked; - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - { - DBVARIANT dbv; - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - TranslateDialogDefault(hwndDlg); - if (!db_get_ts(NULL, proto->m_szModuleName, "LoginServer", &dbv)) { - SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, dbv.ptszVal); - db_free(&dbv); - } - else SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, _T("tlen.pl")); - - EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_HOSTPORT), TRUE); - - if (!db_get_ts(NULL, proto->m_szModuleName, "ManualHost", &dbv)) { - SetDlgItemText(hwndDlg, IDC_HOST, dbv.ptszVal); - db_free(&dbv); - } - else SetDlgItemText(hwndDlg, IDC_HOST, _T("s1.tlen.pl")); - - SetDlgItemInt(hwndDlg, IDC_HOSTPORT, db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT), FALSE); - - CheckDlgButton(hwndDlg, IDC_KEEPALIVE, db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE)); - - CheckDlgButton(hwndDlg, IDC_USE_SSL, db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE)); - - CheckDlgButton(hwndDlg, IDC_VISIBILITY_SUPPORT, db_get_b(NULL, proto->m_szModuleName, "VisibilitySupport", FALSE)); - // File transfer options - bChecked = FALSE; - if (db_get_b(NULL, proto->m_szModuleName, "UseFileProxy", FALSE) == TRUE) { - bChecked = TRUE; - CheckDlgButton(hwndDlg, IDC_FILE_USE_PROXY, TRUE); - } - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); - if (db_get_b(NULL, proto->m_szModuleName, "FileProxyAuth", FALSE) == TRUE) - CheckDlgButton(hwndDlg, IDC_FILE_PROXY_USE_AUTH, TRUE); - else - bChecked = FALSE; - - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); - - SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("Forwarding")); - SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("SOCKS4")); - SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("SOCKS5")); - SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_SETCURSEL, db_get_w(NULL, proto->m_szModuleName, "FileProxyType", 0), 0); - if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyHost", &dbv)) { - SetDlgItemText(hwndDlg, IDC_FILE_PROXY_HOST, dbv.ptszVal); - db_free(&dbv); - } - SetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, db_get_w(NULL, proto->m_szModuleName, "FileProxyPort", 0), FALSE); - if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyUsername", &dbv)) { - SetDlgItemText(hwndDlg, IDC_FILE_PROXY_USER, dbv.ptszVal); - db_free(&dbv); - } - if (!db_get_s(NULL, proto->m_szModuleName, "FileProxyPassword", &dbv)) { - SetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, dbv.pszVal); - db_free(&dbv); - } - return TRUE; - } - case WM_COMMAND: - { - switch (LOWORD(wParam)) { - case IDC_FILE_PROXY_TYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) - MarkChanges(4, hwndDlg); - break; - case IDC_EDIT_LOGIN_SERVER: - case IDC_HOST: - case IDC_HOSTPORT: - case IDC_FILE_PROXY_HOST: - case IDC_FILE_PROXY_PORT: - case IDC_FILE_PROXY_USER: - case IDC_FILE_PROXY_PASSWORD: - if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) - MarkChanges(4, hwndDlg); - break; - case IDC_FILE_USE_PROXY: - bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); - case IDC_FILE_PROXY_USE_AUTH: - bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH) & IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); - MarkChanges(4, hwndDlg); - break; - case IDC_KEEPALIVE: - case IDC_VISIBILITY_SUPPORT: - case IDC_USE_SSL: - MarkChanges(4, hwndDlg); - break; - } - } - break; - - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - WORD port; - BOOL useEncryption; - BOOL reconnectRequired = FALSE; - DBVARIANT dbv; - GetDlgItemTextA(hwndDlg, IDC_EDIT_LOGIN_SERVER, text, sizeof(text)); - if (db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) db_free(&dbv); - db_set_s(NULL, proto->m_szModuleName, "LoginServer", strlwr(text)); - - GetDlgItemTextA(hwndDlg, IDC_HOST, text, sizeof(text)); - if (db_get(NULL, proto->m_szModuleName, "ManualHost", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) db_free(&dbv); - db_set_s(NULL, proto->m_szModuleName, "ManualHost", text); - - port = (WORD) GetDlgItemInt(hwndDlg, IDC_HOSTPORT, NULL, FALSE); - if (db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT) != port) - reconnectRequired = TRUE; - db_set_w(NULL, proto->m_szModuleName, "ManualPort", port); - - proto->tlenOptions.sendKeepAlive = IsDlgButtonChecked(hwndDlg, IDC_KEEPALIVE); - db_set_b(NULL, proto->m_szModuleName, "KeepAlive", (BYTE) proto->tlenOptions.sendKeepAlive); - - useEncryption = IsDlgButtonChecked(hwndDlg, IDC_USE_SSL); - if (db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE) != useEncryption) - reconnectRequired = TRUE; - db_set_b(NULL, proto->m_szModuleName, "UseEncryption", (BYTE) useEncryption); - - db_set_b(NULL, proto->m_szModuleName, "VisibilitySupport", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VISIBILITY_SUPPORT)); - - // File transfer options - db_set_b(NULL, proto->m_szModuleName, "UseFileProxy", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY)); - db_set_w(NULL, proto->m_szModuleName, "FileProxyType", (WORD) SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_GETCURSEL, 0, 0)); - - GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_HOST, text, sizeof(text)); - db_set_s(NULL, proto->m_szModuleName, "FileProxyHost", text); - - db_set_w(NULL, proto->m_szModuleName, "FileProxyPort", (WORD) GetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, NULL, FALSE)); - db_set_b(NULL, proto->m_szModuleName, "FileProxyAuth", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH)); - - GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_USER, text, sizeof(text)); - db_set_s(NULL, proto->m_szModuleName, "FileProxyUsername", text); - - GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, text, sizeof(text)); - db_set_s(NULL, proto->m_szModuleName, "FileProxyPassword", text); - - if (reconnectRequired && proto->isConnected) - MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); - ApplyChanges(proto, 4); - return TRUE; - } - break; - } - - return FALSE; -} - -#define POPUP_DEFAULT_COLORBKG 0xDCBDA5 -#define POPUP_DEFAULT_COLORTXT 0x000000 - -static void MailPopupPreview(DWORD colorBack, DWORD colorText, TCHAR *title, TCHAR *emailInfo, int delay) -{ - POPUPDATAT ppd = { 0 }; - HICON hIcon = GetIcolibIcon(IDI_MAIL); - ppd.lchIcon = CopyIcon(hIcon); - ReleaseIcolibIcon(hIcon); - _tcscpy(ppd.lptzContactName, title); - _tcscpy(ppd.lptzText, emailInfo); - ppd.colorBack = colorBack; - ppd.colorText = colorText; - ppd.iSeconds = delay; - if ( ServiceExists(MS_POPUP_ADDPOPUPT)) - PUAddPopupT(&ppd); -} - -static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - BYTE delayMode; - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - TranslateDialogDefault(hwndDlg); - CheckDlgButton(hwndDlg, IDC_ENABLEPOPUP, db_get_b(NULL, proto->m_szModuleName, "MailPopupEnabled", TRUE)); - SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_SETCOLOUR, 0, db_get_dw(NULL, proto->m_szModuleName, "MailPopupBack", POPUP_DEFAULT_COLORBKG)); - SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, db_get_dw(NULL, proto->m_szModuleName, "MailPopupText", POPUP_DEFAULT_COLORTXT)); - SetDlgItemInt(hwndDlg, IDC_DELAY, db_get_dw(NULL, proto->m_szModuleName, "MailPopupDelay", 4), FALSE); - delayMode = db_get_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", 0); - if (delayMode == 1) { - CheckDlgButton(hwndDlg, IDC_DELAY_CUSTOM, TRUE); - } else if (delayMode == 2) { - CheckDlgButton(hwndDlg, IDC_DELAY_PERMANENT, TRUE); - } else { - CheckDlgButton(hwndDlg, IDC_DELAY_POPUP, TRUE); - } - return TRUE; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COLORTXT: - case IDC_COLORBKG: - case IDC_ENABLEPOPUP: - case IDC_DELAY: - case IDC_DELAY_POPUP: - case IDC_DELAY_CUSTOM: - case IDC_DELAY_PERMANENT: - MarkChanges(8, hwndDlg); - break; - case IDC_PREVIEW: - { - int delay; - TCHAR title[256]; - if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_POPUP)) { - delay=0; - } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { - delay=-1; - } else { - delay=GetDlgItemInt(hwndDlg, IDC_DELAY, NULL, FALSE); - } - mir_sntprintf(title, SIZEOF(title), TranslateT("%S mail"), proto->m_szModuleName); - MailPopupPreview((DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0), - (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0), - title, - _T("From: test@test.test\nSubject: test"), - delay); - } - - } - break; - - - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - BYTE delayMode; - db_set_b(NULL, proto->m_szModuleName, "MailPopupEnabled", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLEPOPUP)); - db_set_dw(NULL, proto->m_szModuleName, "MailPopupBack", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0)); - db_set_dw(NULL, proto->m_szModuleName, "MailPopupText", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0)); - db_set_dw(NULL, proto->m_szModuleName, "MailPopupDelay", (DWORD) GetDlgItemInt(hwndDlg,IDC_DELAY, NULL, FALSE)); - delayMode=0; - if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_CUSTOM)) { - delayMode=1; - } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { - delayMode=2; - - } - db_set_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", delayMode); - ApplyChanges(proto, 8); - return TRUE; - } - } - break; - - } - return FALSE; -} - +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +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. + +*/ + +#include "tlen.h" +#include "tlen_list.h" +#include "tlen_voice.h" +#include +#include "resource.h" + +static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +typedef struct TabDefStruct { + DLGPROC dlgProc; + DWORD dlgId; + TCHAR *tabName; +} TabDef; + +static TabDef tabPages[] = { + {TlenBasicOptDlgProc, IDD_OPTIONS_BASIC, LPGENT("General")}, + {TlenVoiceOptDlgProc, IDD_OPTIONS_VOICE, LPGENT("Voice Chats")}, + {TlenAdvOptDlgProc, IDD_OPTIONS_ADVANCED, LPGENT("Advanced")}, + {TlenPopupsDlgProc, IDD_OPTIONS_POPUPS, LPGENT("Notifications")} + }; + +void TlenLoadOptions(TlenProtocol *proto) +{ + proto->tlenOptions.savePassword = db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE); + proto->tlenOptions.useEncryption = db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE); + proto->tlenOptions.reconnect = db_get_b(NULL, proto->m_szModuleName, "Reconnect", TRUE); + proto->tlenOptions.alertPolicy = db_get_w(NULL, proto->m_szModuleName, "AlertPolicy", TLEN_ALERTS_IGNORE_NIR); + proto->tlenOptions.rosterSync = db_get_b(NULL, proto->m_szModuleName, "RosterSync", FALSE); + proto->tlenOptions.offlineAsInvisible = db_get_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", FALSE); + proto->tlenOptions.leaveOfflineMessage = db_get_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", TRUE); + proto->tlenOptions.offlineMessageOption = db_get_w(NULL, proto->m_szModuleName, "OfflineMessageOption", 0); + proto->tlenOptions.ignoreAdvertisements = db_get_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", TRUE); + proto->tlenOptions.groupChatPolicy = db_get_w(NULL, proto->m_szModuleName, "GroupChatPolicy", TLEN_MUC_ASK); + proto->tlenOptions.voiceChatPolicy = db_get_w(NULL, proto->m_szModuleName, "VoiceChatPolicy", TLEN_MUC_ASK); + proto->tlenOptions.imagePolicy = db_get_w(NULL, proto->m_szModuleName, "ImagePolicy",TLEN_IMAGES_IGNORE_NIR); + proto->tlenOptions.enableAvatars = db_get_b(NULL, proto->m_szModuleName, "EnableAvatars", TRUE); + proto->tlenOptions.enableVersion = db_get_b(NULL, proto->m_szModuleName, "EnableVersion", TRUE); + proto->tlenOptions.useNudge = db_get_b(NULL, proto->m_szModuleName, "UseNudge", FALSE); + proto->tlenOptions.logAlerts = db_get_b(NULL, proto->m_szModuleName, "LogAlerts", TRUE); + proto->tlenOptions.sendKeepAlive = db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE); + proto->tlenOptions.useNewP2P = TRUE; +} + +static int changed = 0; + +static void ApplyChanges(TlenProtocol *proto, int i) { + changed &= ~i; + if (changed == 0) { + TlenLoadOptions(proto); + } +} + +static void MarkChanges(int i, HWND hWnd) { + SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); + changed |= i; +} + + +int TlenProtocol::OptionsInit(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.hInstance = hInst; + odp.ptszGroup = LPGENT("Network"); + odp.ptszTitle = m_tszUserName; + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; + odp.dwInitParam = (LPARAM)this; + for (int i = 0; i < SIZEOF(tabPages); i++) { + odp.pszTemplate = MAKEINTRESOURCEA(tabPages[i].dlgId); + odp.pfnDlgProc = tabPages[i].dlgProc; + odp.ptszTab = tabPages[i].tabName; + Options_AddPage(wParam, &odp); + } + return 0; +} + +static LRESULT CALLBACK TlenValidateUsernameWndProc(HWND hwndEdit, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_CHAR: + if (strchr("\"&'/:<>@", wParam&0xff) != NULL) + return 0; + break; + } + return mir_callNextSubclass(hwndEdit, TlenValidateUsernameWndProc, msg, wParam, lParam); +} + +INT_PTR CALLBACK TlenAccMgrUIDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char text[256]; + + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + DBVARIANT dbv; + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + TranslateDialogDefault(hwndDlg); + if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) { + SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); + db_free(&dbv); + } + if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) { + SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); + db_free(&dbv); + } + CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE)); + + mir_subclassWindow(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), TlenValidateUsernameWndProc); + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_EDIT_USERNAME: + case IDC_EDIT_PASSWORD: + if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_SAVEPASSWORD: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_REGISTERACCOUNT: + CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); + break; + } + break; + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + BOOL reconnectRequired = FALSE; + DBVARIANT dbv; + + GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); + dbv.pszVal = NULL; + if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || lstrcmpA(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) + db_free(&dbv); + db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text)); + + if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { + GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); + dbv.pszVal = NULL; + if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || lstrcmpA(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) + db_free(&dbv); + db_set_s(NULL, proto->m_szModuleName, "Password", text); + } + else + db_unset(NULL, proto->m_szModuleName, "Password"); + + db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); + if (reconnectRequired && proto->isConnected) + MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); + TlenLoadOptions(proto); + return TRUE; + } + } + break; + } + return FALSE; +} + +static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char text[256]; + + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + DBVARIANT dbv; + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + TranslateDialogDefault(hwndDlg); + if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) { + SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); + db_free(&dbv); + } + if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) { + SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); + db_free(&dbv); + } + CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE)); + + CheckDlgButton(hwndDlg, IDC_RECONNECT, proto->tlenOptions.reconnect); + CheckDlgButton(hwndDlg, IDC_ROSTER_SYNC, proto->tlenOptions.rosterSync); + CheckDlgButton(hwndDlg, IDC_SHOW_OFFLINE, proto->tlenOptions.offlineAsInvisible); + CheckDlgButton(hwndDlg, IDC_OFFLINE_MESSAGE, proto->tlenOptions.leaveOfflineMessage); + CheckDlgButton(hwndDlg, IDC_IGNORE_ADVERTISEMENTS, proto->tlenOptions.ignoreAdvertisements); + CheckDlgButton(hwndDlg, IDC_AVATARS, proto->tlenOptions.enableAvatars); + CheckDlgButton(hwndDlg, IDC_VERSIONINFO, proto->tlenOptions.enableVersion); + CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, proto->tlenOptions.useNudge); + CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, proto->tlenOptions.logAlerts); + + SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all alerts")); + SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore alerts from unauthorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all alerts")); + SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_SETCURSEL, proto->tlenOptions.alertPolicy, 0); + + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_SETCURSEL, proto->tlenOptions.groupChatPolicy, 0); + + SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all images")); + SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore images from unauthorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all images")); + SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_SETCURSEL, proto->tlenOptions.imagePolicy, 0); + + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("")); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_ONLINE, 0)); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_AWAY, 0)); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_NA, 0)); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_DND, 0)); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_FREECHAT, 0)); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_INVISIBLE, 0)); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_SETCURSEL, proto->tlenOptions.offlineMessageOption, 0); + + mir_subclassWindow(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), TlenValidateUsernameWndProc); + return TRUE; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_EDIT_USERNAME: + case IDC_EDIT_PASSWORD: + if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + // Fall through + case IDC_SAVEPASSWORD: + case IDC_RECONNECT: + case IDC_ROSTER_SYNC: + case IDC_IGNORE_ADVERTISEMENTS: + case IDC_SHOW_OFFLINE: + case IDC_OFFLINE_MESSAGE: + MarkChanges(1, hwndDlg); + break; + case IDC_LOG_ALERTS: + CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, BST_UNCHECKED); + MarkChanges(1, hwndDlg); + break; + case IDC_NUDGE_SUPPORT: + CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, BST_UNCHECKED); + MarkChanges(1, hwndDlg); + break; + case IDC_REGISTERACCOUNT: + CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); + break; + case IDC_OFFLINE_MESSAGE_OPTION: + case IDC_ALERT_POLICY: + case IDC_MUC_POLICY: + if (HIWORD(wParam) == CBN_SELCHANGE) + MarkChanges(1, hwndDlg); + break; + default: + MarkChanges(1, hwndDlg); + break; + } + break; + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + BOOL reconnectRequired = FALSE; + DBVARIANT dbv; + + GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); + dbv.pszVal = NULL; + if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || lstrcmpA(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) + db_free(&dbv); + db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text)); + + if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { + GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); + dbv.pszVal = NULL; + if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || lstrcmpA(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) + db_free(&dbv); + db_set_s(NULL, proto->m_szModuleName, "Password", text); + } + else + db_unset(NULL, proto->m_szModuleName, "Password"); + + db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); + db_set_b(NULL, proto->m_szModuleName, "Reconnect", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_RECONNECT)); + db_set_b(NULL, proto->m_szModuleName, "RosterSync", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ROSTER_SYNC)); + db_set_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOW_OFFLINE)); + db_set_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IGNORE_ADVERTISEMENTS)); + db_set_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_OFFLINE_MESSAGE)); + db_set_w(NULL, proto->m_szModuleName, "OfflineMessageOption", (WORD) SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_GETCURSEL, 0, 0)); + db_set_w(NULL, proto->m_szModuleName, "AlertPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_GETCURSEL, 0, 0)); + db_set_w(NULL, proto->m_szModuleName, "GroupChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_GETCURSEL, 0, 0)); + db_set_w(NULL, proto->m_szModuleName, "ImagePolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_GETCURSEL, 0, 0)); + db_set_b(NULL, proto->m_szModuleName, "EnableAvatars", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AVATARS)); + db_set_b(NULL, proto->m_szModuleName, "EnableVersion", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VERSIONINFO)); + db_set_b(NULL, proto->m_szModuleName, "UseNudge", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_NUDGE_SUPPORT)); + db_set_b(NULL, proto->m_szModuleName, "LogAlerts", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LOG_ALERTS)); + if (reconnectRequired && proto->isConnected) + MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); + ApplyChanges(proto, 1); + return TRUE; + } + } + break; + } + return FALSE; +} + +static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_SETCURSEL, proto->tlenOptions.voiceChatPolicy, 0); + TlenVoiceBuildInDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_IN)); + TlenVoiceBuildOutDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_OUT)); + return TRUE; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_VOICE_POLICY: + case IDC_VOICE_DEVICE_IN: + case IDC_VOICE_DEVICE_OUT: + if (HIWORD(wParam) == CBN_SELCHANGE) + MarkChanges(2, hwndDlg); + break; + } + break; + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + db_set_w(NULL, proto->m_szModuleName, "VoiceChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_GETCURSEL, 0, 0)); + db_set_w(NULL, proto->m_szModuleName, "VoiceDeviceIn", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_IN, CB_GETCURSEL, 0, 0)); + db_set_w(NULL, proto->m_szModuleName, "VoiceDeviceOut", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_OUT, CB_GETCURSEL, 0, 0)); + ApplyChanges(proto, 2); + return TRUE; + } + } + break; + } + + return FALSE; +} + +static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char text[256]; + BOOL bChecked; + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + switch (msg) { + case WM_INITDIALOG: + { + DBVARIANT dbv; + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + TranslateDialogDefault(hwndDlg); + if (!db_get_ts(NULL, proto->m_szModuleName, "LoginServer", &dbv)) { + SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, dbv.ptszVal); + db_free(&dbv); + } + else SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, _T("tlen.pl")); + + EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_HOSTPORT), TRUE); + + if (!db_get_ts(NULL, proto->m_szModuleName, "ManualHost", &dbv)) { + SetDlgItemText(hwndDlg, IDC_HOST, dbv.ptszVal); + db_free(&dbv); + } + else SetDlgItemText(hwndDlg, IDC_HOST, _T("s1.tlen.pl")); + + SetDlgItemInt(hwndDlg, IDC_HOSTPORT, db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT), FALSE); + + CheckDlgButton(hwndDlg, IDC_KEEPALIVE, db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE)); + + CheckDlgButton(hwndDlg, IDC_USE_SSL, db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE)); + + CheckDlgButton(hwndDlg, IDC_VISIBILITY_SUPPORT, db_get_b(NULL, proto->m_szModuleName, "VisibilitySupport", FALSE)); + // File transfer options + bChecked = FALSE; + if (db_get_b(NULL, proto->m_szModuleName, "UseFileProxy", FALSE) == TRUE) { + bChecked = TRUE; + CheckDlgButton(hwndDlg, IDC_FILE_USE_PROXY, TRUE); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); + if (db_get_b(NULL, proto->m_szModuleName, "FileProxyAuth", FALSE) == TRUE) + CheckDlgButton(hwndDlg, IDC_FILE_PROXY_USE_AUTH, TRUE); + else + bChecked = FALSE; + + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); + + SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("Forwarding")); + SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("SOCKS4")); + SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("SOCKS5")); + SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_SETCURSEL, db_get_w(NULL, proto->m_szModuleName, "FileProxyType", 0), 0); + if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyHost", &dbv)) { + SetDlgItemText(hwndDlg, IDC_FILE_PROXY_HOST, dbv.ptszVal); + db_free(&dbv); + } + SetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, db_get_w(NULL, proto->m_szModuleName, "FileProxyPort", 0), FALSE); + if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyUsername", &dbv)) { + SetDlgItemText(hwndDlg, IDC_FILE_PROXY_USER, dbv.ptszVal); + db_free(&dbv); + } + if (!db_get_s(NULL, proto->m_szModuleName, "FileProxyPassword", &dbv)) { + SetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, dbv.pszVal); + db_free(&dbv); + } + return TRUE; + } + case WM_COMMAND: + { + switch (LOWORD(wParam)) { + case IDC_FILE_PROXY_TYPE: + if (HIWORD(wParam) == CBN_SELCHANGE) + MarkChanges(4, hwndDlg); + break; + case IDC_EDIT_LOGIN_SERVER: + case IDC_HOST: + case IDC_HOSTPORT: + case IDC_FILE_PROXY_HOST: + case IDC_FILE_PROXY_PORT: + case IDC_FILE_PROXY_USER: + case IDC_FILE_PROXY_PASSWORD: + if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) + MarkChanges(4, hwndDlg); + break; + case IDC_FILE_USE_PROXY: + bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); + case IDC_FILE_PROXY_USE_AUTH: + bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH) & IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); + MarkChanges(4, hwndDlg); + break; + case IDC_KEEPALIVE: + case IDC_VISIBILITY_SUPPORT: + case IDC_USE_SSL: + MarkChanges(4, hwndDlg); + break; + } + } + break; + + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + WORD port; + BOOL useEncryption; + BOOL reconnectRequired = FALSE; + DBVARIANT dbv; + + GetDlgItemTextA(hwndDlg, IDC_EDIT_LOGIN_SERVER, text, sizeof(text)); + dbv.pszVal = NULL; + if (db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv) || lstrcmpA(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) + db_free(&dbv); + db_set_s(NULL, proto->m_szModuleName, "LoginServer", strlwr(text)); + + GetDlgItemTextA(hwndDlg, IDC_HOST, text, sizeof(text)); + dbv.pszVal = NULL; + if (db_get(NULL, proto->m_szModuleName, "ManualHost", &dbv) || lstrcmpA(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) + db_free(&dbv); + db_set_s(NULL, proto->m_szModuleName, "ManualHost", text); + + port = (WORD) GetDlgItemInt(hwndDlg, IDC_HOSTPORT, NULL, FALSE); + if (db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT) != port) + reconnectRequired = TRUE; + db_set_w(NULL, proto->m_szModuleName, "ManualPort", port); + + proto->tlenOptions.sendKeepAlive = IsDlgButtonChecked(hwndDlg, IDC_KEEPALIVE); + db_set_b(NULL, proto->m_szModuleName, "KeepAlive", (BYTE) proto->tlenOptions.sendKeepAlive); + + useEncryption = IsDlgButtonChecked(hwndDlg, IDC_USE_SSL); + if (db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE) != useEncryption) + reconnectRequired = TRUE; + db_set_b(NULL, proto->m_szModuleName, "UseEncryption", (BYTE) useEncryption); + + db_set_b(NULL, proto->m_szModuleName, "VisibilitySupport", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VISIBILITY_SUPPORT)); + + // File transfer options + db_set_b(NULL, proto->m_szModuleName, "UseFileProxy", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY)); + db_set_w(NULL, proto->m_szModuleName, "FileProxyType", (WORD) SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_GETCURSEL, 0, 0)); + + GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_HOST, text, sizeof(text)); + db_set_s(NULL, proto->m_szModuleName, "FileProxyHost", text); + + db_set_w(NULL, proto->m_szModuleName, "FileProxyPort", (WORD) GetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, NULL, FALSE)); + db_set_b(NULL, proto->m_szModuleName, "FileProxyAuth", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH)); + + GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_USER, text, sizeof(text)); + db_set_s(NULL, proto->m_szModuleName, "FileProxyUsername", text); + + GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, text, sizeof(text)); + db_set_s(NULL, proto->m_szModuleName, "FileProxyPassword", text); + + if (reconnectRequired && proto->isConnected) + MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); + ApplyChanges(proto, 4); + return TRUE; + } + break; + } + + return FALSE; +} + +#define POPUP_DEFAULT_COLORBKG 0xDCBDA5 +#define POPUP_DEFAULT_COLORTXT 0x000000 + +static void MailPopupPreview(DWORD colorBack, DWORD colorText, TCHAR *title, TCHAR *emailInfo, int delay) +{ + POPUPDATAT ppd = { 0 }; + HICON hIcon = GetIcolibIcon(IDI_MAIL); + ppd.lchIcon = CopyIcon(hIcon); + ReleaseIcolibIcon(hIcon); + _tcscpy(ppd.lptzContactName, title); + _tcscpy(ppd.lptzText, emailInfo); + ppd.colorBack = colorBack; + ppd.colorText = colorText; + ppd.iSeconds = delay; + if ( ServiceExists(MS_POPUP_ADDPOPUPT)) + PUAddPopupT(&ppd); +} + +static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + BYTE delayMode; + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + TranslateDialogDefault(hwndDlg); + CheckDlgButton(hwndDlg, IDC_ENABLEPOPUP, db_get_b(NULL, proto->m_szModuleName, "MailPopupEnabled", TRUE)); + SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_SETCOLOUR, 0, db_get_dw(NULL, proto->m_szModuleName, "MailPopupBack", POPUP_DEFAULT_COLORBKG)); + SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, db_get_dw(NULL, proto->m_szModuleName, "MailPopupText", POPUP_DEFAULT_COLORTXT)); + SetDlgItemInt(hwndDlg, IDC_DELAY, db_get_dw(NULL, proto->m_szModuleName, "MailPopupDelay", 4), FALSE); + delayMode = db_get_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", 0); + if (delayMode == 1) { + CheckDlgButton(hwndDlg, IDC_DELAY_CUSTOM, TRUE); + } else if (delayMode == 2) { + CheckDlgButton(hwndDlg, IDC_DELAY_PERMANENT, TRUE); + } else { + CheckDlgButton(hwndDlg, IDC_DELAY_POPUP, TRUE); + } + return TRUE; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_COLORTXT: + case IDC_COLORBKG: + case IDC_ENABLEPOPUP: + case IDC_DELAY: + case IDC_DELAY_POPUP: + case IDC_DELAY_CUSTOM: + case IDC_DELAY_PERMANENT: + MarkChanges(8, hwndDlg); + break; + case IDC_PREVIEW: + { + int delay; + TCHAR title[256]; + if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_POPUP)) { + delay=0; + } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { + delay=-1; + } else { + delay=GetDlgItemInt(hwndDlg, IDC_DELAY, NULL, FALSE); + } + mir_sntprintf(title, SIZEOF(title), TranslateT("%S mail"), proto->m_szModuleName); + MailPopupPreview((DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0), + (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0), + title, + _T("From: test@test.test\nSubject: test"), + delay); + } + + } + break; + + + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + BYTE delayMode; + db_set_b(NULL, proto->m_szModuleName, "MailPopupEnabled", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLEPOPUP)); + db_set_dw(NULL, proto->m_szModuleName, "MailPopupBack", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0)); + db_set_dw(NULL, proto->m_szModuleName, "MailPopupText", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0)); + db_set_dw(NULL, proto->m_szModuleName, "MailPopupDelay", (DWORD) GetDlgItemInt(hwndDlg,IDC_DELAY, NULL, FALSE)); + delayMode=0; + if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_CUSTOM)) { + delayMode=1; + } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { + delayMode=2; + + } + db_set_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", delayMode); + ApplyChanges(proto, 8); + return TRUE; + } + } + break; + + } + return FALSE; +} + diff --git a/protocols/Tlen/src/tlen_xml.cpp b/protocols/Tlen/src/tlen_xml.cpp index a3e2d892e8..87fdd52211 100644 --- a/protocols/Tlen/src/tlen_xml.cpp +++ b/protocols/Tlen/src/tlen_xml.cpp @@ -1,569 +1,572 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda NG -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -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. - -*/ - -#include "tlen.h" -#include - -static BOOL TlenXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr); -static void TlenXmlRemoveChild(XmlNode *node, XmlNode *child); - -void TlenXmlInitState(XmlState *xmlState) -{ - if (xmlState == NULL) return; - xmlState->root.name = NULL; - xmlState->root.depth = 0; - xmlState->root.numAttr = 0; - xmlState->root.maxNumAttr = 0; - xmlState->root.attr = NULL; - xmlState->root.numChild = 0; - xmlState->root.maxNumChild = 0; - xmlState->root.child = NULL; - xmlState->root.text = NULL; - xmlState->root.state = NODE_OPEN; - xmlState->callback1_open = NULL; - xmlState->callback1_close = NULL; - xmlState->callback2_open = NULL; - xmlState->callback2_close = NULL; - xmlState->userdata1_open = NULL; - xmlState->userdata1_close = NULL; - xmlState->userdata2_open = NULL; - xmlState->userdata2_close = NULL; -} - -void TlenXmlDestroyState(XmlState *xmlState) -{ - int i; - XmlNode *node; - - if (xmlState == NULL) return; - // Note: cannot use TlenXmlFreeNode() to free xmlState->root - // because it will do mir_free(xmlState->root) which is not freeable. - node = &(xmlState->root); - // Free all children first - for (i=0; inumChild; i++) - TlenXmlFreeNode(node->child[i]); - if (node->child) mir_free(node->child); - // Free all attributes - for (i=0; inumAttr; i++) { - if (node->attr[i]->name) mir_free(node->attr[i]->name); - if (node->attr[i]->value) mir_free(node->attr[i]->value); - mir_free(node->attr[i]); - } - if (node->attr) mir_free(node->attr); - // Free string field - if (node->text) mir_free(node->text); - if (node->name) mir_free(node->name); -} - -BOOL TlenXmlSetCallback(XmlState *xmlState, int depth, XmlElemType type, void (*callback)(XmlNode*, void*), void *userdata) -{ - if (depth == 1 && type == ELEM_OPEN) { - xmlState->callback1_open = callback; - xmlState->userdata1_open = userdata; - } - else if (depth == 1 && type == ELEM_CLOSE) { - xmlState->callback1_close = callback; - xmlState->userdata1_close = userdata; - } - else if (depth == 2 && type == ELEM_OPEN) { - xmlState->callback2_open = callback; - xmlState->userdata2_open = userdata; - } - else if (depth == 2 && type == ELEM_CLOSE) { - xmlState->callback2_close = callback; - xmlState->userdata2_close = userdata; - } - else - return FALSE; - - return TRUE; -} - -#define TAG_MAX_LEN 50 -#define ATTR_MAX_LEN 1024 -int TlenXmlParse(XmlState *xmlState, char *buffer, int datalen) -{ - char *p, *q, *r, *eob; - char *str; - int num; - char tag[TAG_MAX_LEN]; - char attr[ATTR_MAX_LEN]; - XmlElemType elemType = ELEM_OPEN; - - eob = buffer + datalen; - num = 0; - // Skip leading whitespaces - for (p=buffer; p TAG_MAX_LEN) { -// TlenLog("TAG_MAX_LEN too small, ignore current tag"); - } - else { - if (*(p+1) == '/') { // closing tag - strncpy(tag, p+2, r-(p+2)); - tag[r-(p+2)] = '\0'; - elemType = ELEM_CLOSE; - } - else { - if (*(r-1) == '/') { // single open/close tag - strncpy(tag, p+1, r-(p+1)-1); - tag[r-(p+1)-1] = '\0'; - elemType = ELEM_OPENCLOSE; - } - else { - strncpy(tag, p+1, r-(p+1)); - tag[r-(p+1)] = '\0'; - elemType = ELEM_OPEN; - } - } - for (;r ATTR_MAX_LEN) { -// TlenLog("ATTR_MAX_LEN too small, ignore current tag"); - } - else { - strncpy(attr, r, q-r); - if ((q-r)>0 && attr[q-r-1] == '/') { - attr[q-r-1] = '\0'; - elemType = ELEM_OPENCLOSE; - } - else - attr[q-r] = '\0'; - TlenXmlProcessElem(xmlState, elemType, tag, attr); - } - } - num += (q-p+1); - p = q + 1; - if (elemType == ELEM_CLOSE || elemType == ELEM_OPENCLOSE) { - // Skip whitespaces after end tags - for (; pnumAttr >= node->maxNumAttr) { - node->maxNumAttr = node->numAttr + 20; - node->attr = (XmlAttr **) mir_realloc(node->attr, node->maxNumAttr*sizeof(XmlAttr *)); - } - a = node->attr[node->numAttr] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); - node->numAttr++; - - // Skip possible whitespaces between key and '=' - for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++); - - if (*p == '\0') { - a->name = (char *) mir_alloc(klen+1); - strncpy(a->name, kstart, klen); - a->name[klen] = '\0'; - a->value = mir_strdup(""); - break; - } - - if (*p != '=') { - a->name = (char *) mir_alloc(klen+1); - strncpy(a->name, kstart, klen); - a->name[klen] = '\0'; - a->value = mir_strdup(""); - continue; - } - - // Found '=' - p++; - - // Skip possible whitespaces between '=' and value - for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++); - - if (*p == '\0') { - a->name = (char *) mir_alloc(klen+1); - strncpy(a->name, kstart, klen); - a->name[klen] = '\0'; - a->value = mir_strdup(""); - break; - } - - // Fetch value - if (*p == '\'' || *p == '"') { - p++; - vstart = p; - for (;*p != '\0' && *p != *(vstart-1); p++); - vlen = p-vstart; - if (*p != '\0') p++; - } - else { - vstart = p; - for (;*p != '\0' && *p != ' ' && *p != '\t'; p++); - vlen = p-vstart; - } - - a->name = (char *) mir_alloc(klen+1); - strncpy(a->name, kstart, klen); - a->name[klen] = '\0'; - a->value = (char *) mir_alloc(vlen+1); - strncpy(a->value, vstart, vlen); - a->value[vlen] = '\0'; - } -} - -static BOOL TlenXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr) -{ - XmlNode *node, *parentNode, *n; - //BOOL activateCallback = FALSE; - char *text, *attr; - - if (elemText == NULL) return FALSE; - - if (elemType == ELEM_OPEN && !strcmp(elemText, "?xml")) { -// TlenLog("XML: skip tag"); - return TRUE; - } - - // Find active node - node = &(xmlState->root); - parentNode = NULL; - while (node->numChild>0 && node->child[node->numChild-1]->state == NODE_OPEN) { - parentNode = node; - node = node->child[node->numChild-1]; - } - - if (node->state != NODE_OPEN) return FALSE; - - text = mir_strdup(elemText); - - if (elemAttr) - attr = mir_strdup(elemAttr); - else - attr = NULL; - - switch (elemType) { - case ELEM_OPEN: - if (node->numChild >= node->maxNumChild) { - node->maxNumChild = node->numChild + 20; - node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *)); - } - n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode)); - node->numChild++; - n->name = text; - n->depth = node->depth + 1; - n->state = NODE_OPEN; - n->numChild = n->maxNumChild = 0; - n->child = NULL; - n->numAttr = n->maxNumAttr = 0; - n->attr = NULL; - TlenXmlParseAttr(n, attr); - n->text = NULL; - if (n->depth == 1 && xmlState->callback1_open != NULL) - (*(xmlState->callback1_open))(n, xmlState->userdata1_open); - if (n->depth == 2 && xmlState->callback2_open != NULL) - (*xmlState->callback2_open)(n, xmlState->userdata2_open); - break; - case ELEM_OPENCLOSE: - if (node->numChild >= node->maxNumChild) { - node->maxNumChild = node->numChild + 20; - node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *)); - } - n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode)); - node->numChild++; - n->name = text; - n->depth = node->depth + 1; - n->state = NODE_CLOSE; - n->numChild = n->maxNumAttr = 0; - n->child = NULL; - n->numAttr = n->maxNumAttr = 0; - n->attr = NULL; - TlenXmlParseAttr(n, attr); - n->text = NULL; - if (n->depth == 1 && xmlState->callback1_close != NULL) { - (*(xmlState->callback1_close))(n, xmlState->userdata1_close); - TlenXmlRemoveChild(node, n); - } - if (n->depth == 2 && xmlState->callback2_close != NULL) { - (*xmlState->callback2_close)(n, xmlState->userdata2_close); - TlenXmlRemoveChild(node, n); - } - break; - case ELEM_CLOSE: - if (node->name != NULL && !strcmp(node->name, text)) { - node->state = NODE_CLOSE; - int nodeDepth = node->depth; - if (nodeDepth == 1 && xmlState->callback1_close != NULL) { - (*(xmlState->callback1_close))(node, xmlState->userdata1_close); - TlenXmlRemoveChild(parentNode, node); - } - if (nodeDepth == 2 && xmlState->callback2_close != NULL) { - (*xmlState->callback2_close)(node, xmlState->userdata2_close); - TlenXmlRemoveChild(parentNode, node); - } - mir_free(text); - } - else { -// TlenLog("XML: Closing without opening tag", text); - mir_free(text); - if (attr) mir_free(attr); - return FALSE; - } - break; - case ELEM_TEXT: - node->text = text; - break; - default: - mir_free(text); - if (attr) mir_free(attr); - return FALSE; - } - - if (attr) mir_free(attr); - - return TRUE; -} - -char *TlenXmlGetAttrValue(XmlNode *node, char *key) -{ - int i; - - if (node == NULL || node->numAttr <= 0 || key == NULL || strlen(key) <= 0) - return NULL; - for (i=0; inumAttr; i++) { - if (node->attr[i]->name && !strcmp(key, node->attr[i]->name)) - return node->attr[i]->value; - } - return NULL; -} - -XmlNode *TlenXmlGetChild(XmlNode *node, char *tag) -{ - return TlenXmlGetNthChild(node, tag, 1); -} - -XmlNode *TlenXmlGetNthChild(XmlNode *node, char *tag, int nth) -{ - int i, num; - - if (node == NULL || node->numChild <= 0 || tag == NULL || strlen(tag) <= 0 || nth < 1) - return NULL; - num = 1; - for (i=0; inumChild; i++) { - if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) { - if (num == nth) { - return node->child[i]; - } - num++; - } - } - return NULL; -} - -XmlNode *TlenXmlGetChildWithGivenAttrValue(XmlNode *node, char *tag, char *attrKey, char *attrValue) -{ - int i; - char *str; - - if (node == NULL || node->numChild <= 0 || tag == NULL || strlen(tag) <= 0 || attrKey == NULL || strlen(attrKey) <= 0 || attrValue == NULL || strlen(attrValue) <= 0) - return NULL; - for (i=0; inumChild; i++) { - if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) { - if ((str=TlenXmlGetAttrValue(node->child[i], attrKey)) != NULL) - if (!strcmp(str, attrValue)) - return node->child[i]; - } - } - return NULL; -} - -static void TlenXmlRemoveChild(XmlNode *node, XmlNode *child) -{ - int i; - - if (node == NULL || child == NULL || node->numChild <= 0) return; - for (i=0; inumChild; i++) { - if (node->child[i] == child) - break; - } - if (i < node->numChild) { - for (++i; inumChild; i++) - node->child[i-1] = node->child[i]; - node->numChild--; - TlenXmlFreeNode(child); - } -} - -void TlenXmlFreeNode(XmlNode *node) -{ - int i; - - if (node == NULL) return; - // Free all children first - for (i=0; inumChild; i++) - TlenXmlFreeNode(node->child[i]); - if (node->child) mir_free(node->child); - // Free all attributes - for (i=0; inumAttr; i++) { - if (node->attr[i]->name) mir_free(node->attr[i]->name); - if (node->attr[i]->value) mir_free(node->attr[i]->value); - mir_free(node->attr[i]); - } - if (node->attr) mir_free(node->attr); - // Free string field - if (node->text) mir_free(node->text); - if (node->name) mir_free(node->name); - // Free the node itself - mir_free(node); -} - -XmlNode *TlenXmlCopyNode(XmlNode *node) -{ - XmlNode *n; - int i; - - if (node == NULL) return NULL; - n = (XmlNode *) mir_alloc(sizeof(XmlNode)); - // Copy attributes - if (node->numAttr > 0) { - n->attr = (XmlAttr **) mir_alloc(node->numAttr*sizeof(XmlAttr *)); - for (i=0; inumAttr; i++) { - n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); - if (node->attr[i]->name) n->attr[i]->name = mir_strdup(node->attr[i]->name); - else n->attr[i]->name = NULL; - if (node->attr[i]->value) n->attr[i]->value = mir_strdup(node->attr[i]->value); - else n->attr[i]->value = NULL; - } - } - else - n->attr = NULL; - // Recursively copy children - if (node->numChild > 0) { - n->child = (XmlNode **) mir_alloc(node->numChild*sizeof(XmlNode *)); - for (i=0; inumChild; i++) - n->child[i] = TlenXmlCopyNode(node->child[i]); - } - else - n->child = NULL; - // Copy other fields - n->numAttr = node->numAttr; - n->maxNumAttr = node->numAttr; - n->numChild = node->numChild; - n->maxNumChild = node->numChild; - n->depth = node->depth; - n->state = node->state; - n->name = (node->name)?mir_strdup(node->name):NULL; - n->text = (node->text)?mir_strdup(node->text):NULL; - - return n; -} - -XmlNode *TlenXmlCreateNode(char *name) -{ - XmlNode *n; - - if (name == NULL) - return NULL; - - n = (XmlNode *) mir_alloc(sizeof(XmlNode)); - memset(n, 0, sizeof(XmlNode)); - n->name = mir_strdup(name); - return n; -} - -void TlenXmlAddAttr(XmlNode *n, char *name, char *value) -{ - int i; - - if (n == NULL || name == NULL || value == NULL) - return; - - i = n->numAttr; - (n->numAttr)++; - n->attr = (XmlAttr **) mir_realloc(n->attr, sizeof(XmlAttr *) * n->numAttr); - n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); - n->attr[i]->name = mir_strdup(name); - n->attr[i]->value = mir_strdup(value); -} - -XmlNode *TlenXmlAddChild(XmlNode *n, char *name) -{ - int i; - - if (n == NULL || name == NULL) - return NULL; - - i = n->numChild; - n->numChild++; - n->child = (XmlNode **) mir_realloc(n->child, sizeof(XmlNode *) * n->numChild); - n->child[i] = (XmlNode *) mir_alloc(sizeof(XmlNode)); - memset(n->child[i], 0, sizeof(XmlNode)); - n->child[i]->name = mir_strdup(name); - return n->child[i]; -} - -void TlenXmlAddText(XmlNode *n, char *text) -{ - if (n != NULL && text != NULL) { - if (n->text) mir_free(n->text); - n->text = mir_strdup(text); - } -} - +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda NG +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +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. + +*/ + +#include "tlen.h" +#include + +static BOOL TlenXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr); +static void TlenXmlRemoveChild(XmlNode *node, XmlNode *child); + +void TlenXmlInitState(XmlState *xmlState) +{ + if (xmlState == NULL) return; + xmlState->root.name = NULL; + xmlState->root.depth = 0; + xmlState->root.numAttr = 0; + xmlState->root.maxNumAttr = 0; + xmlState->root.attr = NULL; + xmlState->root.numChild = 0; + xmlState->root.maxNumChild = 0; + xmlState->root.child = NULL; + xmlState->root.text = NULL; + xmlState->root.state = NODE_OPEN; + xmlState->callback1_open = NULL; + xmlState->callback1_close = NULL; + xmlState->callback2_open = NULL; + xmlState->callback2_close = NULL; + xmlState->userdata1_open = NULL; + xmlState->userdata1_close = NULL; + xmlState->userdata2_open = NULL; + xmlState->userdata2_close = NULL; +} + +void TlenXmlDestroyState(XmlState *xmlState) +{ + int i; + XmlNode *node; + + if (xmlState == NULL) + return; + // Note: cannot use TlenXmlFreeNode() to free xmlState->root + // because it will do mir_free(xmlState->root) which is not freeable. + node = &(xmlState->root); + // Free all children first + for (i=0; inumChild; i++) + TlenXmlFreeNode(node->child[i]); + mir_free(node->child); + // Free all attributes + for (i=0; inumAttr; i++) { + mir_free(node->attr[i]->name); + mir_free(node->attr[i]->value); + mir_free(node->attr[i]); + } + mir_free(node->attr); + // Free string field + mir_free(node->text); + mir_free(node->name); + /* mir_free(xmlState) - no need, work with static. */ +} + +BOOL TlenXmlSetCallback(XmlState *xmlState, int depth, XmlElemType type, void (*callback)(XmlNode*, void*), void *userdata) +{ + if (depth == 1 && type == ELEM_OPEN) { + xmlState->callback1_open = callback; + xmlState->userdata1_open = userdata; + } + else if (depth == 1 && type == ELEM_CLOSE) { + xmlState->callback1_close = callback; + xmlState->userdata1_close = userdata; + } + else if (depth == 2 && type == ELEM_OPEN) { + xmlState->callback2_open = callback; + xmlState->userdata2_open = userdata; + } + else if (depth == 2 && type == ELEM_CLOSE) { + xmlState->callback2_close = callback; + xmlState->userdata2_close = userdata; + } + else + return FALSE; + + return TRUE; +} + +#define TAG_MAX_LEN 50 +#define ATTR_MAX_LEN 1024 +int TlenXmlParse(XmlState *xmlState, char *buffer, int datalen) +{ + char *p, *q, *r, *eob; + char *str; + int num; + char tag[TAG_MAX_LEN]; + char attr[ATTR_MAX_LEN]; + XmlElemType elemType = ELEM_OPEN; + + eob = buffer + datalen; + num = 0; + // Skip leading whitespaces + for (p=buffer; p TAG_MAX_LEN) { +// TlenLog("TAG_MAX_LEN too small, ignore current tag"); + } + else { + if (*(p+1) == '/') { // closing tag + strncpy(tag, p+2, r-(p+2)); + tag[r-(p+2)] = '\0'; + elemType = ELEM_CLOSE; + } + else { + if (*(r-1) == '/') { // single open/close tag + strncpy(tag, p+1, r-(p+1)-1); + tag[r-(p+1)-1] = '\0'; + elemType = ELEM_OPENCLOSE; + } + else { + strncpy(tag, p+1, r-(p+1)); + tag[r-(p+1)] = '\0'; + elemType = ELEM_OPEN; + } + } + for (;r ATTR_MAX_LEN) { +// TlenLog("ATTR_MAX_LEN too small, ignore current tag"); + } + else { + strncpy(attr, r, q-r); + if ((q-r)>0 && attr[q-r-1] == '/') { + attr[q-r-1] = '\0'; + elemType = ELEM_OPENCLOSE; + } + else + attr[q-r] = '\0'; + TlenXmlProcessElem(xmlState, elemType, tag, attr); + } + } + num += (q-p+1); + p = q + 1; + if (elemType == ELEM_CLOSE || elemType == ELEM_OPENCLOSE) { + // Skip whitespaces after end tags + for (; pnumAttr >= node->maxNumAttr) { + node->maxNumAttr = node->numAttr + 20; + node->attr = (XmlAttr **) mir_realloc(node->attr, node->maxNumAttr*sizeof(XmlAttr *)); + } + a = node->attr[node->numAttr] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); + node->numAttr++; + + // Skip possible whitespaces between key and '=' + for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++); + + if (*p == '\0') { + a->name = (char *) mir_alloc(klen+1); + strncpy(a->name, kstart, klen); + a->name[klen] = '\0'; + a->value = mir_strdup(""); + break; + } + + if (*p != '=') { + a->name = (char *) mir_alloc(klen+1); + strncpy(a->name, kstart, klen); + a->name[klen] = '\0'; + a->value = mir_strdup(""); + continue; + } + + // Found '=' + p++; + + // Skip possible whitespaces between '=' and value + for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++); + + if (*p == '\0') { + a->name = (char *) mir_alloc(klen+1); + strncpy(a->name, kstart, klen); + a->name[klen] = '\0'; + a->value = mir_strdup(""); + break; + } + + // Fetch value + if (*p == '\'' || *p == '"') { + p++; + vstart = p; + for (;*p != '\0' && *p != *(vstart-1); p++); + vlen = p-vstart; + if (*p != '\0') p++; + } + else { + vstart = p; + for (;*p != '\0' && *p != ' ' && *p != '\t'; p++); + vlen = p-vstart; + } + + a->name = (char *) mir_alloc(klen+1); + strncpy(a->name, kstart, klen); + a->name[klen] = '\0'; + a->value = (char *) mir_alloc(vlen+1); + strncpy(a->value, vstart, vlen); + a->value[vlen] = '\0'; + } +} + +static BOOL TlenXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr) +{ + XmlNode *node, *parentNode, *n; + //BOOL activateCallback = FALSE; + char *text, *attr; + + if (elemText == NULL) return FALSE; + + if (elemType == ELEM_OPEN && !strcmp(elemText, "?xml")) { +// TlenLog("XML: skip tag"); + return TRUE; + } + + // Find active node + node = &(xmlState->root); + parentNode = NULL; + while (node->numChild>0 && node->child[node->numChild-1]->state == NODE_OPEN) { + parentNode = node; + node = node->child[node->numChild-1]; + } + + if (node->state != NODE_OPEN) return FALSE; + + text = mir_strdup(elemText); + + if (elemAttr) + attr = mir_strdup(elemAttr); + else + attr = NULL; + + switch (elemType) { + case ELEM_OPEN: + if (node->numChild >= node->maxNumChild) { + node->maxNumChild = node->numChild + 20; + node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *)); + } + n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode)); + node->numChild++; + n->name = text; + n->depth = node->depth + 1; + n->state = NODE_OPEN; + n->numChild = n->maxNumChild = 0; + n->child = NULL; + n->numAttr = n->maxNumAttr = 0; + n->attr = NULL; + TlenXmlParseAttr(n, attr); + n->text = NULL; + if (n->depth == 1 && xmlState->callback1_open != NULL) + (*(xmlState->callback1_open))(n, xmlState->userdata1_open); + if (n->depth == 2 && xmlState->callback2_open != NULL) + (*xmlState->callback2_open)(n, xmlState->userdata2_open); + break; + case ELEM_OPENCLOSE: + if (node->numChild >= node->maxNumChild) { + node->maxNumChild = node->numChild + 20; + node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *)); + } + n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode)); + node->numChild++; + n->name = text; + n->depth = node->depth + 1; + n->state = NODE_CLOSE; + n->numChild = n->maxNumAttr = 0; + n->child = NULL; + n->numAttr = n->maxNumAttr = 0; + n->attr = NULL; + TlenXmlParseAttr(n, attr); + n->text = NULL; + if (n->depth == 1 && xmlState->callback1_close != NULL) { + (*(xmlState->callback1_close))(n, xmlState->userdata1_close); + TlenXmlRemoveChild(node, n); + } + if (n->depth == 2 && xmlState->callback2_close != NULL) { + (*xmlState->callback2_close)(n, xmlState->userdata2_close); + TlenXmlRemoveChild(node, n); + } + break; + case ELEM_CLOSE: + if (node->name != NULL && !strcmp(node->name, text)) { + node->state = NODE_CLOSE; + int nodeDepth = node->depth; + if (nodeDepth == 1 && xmlState->callback1_close != NULL) { + (*(xmlState->callback1_close))(node, xmlState->userdata1_close); + TlenXmlRemoveChild(parentNode, node); + } + if (nodeDepth == 2 && xmlState->callback2_close != NULL) { + (*xmlState->callback2_close)(node, xmlState->userdata2_close); + TlenXmlRemoveChild(parentNode, node); + } + mir_free(text); + } + else { +// TlenLog("XML: Closing without opening tag", text); + mir_free(text); + if (attr) mir_free(attr); + return FALSE; + } + break; + case ELEM_TEXT: + node->text = text; + break; + default: + mir_free(text); + if (attr) mir_free(attr); + return FALSE; + } + + if (attr) mir_free(attr); + + return TRUE; +} + +char *TlenXmlGetAttrValue(XmlNode *node, char *key) +{ + int i; + + if (node == NULL || node->numAttr <= 0 || key == NULL || strlen(key) <= 0) + return NULL; + for (i=0; inumAttr; i++) { + if (node->attr[i]->name && !strcmp(key, node->attr[i]->name)) + return node->attr[i]->value; + } + return NULL; +} + +XmlNode *TlenXmlGetChild(XmlNode *node, char *tag) +{ + return TlenXmlGetNthChild(node, tag, 1); +} + +XmlNode *TlenXmlGetNthChild(XmlNode *node, char *tag, int nth) +{ + int i, num; + + if (node == NULL || node->numChild <= 0 || tag == NULL || strlen(tag) <= 0 || nth < 1) + return NULL; + num = 1; + for (i=0; inumChild; i++) { + if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) { + if (num == nth) { + return node->child[i]; + } + num++; + } + } + return NULL; +} + +XmlNode *TlenXmlGetChildWithGivenAttrValue(XmlNode *node, char *tag, char *attrKey, char *attrValue) +{ + int i; + char *str; + + if (node == NULL || node->numChild <= 0 || tag == NULL || strlen(tag) <= 0 || attrKey == NULL || strlen(attrKey) <= 0 || attrValue == NULL || strlen(attrValue) <= 0) + return NULL; + for (i=0; inumChild; i++) { + if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) { + if ((str=TlenXmlGetAttrValue(node->child[i], attrKey)) != NULL) + if (!strcmp(str, attrValue)) + return node->child[i]; + } + } + return NULL; +} + +static void TlenXmlRemoveChild(XmlNode *node, XmlNode *child) +{ + int i; + + if (node == NULL || child == NULL || node->numChild <= 0) return; + for (i=0; inumChild; i++) { + if (node->child[i] == child) + break; + } + if (i < node->numChild) { + for (++i; inumChild; i++) + node->child[i-1] = node->child[i]; + node->numChild--; + TlenXmlFreeNode(child); + } +} + +void TlenXmlFreeNode(XmlNode *node) +{ + int i; + + if (node == NULL) + return; + // Free all children first + for (i=0; inumChild; i++) + TlenXmlFreeNode(node->child[i]); + mir_free(node->child); + // Free all attributes + for (i=0; inumAttr; i++) { + mir_free(node->attr[i]->name); + mir_free(node->attr[i]->value); + mir_free(node->attr[i]); + } + mir_free(node->attr); + // Free string field + mir_free(node->text); + mir_free(node->name); + // Free the node itself + mir_free(node); +} + +XmlNode *TlenXmlCopyNode(XmlNode *node) +{ + XmlNode *n; + int i; + + if (node == NULL) return NULL; + n = (XmlNode *) mir_alloc(sizeof(XmlNode)); + // Copy attributes + if (node->numAttr > 0) { + n->attr = (XmlAttr **) mir_alloc(node->numAttr*sizeof(XmlAttr *)); + for (i=0; inumAttr; i++) { + n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); + if (node->attr[i]->name) n->attr[i]->name = mir_strdup(node->attr[i]->name); + else n->attr[i]->name = NULL; + if (node->attr[i]->value) n->attr[i]->value = mir_strdup(node->attr[i]->value); + else n->attr[i]->value = NULL; + } + } + else + n->attr = NULL; + // Recursively copy children + if (node->numChild > 0) { + n->child = (XmlNode **) mir_alloc(node->numChild*sizeof(XmlNode *)); + for (i=0; inumChild; i++) + n->child[i] = TlenXmlCopyNode(node->child[i]); + } + else + n->child = NULL; + // Copy other fields + n->numAttr = node->numAttr; + n->maxNumAttr = node->numAttr; + n->numChild = node->numChild; + n->maxNumChild = node->numChild; + n->depth = node->depth; + n->state = node->state; + n->name = (node->name)?mir_strdup(node->name):NULL; + n->text = (node->text)?mir_strdup(node->text):NULL; + + return n; +} + +XmlNode *TlenXmlCreateNode(char *name) +{ + XmlNode *n; + + if (name == NULL) + return NULL; + + n = (XmlNode *) mir_alloc(sizeof(XmlNode)); + memset(n, 0, sizeof(XmlNode)); + n->name = mir_strdup(name); + return n; +} + +void TlenXmlAddAttr(XmlNode *n, char *name, char *value) +{ + int i; + + if (n == NULL || name == NULL || value == NULL) + return; + + i = n->numAttr; + (n->numAttr)++; + n->attr = (XmlAttr **) mir_realloc(n->attr, sizeof(XmlAttr *) * n->numAttr); + n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); + n->attr[i]->name = mir_strdup(name); + n->attr[i]->value = mir_strdup(value); +} + +XmlNode *TlenXmlAddChild(XmlNode *n, char *name) +{ + int i; + + if (n == NULL || name == NULL) + return NULL; + + i = n->numChild; + n->numChild++; + n->child = (XmlNode **) mir_realloc(n->child, sizeof(XmlNode *) * n->numChild); + n->child[i] = (XmlNode *) mir_alloc(sizeof(XmlNode)); + memset(n->child[i], 0, sizeof(XmlNode)); + n->child[i]->name = mir_strdup(name); + return n->child[i]; +} + +void TlenXmlAddText(XmlNode *n, char *text) +{ + if (n != NULL && text != NULL) { + if (n->text) mir_free(n->text); + n->text = mir_strdup(text); + } +} + -- cgit v1.2.3