From a76ced5d4ff852dcbe7a96824ca1bb6dc219a1fd Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Tue, 18 Dec 2012 20:03:40 +0000 Subject: - first approach of group chat support git-svn-id: http://svn.miranda-ng.org/main/trunk@2764 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Skype/Skype.vcxproj | 9 +++ protocols/Skype/Skype.vcxproj.filters | 11 +++ protocols/Skype/res/Resource.rc | 50 +++++++++++- protocols/Skype/src/resource.h | 6 +- protocols/Skype/src/skype.h | 4 +- protocols/Skype/src/skype_chat.cpp | 137 +++++++++++++++++++++++++++++++++ protocols/Skype/src/skype_contacts.cpp | 6 +- protocols/Skype/src/skype_dialogs.cpp | 95 +++++++++++++++++++++++ protocols/Skype/src/skype_events.cpp | 2 + protocols/Skype/src/skype_menus.cpp | 47 +++++++++++ protocols/Skype/src/skype_proto.cpp | 3 + protocols/Skype/src/skype_proto.h | 32 +++++++- 12 files changed, 395 insertions(+), 7 deletions(-) create mode 100644 protocols/Skype/src/skype_chat.cpp (limited to 'protocols/Skype') diff --git a/protocols/Skype/Skype.vcxproj b/protocols/Skype/Skype.vcxproj index c96de18388..34cf70bd08 100644 --- a/protocols/Skype/Skype.vcxproj +++ b/protocols/Skype/Skype.vcxproj @@ -189,6 +189,7 @@ + @@ -208,6 +209,14 @@ + + + + + + + + diff --git a/protocols/Skype/Skype.vcxproj.filters b/protocols/Skype/Skype.vcxproj.filters index affd230602..4d031f4ed2 100644 --- a/protocols/Skype/Skype.vcxproj.filters +++ b/protocols/Skype/Skype.vcxproj.filters @@ -63,6 +63,9 @@ Source Files + + Source Files + @@ -89,4 +92,12 @@ Resource Filess + + + + + + + + \ No newline at end of file diff --git a/protocols/Skype/res/Resource.rc b/protocols/Skype/res/Resource.rc index ad333ebf1c..04acddc71b 100644 --- a/protocols/Skype/res/Resource.rc +++ b/protocols/Skype/res/Resource.rc @@ -12,6 +12,54 @@ ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1251) + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_CHATROOM_INVITE DIALOGEX 0, 0, 190, 179 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOPMOST +CAPTION "Invite Contact To Chat" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + LTEXT "sid",-1,7,128,43,9 + PUSHBUTTON "&Invite",IDOK,29,159,46,14 + PUSHBUTTON "&Cancel",IDCANCEL,112,159,45,14 + CONTROL "",IDC_CCLIST,"CListControl",WS_TABSTOP | 0x16f,7,4,174,119,WS_EX_CLIENTEDGE + EDITTEXT IDC_EDITSCR,7,138,121,12,ES_AUTOHSCROLL + PUSHBUTTON "Add",IDC_ADDSCR,133,136,49,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_CHATROOM_INVITE, DIALOG + BEGIN + RIGHTMARGIN, 188 + TOPMARGIN, 4 + BOTTOMMARGIN, 173 + END +END +#endif // APSTUDIO_INVOKED + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// // Neutral (Default) resources @@ -221,7 +269,7 @@ END #endif // APSTUDIO_INVOKED -#endif // Русский (Россия) resources +#endif // Russian (Russia) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/protocols/Skype/src/resource.h b/protocols/Skype/src/resource.h index 30ff3dace7..715b1b9b1c 100644 --- a/protocols/Skype/src/resource.h +++ b/protocols/Skype/src/resource.h @@ -1,11 +1,12 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by protocols\Skype\res\Resource.rc +// Used by e:\Projects\C++\MirandaNG\protocols\Skype\res\Resource.rc // #define IDD_SKYPEACCOUNT 9 #define IDD_OPTIONS 10 #define IDD_INFO_SKYPE 11 #define IDD_OWNINFO_SKYPE 12 +#define IDD_CHATROOM_INVITE 40 #define IDI_ICON 101 #define IDR_RUNTIME 102 #define IDI_AUTH_GRANT 103 @@ -13,6 +14,9 @@ #define IDI_AUTH_REVOKE 105 #define IDD_PASSWORDREQUEST 106 #define IDR_KEY 107 +#define IDC_CCLIST 173 +#define IDC_EDITSCR 174 +#define IDC_ADDSCR 175 #define IDC_SN 1001 #define IDC_PW 1002 #define IDC_SL 1003 diff --git a/protocols/Skype/src/skype.h b/protocols/Skype/src/skype.h index b47231f46e..e9011fc3ec 100644 --- a/protocols/Skype/src/skype.h +++ b/protocols/Skype/src/skype.h @@ -60,7 +60,7 @@ extern "C" #include "..\..\..\skypekit\key.h" #define MODULE "Skype" -#define SKYPE_LOGIN_LIMIT 128 +#define SKYPE_SID_LIMIT 128 #define SKYPE_PASSWORD_LIMIT 128 #define SKYPE_SETTINGS_NAME "Name" #define SKYPE_SETTINGS_STATUS "Status" @@ -75,6 +75,8 @@ extern "C" #define CMI_AUTH_REQUEST 1 #define CMI_AUTH_GRANT 2 +#define SMI_CHAT_INVOKE 0 + #define CMITEMS_COUNT 3 extern CSkype* g_skype; diff --git a/protocols/Skype/src/skype_chat.cpp b/protocols/Skype/src/skype_chat.cpp new file mode 100644 index 0000000000..358c435cc9 --- /dev/null +++ b/protocols/Skype/src/skype_chat.cpp @@ -0,0 +1,137 @@ +#include "skype_proto.h" +#include + +bool CSkypeProto::IsChatRoom(HANDLE hContact) +{ + return ::DBGetContactSettingByte(hContact, this->m_szModuleName, "ChatRoom", 0) > 0; +} + +void CSkypeProto::ChatValidateContact(HANDLE hItem, HWND hwndList) +{ + if ( !this->IsProtoContact(hItem) || this->IsChatRoom(hItem)) + ::SendMessage(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0); +} + +void CSkypeProto::ChatPrepare(HANDLE hItem, HWND hwndList) +{ + if (hItem == NULL) + hItem = (HANDLE)::SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_ROOT, 0); + + while (hItem) + { + HANDLE hItemN = (HANDLE)::SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXT, (LPARAM)hItem); + + if (IsHContactGroup(hItem)) + { + HANDLE hItemT = (HANDLE)::SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); + if (hItemT) this->ChatPrepare(hItemT, hwndList); + } + else if (IsHContactContact(hItem)) + this->ChatValidateContact(hItem, hwndList); + + hItem = hItemN; + } +} + +void CSkypeProto::FillChatList(HANDLE hItem, HWND hwndList, SEStringList &chatTargets) +{ + if (hItem == NULL) + hItem = (HANDLE)::SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_ROOT, 0); + + while (hItem) + { + if (IsHContactGroup(hItem)) + { + HANDLE hItemT = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); + if (hItemT) this->FillChatList(hItemT, hwndList, chatTargets); + } + else + { + int chk = SendMessage(hwndList, CLM_GETCHECKMARK, (WPARAM)hItem, 0); + if (chk) + { + if (IsHContactInfo(hItem)) + { + TCHAR buf[128] = _T(""); + SendMessage(hwndList, CLM_GETITEMTEXT, (WPARAM)hItem, (LPARAM)buf); + + if (buf[0]) chatTargets.append(mir_t2a(buf)); + } + else + { + char *sid = ::DBGetString(hItem, this->m_szModuleName, "sid"); + if (sid) chatTargets.append(sid); + } + } + } + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXT, (LPARAM)hItem); + } +} + +static const COLORREF crCols[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +void CSkypeProto::RegisterChat() +{ + GCREGISTER gcr = {0}; + gcr.cbSize = sizeof(gcr); + gcr.dwFlags = GC_TYPNOTIF | GC_CHANMGR;// | GC_TCHAR; + gcr.iMaxText = 0; + gcr.nColors = 16; + gcr.pColors = (COLORREF*)crCols; + gcr.pszModuleDispName = ::mir_u2a(this->m_tszUserName); + gcr.pszModule = this->m_szModuleName; + CallServiceSync(MS_GC_REGISTER, 0, (LPARAM)&gcr); + + //YHookEvent(ME_GC_EVENT, &CYahooProto::OnGCEventHook); + //YHookEvent(ME_GC_BUILDMENU, &CYahooProto::OnGCMenuHook); +} + +void CSkypeProto::StartChat(SEStringList &chatTargets) +{ + CConversation::Ref conference; + g_skype->CreateConference(conference); + conference->AddConsumers(chatTargets); + + SEString identity; + conference->GetPropIdentity(identity); + char *chatID = ::mir_strdup((const char *)identity); + + GCSESSION gcw = {0}; + gcw.cbSize = sizeof(gcw); + //gcw.dwFlags = GC_TCHAR; + gcw.iType = GCW_CHATROOM; + gcw.pszModule = m_szModuleName; + gcw.pszName = "Chat"; + gcw.pszID = chatID; + ::CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw); + + GCDEST gcd = { m_szModuleName, { NULL }, GC_EVENT_ADDGROUP }; + gcd.pszID = chatID; + + GCEVENT gce = {0}; + gce.cbSize = sizeof(GCEVENT); + //gce.dwFlags = GC_TCHAR; + gce.pDest = &gcd; + gce.pszStatus = Translate("Me"); + ::CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); + + gcd.iType = GC_EVENT_ADDGROUP; + gce.pszStatus = Translate("Others"); + ::CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); + + for (uint i = 0; i < chatTargets.size(); i++) + { + HANDLE hContact = this->GetContactBySid(chatTargets[i]); + gcd.iType = GC_EVENT_JOIN; + gce.pszNick = ::DBGetString(hContact, this->m_szModuleName, "Nick"); + gce.pszUID = chatTargets[i]; + ::CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); + } + + gcd.iType = GC_EVENT_CONTROL; + ::CallServiceSync(MS_GC_EVENT, SESSION_INITDONE, (LPARAM)&gce); + ::CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, (LPARAM)&gce); + ::CallServiceSync(MS_GC_EVENT, WINDOW_VISIBLE, (LPARAM)&gce); + + ::mir_free(chatID); +} \ No newline at end of file diff --git a/protocols/Skype/src/skype_contacts.cpp b/protocols/Skype/src/skype_contacts.cpp index e92fc135b7..eae999ef92 100644 --- a/protocols/Skype/src/skype_contacts.cpp +++ b/protocols/Skype/src/skype_contacts.cpp @@ -534,7 +534,7 @@ HANDLE CSkypeProto::GetContactBySid(const char *sid) HANDLE hContact = db_find_first(); while (hContact) { - if (this->IsProtoContact(hContact)) + if (this->IsProtoContact(hContact) && !this->IsChatRoom(hContact)) { if (::strcmp(sid, ::DBGetString(hContact, this->m_szModuleName, "sid")) == 0) return hContact; @@ -693,10 +693,10 @@ void __cdecl CSkypeProto::LoadContactList(void*) char *sid = ::mir_strdup((const char *)data); contact->GetPropDisplayname(data); - char *nick = ::mir_strdup((const char *)data); + char *nick = ::mir_utf8decodeA((const char *)data); contact->GetPropFullname(data); - char *name = ::mir_strdup((const char *)data); + char *name = ::mir_utf8decodeA((const char *)data); DWORD flags = 0; CContact::AVAILABILITY availability; diff --git a/protocols/Skype/src/skype_dialogs.cpp b/protocols/Skype/src/skype_dialogs.cpp index 9657513d64..1505a08c9f 100644 --- a/protocols/Skype/src/skype_dialogs.cpp +++ b/protocols/Skype/src/skype_dialogs.cpp @@ -435,4 +435,99 @@ int __cdecl CSkypeProto::OnUserInfoInit(WPARAM wParam, LPARAM lParam) } return 0; +} + +INT_PTR CALLBACK CSkypeProto::InviteToChatProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + InviteChatParam *param = (InviteChatParam *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + switch (msg) + { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); + param = (InviteChatParam*)lParam; + +// WindowSetIcon(hwndDlg, "msn"); + break; + + case WM_CLOSE: + EndDialog(hwndDlg, 0); + break; + + case WM_NCDESTROY: +// WindowFreeIcon(hwndDlg); + delete param; + break; + + case WM_NOTIFY: + { + NMCLISTCONTROL* nmc = (NMCLISTCONTROL*)lParam; + if (nmc->hdr.idFrom == IDC_CCLIST) + { + switch (nmc->hdr.code) + { + case CLN_NEWCONTACT: + if (param && (nmc->flags & (CLNF_ISGROUP | CLNF_ISINFO)) == 0) + { + param->ppro->ChatValidateContact(nmc->hItem, nmc->hdr.hwndFrom); + } + break; + + case CLN_LISTREBUILT: + if (param) + param->ppro->ChatPrepare(NULL, nmc->hdr.hwndFrom); + break; + } + } + } + break; + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_ADDSCR: + if (param->ppro->IsOnline()) + { + wchar_t sid[SKYPE_SID_LIMIT]; + ::GetDlgItemText(hwndDlg, IDC_EDITSCR, sid, SIZEOF(sid)); + + CLCINFOITEM cii = {0}; + cii.cbSize = sizeof(cii); + cii.flags = CLCIIF_CHECKBOX | CLCIIF_BELOWCONTACTS; + cii.pszText = ::wcslwr(sid); + + HANDLE hItem = (HANDLE)::SendDlgItemMessage( + hwndDlg, + IDC_CCLIST, + CLM_ADDINFOITEM, + 0, + (LPARAM)&cii); + ::SendDlgItemMessage(hwndDlg, IDC_CCLIST, CLM_SETCHECKMARK, (LPARAM)hItem, 1); + } + break; + + case IDOK: + { + char sid[SKYPE_SID_LIMIT] = ""; + HWND hwndList = ::GetDlgItem(hwndDlg, IDC_CCLIST); + + SEStringList chatTargets; + param->ppro->FillChatList(NULL, hwndList, chatTargets); + param->ppro->StartChat(chatTargets); + } + + EndDialog(hwndDlg, IDOK); + break; + + case IDCANCEL: + EndDialog(hwndDlg, IDCANCEL); + break; + } + } + break; + } + return FALSE; } \ No newline at end of file diff --git a/protocols/Skype/src/skype_events.cpp b/protocols/Skype/src/skype_events.cpp index 8b99ec5219..8ceb136173 100644 --- a/protocols/Skype/src/skype_events.cpp +++ b/protocols/Skype/src/skype_events.cpp @@ -2,8 +2,10 @@ int CSkypeProto::OnModulesLoaded(WPARAM, LPARAM) { + this->RegisterChat(); this->HookEvent(ME_OPT_INITIALISE, &CSkypeProto::OnOptionsInit); this->HookEvent(ME_USERINFO_INITIALISE, &CSkypeProto::OnUserInfoInit); + this->login = ::DBGetString(NULL, this->m_szModuleName, "sid"); this->rememberPassword = this->GetSettingByte("RememberPassword") > 0; diff --git a/protocols/Skype/src/skype_menus.cpp b/protocols/Skype/src/skype_menus.cpp index e0a33fb9d1..65022f494a 100644 --- a/protocols/Skype/src/skype_menus.cpp +++ b/protocols/Skype/src/skype_menus.cpp @@ -106,6 +106,17 @@ int CSkypeProto::RevokeAuth(WPARAM wParam, LPARAM lParam) return 0; } +int CSkypeProto::InviteCommand(WPARAM, LPARAM) +{ + ::DialogBoxParam( + g_hInstance, + MAKEINTRESOURCE(IDD_CHATROOM_INVITE), + NULL, + CSkypeProto::InviteToChatProc, + LPARAM(new InviteChatParam(NULL, NULL, this))); + return 0; +} + int CSkypeProto::PrebuildContactMenu(WPARAM wParam, LPARAM lParam) { for (size_t i=0; iCreateService(tDest, &CSkypeProto::InviteCommand); + mi.ptszName = LPGENT("Invite to conference"); + mi.position = 200001; + mi.icolibItem = CSkypeProto::GetIconHandle("confInvite"); + ::Menu_AddProtoMenuItem(&mi); } \ No newline at end of file diff --git a/protocols/Skype/src/skype_proto.cpp b/protocols/Skype/src/skype_proto.cpp index c4bd2c6a30..aba0cc485b 100644 --- a/protocols/Skype/src/skype_proto.cpp +++ b/protocols/Skype/src/skype_proto.cpp @@ -343,6 +343,9 @@ int __cdecl CSkypeProto::OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPA case EV_PROTO_ONEXIT: return this->OnPreShutdown(wParam, lParam); + case EV_PROTO_ONMENU: + this->OnInitStatusMenu(); + case EV_PROTO_ONCONTACTDELETED: return this->OnContactDeleted(wParam, lParam); } diff --git a/protocols/Skype/src/skype_proto.h b/protocols/Skype/src/skype_proto.h index db10c7522e..6d849abf35 100644 --- a/protocols/Skype/src/skype_proto.h +++ b/protocols/Skype/src/skype_proto.h @@ -61,6 +61,19 @@ const SettingItem setting[]={ {LPGENT("About"), "About", DBVT_WCHAR, LI_STRING} }; +struct InviteChatParam +{ + TCHAR *id; + HANDLE hContact; + CSkypeProto *ppro; + + InviteChatParam(const TCHAR *id, HANDLE hContact, CSkypeProto *ppro) + : id(mir_tstrdup(id)), hContact(hContact), ppro(ppro) {} + + ~InviteChatParam() + { mir_free(id); } +}; + struct CSkypeProto : public PROTO_INTERFACE, public MZeroedObject { public: @@ -140,12 +153,17 @@ public: static HANDLE GetIconHandle(const char *name); // menus + void OnInitStatusMenu(); static void InitMenus(); static void UninitMenus(); + int __cdecl InviteCommand(WPARAM, LPARAM); + static CSkypeProto* GetInstanceByHContact(HANDLE hContact); static int PrebuildContactMenu(WPARAM wParam, LPARAM lParam); + bool IsOnline(); + protected: DWORD dwCMDNum; CAccount::Ref account; @@ -154,7 +172,7 @@ protected: CContactGroup::Ref authWaitList; // account - bool IsOnline(); + void OnAccountChanged(int prop); char *login; @@ -174,6 +192,16 @@ protected: void OnMessageSended(CConversation::Ref conversation, CMessage::Ref message); void OnMessageReceived(CConversation::Ref conversation, CMessage::Ref message); + // chat + bool IsChatRoom(HANDLE hContact); + + void ChatValidateContact(HANDLE hItem, HWND hwndList); + void ChatPrepare(HANDLE hItem, HWND hwndList); + void FillChatList(HANDLE hItem, HWND hwndList, SEStringList &chatTargets); + + void RegisterChat(); + void StartChat(SEStringList &chatTargets); + // contacts void UpdateContactAboutText(HANDLE hContact, CContact::Ref contact); void UpdateContactAuthState(HANDLE hContact, CContact::Ref contact); @@ -288,6 +316,7 @@ protected: static _tag_iconList iconList[]; // menu + HGENMENU m_hMenuRoot; static HANDLE hChooserMenu; static HANDLE hPrebuildMenuHook; static HANDLE g_hContactMenuItems[CMITEMS_COUNT]; @@ -346,4 +375,5 @@ protected: static INT_PTR CALLBACK SkypePasswordProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK SkypeDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK OwnSkypeDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK InviteToChatProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); }; \ No newline at end of file -- cgit v1.2.3