From 467eb738e716c92abc1232c3f81c77c4c9098415 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 19 Dec 2013 19:30:14 +0000 Subject: total dejunkification of Contacts+: - Unicode; - own utf8 engine removed; - version bump git-svn-id: http://svn.miranda-ng.org/main/trunk@7288 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/ContactsPlus/src/send.cpp | 919 ++++++++++++++++++-------------------- 1 file changed, 439 insertions(+), 480 deletions(-) (limited to 'plugins/ContactsPlus/src/send.cpp') diff --git a/plugins/ContactsPlus/src/send.cpp b/plugins/ContactsPlus/src/send.cpp index 7c3677d040..4ee9b17b91 100644 --- a/plugins/ContactsPlus/src/send.cpp +++ b/plugins/ContactsPlus/src/send.cpp @@ -26,172 +26,165 @@ /* TSendProcessList */ -void TSendProcessList::Add(HANDLE hProcc) { - EnterCriticalSection(&lock); - Items=(HANDLE*)realloc(Items, (Count+1)*sizeof(HANDLE)); - Items[Count]=hProcc; - Count++; - LeaveCriticalSection(&lock); +TSendProcessList::TSendProcessList() +{ + InitializeCriticalSection(&lock); + Count = 0; + Items = NULL; } - -void TSendProcessList::Remove(HANDLE hProcc) { - EnterCriticalSection(&lock); - for (int i=0; inContacts = nContacts; + ackData->aContacts = (HANDLE*)mir_alloc(nContacts*sizeof(HANDLE)); + memmove(ackData->aContacts, phContacts, nContacts*sizeof(HANDLE)); // copy the array of hContact for ack array + EnableDlgItem(hwndDlg, IDOK, FALSE); + EnableDlgItem(hwndDlg, IDC_LIST, FALSE); + return TRUE; // Success } +int TSendContactsData::SendContacts(HWND hwndDlg) +{ + char *szProto = GetContactProto(hContact); + int nMaxContacts = CallProtoService(szProto, PS_GETCAPS, PFLAG_MAXCONTACTSPERPACKET, (LPARAM)hContact); -void TSendContactsData::AddContact(HANDLE hContact) { - aContacts = (HANDLE*)realloc(aContacts, (nContacts+1)*sizeof(HANDLE)); - aContacts[nContacts] = hContact; - nContacts++; -} + if (!nMaxContacts) { + ShowErrorDlg(hwndDlg, "The selected contact does not support receiving contacts.", FALSE); + return FALSE; + } + // hook event - we want to receive protocol acknowledgements + HookProtoAck(hwndDlg); -int TSendContactsData::SendContactsPacket(HWND hwndDlg, HANDLE *phContacts, int nContacts) { - HANDLE hProcc = (HANDLE)CallContactService(hContact, PSS_CONTACTS, MAKEWPARAM(0, nContacts), (LPARAM)phContacts); - if (!hProcc) - { // on trivial error - do not close dialog - ShowErrorDlg(hwndDlg, "Contacts transfer failed!", FALSE); - return FALSE; // Failure - } - TAckData* ackData = gaAckData.Add(hProcc, new TAckData(hContact)); - uacklist.Add(hProcc); - ackData->nContacts = nContacts; - ackData->aContacts = (HANDLE*)malloc(nContacts*sizeof(HANDLE)); - memmove(ackData->aContacts, phContacts, nContacts*sizeof(HANDLE)); // copy the array of hContact for ack array - EnableDlgItem(hwndDlg, IDOK, FALSE); - EnableDlgItem(hwndDlg, IDC_LIST, FALSE); - - return TRUE; // Success -} + // send in packets, each of nMaxContacts contacts + for (int j = 0; j < nContacts / nMaxContacts; j++) + if (!SendContactsPacket(hwndDlg, aContacts + j*nMaxContacts, nMaxContacts)) + return FALSE; + if (nContacts%nMaxContacts != 0) + if (!SendContactsPacket(hwndDlg, aContacts + nContacts / nMaxContacts*nMaxContacts, nContacts%nMaxContacts)) + return FALSE; -int TSendContactsData::SendContacts(HWND hwndDlg) { - char* szProto =GetContactProto(hContact); - int nMaxContacts = CallProtoService(szProto, PS_GETCAPS, PFLAG_MAXCONTACTSPERPACKET, (LPARAM)hContact); - - if (!nMaxContacts) { - ShowErrorDlg(hwndDlg, "The selected contact does not support receiving contacts.", FALSE); - return FALSE; - } - // hook event - we want to receive protocol acknowledgements - HookProtoAck(hwndDlg); - - for (int j = 0; j < nContacts / nMaxContacts; j++ ) - { // send in packets, each of nMaxContacts contacts - if (!SendContactsPacket(hwndDlg, aContacts + j*nMaxContacts, nMaxContacts)) - return FALSE; - } - if (nContacts%nMaxContacts!=0) - { - if (!SendContactsPacket(hwndDlg, aContacts + nContacts/nMaxContacts*nMaxContacts, nContacts%nMaxContacts)) - return FALSE; - } - return TRUE; + return TRUE; } - /* Send Dialog Implementation */ static void ResetListOptions(HWND hwndList) { - COLORREF bgColour,fgColour; - - SendMessageT(hwndList,CLM_SETBKBITMAP,0,(LPARAM)(HBITMAP)NULL); - bgColour=GetSysColor(COLOR_WINDOW); - SendMessageT(hwndList,CLM_SETBKCOLOR,bgColour,0); - SendMessageT(hwndList,CLM_SETGREYOUTFLAGS,0,0); - SendMessageT(hwndList,CLM_SETLEFTMARGIN,4,0); - SendMessageT(hwndList,CLM_SETINDENT,10,0); - for(int i=0; i<=FONTID_MAX; i++) - { - fgColour=(COLORREF)SendMessageT(hwndList,CLM_GETTEXTCOLOR,i,0); - if(abs(GetRValue(fgColour)-GetRValue(bgColour))<10 && - abs(GetGValue(fgColour)-GetGValue(bgColour))<10 && - abs(GetBValue(fgColour)-GetBValue(bgColour))<10) - SendMessageT(hwndList,CLM_SETTEXTCOLOR,i,GetSysColor(COLOR_WINDOWTEXT)); - } + COLORREF bgColour, fgColour; + + SendMessage(hwndList, CLM_SETBKBITMAP, 0, (LPARAM)(HBITMAP)NULL); + bgColour = GetSysColor(COLOR_WINDOW); + SendMessage(hwndList, CLM_SETBKCOLOR, bgColour, 0); + SendMessage(hwndList, CLM_SETGREYOUTFLAGS, 0, 0); + SendMessage(hwndList, CLM_SETLEFTMARGIN, 4, 0); + SendMessage(hwndList, CLM_SETINDENT, 10, 0); + for (int i = 0; i <= FONTID_MAX; i++) { + fgColour = (COLORREF)SendMessage(hwndList, CLM_GETTEXTCOLOR, i, 0); + if (abs(GetRValue(fgColour) - GetRValue(bgColour)) < 10 && + abs(GetGValue(fgColour) - GetGValue(bgColour)) < 10 && + abs(GetBValue(fgColour) - GetBValue(bgColour)) < 10) + SendMessage(hwndList, CLM_SETTEXTCOLOR, i, GetSysColor(COLOR_WINDOWTEXT)); + } } - static HANDLE FindNextClistContact(HWND hList, HANDLE hContact, HANDLE *phItem) { HANDLE hNextContact = db_find_next(hContact); HANDLE hNextItem = NULL; - - while (hNextContact && !(hNextItem = (HANDLE)SendMessageT(hList, CLM_FINDCONTACT, (WPARAM)hNextContact,0))) + + while (hNextContact && !(hNextItem = (HANDLE)SendMessage(hList, CLM_FINDCONTACT, (WPARAM)hNextContact, 0))) hNextContact = db_find_next(hNextContact); if (phItem) @@ -204,11 +197,11 @@ static HANDLE FindNextClistContact(HWND hList, HANDLE hContact, HANDLE *phItem) static HANDLE FindFirstClistContact(HWND hList, HANDLE *phItem) { HANDLE hContact = db_find_first(); - HANDLE hItem = (HANDLE)SendMessageT(hList, CLM_FINDCONTACT, (WPARAM)hContact, 0); + HANDLE hItem = (HANDLE)SendMessage(hList, CLM_FINDCONTACT, (WPARAM)hContact, 0); if (hContact && !hItem) return FindNextClistContact(hList, hContact, phItem); - + if (phItem) *phItem = hItem; @@ -220,317 +213,289 @@ bool binListEvent = FALSE; static void SetAllContactChecks(HWND hwndList, HANDLE hReceiver) // doubtful name { - HANDLE hContact, hItem; - - if (binListEvent) return; - binListEvent = TRUE; - char* szProto =GetContactProto(hReceiver); - if (szProto == NULL) return; - - if (CallService(MS_CLUI_GETCAPS, 0, 0) & CLUIF_HIDEEMPTYGROUPS && db_get_b(NULL, "CList", "HideEmptyGroups", SETTING_USEGROUPS_DEFAULT)) - SendMessageT(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM) TRUE, 0); - else - SendMessageT(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM) FALSE, 0); - - hContact = FindFirstClistContact(hwndList, &hItem); - while (hContact) - { - char* szProto2 =GetContactProto(hContact); - - if (strcmpnull(szProto, szProto2)) - { // different protocols or protocol undefined, remove contact, useless anyway - SendMessageT(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0); - } - else // otherwise uncheck - SendMessageT(hwndList, CLM_SETCHECKMARK,(WPARAM)hItem, 0); - - hContact = FindNextClistContact(hwndList, hContact, &hItem); - } - - binListEvent = FALSE; -} + if (binListEvent) + return; + + binListEvent = TRUE; + char *szProto = GetContactProto(hReceiver); + if (szProto == NULL) + return; + + if (CallService(MS_CLUI_GETCAPS, 0, 0) & CLUIF_HIDEEMPTYGROUPS && db_get_b(NULL, "CList", "HideEmptyGroups", SETTING_USEGROUPS_DEFAULT)) + SendMessage(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM)TRUE, 0); + else + SendMessage(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM)FALSE, 0); + HANDLE hItem, hContact = FindFirstClistContact(hwndList, &hItem); + while (hContact) { + char* szProto2 = GetContactProto(hContact); + + // different protocols or protocol undefined, remove contact, useless anyway + if (strcmpnull(szProto, szProto2)) + SendMessage(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0); + else // otherwise uncheck + SendMessage(hwndList, CLM_SETCHECKMARK, (WPARAM)hItem, 0); + + hContact = FindNextClistContact(hwndList, hContact, &hItem); + } + + binListEvent = FALSE; +} -INT_PTR CALLBACK SendDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +INT_PTR CALLBACK SendDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - TSendContactsData* wndData = (TSendContactsData*)GetWindowLongPtr(hwndDlg, DWLP_USER); - - switch (msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - SendMessageT(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); - ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST)); - SetAllContactChecks(GetDlgItem(hwndDlg,IDC_LIST), (HANDLE)lParam); - WindowList_Add(ghSendWindowList, hwndDlg, (HANDLE)lParam); - wndData = new TSendContactsData((HANDLE)lParam); - SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)wndData); - // new dlg init - wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), LPGEN("Add Contact Permanently to List")); - wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), LPGEN("View User's Details")); - wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), LPGEN("View User's History")); - wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), LPGEN("User Menu")); - - SendMessageT(hwndDlg,DM_UPDATETITLE,0,0); - // new dialog init done - return TRUE; - } - - case WM_SETFOCUS: - SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->idFrom == IDC_LIST) - { - switch (((LPNMHDR)lParam)->code) - { - case CLN_NEWCONTACT: - case CLN_LISTREBUILT: // rebuild list - if (wndData) SetAllContactChecks(GetDlgItem(hwndDlg,IDC_LIST), wndData->hContact); - case CLN_OPTIONSCHANGED: - ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST)); - break; - } - } - break; - - case WM_TIMER: - if (wParam == TIMERID_MSGSEND) - { - KillTimer(hwndDlg,wParam); - wndData->ShowErrorDlg(hwndDlg, "The contacts send timed out.", TRUE); - } - break; - - case DM_ERRORDECIDED: - { - EnableWindow(hwndDlg,TRUE); - wndData->hError = NULL; - switch(wParam) - { - case MSGERROR_CANCEL: - { - wndData->UnhookProtoAck(); - if (wndData->uacklist.Count) - { - for (int i=0; iuacklist.Count; i++) - { - delete gaAckData.Remove(wndData->uacklist.Items[i]); // remove our ackdata & release structure - } - SAFE_FREE((void**)&wndData->uacklist.Items); - wndData->uacklist.Count = 0; - } - EnableDlgItem(hwndDlg,IDOK,TRUE); - EnableDlgItem(hwndDlg,IDC_LIST,TRUE); - ShowWindow(hwndDlg,SW_SHOWNORMAL); - SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); - break; - } - case MSGERROR_DONE: - // contacts were delivered succesfully after timeout - SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); - wndData->UnhookProtoAck(); - break; - - case MSGERROR_RETRY:// resend timeouted packets - - for (int i=0; iuacklist.Count; i++) - { - TAckData* lla = gaAckData.Remove(wndData->uacklist.Items[i]); - HANDLE hProcc = (HANDLE)CallContactService(wndData->hContact, PSS_CONTACTS, MAKEWPARAM(0, lla->nContacts), (LPARAM)lla->aContacts); - - if (!hProcc) // if fatal do not include - { - wndData->uacklist.Remove(wndData->uacklist.Items[i]); - delete lla; // release the structure - continue; - } - else - { // update process code - wndData->uacklist.Items[i] = hProcc; - gaAckData.Add(hProcc, lla); - } - }// collect TAckData for our window, resend - break; - } - break; - } - - case WM_COMMAND: - { - if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->hContact)) - break; - - switch(LOWORD(wParam)) - { - case IDOK: - { - if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDOK))) break; - HANDLE hContact, hItem; - wndData->ClearContacts(); // do not include contacts twice - - HWND hList = GetDlgItem(hwndDlg, IDC_LIST); - hContact = FindFirstClistContact(hList, &hItem); - while (hContact) - { - if (SendMessageT(hList, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) - { // build list of contacts to send - wndData->AddContact(hContact); - } - hContact = FindNextClistContact(hList, hContact, &hItem); - } - /* send contacts */ - if (!wndData->SendContacts(hwndDlg)) - break; - - SetTimer(hwndDlg,TIMERID_MSGSEND,db_get_dw(NULL,"SRMsg","MessageTimeout",TIMEOUT_MSGSEND),NULL); - - break; - } - case IDCANCEL: - { - DestroyWindow(hwndDlg); - break; - } - case ID_SELECTALL: - { // select all contacts - HANDLE hContact, hItem; - HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST); - - hContact = FindFirstClistContact(hwndList, &hItem); - while (hContact) { - SendMessageT(hwndList,CLM_SETCHECKMARK,(WPARAM)hItem, 1); - hContact = FindNextClistContact(hwndList, hContact, &hItem); - }; - break; - } - case IDC_USERMENU: - { - RECT rc; - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)wndData->hContact,0); - - GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU),&rc); - TrackPopupMenu(hMenu,0,rc.left,rc.bottom,0,hwndDlg,NULL); - DestroyMenu(hMenu); - break; - } - case IDC_HISTORY: - CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->hContact,0); - break; - - case IDC_DETAILS: - CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->hContact,0); - break; - - case IDC_ADD: - DialogAddContactExecute(hwndDlg, wndData->hContact); - break; - } - break; - } - case HM_EVENTSENT: - { - ACKDATA *ack=(ACKDATA*)lParam; - DBEVENTINFO dbei={0}; - - if (ack->type != ACKTYPE_CONTACTS) break; - - TAckData* ackData = gaAckData.Get(ack->hProcess); - - if (ackData == NULL) break; // on unknown hprocc go away - - if (ackData->hContact != ack->hContact) break; // this is not ours, strange - - if (ack->result == ACKRESULT_FAILED) - { // some process failed, show error dialog - KillTimer(hwndDlg, TIMERID_MSGSEND); - wndData->ShowErrorDlg(hwndDlg, (char *)ack->lParam, TRUE); - // ackData get used in error handling, released there - break; - } - - dbei.cbSize = sizeof(dbei); - dbei.szModule =GetContactProto(ackData->hContact); - dbei.eventType = EVENTTYPE_CONTACTS; - dbei.flags = DBEF_SENT| DBEF_UTF; - dbei.timestamp = time(NULL); - //make blob - TCTSend* maSend = (TCTSend*)_alloca(ackData->nContacts*sizeof(TCTSend)); - ZeroMemory(maSend, ackData->nContacts*sizeof(TCTSend)); - dbei.cbBlob=0; - char* pBlob; - int i; - for (i=0; inContacts; i++) - { // prepare data & count size - maSend[i].mcaNick = make_utf8_string((WCHAR*)GetContactDisplayNameT(ackData->aContacts[i])); - maSend[i].mcaUIN = GetContactUID(ackData->aContacts[i], FALSE); - dbei.cbBlob += (DWORD)strlennull(maSend[i].mcaUIN) + (DWORD)strlennull((char*)maSend[i].mcaNick) + 2; - } - dbei.pBlob = (PBYTE)_alloca(dbei.cbBlob); - for (i=0, pBlob=(char*)dbei.pBlob; i < ackData->nContacts; i++) - { - strcpy(pBlob, (char*)maSend[i].mcaNick); - pBlob += strlennull(pBlob) + 1; - strcpy(pBlob, maSend[i].mcaUIN); - pBlob += strlennull(pBlob) + 1; - } - db_event_add(ackData->hContact, &dbei); - gaAckData.Remove(ack->hProcess); // do not release here, still needed - wndData->uacklist.Remove(ack->hProcess); // packet confirmed - for (i=0; inContacts; i++) - { - SAFE_FREE((void**)&maSend[i].mcaUIN); - SAFE_FREE((void**)&maSend[i].mcaNick); - } - delete ackData; // all done, release structure - if (!wndData->uacklist.Count) - { - SkinPlaySound("SentContacts"); - KillTimer(hwndDlg, TIMERID_MSGSEND); - - if (wndData->hError) - SendMessageT(wndData->hError, DM_ERRORDECIDED, MSGERROR_DONE, 0); - - SendMessageT(hwndDlg, WM_CLOSE, 0, 0); // all packets confirmed, close the dialog - } - break; - } - - case WM_CLOSE: - { - wndData->UnhookProtoAck(); - DestroyWindow(hwndDlg); - break; - } - case WM_DESTROY: - { - int i; - for (i = 0; i < SIZEOF(wndData->hIcons); i++) - DestroyIcon(wndData->hIcons[i]); - WindowList_Remove(ghSendWindowList, hwndDlg); - delete wndData; - break; - } - case WM_MEASUREITEM: - return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam); - - case WM_DRAWITEM: - { - DrawProtocolIcon(hwndDlg, lParam, wndData->hContact); - return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam); - } - case DM_UPDATETITLE: - { - UpdateDialogTitle(hwndDlg, wndData?wndData->hContact:NULL, "Send Contacts to"); - if (wndData) - UpdateDialogAddButton(hwndDlg, wndData->hContact); - break; - } - } - - return FALSE; + TSendContactsData* wndData = (TSendContactsData*)GetWindowLongPtr(hwndDlg, DWLP_USER); + + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); + ResetListOptions(GetDlgItem(hwndDlg, IDC_LIST)); + SetAllContactChecks(GetDlgItem(hwndDlg, IDC_LIST), (HANDLE)lParam); + WindowList_Add(ghSendWindowList, hwndDlg, (HANDLE)lParam); + wndData = new TSendContactsData((HANDLE)lParam); + SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)wndData); + // new dlg init + wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), LPGEN("Add Contact Permanently to List")); + wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), LPGEN("View User's Details")); + wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), LPGEN("View User's History")); + wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), LPGEN("User Menu")); + + SendMessage(hwndDlg, DM_UPDATETITLE, 0, 0); + // new dialog init done + return TRUE; + + case WM_SETFOCUS: + SetFocus(GetDlgItem(hwndDlg, IDC_LIST)); + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->idFrom == IDC_LIST) { + switch (((LPNMHDR)lParam)->code) { + case CLN_NEWCONTACT: + case CLN_LISTREBUILT: // rebuild list + if (wndData) SetAllContactChecks(GetDlgItem(hwndDlg, IDC_LIST), wndData->hContact); + case CLN_OPTIONSCHANGED: + ResetListOptions(GetDlgItem(hwndDlg, IDC_LIST)); + break; + } + } + break; + + case WM_TIMER: + if (wParam == TIMERID_MSGSEND) { + KillTimer(hwndDlg, wParam); + wndData->ShowErrorDlg(hwndDlg, "The contacts send timed out.", TRUE); + } + break; + + case DM_ERRORDECIDED: + EnableWindow(hwndDlg, TRUE); + wndData->hError = NULL; + switch (wParam) { + case MSGERROR_CANCEL: + wndData->UnhookProtoAck(); + if (wndData->uacklist.Count) { + for (int i = 0; i < wndData->uacklist.Count; i++) + delete gaAckData.Remove(wndData->uacklist.Items[i]); // remove our ackdata & release structure + + mir_free(wndData->uacklist.Items); + wndData->uacklist.Items = NULL; + wndData->uacklist.Count = 0; + } + EnableDlgItem(hwndDlg, IDOK, TRUE); + EnableDlgItem(hwndDlg, IDC_LIST, TRUE); + ShowWindow(hwndDlg, SW_SHOWNORMAL); + SetFocus(GetDlgItem(hwndDlg, IDC_LIST)); + break; + + case MSGERROR_DONE: + // contacts were delivered succesfully after timeout + SetFocus(GetDlgItem(hwndDlg, IDC_LIST)); + wndData->UnhookProtoAck(); + break; + + case MSGERROR_RETRY:// resend timeouted packets + for (int i = 0; i < wndData->uacklist.Count; i++) { + TAckData *lla = gaAckData.Remove(wndData->uacklist.Items[i]); + HANDLE hProcc = (HANDLE)CallContactService(wndData->hContact, PSS_CONTACTS, MAKEWPARAM(0, lla->nContacts), (LPARAM)lla->aContacts); + + if (!hProcc) { // if fatal do not include + wndData->uacklist.Remove(wndData->uacklist.Items[i]); + delete lla; // release the structure + continue; + } + else { + // update process code + wndData->uacklist.Items[i] = hProcc; + gaAckData.Add(hProcc, lla); + } + }// collect TAckData for our window, resend + break; + } + break; + + case WM_COMMAND: + if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->hContact)) + break; + + switch (LOWORD(wParam)) { + case IDOK: + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDOK))) { + HANDLE hContact, hItem; + wndData->ClearContacts(); // do not include contacts twice + + HWND hList = GetDlgItem(hwndDlg, IDC_LIST); + hContact = FindFirstClistContact(hList, &hItem); + while (hContact) + { + if (SendMessage(hList, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) + { // build list of contacts to send + wndData->AddContact(hContact); + } + hContact = FindNextClistContact(hList, hContact, &hItem); + } + /* send contacts */ + if (!wndData->SendContacts(hwndDlg)) + break; + + SetTimer(hwndDlg, TIMERID_MSGSEND, db_get_dw(NULL, "SRMsg", "MessageTimeout", TIMEOUT_MSGSEND), NULL); + } + break; + + case IDCANCEL: + DestroyWindow(hwndDlg); + break; + + case ID_SELECTALL: + { + // select all contacts + HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST); + HANDLE hItem, hContact = FindFirstClistContact(hwndList, &hItem); + while (hContact) { + SendMessage(hwndList, CLM_SETCHECKMARK, (WPARAM)hItem, 1); + hContact = FindNextClistContact(hwndList, hContact, &hItem); + } + } + break; + + case IDC_USERMENU: + { + RECT rc; + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)wndData->hContact, 0); + + GetWindowRect(GetDlgItem(hwndDlg, IDC_USERMENU), &rc); + TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); + DestroyMenu(hMenu); + } + break; + + case IDC_HISTORY: + CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)wndData->hContact, 0); + break; + + case IDC_DETAILS: + CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)wndData->hContact, 0); + break; + + case IDC_ADD: + DialogAddContactExecute(hwndDlg, wndData->hContact); + break; + } + break; + + case HM_EVENTSENT: + { + ACKDATA *ack = (ACKDATA*)lParam; + if (ack->type != ACKTYPE_CONTACTS) + break; + + TAckData *ackData = gaAckData.Get(ack->hProcess); + if (ackData == NULL) + break; // on unknown hprocc go away + + if (ackData->hContact != ack->hContact) + break; // this is not ours, strange + + if (ack->result == ACKRESULT_FAILED) { + // some process failed, show error dialog + KillTimer(hwndDlg, TIMERID_MSGSEND); + wndData->ShowErrorDlg(hwndDlg, (char *)ack->lParam, TRUE); + // ackData get used in error handling, released there + break; + } + + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.szModule = GetContactProto(ackData->hContact); + dbei.eventType = EVENTTYPE_CONTACTS; + dbei.flags = DBEF_SENT | DBEF_UTF; + dbei.timestamp = time(NULL); + //make blob + TCTSend* maSend = (TCTSend*)_alloca(ackData->nContacts*sizeof(TCTSend)); + ZeroMemory(maSend, ackData->nContacts*sizeof(TCTSend)); + dbei.cbBlob = 0; + char* pBlob; + int i; + for (i = 0; i < ackData->nContacts; i++) { + // prepare data & count size + maSend[i].mcaNick = mir_utf8encodeT(pcli->pfnGetContactDisplayName(ackData->aContacts[i], 0)); + maSend[i].mcaUIN = mir_utf8encodeT(ptrT(GetContactUID(ackData->aContacts[i]))); + dbei.cbBlob += (DWORD)strlennull(maSend[i].mcaUIN) + (DWORD)strlennull((char*)maSend[i].mcaNick) + 2; + } + dbei.pBlob = (PBYTE)_alloca(dbei.cbBlob); + for (i = 0, pBlob = (char*)dbei.pBlob; i < ackData->nContacts; i++) { + strcpy(pBlob, (char*)maSend[i].mcaNick); + pBlob += strlennull(pBlob) + 1; + strcpy(pBlob, maSend[i].mcaUIN); + pBlob += strlennull(pBlob) + 1; + } + db_event_add(ackData->hContact, &dbei); + gaAckData.Remove(ack->hProcess); // do not release here, still needed + wndData->uacklist.Remove(ack->hProcess); // packet confirmed + for (i = 0; i < ackData->nContacts; i++) { + mir_free(maSend[i].mcaUIN); + mir_free(maSend[i].mcaNick); + } + delete ackData; // all done, release structure + if (!wndData->uacklist.Count) { + SkinPlaySound("SentContacts"); + KillTimer(hwndDlg, TIMERID_MSGSEND); + + if (wndData->hError) + SendMessage(wndData->hError, DM_ERRORDECIDED, MSGERROR_DONE, 0); + + SendMessage(hwndDlg, WM_CLOSE, 0, 0); // all packets confirmed, close the dialog + } + } + break; + + case WM_MEASUREITEM: + return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); + + case WM_DRAWITEM: + DrawProtocolIcon(hwndDlg, lParam, wndData->hContact); + return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); + + case DM_UPDATETITLE: + UpdateDialogTitle(hwndDlg, wndData ? wndData->hContact : NULL, TranslateT("Send Contacts to")); + if (wndData) + UpdateDialogAddButton(hwndDlg, wndData->hContact); + break; + + case WM_CLOSE: + wndData->UnhookProtoAck(); + DestroyWindow(hwndDlg); + break; + + case WM_DESTROY: + for (int i = 0; i < SIZEOF(wndData->hIcons); i++) + DestroyIcon(wndData->hIcons[i]); + WindowList_Remove(ghSendWindowList, hwndDlg); + delete wndData; + break; + } + + return FALSE; } @@ -538,49 +503,43 @@ INT_PTR CALLBACK SendDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPar INT_PTR CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - switch(msg) - { - case WM_INITDIALOG: - { - RECT rc, rcParent; - - TranslateDialogDefault(hwndDlg); - - if (lParam) - { - WCHAR tmp[MAX_PATH]; - - SetDlgItemTextT(hwndDlg, IDC_ERRORTEXT, SRCTranslateT((char*)lParam, tmp)); - } - GetWindowRect(hwndDlg, &rc); - GetWindowRect(GetParent(hwndDlg), &rcParent); - SetWindowPos(hwndDlg, 0, - (rcParent.left+rcParent.right-(rc.right-rc.left))/2, - (rcParent.top+rcParent.bottom-(rc.bottom-rc.top))/2, - 0, 0, SWP_NOZORDER|SWP_NOSIZE); - } - return TRUE; - - case WM_COMMAND: - switch(LOWORD(wParam)) - { - case IDOK: - SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_RETRY, 0); - DestroyWindow(hwndDlg); - break; - - case IDCANCEL: - SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_CANCEL, 0); - DestroyWindow(hwndDlg); - break; - } - break; - case DM_ERRORDECIDED: - if (wParam!=MSGERROR_DONE) break; - SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_DONE, 0); - DestroyWindow(hwndDlg); - break; - } - - return FALSE; + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + { + if (lParam) + SetDlgItemText(hwndDlg, IDC_ERRORTEXT, TranslateTS((TCHAR*)lParam)); + + RECT rc, rcParent; + GetWindowRect(hwndDlg, &rc); + GetWindowRect(GetParent(hwndDlg), &rcParent); + SetWindowPos(hwndDlg, 0, + (rcParent.left + rcParent.right - (rc.right - rc.left)) / 2, + (rcParent.top + rcParent.bottom - (rc.bottom - rc.top)) / 2, + 0, 0, SWP_NOZORDER | SWP_NOSIZE); + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + SendMessage(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_RETRY, 0); + DestroyWindow(hwndDlg); + break; + + case IDCANCEL: + SendMessage(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_CANCEL, 0); + DestroyWindow(hwndDlg); + break; + } + break; + + case DM_ERRORDECIDED: + if (wParam != MSGERROR_DONE) break; + SendMessage(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_DONE, 0); + DestroyWindow(hwndDlg); + break; + } + + return FALSE; } -- cgit v1.2.3