summaryrefslogtreecommitdiff
path: root/plugins/MirFox/src/MirandaUtils.cpp
diff options
context:
space:
mode:
authorSzymon Tokarz <wsx22@o2.pl>2013-05-27 22:29:01 +0000
committerSzymon Tokarz <wsx22@o2.pl>2013-05-27 22:29:01 +0000
commitc628a13d98fde8d2555cc6fa8628e0b575021bd4 (patch)
treef25e89f902c0ac82c8f138badbca7f29d331ba18 /plugins/MirFox/src/MirandaUtils.cpp
parent2f2175b11692b8561fd1018161a62685910d08b0 (diff)
MirFox plugin for Miranda NG added
Version 0.5.0.0 Compatible Firefox addon is now available at: https://addons.mozilla.org/pl/firefox/addon/mirfox/versions/0.5.0.0 or http://wsx22.xpdev-hosted.com/ git-svn-id: http://svn.miranda-ng.org/main/trunk@4826 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/MirFox/src/MirandaUtils.cpp')
-rw-r--r--plugins/MirFox/src/MirandaUtils.cpp705
1 files changed, 705 insertions, 0 deletions
diff --git a/plugins/MirFox/src/MirandaUtils.cpp b/plugins/MirFox/src/MirandaUtils.cpp
new file mode 100644
index 0000000000..28ba5c4294
--- /dev/null
+++ b/plugins/MirFox/src/MirandaUtils.cpp
@@ -0,0 +1,705 @@
+#include "common.h"
+#include "MirandaUtils.h"
+
+
+/*static*/ MirandaUtils * MirandaUtils::m_pOnlyOneInstance;
+
+// private constructor
+MirandaUtils::MirandaUtils()
+ : logger(MFLogger::getInstance())
+{
+
+ netlibHandle = NULL;
+ InitializeCriticalSection(&ackMapCs);
+
+}
+
+
+/* static */ void
+MirandaUtils::netlibLog(const wchar_t* szText){
+ MirandaUtils::getInstance()->netlibLog_int(szText);
+}
+
+void
+MirandaUtils::netlibLog_int(const wchar_t* szText){
+ if (netlibHandle) {
+ CallService(MS_NETLIB_LOGW, (WPARAM)netlibHandle, (LPARAM)szText);
+ }
+#ifdef _DEBUG
+ OutputDebugString(szText);
+#endif //_DEBUG
+}
+
+void
+MirandaUtils::netlibRegister(){
+
+ // Register netlib user for logging function
+ NETLIBUSER nlu = { 0 };
+ nlu.cbSize = sizeof(nlu);
+ nlu.flags = NUF_TCHAR | NUF_NOOPTIONS;
+ nlu.szSettingsModule = PLUGIN_DB_ID;
+ nlu.ptszDescriptiveName = mfTranslate(LPGENT("mirfox.netlib.name"), TEXT("MirFox log"));
+
+ netlibHandle = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
+
+}
+
+void
+MirandaUtils::netlibUnregister(){
+
+ Netlib_CloseHandle(netlibHandle);
+ netlibHandle = NULL;
+
+}
+
+
+std::wstring&
+MirandaUtils::getProfileName()
+{
+ if (profileName.size()>0){
+ //profileName is now inited
+ return profileName;
+ }
+
+ wchar_t mirandaProfileNameW[128] = {0};
+ CallService(MS_DB_GETPROFILENAMEW, SIZEOF(mirandaProfileNameW), (WPARAM)mirandaProfileNameW);
+ profileName.append(mirandaProfileNameW);
+
+ return profileName;
+}
+
+
+std::wstring&
+MirandaUtils::getDisplayName()
+{
+ if (displayName.size()>0){
+ //displayName is now inited
+ return displayName;
+ }
+
+ displayName.append(L"Miranda NG v.");
+ char mirandaVersion[128];
+ CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM)SIZEOF(mirandaVersion), (LPARAM)mirandaVersion);
+ displayName.append(_A2T(mirandaVersion));
+ displayName.append(L" (");
+ displayName.append(getProfileName());
+ displayName.append(L")");
+
+ return displayName;
+
+}
+
+
+/*
+ * mfTranslate
+ * It is my old solution of problem with not unique strings that must be translate by miranda.
+ * Function takes unique code (string id) and default translation (english)
+ * if no translation for code is found it returns default string.
+ * mfTranslate works on plugins layer and can't be used with core translated strings
+ * Tell me if this not standard solution cause problems in NG langpacks environment.
+ */
+TCHAR*
+MirandaUtils::mfTranslate(const TCHAR* msgCode, TCHAR* msgDefault)
+{
+ TCHAR* msgTranslated = TranslateTS(msgCode);
+ if (_tcscmp(msgCode, msgTranslated) == 0){
+ //no translation in miranda langpack
+ return msgDefault;
+ } else {
+ return msgTranslated;
+ }
+}
+
+
+void
+MirandaUtils::mfTranslateControl(HWND parentWindowHwnd, long controlId, const TCHAR* msgCode, TCHAR* msgDefault)
+{
+ HWND controlHwnd = GetDlgItem(parentWindowHwnd, controlId);
+ if (controlHwnd != NULL){
+ int currentTextLength = GetWindowTextLength(controlHwnd) + 1;
+ TCHAR* currentTextPtr = new TCHAR[currentTextLength];
+ GetWindowText(controlHwnd, currentTextPtr, currentTextLength);
+ SetWindowText(controlHwnd, mfTranslate(msgCode, msgDefault));
+ delete [] currentTextPtr;
+ }
+}
+
+
+
+
+/*static*/ void
+MirandaUtils::userActionThread(void* threadArg)
+{
+ Thread_Push(0);
+ ActionThreadArgStruct* actionThreadArgPtr = (ActionThreadArgStruct*)threadArg;
+
+ if (actionThreadArgPtr->mirfoxDataPtr == NULL){
+ MFLogger::getInstance()->log(L"MirandaUtils::userActionThread: ERROR mirfoxDataPtr == NULL");
+ return;
+ }
+
+ if (actionThreadArgPtr->mirfoxDataPtr->Plugin_Terminated){
+ MFLogger::getInstance()->log(L"MirandaUtils::userActionThread: Plugin_Terminated return");
+ return;
+ }
+
+ actionThreadArgPtr->mirfoxDataPtr->workerThreadsCount++;
+
+ if (actionThreadArgPtr->menuItemType == 'C'){
+ actionThreadArgPtr->instancePtr->sendMessageToContact(actionThreadArgPtr);
+ } else if (actionThreadArgPtr->menuItemType == 'A'){
+ actionThreadArgPtr->instancePtr->setStatusOnAccount(actionThreadArgPtr);
+ delete actionThreadArgPtr->accountSzModuleName;
+ } else {
+ MFLogger::getInstance()->log(TEXT("MirandaUtils::userActionThread: ERROR: unknown actionThreadArgPtr->menuItemType"));
+ }
+
+ delete actionThreadArgPtr->userActionSelection;
+ actionThreadArgPtr->mirfoxDataPtr->workerThreadsCount--;
+ delete threadArg;
+
+ Thread_Pop();
+ return;
+
+}
+
+
+
+void
+MirandaUtils::sendMessageToContact(ActionThreadArgStruct* args)
+{
+
+ logger->log(L"MirandaUtils::sendMessageToContact: start");
+
+ if (args->targetHandle == NULL){
+ logger->log(L"MirandaUtils::sendMessageToContact: ERROR targetHandle == NULL");
+ return;
+ }
+
+ if (args->userButton == 'R'){ //'R'ight mouse button
+ this->sendMessage(args, args->mirfoxDataPtr->rightClickSendMode);
+ } else if (args->userButton == 'M'){ //'M'iddle mouse button
+ this->sendMessage(args, args->mirfoxDataPtr->middleClickSendMode);
+ } else { //'L'eft mouse button
+ this->sendMessage(args, args->mirfoxDataPtr->leftClickSendMode);
+ }
+
+}
+
+
+void
+MirandaUtils::sendMessage(ActionThreadArgStruct* args, MFENUM_SEND_MESSAGE_MODE mode)
+{
+
+ logger->log_p(L"MirandaUtils::sendMessage: mode = [%d] to = [" SCNuPTR L"] msg = [%s]", mode, args->targetHandle, args->userActionSelection );
+
+ if (mode == MFENUM_SMM_ONLY_SEND || mode == MFENUM_SMM_SEND_AND_SHOW_MW){
+
+ //TODO - metacontacts support - C:\MIRANDA\SOURCES\PLUGINS\popup_trunk\src\popup_wnd2.cpp : 1083
+ // //check for MetaContact and get szProto from subcontact
+ // if(strcmp(targetHandleSzProto, gszMetaProto)==0) {
+ // HANDLE hSubContact = (HANDLE)CallService(MS_MC_GETDEFAULTCONTACT, (WPARAM)hContact, 0);
+ // if(!hSubContact) return FALSE;
+ // targetHandleSzProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hSubContact, 0);
+ // }
+
+ char* targetHandleSzProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)args->targetHandle, 0); //targetHandleSzProto doesnt need mir_free or delete
+ if (targetHandleSzProto == NULL){
+ logger->log(L"MirandaUtils::sendMessageToContact: ERROR targetHandleSzProto == NULL");
+ return;
+ }
+
+ int mirandaSendModeFlag = getMirandaSendModeFlag(targetHandleSzProto);
+
+ char* msgBuffer = NULL;
+ std::size_t bufSize = 0;
+
+ if (mirandaSendModeFlag == PREF_UTF){
+
+ msgBuffer = mir_utf8encodeW(args->userActionSelection);
+ bufSize = strlen(msgBuffer) + 1;
+
+ } else if (mirandaSendModeFlag == PREF_UNICODE){
+
+ msgBuffer = mir_t2a(args->userActionSelection);
+ bufSize = strlen(msgBuffer) + 1;
+ size_t bufSizeT = (wcslen(args->userActionSelection) + 1) * sizeof(wchar_t);
+ msgBuffer = (char*)mir_realloc(msgBuffer, bufSizeT + bufSize);
+ memcpy((wchar_t*)&msgBuffer[bufSize], args->userActionSelection, bufSizeT);
+ bufSize += bufSizeT;
+
+ }
+
+ logger->log_p(L"SMTC: mirandaSendModeFlag = [%d] bufSize = [%d]", mirandaSendModeFlag, bufSize);
+ HANDLE hProcess = sendMessageMiranda(args->targetHandle, mirandaSendModeFlag, msgBuffer);
+ logger->log_p(L"SMTC: hProcess = [" SCNuPTR L"]", hProcess);
+
+ MIRFOXACKDATA* myMfAck = NULL;
+
+ if (hProcess != NULL){
+ //if hProcess of sending process is null there will not be any ack
+
+ EnterCriticalSection(&ackMapCs);
+ ackMap[hProcess] = (MIRFOXACKDATA*)NULL;
+ LeaveCriticalSection(&ackMapCs);
+
+ int counter = 0;
+ const int ACK_WAIT_TIME = 250; //[ms]
+ const int MAX_ACK_WAIT_COUNTER = 40; //40 * 250ms = 10s
+
+ do {
+ SleepEx(ACK_WAIT_TIME, TRUE);
+ counter++;
+ EnterCriticalSection(&ackMapCs);
+ myMfAck = ackMap[hProcess];
+ LeaveCriticalSection(&ackMapCs);
+ if(Miranda_Terminated() || args->mirfoxDataPtr->Plugin_Terminated){
+ logger->log_p(L"SMTC: ACK break by Plugin_Terminated (=%d) or Miranda_Terminated()", args->mirfoxDataPtr->Plugin_Terminated);
+ break;
+ }
+ } while (myMfAck == NULL && counter <= MAX_ACK_WAIT_COUNTER); //TODO or Plugin_Terminated or Miranda_Terminated()
+
+ logger->log_p(L"SMTC: ACK found counter = [%d] myMfAck = [" SCNuPTR L"]", counter, myMfAck);
+
+ }
+
+
+ MirandaContact* mirandaContact = args->mirfoxDataPtr->getMirandaContactPtrByHandle(args->targetHandle);
+ const wchar_t* contactNameW = NULL;
+ TCHAR* tszAccountName = NULL;
+ if (mirandaContact){
+ contactNameW = mirandaContact->contactNameW.c_str();
+ MirandaAccount* mirandaAccount = mirandaContact->mirandaAccountPtr;
+ if (mirandaAccount){
+ tszAccountName = mirandaAccount->tszAccountName;
+ }
+ }
+
+ if(myMfAck != NULL && myMfAck->result == ACKRESULT_SUCCESS){
+
+ addMessageToDB(args->targetHandle, mirandaSendModeFlag, msgBuffer, bufSize, targetHandleSzProto);
+
+ if (mode == MFENUM_SMM_ONLY_SEND){
+
+ //show notyfication popup (only in SMM_ONLY_SEND mode)
+ wchar_t* buffer = new wchar_t[1024 * sizeof(wchar_t)];
+ if (contactNameW != NULL && tszAccountName != NULL){
+ mir_sntprintf(buffer, 1024, mfTranslate(LPGENT("mirfox.message.sent"), TEXT("Message sent to %s (%s)")), contactNameW, tszAccountName);
+ } else {
+ buffer = mir_wstrdup(mfTranslate(LPGENT("mirfox.message.sent.unknown"), TEXT("Message sent")));
+ }
+
+ if(ServiceExists(MS_POPUP_ADDPOPUPCLASS)) {
+ ShowClassPopupT("MirFox_Notify", mfTranslate(LPGENT("mirfox.popup.notify.title"), TEXT("MirFox")), buffer);
+ } else {
+ PUShowMessageT(buffer, SM_NOTIFY);
+ }
+
+ delete buffer;
+
+ } else if (mode == MFENUM_SMM_SEND_AND_SHOW_MW){
+
+ //notify hook to open window
+ if (args->mirfoxDataPtr != NULL && args->mirfoxDataPtr->hhook_EventOpenMW != NULL){
+
+ OnHookOpenMvStruct* onHookOpenMv = new(OnHookOpenMvStruct);
+ onHookOpenMv->targetHandle = args->targetHandle;
+ onHookOpenMv->msgBuffer = NULL;
+ NotifyEventHooks(args->mirfoxDataPtr->hhook_EventOpenMW, (WPARAM)onHookOpenMv, (LPARAM)NULL);
+
+ } else {
+
+ logger->log(L"SMTC: ERROR1 args->mirfoxDataPtr == NULL || args->mirfoxDataPtr->hhook_EventOpenMW == NULL");
+
+ }
+
+ }
+
+ } else {
+
+ //error - show error popup
+ wchar_t* buffer = new wchar_t[1024 * sizeof(wchar_t)];
+ if (myMfAck != NULL){
+ logger->log_p(L"SMTC: ERROR - Can not send message - result = [%d] ", myMfAck->result);
+ if (myMfAck->errorDesc != NULL){
+ if (contactNameW != NULL && tszAccountName != NULL){
+ mir_sntprintf(buffer, 1024, mfTranslate(LPGENT("mirfox.message.badack.errordesc"), TEXT("Can not send message to %s (%s) - %S")), contactNameW, tszAccountName, myMfAck->errorDesc);
+ } else {
+ mir_sntprintf(buffer, 1024, mfTranslate(LPGENT("mirfox.message.badack.errordesc.unknown"), TEXT("Can not send message - %S")), myMfAck->errorDesc);
+ }
+ } else {
+ if (contactNameW != NULL && tszAccountName != NULL){
+ mir_sntprintf(buffer, 1024, mfTranslate(LPGENT("mirfox.message.badack"), TEXT("Can not send message to %s (%s)")), contactNameW, tszAccountName);
+ } else {
+ buffer = mir_wstrdup(mfTranslate(LPGENT("mirfox.message.badack.unknown"), TEXT("Can not send message - %S")));
+ }
+ }
+
+ } else {
+ logger->log(L"SMTC: ERROR - Can not send message 2");
+ if (contactNameW != NULL && tszAccountName != NULL){
+ mir_sntprintf(buffer, 1024, mfTranslate(LPGENT("mirfox.message.noack"), TEXT("Can not send message to %s (%s)")), contactNameW, tszAccountName);
+ } else {
+ buffer = mir_wstrdup(mfTranslate(LPGENT("mirfox.message.noack.unknown"), TEXT("Can not send message")));
+ }
+ }
+
+ if(ServiceExists(MS_POPUP_ADDPOPUPCLASS)) {
+ ShowClassPopupT("MirFox_Error", mfTranslate(LPGENT("mirfox.popup.error.title"), TEXT("MirFox error")), buffer);
+ } else {
+ PUShowMessageT(buffer, SM_WARNING);
+ }
+
+ delete buffer;
+
+ }
+
+ if (myMfAck != NULL){ //when we found ack, not when we exceed MAX_ACK_WAIT_COUNTER
+ if (myMfAck->errorDesc != NULL) delete myMfAck->errorDesc;
+ delete myMfAck->szModule;
+ delete myMfAck;
+ }
+ EnterCriticalSection(&ackMapCs);
+ ackMap.erase(hProcess);
+ LeaveCriticalSection(&ackMapCs);
+
+ mir_free(msgBuffer);
+
+ } else if (mode == MFENUM_SMM_ONLY_SHOW_MW){
+
+ //notify hook to open window
+ if (args->mirfoxDataPtr != NULL && args->mirfoxDataPtr->hhook_EventOpenMW != NULL){
+
+ OnHookOpenMvStruct* onHookOpenMv = new(OnHookOpenMvStruct);
+ onHookOpenMv->targetHandle = args->targetHandle;
+ //adding newline to message in Message Window, only in this mode
+ std::wstring* msgBuffer = new std::wstring(); //deleted at on_hook_OpenMW
+ msgBuffer->append(args->userActionSelection);
+ msgBuffer->append(L"\r\n");
+ onHookOpenMv->msgBuffer = msgBuffer;
+ NotifyEventHooks(args->mirfoxDataPtr->hhook_EventOpenMW, (WPARAM)onHookOpenMv, (LPARAM)NULL);
+
+ } else {
+ logger->log(L"SMTC: ERROR1 args->mirfoxDataPtr == NULL || args->mirfoxDataPtr->hhook_EventOpenMW == NULL");
+ }
+
+ }
+
+}
+
+
+int
+MirandaUtils::getMirandaSendModeFlag(char* targetHandleSzProto)
+{
+ if (CallProtoService(targetHandleSzProto, PS_GETCAPS, PFLAGNUM_4, 0) & PF4_IMSENDUTF){
+ return PREF_UTF;
+ } else {
+ return PREF_UNICODE;
+ }
+
+}
+
+
+HANDLE
+MirandaUtils::sendMessageMiranda(HANDLE hContact, int mirandaSendModeFlag, char* msgBuffer)
+{
+ return (HANDLE)CallContactService(hContact, PSS_MESSAGE, (WPARAM)mirandaSendModeFlag, (LPARAM)msgBuffer);
+}
+
+
+void
+MirandaUtils::addMessageToDB(HANDLE hContact, int mirandaSendModeFlag, char* msgBuffer, std::size_t bufSize, char* targetHandleSzProto)
+{
+ DBEVENTINFO dbei = {0};
+ dbei.cbSize = sizeof(dbei);
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.flags = DBEF_SENT | ((mirandaSendModeFlag&PREF_UTF)==PREF_UTF ? DBEF_UTF : 0);
+ dbei.szModule = targetHandleSzProto;
+ dbei.timestamp = (DWORD)time(NULL);
+ dbei.cbBlob = (DWORD)bufSize;
+ dbei.pBlob = (PBYTE)msgBuffer;
+ CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei);
+}
+
+
+//http://www.shloemi.com/2012/09/solved-setforegroundwindow-win32-api-not-always-works/
+/*static*/ void
+MirandaUtils::ForceForegroundWindow(HWND hWnd)
+{
+ DWORD foreThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
+ DWORD appThread = GetCurrentThreadId();
+
+ if (foreThread != appThread) {
+ AttachThreadInput(foreThread, appThread, true);
+ BringWindowToTop(hWnd);
+ ShowWindow(hWnd, SW_SHOW);
+ AttachThreadInput(foreThread, appThread, false);
+ } else {
+ BringWindowToTop(hWnd);
+ ShowWindow(hWnd, SW_SHOW);
+ }
+}
+
+
+/*static*/ int
+MirandaUtils::on_hook_OpenMW(WPARAM wParam, LPARAM lParam)
+{
+
+ OnHookOpenMvStruct* param = (OnHookOpenMvStruct*)wParam;
+
+ if (param->msgBuffer != NULL){
+
+ //open window and paste text
+ if (ServiceExists(MS_MSG_SENDMESSAGEW)){
+
+ char* msgBuffer = (char*)mir_wstrdup(param->msgBuffer->c_str());
+ CallServiceSync(MS_MSG_SENDMESSAGEW, (WPARAM)param->targetHandle, (LPARAM)msgBuffer);
+ mir_free(msgBuffer);
+
+ } else {
+
+ char* msgBuffer = mir_u2a(param->msgBuffer->c_str());
+ CallServiceSync(MS_MSG_SENDMESSAGE, (WPARAM)param->targetHandle, (LPARAM)msgBuffer);
+ mir_free(msgBuffer);
+
+ }
+
+ delete param->msgBuffer;
+
+ } else {
+
+ //only open window
+ CallServiceSync(MS_MSG_SENDMESSAGE, (WPARAM)param->targetHandle, LPARAM(NULL));
+
+ }
+
+ // show and focus window
+ if (db_get_b(0, PLUGIN_DB_ID, "doNotFocusWhenOpenMW", 0) == 1){
+ delete param;
+ return 0;
+ }
+
+ MessageWindowData mwd;
+ mwd.cbSize = sizeof(MessageWindowData);
+ mwd.hContact = param->targetHandle;
+ mwd.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+
+ MessageWindowInputData mwid;
+ mwid.cbSize = sizeof(MessageWindowInputData);
+ mwid.hContact = param->targetHandle;
+ mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+
+ delete param;
+
+ if (!CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&mwid, (LPARAM)&mwd) && mwd.hwndWindow){
+ HWND parent;
+ HWND hWnd = mwd.hwndWindow;
+ while((parent = GetParent(hWnd)) != 0) hWnd = parent; // ensure we have the top level window (need parent window for scriver & tabsrmm)
+ ForceForegroundWindow(hWnd);
+ }
+
+ return 0;
+}
+
+
+
+
+
+void
+MirandaUtils::setStatusOnAccount(ActionThreadArgStruct* args)
+{
+
+ logger->log(L"MirandaUtils::setStatusOnAccount: start");
+ int status = CallProtoService(args->accountSzModuleName, PS_GETSTATUS, 0, 0);
+ logger->log_p(L"SSOA: on account: [%S] targetHandle = [" SCNuPTR L"] at status = [%d]", args->accountSzModuleName, args->targetHandle, status);
+
+ int result = -1;
+
+ if (!(CallProtoService(args->accountSzModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_INDIVMODEMSG)){
+ result = CallProtoService(args->accountSzModuleName, PS_SETAWAYMSGW, (WPARAM)status, (LPARAM)args->userActionSelection);
+ if (result == CALLSERVICE_NOTFOUND){
+ char *szMsg = mir_u2a(args->userActionSelection);
+ result = CallProtoService(args->accountSzModuleName, PS_SETAWAYMSG, (WPARAM)status, (LPARAM)szMsg);
+ mir_free(szMsg);
+ }
+ }
+
+ MirandaAccount* mirandaAccount = args->mirfoxDataPtr->getMirandaAccountPtrBySzModuleName(args->accountSzModuleName);
+ TCHAR* tszAccountName = NULL;
+ if (mirandaAccount){
+ tszAccountName = mirandaAccount->tszAccountName;
+ }
+
+ wchar_t* buffer = new wchar_t[1024 * sizeof(wchar_t)];
+ if(result == 0){
+
+ if (tszAccountName != NULL){
+ logger->log_p(L"SSOA: Status message set on [%s]", tszAccountName);
+ mir_sntprintf(buffer, 1024, mfTranslate(LPGENT("mirfox.statusmsg.set"), TEXT("Status message set on %s")), tszAccountName);
+ } else {
+ logger->log(L"SSOA: Status message set");
+ buffer = mir_wstrdup(mfTranslate(LPGENT("mirfox.statusmsg.set.unknown"), TEXT("Status message set")));
+ }
+
+ if(ServiceExists(MS_POPUP_ADDPOPUPCLASS)) {
+ ShowClassPopupT("MirFox_Notify", mfTranslate(LPGENT("mirfox.popup.notify.title"), TEXT("MirFox")), buffer);
+ } else {
+ PUShowMessageT(buffer, SM_NOTIFY);
+ }
+
+ } else {
+
+ if (tszAccountName != NULL){
+ logger->log_p(L"SSOA: ERROR - Can not set status message 2 on [%s] - result = [%d] ", tszAccountName, result);
+ mir_sntprintf(buffer, 1024, mfTranslate(LPGENT("mirfox.statusmsg.error"), TEXT("Can not set status message on %s")), tszAccountName);
+ } else {
+ logger->log_p(L"SSOA: ERROR - Can not set status message 2 - result = [%d] ", result);
+ buffer = mir_wstrdup(mfTranslate(LPGENT("mirfox.statusmsg.error.unknown"), TEXT("Can not set status message")));
+ }
+
+ if(ServiceExists(MS_POPUP_ADDPOPUPCLASS)) {
+ ShowClassPopupT("MirFox_Error", mfTranslate(LPGENT("mirfox.popup.error.title"), TEXT("MirFox error")), buffer);
+ } else {
+ PUShowMessageT(buffer, SM_WARNING);
+ }
+
+ }
+ delete buffer;
+
+}
+
+
+
+
+int
+MirandaUtils::onProtoAck(WPARAM wParam, LPARAM lParam)
+{
+ MirandaUtils* mirandaUtils = MirandaUtils::getInstance();
+ mirandaUtils->onProtoAckOnInstance((ACKDATA*)lParam);
+ return 0;
+}
+
+
+void
+MirandaUtils::onProtoAckOnInstance(ACKDATA* ack)
+{
+
+ if (ack == NULL || ack->type != ACKTYPE_MESSAGE){
+ //we are waiting for ACKTYPE_MESSAGE ack's
+ return;
+ }
+
+ EnterCriticalSection(&ackMapCs);
+ ackMapIt = ackMap.find(ack->hProcess);
+ if (ackMapIt != ackMap.end()){
+ //we waited for this ack, save copy (only needed data) to our map. Oryginal ack object is unstable, it is probably controled not in our thread
+ logger->log_p(L"!!! ACK received acl: hContact = [" SCNuPTR L"] result = [%d] szModule = [%S] lParam = [%S]", ack->hProcess, ack->result, ack->szModule, (ack->lParam != NULL && *((char*)ack->lParam) != '\0') ? (char*)ack->lParam : "null");
+ MIRFOXACKDATA* myMfAck = new(MIRFOXACKDATA);
+ myMfAck->result = ack->result;
+ myMfAck->hContact = ack->hContact;
+ size_t len1 = strlen(ack->szModule) + 1;
+ char* myMfSzModulePtr = new char[len1];
+ strcpy_s(myMfSzModulePtr, len1, ack->szModule);
+ myMfAck->szModule = myMfSzModulePtr;
+ if (ack->lParam != NULL && *((char*)ack->lParam) != '\0'){
+ size_t len2 = strlen((char*)ack->lParam) + 1;
+ char* myMfSzLparamPtr = new char[len2];
+ strcpy_s(myMfSzLparamPtr, len2, (char*)ack->lParam);
+ myMfAck->errorDesc = myMfSzLparamPtr;
+ } else {
+ myMfAck->errorDesc = NULL;
+ }
+
+ ackMap[ack->hProcess] = myMfAck;
+ }
+ LeaveCriticalSection(&ackMapCs);
+
+}
+
+
+
+
+
+
+
+
+#define OLD_PLUGIN_DB_ID "MirfoxMiranda"
+/**
+ * function changes db module name from "MirfoxMiranda" (used before 0.3.0.0) to "Mirfox"
+ */
+void
+MirandaUtils::translateOldDBNames() {
+
+
+ //settings "clientsProfilesFilterCheckbox", "clientsProfilesFilterString"
+ int opt1KeyValue = db_get_b(0, OLD_PLUGIN_DB_ID, "clientsProfilesFilterCheckbox", 0);
+ if (opt1KeyValue != 0){
+
+ db_set_b(0, PLUGIN_DB_ID, "clientsProfilesFilterCheckbox", opt1KeyValue);
+ db_unset(0, OLD_PLUGIN_DB_ID, "clientsProfilesFilterCheckbox");
+ logger->log(L"TranslateOldDBNames: 'clientsProfilesFilterCheckbox' db entry found and moved");
+
+ } else {
+
+ logger->log(L"TranslateOldDBNames: no old settings found. returning.");
+ return;
+
+ }
+
+
+ DBVARIANT opt2Dbv = {0};
+ INT_PTR opt2Result = db_get_s(0, OLD_PLUGIN_DB_ID, "clientsProfilesFilterString", &opt2Dbv, DBVT_TCHAR);
+ if (opt2Result == 0){ //success
+
+ std::wstring clientsProfilesFilterString = opt2Dbv.pwszVal;
+ db_set_ts(0, PLUGIN_DB_ID, "clientsProfilesFilterString", clientsProfilesFilterString.c_str());
+ db_unset(0, OLD_PLUGIN_DB_ID, "clientsProfilesFilterString");
+ logger->log(L"TranslateOldDBNames: 'clientsProfilesFilterString' db entry found and moved");
+
+ }
+ db_free(&opt2Dbv);
+
+
+
+
+ //account's settings "ACCOUNTSTATE_"
+ int accountsTmpCount = 0;
+ PROTOACCOUNT **accountsTmp;
+ CallService(MS_PROTO_ENUMACCOUNTS, (WPARAM)&accountsTmpCount, (LPARAM)&accountsTmp);
+ for(int i=0; i<accountsTmpCount; i++) {
+
+ logger->log_p(L"TranslateOldDBNames: found ACCOUNT: [%s] protocol: [%S]", accountsTmp[i]->tszAccountName, accountsTmp[i]->szProtoName);
+
+ std::string mirandaAccountDBKey("ACCOUNTSTATE_");
+ mirandaAccountDBKey += accountsTmp[i]->szModuleName;
+ int keyValue = db_get_b(0, OLD_PLUGIN_DB_ID, mirandaAccountDBKey.c_str(), 0);
+ if (keyValue != 0){
+ db_set_b(0, PLUGIN_DB_ID, mirandaAccountDBKey.c_str(), keyValue);
+ db_unset(0, OLD_PLUGIN_DB_ID, mirandaAccountDBKey.c_str());
+ logger->log(L"TranslateOldDBNames: ACCOUNT db entry found and moved");
+ }
+
+ }
+
+
+ //contacts "state"
+ for (HANDLE hContact = db_find_first(); hContact; hContact = db_find_next(hContact)){
+
+ logger->log_p(L"TranslateOldDBNames: found CONTACT: [" SCNuPTR L"]", hContact);
+
+ int keyValue = db_get_b(hContact, OLD_PLUGIN_DB_ID, "state", 0);
+ if (keyValue != 0){
+ db_set_b(hContact, PLUGIN_DB_ID, "state", keyValue);
+ db_unset(hContact, OLD_PLUGIN_DB_ID, "state");
+ logger->log(L"TranslateOldDBNames: CONTACT db entry found and moved");
+ }
+
+ }
+
+
+
+ //delete db module
+ CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)OLD_PLUGIN_DB_ID);
+
+}
+