/* Jabber Protocol Plugin for Miranda IM Copyright (C) 2002-04 Santithorn Bunchua Copyright (C) 2005-12 George Hazan Copyright (C) 2007 Maxim Mluhov 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 "jabber.h" #include "jabber_list.h" #include "jabber_caps.h" #include "jabber_opttree.h" #include "m_modernopt.h" static BOOL (WINAPI *pfnEnableThemeDialogTexture)(HANDLE, DWORD) = 0; ///////////////////////////////////////////////////////////////////////////////////////// // JabberRegisterDlgProc - the dialog proc for registering new account #define STR_FORMAT _T("%s %s@%S:%d?") struct { TCHAR *szCode; TCHAR *szDescription; } g_LanguageCodes[] = { { _T("aa"), _T("Afar") }, { _T("ab"), _T("Abkhazian") }, { _T("af"), _T("Afrikaans") }, { _T("ak"), _T("Akan") }, { _T("sq"), _T("Albanian") }, { _T("am"), _T("Amharic") }, { _T("ar"), _T("Arabic") }, { _T("an"), _T("Aragonese") }, { _T("hy"), _T("Armenian") }, { _T("as"), _T("Assamese") }, { _T("av"), _T("Avaric") }, { _T("ae"), _T("Avestan") }, { _T("ay"), _T("Aymara") }, { _T("az"), _T("Azerbaijani") }, { _T("ba"), _T("Bashkir") }, { _T("bm"), _T("Bambara") }, { _T("eu"), _T("Basque") }, { _T("be"), _T("Belarusian") }, { _T("bn"), _T("Bengali") }, { _T("bh"), _T("Bihari") }, { _T("bi"), _T("Bislama") }, { _T("bs"), _T("Bosnian") }, { _T("br"), _T("Breton") }, { _T("bg"), _T("Bulgarian") }, { _T("my"), _T("Burmese") }, { _T("ca"), _T("Catalan; Valencian") }, { _T("ch"), _T("Chamorro") }, { _T("ce"), _T("Chechen") }, { _T("zh"), _T("Chinese") }, { _T("cu"), _T("Church Slavic; Old Slavonic") }, { _T("cv"), _T("Chuvash") }, { _T("kw"), _T("Cornish") }, { _T("co"), _T("Corsican") }, { _T("cr"), _T("Cree") }, { _T("cs"), _T("Czech") }, { _T("da"), _T("Danish") }, { _T("dv"), _T("Divehi; Dhivehi; Maldivian") }, { _T("nl"), _T("Dutch; Flemish") }, { _T("dz"), _T("Dzongkha") }, { _T("en"), _T("English") }, { _T("eo"), _T("Esperanto") }, { _T("et"), _T("Estonian") }, { _T("ee"), _T("Ewe") }, { _T("fo"), _T("Faroese") }, { _T("fj"), _T("Fijian") }, { _T("fi"), _T("Finnish") }, { _T("fr"), _T("French") }, { _T("fy"), _T("Western Frisian") }, { _T("ff"), _T("Fulah") }, { _T("ka"), _T("Georgian") }, { _T("de"), _T("German") }, { _T("gd"), _T("Gaelic; Scottish Gaelic") }, { _T("ga"), _T("Irish") }, { _T("gl"), _T("Galician") }, { _T("gv"), _T("Manx") }, { _T("el"), _T("Greek, Modern (1453-)") }, { _T("gn"), _T("Guarani") }, { _T("gu"), _T("Gujarati") }, { _T("ht"), _T("Haitian; Haitian Creole") }, { _T("ha"), _T("Hausa") }, { _T("he"), _T("Hebrew") }, { _T("hz"), _T("Herero") }, { _T("hi"), _T("Hindi") }, { _T("ho"), _T("Hiri Motu") }, { _T("hu"), _T("Hungarian") }, { _T("ig"), _T("Igbo") }, { _T("is"), _T("Icelandic") }, { _T("io"), _T("Ido") }, { _T("ii"), _T("Sichuan Yi") }, { _T("iu"), _T("Inuktitut") }, { _T("ie"), _T("Interlingue") }, { _T("ia"), _T("Interlingua (International Auxiliary Language Association)") }, { _T("id"), _T("Indonesian") }, { _T("ik"), _T("Inupiaq") }, { _T("it"), _T("Italian") }, { _T("jv"), _T("Javanese") }, { _T("ja"), _T("Japanese") }, { _T("kl"), _T("Kalaallisut; Greenlandic") }, { _T("kn"), _T("Kannada") }, { _T("ks"), _T("Kashmiri") }, { _T("kr"), _T("Kanuri") }, { _T("kk"), _T("Kazakh") }, { _T("km"), _T("Central Khmer") }, { _T("ki"), _T("Kikuyu; Gikuyu") }, { _T("rw"), _T("Kinyarwanda") }, { _T("ky"), _T("Kirghiz; Kyrgyz") }, { _T("kv"), _T("Komi") }, { _T("kg"), _T("Kongo") }, { _T("ko"), _T("Korean") }, { _T("kj"), _T("Kuanyama; Kwanyama") }, { _T("ku"), _T("Kurdish") }, { _T("lo"), _T("Lao") }, { _T("la"), _T("Latin") }, { _T("lv"), _T("Latvian") }, { _T("li"), _T("Limburgan; Limburger; Limburgish") }, { _T("ln"), _T("Lingala") }, { _T("lt"), _T("Lithuanian") }, { _T("lb"), _T("Luxembourgish; Letzeburgesch") }, { _T("lu"), _T("Luba-Katanga") }, { _T("lg"), _T("Ganda") }, { _T("mk"), _T("Macedonian") }, { _T("mh"), _T("Marshallese") }, { _T("ml"), _T("Malayalam") }, { _T("mi"), _T("Maori") }, { _T("mr"), _T("Marathi") }, { _T("ms"), _T("Malay") }, { _T("mg"), _T("Malagasy") }, { _T("mt"), _T("Maltese") }, { _T("mo"), _T("Moldavian") }, { _T("mn"), _T("Mongolian") }, { _T("na"), _T("Nauru") }, { _T("nv"), _T("Navajo; Navaho") }, { _T("nr"), _T("Ndebele, South; South Ndebele") }, { _T("nd"), _T("Ndebele, North; North Ndebele") }, { _T("ng"), _T("Ndonga") }, { _T("ne"), _T("Nepali") }, { _T("nn"), _T("Norwegian Nynorsk; Nynorsk, Norwegian") }, { _T("nb"), _T("Bokmaal, Norwegian; Norwegian Bokmaal") }, { _T("no"), _T("Norwegian") }, { _T("ny"), _T("Chichewa; Chewa; Nyanja") }, { _T("oc"), _T("Occitan (post 1500); Provencal") }, { _T("oj"), _T("Ojibwa") }, { _T("or"), _T("Oriya") }, { _T("om"), _T("Oromo") }, { _T("os"), _T("Ossetian; Ossetic") }, { _T("pa"), _T("Panjabi; Punjabi") }, { _T("fa"), _T("Persian") }, { _T("pi"), _T("Pali") }, { _T("pl"), _T("Polish") }, { _T("pt"), _T("Portuguese") }, { _T("ps"), _T("Pushto") }, { _T("qu"), _T("Quechua") }, { _T("rm"), _T("Romansh") }, { _T("ro"), _T("Romanian") }, { _T("rn"), _T("Rundi") }, { _T("ru"), _T("Russian") }, { _T("sg"), _T("Sango") }, { _T("sa"), _T("Sanskrit") }, { _T("sr"), _T("Serbian") }, { _T("hr"), _T("Croatian") }, { _T("si"), _T("Sinhala; Sinhalese") }, { _T("sk"), _T("Slovak") }, { _T("sl"), _T("Slovenian") }, { _T("se"), _T("Northern Sami") }, { _T("sm"), _T("Samoan") }, { _T("sn"), _T("Shona") }, { _T("sd"), _T("Sindhi") }, { _T("so"), _T("Somali") }, { _T("st"), _T("Sotho, Southern") }, { _T("es"), _T("Spanish; Castilian") }, { _T("sc"), _T("Sardinian") }, { _T("ss"), _T("Swati") }, { _T("su"), _T("Sundanese") }, { _T("sw"), _T("Swahili") }, { _T("sv"), _T("Swedish") }, { _T("ty"), _T("Tahitian") }, { _T("ta"), _T("Tamil") }, { _T("tt"), _T("Tatar") }, { _T("te"), _T("Telugu") }, { _T("tg"), _T("Tajik") }, { _T("tl"), _T("Tagalog") }, { _T("th"), _T("Thai") }, { _T("bo"), _T("Tibetan") }, { _T("ti"), _T("Tigrinya") }, { _T("to"), _T("Tonga (Tonga Islands)") }, { _T("tn"), _T("Tswana") }, { _T("ts"), _T("Tsonga") }, { _T("tk"), _T("Turkmen") }, { _T("tr"), _T("Turkish") }, { _T("tw"), _T("Twi") }, { _T("ug"), _T("Uighur; Uyghur") }, { _T("uk"), _T("Ukrainian") }, { _T("ur"), _T("Urdu") }, { _T("uz"), _T("Uzbek") }, { _T("ve"), _T("Venda") }, { _T("vi"), _T("Vietnamese") }, { _T("vo"), _T("Volapuk") }, { _T("cy"), _T("Welsh") }, { _T("wa"), _T("Walloon") }, { _T("wo"), _T("Wolof") }, { _T("xh"), _T("Xhosa") }, { _T("yi"), _T("Yiddish") }, { _T("yo"), _T("Yoruba") }, { _T("za"), _T("Zhuang; Chuang") }, { _T("zu"), _T("Zulu") }, { NULL, NULL } }; class CJabberDlgRegister: public CJabberDlgBase { typedef CJabberDlgBase CSuper; public: CJabberDlgRegister(CJabberProto *proto, HWND hwndParent, ThreadData *regInfo): CJabberDlgBase(proto, IDD_OPT_REGISTER, hwndParent, false), m_bProcessStarted(false), m_regInfo(regInfo), m_btnOk(this, IDOK) { m_autoClose = CLOSE_ON_CANCEL; m_btnOk.OnClick = Callback(this, &CJabberDlgRegister::btnOk_OnClick); } protected: void OnInitDialog() { TCHAR text[256]; mir_sntprintf(text, SIZEOF(text), STR_FORMAT, TranslateT("Register"), m_regInfo->username, m_regInfo->server, m_regInfo->port); SetDlgItemText(m_hwnd, IDC_REG_STATUS, text); } INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_JABBER_REGDLG_UPDATE: // wParam=progress (0-100), lparam=status string if ((TCHAR*)lParam == NULL) SetDlgItemText(m_hwnd, IDC_REG_STATUS, TranslateT("No message")); else SetDlgItemText(m_hwnd, IDC_REG_STATUS, (TCHAR*)lParam); if (wParam >= 0) SendMessage(GetDlgItem(m_hwnd, IDC_PROGRESS_REG), PBM_SETPOS, wParam, 0); if (wParam >= 100) m_btnOk.SetText(TranslateT("Close")); else SetFocus(GetDlgItem(m_hwnd, IDC_PROGRESS_REG)); return TRUE; } return CSuper::DlgProc(msg, wParam, lParam); } private: bool m_bProcessStarted; ThreadData *m_regInfo; CCtrlButton m_btnOk; void btnOk_OnClick(CCtrlButton *) { if (m_bProcessStarted) { Close(); return; } ShowWindow(GetDlgItem(m_hwnd, IDC_PROGRESS_REG), SW_SHOW); ThreadData *thread = new ThreadData(m_regInfo->proto, JABBER_SESSION_REGISTER); _tcsncpy(thread->username, m_regInfo->username, SIZEOF(thread->username)); _tcsncpy(thread->password, m_regInfo->password, SIZEOF(thread->password)); strncpy(thread->server, m_regInfo->server, SIZEOF(thread->server)); strncpy(thread->manualHost, m_regInfo->manualHost, SIZEOF(thread->manualHost)); thread->port = m_regInfo->port; thread->useSSL = m_regInfo->useSSL; thread->reg_hwndDlg= m_hwnd; m_proto->JForkThread((JThreadFunc)&CJabberProto::ServerThread, thread); m_btnOk.SetText(TranslateT("Cancel")); m_bProcessStarted = true; m_lresult = TRUE; } }; ///////////////////////////////////////////////////////////////////////////////////////// // JabberOptDlgProc - main options dialog procedure class CCtrlEditJid: public CCtrlEdit { typedef CCtrlEdit CSuper; public: CCtrlEditJid(CDlgBase* dlg, int ctrlId); void OnInit() { CCtrlEdit::OnInit(); Subclass(); } protected: virtual LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_CHAR) { switch(wParam) { case '\"': case '&': case '\'': case '/': case ':': case '<': case '>': case '@': MessageBeep(MB_ICONASTERISK); return 0; } } return CCtrlEdit::CustomWndProc(msg, wParam, lParam); } }; CCtrlEditJid::CCtrlEditJid(CDlgBase* dlg, int ctrlId): CCtrlEdit(dlg, ctrlId) { } static void sttStoreJidFromUI(CJabberProto *ppro, CCtrlEdit &txtUsername, CCtrlCombo &cbServer) { TCHAR *user = txtUsername.GetText(); TCHAR *server = cbServer.GetText(); int len = lstrlen(user) + lstrlen(server) + 2; TCHAR *jid = (TCHAR *)mir_alloc(len * sizeof(TCHAR)); mir_sntprintf(jid, len, _T("%s@%s"), user, server); ppro->JSetStringT(NULL, "jid", jid); mir_free(jid); mir_free(server); mir_free(user); } class CDlgOptAccount: public CJabberDlgBase { typedef CJabberDlgBase CSuper; CCtrlEditJid m_txtUsername; CCtrlEdit m_txtPassword; CCtrlEdit m_txtPriority; CCtrlCheck m_chkSavePassword; CCtrlCombo m_cbResource; CCtrlCheck m_chkUseHostnameAsResource; CCtrlCheck m_chkUseDomainLogin; CCtrlCombo m_cbServer; CCtrlEdit m_txtPort; CCtrlCheck m_chkUseSsl; CCtrlCheck m_chkUseTls; CCtrlCheck m_chkManualHost; CCtrlEdit m_txtManualHost; CCtrlEdit m_txtManualPort; CCtrlCheck m_chkKeepAlive; CCtrlCheck m_chkAutoDeleteContacts; CCtrlEdit m_txtUserDirectory; CCtrlCombo m_cbLocale; CCtrlButton m_btnRegister; CCtrlButton m_btnUnregister; CCtrlButton m_btnChangePassword; CCtrlHyperlink m_lnkServers; public: CDlgOptAccount(CJabberProto *proto): CJabberDlgBase(proto, IDD_OPT_JABBER, NULL, false), m_txtUsername(this, IDC_EDIT_USERNAME), m_txtPassword(this, IDC_EDIT_PASSWORD), m_txtPriority(this, IDC_PRIORITY), m_chkSavePassword(this, IDC_SAVEPASSWORD), m_cbResource(this, IDC_COMBO_RESOURCE), m_chkUseHostnameAsResource(this,IDC_HOSTNAME_AS_RESOURCE), m_chkUseDomainLogin(this, IDC_USEDOMAINLOGIN), m_cbServer(this, IDC_EDIT_LOGIN_SERVER), m_txtPort(this, IDC_PORT), m_chkUseSsl(this, IDC_USE_SSL), m_chkUseTls(this, IDC_USE_TLS), m_chkManualHost(this, IDC_MANUAL), m_txtManualHost(this, IDC_HOST), m_txtManualPort(this, IDC_HOSTPORT), m_chkKeepAlive(this, IDC_KEEPALIVE), m_chkAutoDeleteContacts(this, IDC_ROSTER_SYNC), m_txtUserDirectory(this, IDC_JUD), m_cbLocale(this, IDC_MSGLANG), m_btnRegister(this, IDC_BUTTON_REGISTER), m_btnUnregister(this, IDC_UNREGISTER), m_btnChangePassword(this, IDC_BUTTON_CHANGE_PASSWORD), m_lnkServers(this, IDC_LINK_PUBLIC_SERVER, "http://xmpp.org/services/") { CreateLink(m_txtUsername, "LoginName", _T("")); CreateLink(m_txtPriority, "Priority", DBVT_WORD, 0, true); CreateLink(m_chkSavePassword, proto->m_options.SavePassword); CreateLink(m_cbResource, "Resource", _T("Miranda")); CreateLink(m_chkUseHostnameAsResource, proto->m_options.HostNameAsResource); CreateLink(m_chkUseDomainLogin, proto->m_options.UseDomainLogin); CreateLink(m_cbServer, "LoginServer", _T("jabber.org")); CreateLink(m_txtPort, "Port", DBVT_WORD, 5222); CreateLink(m_chkUseSsl, proto->m_options.UseSSL); CreateLink(m_chkUseTls, proto->m_options.UseTLS); CreateLink(m_chkManualHost, proto->m_options.ManualConnect); CreateLink(m_txtManualHost, "ManualHost", _T("")); CreateLink(m_txtManualPort, "ManualPort", DBVT_WORD, 0); CreateLink(m_chkKeepAlive, proto->m_options.KeepAlive); CreateLink(m_chkAutoDeleteContacts, proto->m_options.RosterSync); CreateLink(m_txtUserDirectory, "Jud", _T("")); // Bind events m_cbServer.OnDropdown = Callback(this, &CDlgOptAccount::cbServer_OnDropdown); m_chkManualHost.OnChange = Callback(this, &CDlgOptAccount::chkManualHost_OnChange); m_chkUseHostnameAsResource.OnChange = Callback(this, &CDlgOptAccount::chkUseHostnameAsResource_OnChange); m_chkUseDomainLogin.OnChange = Callback(this, &CDlgOptAccount::chkUseDomainLogin_OnChange); m_chkUseSsl.OnChange = Callback(this, &CDlgOptAccount::chkUseSsl_OnChange); m_chkUseTls.OnChange = Callback(this, &CDlgOptAccount::chkUseTls_OnChange); m_btnRegister.OnClick = Callback(this, &CDlgOptAccount::btnRegister_OnClick); m_btnUnregister.OnClick = Callback(this, &CDlgOptAccount::btnUnregister_OnClick); m_btnChangePassword.OnClick = Callback(this, &CDlgOptAccount::btnChangePassword_OnClick); } static CDlgBase *Create(void *param) { return new CDlgOptAccount((CJabberProto *)param); } protected: void OnInitDialog() { CSuper::OnInitDialog(); int i; DBVARIANT dbv; m_gotservers = false; SendDlgItemMessage(m_hwnd, IDC_PRIORITY_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(127, -128)); TCHAR *passw = m_proto->JGetStringCrypt(NULL, "LoginPassword"); if (passw) { m_txtPassword.SetText(passw); mir_free(passw); } m_cbServer.AddString(TranslateT("Loading...")); // fill predefined resources TCHAR* szResources[] = { _T("Home"), _T("Work"), _T("Office"), _T("Miranda") }; for (i = 0; i < SIZEOF(szResources); ++i) m_cbResource.AddString(szResources[i]); // append computer name to the resource list TCHAR szCompName[ MAX_COMPUTERNAME_LENGTH + 1]; DWORD dwCompNameLength = MAX_COMPUTERNAME_LENGTH; if (GetComputerName(szCompName, &dwCompNameLength)) m_cbResource.AddString(szCompName); if ( !DBGetContactSettingTString(NULL, m_proto->m_szModuleName, "Resource", &dbv)) { if (CB_ERR == m_cbResource.FindString(dbv.ptszVal, -1, true)) m_cbResource.AddString(dbv.ptszVal); m_cbResource.SetText(dbv.ptszVal); db_free(&dbv); } else m_cbResource.SetText(_T("Miranda")); for (i = 0; g_LanguageCodes[i].szCode; ++i) { int iItem = m_cbLocale.AddString(TranslateTS(g_LanguageCodes[i].szDescription), (LPARAM)g_LanguageCodes[i].szCode); if ( !_tcscmp(m_proto->m_tszSelectedLang, g_LanguageCodes[i].szCode)) m_cbLocale.SetCurSel(iItem); } EnableWindow(GetDlgItem(m_hwnd, IDC_COMBO_RESOURCE), m_chkUseHostnameAsResource.GetState() != BST_CHECKED); EnableWindow(GetDlgItem(m_hwnd, IDC_UNREGISTER), m_proto->m_bJabberOnline); m_chkUseTls.Enable(!m_proto->m_options.Disable3920auth && (m_proto->m_options.UseSSL ? false : true)); if (m_proto->m_options.Disable3920auth) m_chkUseTls.SetState(BST_UNCHECKED); m_chkUseSsl.Enable(m_proto->m_options.Disable3920auth || (m_proto->m_options.UseTLS ? false : true)); if (m_proto->m_options.ManualConnect) { m_txtManualHost.Enable(); m_txtManualPort.Enable(); m_txtPort.Disable(); } if (m_proto->m_options.UseDomainLogin) chkUseDomainLogin_OnChange(&m_chkUseDomainLogin); CheckRegistration(); } void OnApply() { // clear saved password *m_proto->m_savedPassword = 0; if (m_chkSavePassword.GetState() == BST_CHECKED) { TCHAR *text = m_txtPassword.GetText(); m_proto->JSetStringCrypt(NULL, "LoginPassword", text); mir_free(text); } else m_proto->JDeleteSetting(NULL, "LoginPassword"); int index = m_cbLocale.GetCurSel(); if (index >= 0) { TCHAR *szLanguageCode = (TCHAR *)m_cbLocale.GetItemData(index); if (szLanguageCode) { m_proto->JSetStringT(NULL, "XmlLang", szLanguageCode); mir_free(m_proto->m_tszSelectedLang); m_proto->m_tszSelectedLang = mir_tstrdup(szLanguageCode); } } sttStoreJidFromUI(m_proto, m_txtUsername, m_cbServer); if (m_proto->m_bJabberOnline) { if (m_txtUsername.IsChanged() || m_txtPassword.IsChanged() || m_cbResource.IsChanged() || m_cbServer.IsChanged() || m_chkUseHostnameAsResource.IsChanged() || m_txtPort.IsChanged() || m_txtManualHost.IsChanged() || m_txtManualPort.IsChanged() || m_cbLocale.IsChanged()) { MessageBox(m_hwnd, TranslateT("These changes will take effect the next time you connect to the Jabber network."), TranslateT("Jabber Protocol Option"), MB_OK|MB_SETFOREGROUND); } m_proto->SendPresence(m_proto->m_iStatus, true); } } void OnChange(CCtrlBase*) { if (m_initialized) CheckRegistration(); } INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_ACTIVATE: m_chkUseTls.Enable(!m_proto->m_options.Disable3920auth && (m_proto->m_options.UseSSL ? false : true)); if (m_proto->m_options.Disable3920auth) m_chkUseTls.SetState(BST_UNCHECKED); break; case WM_JABBER_REFRESH: RefreshServers((HXML)lParam); break; } return CSuper::DlgProc(msg, wParam, lParam); } private: bool m_gotservers; void btnRegister_OnClick(CCtrlButton *) { TCHAR buf[512] = _T(""), pass[512]; if ( !m_proto->EnterString(buf, SIZEOF(buf), TranslateT("Confirm password"), JES_PASSWORD)) return; m_txtPassword.GetText(pass, SIZEOF(pass)); if (lstrcmp(buf, pass)) { MessageBox(m_hwnd, TranslateT("Passwords do not match."), _T("Miranda NG"), MB_ICONSTOP|MB_OK); return; } ThreadData regInfo(m_proto, JABBER_SESSION_NORMAL); m_txtUsername.GetText(regInfo.username, SIZEOF(regInfo.username)); m_txtPassword.GetText(regInfo.password, SIZEOF(regInfo.password)); m_cbServer.GetTextA(regInfo.server, SIZEOF(regInfo.server)); if (m_chkManualHost.GetState() == BST_CHECKED) { regInfo.port = (WORD)m_txtManualPort.GetInt(); m_txtManualHost.GetTextA(regInfo.manualHost, SIZEOF(regInfo.manualHost)); } else { regInfo.port = (WORD)m_txtPort.GetInt(); regInfo.manualHost[0] = '\0'; } if (regInfo.username[0] && regInfo.password[0] && regInfo.server[0] && regInfo.port>0 && ((m_chkManualHost.GetState() != BST_CHECKED) || regInfo.manualHost[0])) { CJabberDlgRegister dlg(m_proto, m_hwnd, ®Info); dlg.DoModal(); // DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_OPT_REGISTER), m_hwnd, JabberRegisterDlgProc, (LPARAM)®Info); } } void btnUnregister_OnClick(CCtrlButton *) { int res = MessageBox(NULL, TranslateT("This operation will kill your account, roster and all another information stored at the server. Are you ready to do that?"), TranslateT("Account removal warning"), MB_YESNOCANCEL); if (res == IDYES) m_proto->m_ThreadInfo->send( XmlNodeIq(_T("set"), m_proto->SerialNext(), m_proto->m_szJabberJID) << XQUERY(_T(JABBER_FEAT_REGISTER)) << XCHILD(_T("remove"))); } void btnChangePassword_OnClick(CCtrlButton *) { if ( !m_proto->m_bJabberOnline) { MessageBox(NULL, TranslateT("You can change your password only when you are online"), TranslateT("You must be online"), MB_OK | MB_ICONSTOP); return; } m_proto->OnMenuHandleChangePassword(0, 0); } void cbServer_OnDropdown(CCtrlCombo*) { if ( !m_gotservers) mir_forkthread(QueryServerListThread, this); } void chkManualHost_OnChange(CCtrlData *sender) { CCtrlCheck *chk = (CCtrlCheck *)sender; if (chk->GetState() == BST_CHECKED) { m_txtManualHost.Enable(); m_txtManualPort.Enable(); m_txtPort.Disable(); } else { m_txtManualHost.Disable(); m_txtManualPort.Disable(); m_txtPort.Enable(); } } void chkUseHostnameAsResource_OnChange(CCtrlData *sender) { CCtrlCheck *chk = (CCtrlCheck *)sender; m_cbResource.Enable(chk->GetState() != BST_CHECKED); if (chk->GetState() == BST_CHECKED) { TCHAR szCompName[MAX_COMPUTERNAME_LENGTH + 1]; DWORD dwCompNameLength = MAX_COMPUTERNAME_LENGTH; if (GetComputerName(szCompName, &dwCompNameLength)) m_cbResource.SetText(szCompName); } } void chkUseDomainLogin_OnChange(CCtrlData *sender) { CCtrlCheck *chk = (CCtrlCheck *)sender; BOOL checked = chk->GetState() == BST_CHECKED; m_txtPassword.Enable(!checked); m_txtUsername.Enable(!checked); m_chkSavePassword.Enable(!checked); if (checked) { m_txtPassword.SetText(_T("")); m_txtUsername.SetText(_T("")); m_chkSavePassword.SetState(BST_CHECKED); } } void chkUseSsl_OnChange(CCtrlData*) { BOOL bManualHost = m_chkManualHost.GetState() == BST_CHECKED; if (m_chkUseSsl.GetState() == BST_CHECKED) { m_chkUseTls.Disable(); if ( !bManualHost) m_txtPort.SetInt(5223); } else { if ( !m_proto->m_options.Disable3920auth) m_chkUseTls.Enable(); if ( !bManualHost) m_txtPort.SetInt(5222); } } void chkUseTls_OnChange(CCtrlData*) { if (m_chkUseTls.GetState() == BST_CHECKED) m_chkUseSsl.Disable(); else m_chkUseSsl.Enable(); } void CheckRegistration() { ThreadData regInfo(m_proto, JABBER_SESSION_NORMAL); m_txtUsername.GetText(regInfo.username, SIZEOF(regInfo.username)); m_txtPassword.GetText(regInfo.password, SIZEOF(regInfo.password)); m_cbServer.GetTextA(regInfo.server, SIZEOF(regInfo.server)); if (m_chkManualHost.GetState() == BST_CHECKED) { regInfo.port = (WORD)m_txtManualPort.GetInt(); m_txtManualHost.GetTextA(regInfo.manualHost, SIZEOF(regInfo.manualHost)); } else { regInfo.port = (WORD)m_txtPort.GetInt(); regInfo.manualHost[0] = '\0'; } if (regInfo.username[0] && regInfo.password[0] && regInfo.server[0] && regInfo.port>0 && ((m_chkManualHost.GetState() != BST_CHECKED) || regInfo.manualHost[0])) EnableWindow(GetDlgItem(m_hwnd, IDC_BUTTON_REGISTER), TRUE); else EnableWindow(GetDlgItem(m_hwnd, IDC_BUTTON_REGISTER), FALSE); } void RefreshServers(HXML node) { m_gotservers = node != NULL; TCHAR *server = m_cbServer.GetText(); bool bDropdown = m_cbServer.GetDroppedState(); if (bDropdown) m_cbServer.ShowDropdown(false); m_cbServer.ResetContent(); if (node) { for (int i = 0; ; ++i) { HXML n = xmlGetChild(node, i); if ( !n) break; if ( !lstrcmp(xmlGetName(n), _T("item"))) if (const TCHAR *jid = xmlGetAttrValue(n, _T("jid"))) if (m_cbServer.FindString(jid, -1, true) == CB_ERR) m_cbServer.AddString(jid); } } m_cbServer.SetText(server); if (bDropdown) m_cbServer.ShowDropdown(); mir_free(server); } static void QueryServerListThread(void *arg) { CDlgOptAccount *wnd = (CDlgOptAccount *)arg; HWND hwnd = wnd->GetHwnd(); bool bIsError = true; if ( !IsWindow(hwnd)) return; NETLIBHTTPREQUEST request = {0}; request.cbSize = sizeof(request); request.requestType = REQUEST_GET; request.flags = NLHRF_REDIRECT | NLHRF_HTTP11; request.szUrl = "http://xmpp.org/services/services.xml"; NETLIBHTTPREQUEST *result = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)wnd->GetProto()->m_hNetlibUser, (LPARAM)&request); if (result) { if (result->resultCode == 200 && result->dataLength && result->pData) { TCHAR* buf = mir_a2t(result->pData); XmlNode node(buf, NULL, NULL); if (node) { HXML queryNode = xmlGetChild(node, _T("query")); SendMessage(hwnd, WM_JABBER_REFRESH, 0, (LPARAM)queryNode); bIsError = false; } mir_free(buf); } CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)result); } if (bIsError) SendMessage(hwnd, WM_JABBER_REFRESH, 0, 0); } }; ///////////////////////////////////////////////////////////////////////////////////////// // JabberAdvOptDlgProc - advanced options dialog procedure class CDlgOptAdvanced: public CJabberDlgBase { typedef CJabberDlgBase CSuper; CCtrlCheck m_chkDirect; CCtrlCheck m_chkDirectManual; CCtrlCheck m_chkProxy; CCtrlEdit m_txtDirect; CCtrlEdit m_txtProxy; CCtrlTreeOpts m_otvOptions; public: CDlgOptAdvanced(CJabberProto *proto): CJabberDlgBase(proto, IDD_OPT_JABBER2, NULL, false), m_chkDirect(this, IDC_DIRECT), m_chkDirectManual(this, IDC_DIRECT_MANUAL), m_chkProxy(this, IDC_PROXY_MANUAL), m_txtDirect(this, IDC_DIRECT_ADDR), m_txtProxy(this, IDC_PROXY_ADDR), m_otvOptions(this, IDC_OPTTREE) { CreateLink(m_chkDirect, proto->m_options.BsDirect); CreateLink(m_chkDirectManual, proto->m_options.BsDirectManual); CreateLink(m_chkProxy, proto->m_options.BsProxyManual); CreateLink(m_txtDirect, "BsDirectAddr", _T("")); CreateLink(m_txtProxy, "BsProxyServer", _T("")); m_chkDirect.OnChange = m_chkDirectManual.OnChange = Callback(this, &CDlgOptAdvanced::chkDirect_OnChange); m_chkProxy.OnChange = Callback(this, &CDlgOptAdvanced::chkProxy_OnChange); m_otvOptions.AddOption(LPGENT("Messaging") _T("/") LPGENT("Send messages slower, but with full acknowledgement"), m_proto->m_options.MsgAck); m_otvOptions.AddOption(LPGENT("Messaging") _T("/") LPGENT("Enable avatars"), m_proto->m_options.EnableAvatars); m_otvOptions.AddOption(LPGENT("Messaging") _T("/") LPGENT("Log chat state changes"), m_proto->m_options.LogChatstates); m_otvOptions.AddOption(LPGENT("Messaging") _T("/") LPGENT("Log presence subscription state changes"), m_proto->m_options.LogPresence); m_otvOptions.AddOption(LPGENT("Messaging") _T("/") LPGENT("Log presence errors"), m_proto->m_options.LogPresenceErrors); m_otvOptions.AddOption(LPGENT("Messaging") _T("/") LPGENT("Enable user moods receiving"), m_proto->m_options.EnableUserMood); m_otvOptions.AddOption(LPGENT("Messaging") _T("/") LPGENT("Enable user tunes receiving"), m_proto->m_options.EnableUserTune); m_otvOptions.AddOption(LPGENT("Messaging") _T("/") LPGENT("Enable user activity receiving"), m_proto->m_options.EnableUserActivity); m_otvOptions.AddOption(LPGENT("Messaging") _T("/") LPGENT("Receive notes"), m_proto->m_options.AcceptNotes); m_otvOptions.AddOption(LPGENT("Messaging") _T("/") LPGENT("Automatically save received notes"), m_proto->m_options.AutosaveNotes); m_otvOptions.AddOption(LPGENT("Server options") _T("/") LPGENT("Disable SASL authentication (for old servers)"), m_proto->m_options.Disable3920auth); m_otvOptions.AddOption(LPGENT("Server options") _T("/") LPGENT("Enable stream compression (if possible)"), m_proto->m_options.EnableZlib); m_otvOptions.AddOption(LPGENT("Other") _T("/") LPGENT("Enable remote controlling (from another resource of same JID only)"), m_proto->m_options.EnableRemoteControl); m_otvOptions.AddOption(LPGENT("Other") _T("/") LPGENT("Show transport agents on contact list"), m_proto->m_options.ShowTransport); m_otvOptions.AddOption(LPGENT("Other") _T("/") LPGENT("Automatically add contact when accept authorization"), m_proto->m_options.AutoAdd); m_otvOptions.AddOption(LPGENT("Other") _T("/") LPGENT("Automatically accept authorization requests"), m_proto->m_options.AutoAcceptAuthorization); m_otvOptions.AddOption(LPGENT("Other") _T("/") LPGENT("Fix incorrect timestamps in incoming messages"), m_proto->m_options.FixIncorrectTimestamps); m_otvOptions.AddOption(LPGENT("Other") _T("/") LPGENT("Disable frame"), m_proto->m_options.DisableFrame); m_otvOptions.AddOption(LPGENT("Other") _T("/") LPGENT("Enable XMPP link processing (requires Association Manager)"), m_proto->m_options.ProcessXMPPLinks); m_otvOptions.AddOption(LPGENT("Other") _T("/") LPGENT("Keep contacts assigned to local groups (ignore roster group)"), m_proto->m_options.IgnoreRosterGroups); m_otvOptions.AddOption(LPGENT("Security") _T("/") LPGENT("Allow servers to request version (XEP-0092)"), m_proto->m_options.AllowVersionRequests); m_otvOptions.AddOption(LPGENT("Security") _T("/") LPGENT("Show information about operating system in version replies"), m_proto->m_options.ShowOSVersion); m_otvOptions.AddOption(LPGENT("Security") _T("/") LPGENT("Accept only in band incoming filetransfers (don't disclose own IP)"), m_proto->m_options.BsOnlyIBB); m_otvOptions.AddOption(LPGENT("Security") _T("/") LPGENT("Accept HTTP Authentication requests (XEP-0070)"), m_proto->m_options.AcceptHttpAuth); } void OnInitDialog() { CSuper::OnInitDialog(); chkDirect_OnChange(&m_chkDirect); chkProxy_OnChange(&m_chkProxy); } void OnApply() { BOOL bChecked = m_proto->m_options.ShowTransport; LISTFOREACH(index, m_proto, LIST_ROSTER) { JABBER_LIST_ITEM* item = m_proto->ListGetItemPtrFromIndex(index); if (item != NULL) { if (_tcschr(item->jid, '@') == NULL) { HANDLE hContact = m_proto->HContactFromJID(item->jid); if (hContact != NULL) { if (bChecked) { if (item->itemResource.status != m_proto->JGetWord(hContact, "Status", ID_STATUS_OFFLINE)) { m_proto->JSetWord(hContact, "Status", (WORD)item->itemResource.status); } } else if (m_proto->JGetWord(hContact, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) m_proto->JSetWord(hContact, "Status", ID_STATUS_OFFLINE); } } } } m_proto->SendPresence(m_proto->m_iStatus, true); } void chkDirect_OnChange(CCtrlData *) { if (m_chkDirect.GetState() == BST_CHECKED) { if (m_chkDirectManual.GetState() == BST_CHECKED) m_txtDirect.Enable(); else m_txtDirect.Disable(); m_chkDirectManual.Enable(); } else { m_txtDirect.Disable(); m_chkDirectManual.Disable(); } } void chkProxy_OnChange(CCtrlData *) { if (m_chkProxy.GetState() == BST_CHECKED) m_txtProxy.Enable(); else m_txtProxy.Disable(); } static CDlgBase *Create(void *param) { return new CDlgOptAdvanced((CJabberProto *)param); } }; ///////////////////////////////////////////////////////////////////////////////////////// // JabberGcOptDlgProc - chat options dialog procedure class CDlgOptGc: public CJabberDlgBase { typedef CJabberDlgBase CSuper; CCtrlEdit m_txtAltNick; CCtrlEdit m_txtSlap; CCtrlEdit m_txtQuit; CCtrlTreeOpts m_otvOptions; public: CDlgOptGc(CJabberProto *proto): CJabberDlgBase(proto, IDD_OPT_JABBER4, NULL, false), m_txtAltNick(this, IDC_TXT_ALTNICK), m_txtSlap(this, IDC_TXT_SLAP), m_txtQuit(this, IDC_TXT_QUIT), m_otvOptions(this, IDC_OPTTREE) { CreateLink(m_txtAltNick, "GcAltNick", _T("")); CreateLink(m_txtSlap, "GcMsgSlap", TranslateTS(JABBER_GC_MSG_SLAP)); CreateLink(m_txtQuit, "GcMsgQuit", TranslateTS(JABBER_GC_MSG_QUIT)); m_otvOptions.AddOption(LPGENT("General") _T("/") LPGENT("Autoaccept multiuser chat invitations"), m_proto->m_options.AutoAcceptMUC); m_otvOptions.AddOption(LPGENT("General") _T("/") LPGENT("Automatically join bookmarks on login"), m_proto->m_options.AutoJoinBookmarks); m_otvOptions.AddOption(LPGENT("General") _T("/") LPGENT("Automatically join conferences on login"), m_proto->m_options.AutoJoinConferences); m_otvOptions.AddOption(LPGENT("General") _T("/") LPGENT("Hide conference windows at startup"), m_proto->m_options.AutoJoinHidden); m_otvOptions.AddOption(LPGENT("General") _T("/") LPGENT("Do not show multiuser chat invitations"), m_proto->m_options.IgnoreMUCInvites); m_otvOptions.AddOption(LPGENT("Log events") _T("/") LPGENT("Ban notifications"), m_proto->m_options.GcLogBans); m_otvOptions.AddOption(LPGENT("Log events") _T("/") LPGENT("Room configuration changes"), m_proto->m_options.GcLogConfig); m_otvOptions.AddOption(LPGENT("Log events") _T("/") LPGENT("Affiliation changes"), m_proto->m_options.GcLogAffiliations); m_otvOptions.AddOption(LPGENT("Log events") _T("/") LPGENT("Role changes"), m_proto->m_options.GcLogRoles); m_otvOptions.AddOption(LPGENT("Log events") _T("/") LPGENT("Status changes"), m_proto->m_options.GcLogStatuses); m_otvOptions.AddOption(LPGENT("Log events") _T("/") LPGENT("Filter history messages"), m_proto->m_options.GcLogChatHistory); } static CDlgBase *Create(void *param) { return new CDlgOptGc((CJabberProto *)param); } }; ////////////////////////////////////////////////////////////////////////// // roster editor // #include #define JM_STATUSCHANGED WM_USER+0x0001 #define fopent(name, mode) _wfopen(name, mode) enum { RRA_FILLLIST = 0, RRA_SYNCROSTER, RRA_SYNCDONE }; typedef struct _tag_RosterhEditDat{ WNDPROC OldEditProc; HWND hList; int index; int subindex; } ROSTEREDITDAT; static WNDPROC _RosterOldListProc=NULL; static int _RosterInsertListItem(HWND hList, const TCHAR * jid, const TCHAR * nick, const TCHAR * group, const TCHAR * subscr, BOOL bChecked) { LVITEM item={0}; int index; item.mask=LVIF_TEXT|LVIF_STATE; item.iItem = ListView_GetItemCount(hList); item.iSubItem = 0; item.pszText = (TCHAR*)jid; index=ListView_InsertItem(hList, &item); if (index<0) return index; ListView_SetCheckState(hList, index, bChecked); ListView_SetItemText(hList, index, 0, (TCHAR*)jid); ListView_SetItemText(hList, index, 1, (TCHAR*)nick); ListView_SetItemText(hList, index, 2, (TCHAR*)group); ListView_SetItemText(hList, index, 3, TranslateTS(subscr)); return index; } static void _RosterListClear(HWND hwndDlg) { HWND hList=GetDlgItem(hwndDlg, IDC_ROSTER); if ( !hList) return; ListView_DeleteAllItems(hList); while ( ListView_DeleteColumn(hList, 0)); LV_COLUMN column={0}; column.mask=LVCF_TEXT; column.cx=500; column.pszText=TranslateT("JID"); ListView_InsertColumn(hList, 1, &column); column.pszText=TranslateT("Nick Name"); ListView_InsertColumn(hList, 2, &column); column.pszText=TranslateT("Group"); ListView_InsertColumn(hList, 3, &column); column.pszText=TranslateT("Subscription"); ListView_InsertColumn(hList, 4, &column); RECT rc; GetClientRect(hList, &rc); int width=rc.right-rc.left; ListView_SetColumnWidth(hList,0,width*40/100); ListView_SetColumnWidth(hList,1,width*25/100); ListView_SetColumnWidth(hList,2,width*20/100); ListView_SetColumnWidth(hList,3,width*10/100); } void CJabberProto::_RosterHandleGetRequest(HXML node) { HWND hList=GetDlgItem(rrud.hwndDlg, IDC_ROSTER); if (rrud.bRRAction==RRA_FILLLIST) { _RosterListClear(rrud.hwndDlg); HXML query = xmlGetChild(node , "query"); if ( !query) return; int i = 1; while (TRUE) { HXML item = xmlGetNthChild(query, _T("item"), i++); if ( !item) break; const TCHAR *jid = xmlGetAttrValue(item, _T("jid")); if ( !jid) continue; const TCHAR *name = xmlGetAttrValue(item, _T("name")); const TCHAR *subscription = xmlGetAttrValue(item, _T("subscription")); const TCHAR *group = NULL; HXML groupNode = xmlGetChild(item , "group"); if (groupNode) group = xmlGetText(groupNode); _RosterInsertListItem(hList, jid, name, group, subscription, TRUE); } // now it is require to process whole contact list to add not in roster contacts { HANDLE hContact = (HANDLE)db_find_first(); while (hContact != NULL) { char* str = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); if (str != NULL && !strcmp(str, m_szModuleName)) { DBVARIANT dbv; if ( !JGetStringT(hContact, "jid", &dbv)) { LVFINDINFO lvfi={0}; lvfi.flags = LVFI_STRING; lvfi.psz = dbv.ptszVal; TCHAR *p = _tcschr(dbv.ptszVal,_T('@')); if (p) { p = _tcschr(dbv.ptszVal, _T('/')); if (p) *p = _T('\0'); } if (ListView_FindItem(hList, -1, &lvfi) == -1) { TCHAR *jid = mir_tstrdup(dbv.ptszVal); TCHAR *name = NULL; TCHAR *group = NULL; DBVARIANT dbvtemp; if ( !DBGetContactSettingTString(hContact, "CList", "MyHandle", &dbvtemp)) { name = mir_tstrdup(dbvtemp.ptszVal); db_free(&dbvtemp); } if ( !DBGetContactSettingTString(hContact, "CList", "Group", &dbvtemp)) { group = mir_tstrdup(dbvtemp.ptszVal); db_free(&dbvtemp); } _RosterInsertListItem(hList, jid, name, group, NULL, FALSE); if (jid) mir_free(jid); if (name) mir_free(name); if (group) mir_free(group); } db_free(&dbv); } } hContact = db_find_next(hContact); } } rrud.bReadyToDownload = FALSE; rrud.bReadyToUpload = TRUE; SetDlgItemText(rrud.hwndDlg, IDC_DOWNLOAD, TranslateT("Download")); SetDlgItemText(rrud.hwndDlg, IDC_UPLOAD, TranslateT("Upload")); SendMessage(rrud.hwndDlg, JM_STATUSCHANGED, 0, 0); return; } else if (rrud.bRRAction == RRA_SYNCROSTER) { SetDlgItemText(rrud.hwndDlg, IDC_UPLOAD, TranslateT("Uploading...")); HXML queryRoster = xmlGetChild(node , "query"); if ( !queryRoster) return; int iqId = SerialNext(); IqAdd(iqId, IQ_PROC_NONE, &CJabberProto::_RosterHandleGetRequest); XmlNode iq(_T("iq")); xmlAddAttr(iq, _T("type"), _T("set")); iq << XATTRID(iqId); HXML query = iq << XCHILDNS(_T("query"), _T(JABBER_FEAT_IQ_ROSTER)); int itemCount=0; int ListItemCount=ListView_GetItemCount(hList); for (int index=0; indexsend(iq); else _RosterSendRequest(rrud.hwndDlg,RRA_FILLLIST); } else { SetDlgItemText(rrud.hwndDlg,IDC_UPLOAD,TranslateT("Upload")); rrud.bReadyToUpload=FALSE; rrud.bReadyToDownload=FALSE; SendMessage(rrud.hwndDlg, JM_STATUSCHANGED,0,0); SetDlgItemText(rrud.hwndDlg,IDC_DOWNLOAD,TranslateT("Downloading...")); _RosterSendRequest(rrud.hwndDlg,RRA_FILLLIST); } } void CJabberProto::_RosterSendRequest(HWND hwndDlg, BYTE rrAction) { rrud.bRRAction=rrAction; rrud.hwndDlg=hwndDlg; int iqId = SerialNext(); IqAdd(iqId, IQ_PROC_NONE, &CJabberProto::_RosterHandleGetRequest); m_ThreadInfo->send(XmlNode(_T("iq")) << XATTR(_T("type"), _T("get")) << XATTRID(iqId) << XCHILDNS(_T("query"), _T(JABBER_FEAT_IQ_ROSTER))); } static void _RosterItemEditEnd(HWND hEditor, ROSTEREDITDAT * edat, BOOL bCancel) { if ( !bCancel) { int len = GetWindowTextLength(hEditor) + 1; TCHAR *buff=(TCHAR*)mir_alloc(len*sizeof(TCHAR)); if (buff) { GetWindowText(hEditor,buff,len); ListView_SetItemText(edat->hList,edat->index, edat->subindex,buff); } mir_free(buff); } DestroyWindow(hEditor); } static BOOL CALLBACK _RosterItemNewEditProc(HWND hEditor, UINT msg, WPARAM wParam, LPARAM lParam) { ROSTEREDITDAT * edat = (ROSTEREDITDAT *) GetWindowLongPtr(hEditor,GWLP_USERDATA); if ( !edat) return 0; switch(msg) { case WM_KEYDOWN: switch(wParam) { case VK_RETURN: _RosterItemEditEnd(hEditor, edat, FALSE); return 0; case VK_ESCAPE: _RosterItemEditEnd(hEditor, edat, TRUE); return 0; } break; case WM_GETDLGCODE: if (lParam) { MSG *msg2 = (MSG*)lParam; if (msg2->message==WM_KEYDOWN && msg2->wParam==VK_TAB) return 0; if (msg2->message==WM_CHAR && msg2->wParam=='\t') return 0; } return DLGC_WANTMESSAGE; case WM_KILLFOCUS: _RosterItemEditEnd(hEditor, edat, FALSE); return 0; } if (msg==WM_DESTROY) { SetWindowLongPtr(hEditor, GWLP_WNDPROC, (LONG_PTR) edat->OldEditProc); SetWindowLongPtr(hEditor, GWLP_USERDATA, (LONG_PTR) 0); free(edat); return 0; } else return CallWindowProc(edat->OldEditProc, hEditor, msg, wParam, lParam); } void CJabberProto::_RosterExportToFile(HWND hwndDlg) { TCHAR filename[MAX_PATH]={0}; TCHAR filter[MAX_PATH]; mir_sntprintf(filter, SIZEOF(filter), _T("%s (*.xml)%c*.xml%c%c"), TranslateT("XML for MS Excel (UTF-8 encoded)"), 0, 0, 0); OPENFILENAME ofn={0}; ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; ofn.hwndOwner = hwndDlg; ofn.hInstance = NULL; ofn.lpstrFilter = filter; ofn.lpstrFile = filename; ofn.Flags = OFN_HIDEREADONLY; ofn.nMaxFile = SIZEOF(filename); ofn.nMaxFileTitle = MAX_PATH; ofn.lpstrDefExt = _T("xml"); if ( !GetSaveFileName(&ofn)) return; FILE * fp = fopent(filename,_T("w")); if ( !fp) return; HWND hList=GetDlgItem(hwndDlg, IDC_ROSTER); int ListItemCount=ListView_GetItemCount(hList); XmlNode root(_T("Workbook")); root << XATTR(_T("xmlns"), _T("urn:schemas-microsoft-com:office:spreadsheet")) << XATTR(_T("xmlns:o"), _T("urn:schemas-microsoft-com:office:office")) << XATTR(_T("xmlns:x"), _T("urn:schemas-microsoft-com:office:excel")) << XATTR(_T("xmlns:ss"), _T("urn:schemas-microsoft-com:office:spreadsheet")) << XATTR(_T("xmlns:html"), _T("http://www.w3.org/TR/REC-html40")); root << XCHILD(_T("ExcelWorkbook")) << XATTR(_T("xmlns"), _T("urn:schemas-microsoft-com:office:excel")); HXML table = root << XCHILD(_T("Worksheet")) << XATTR(_T("ss:Name"), _T("Exported roster")) << XCHILD(_T("Table")); for (int index=0; index\n\n"; fwrite(header, 1, sizeof(header) - 1 /* for zero terminator */, fp); TCHAR *xtmp = xi.toString(root, NULL); char *tmp = mir_utf8encodeT(xtmp); xi.freeMem(xtmp); fwrite(tmp, 1, strlen(tmp), fp); mir_free(tmp); fclose(fp); } void CJabberProto::_RosterImportFromFile(HWND hwndDlg) { char filename[MAX_PATH]={0}; char *filter="XML for MS Excel (UTF-8 encoded)(*.xml)\0*.xml\0\0"; OPENFILENAMEA ofn={0}; ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; ofn.hwndOwner = hwndDlg; ofn.hInstance = NULL; ofn.lpstrFilter = filter; ofn.lpstrFile = filename; ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.nMaxFile = sizeof(filename); ofn.nMaxFileTitle = MAX_PATH; ofn.lpstrDefExt = "xml"; if ( !GetOpenFileNameA(&ofn)) return; FILE * fp=fopen(filename,"r"); if ( !fp) return; DWORD bufsize = _filelength(_fileno(fp)); if (bufsize <= 0) { fclose(fp); return; } char* buffer=(char*)mir_calloc(bufsize+1); // zero-terminate it fread(buffer,1,bufsize,fp); fclose(fp); _RosterListClear(hwndDlg); TCHAR* newBuf = mir_utf8decodeT(buffer); mir_free(buffer); int nBytesProcessed = 0; XmlNode node(newBuf, &nBytesProcessed, NULL); if (node) { HXML Workbook = xmlGetChild(node, _T("Workbook")); if (Workbook) { HXML Worksheet = xmlGetChild(Workbook , "Worksheet"); if (Worksheet) { HXML Table = xmlGetChild(Worksheet , "Table"); if (Table) { int index=1; HWND hList=GetDlgItem(hwndDlg, IDC_ROSTER); while (TRUE) { HXML Row = xmlGetNthChild(Table, _T("Row"), index++); if ( !Row) break; BOOL bAdd=FALSE; const TCHAR *jid=NULL; const TCHAR *name=NULL; const TCHAR *group=NULL; const TCHAR *subscr=NULL; HXML Cell = xmlGetNthChild(Row, _T("Cell"), 1); HXML Data = (Cell) ? xmlGetChild(Cell , "Data") : XmlNode(); if (Data) { if ( !lstrcmpi(xmlGetText(Data),_T("+"))) bAdd=TRUE; else if (lstrcmpi(xmlGetText(Data),_T("-"))) continue; Cell = xmlGetNthChild(Row, _T("Cell"),2); if (Cell) Data=xmlGetChild(Cell , "Data"); else Data = NULL; if (Data) { jid=xmlGetText(Data); if ( !jid || lstrlen(jid)==0) continue; } Cell=xmlGetNthChild(Row,_T("Cell"),3); if (Cell) Data=xmlGetChild(Cell , "Data"); else Data = NULL; if (Data) name=xmlGetText(Data); Cell=xmlGetNthChild(Row,_T("Cell"),4); if (Cell) Data=xmlGetChild(Cell , "Data"); else Data = NULL; if (Data) group=xmlGetText(Data); Cell=xmlGetNthChild(Row,_T("Cell"),5); if (Cell) Data=xmlGetChild(Cell , "Data"); else Data = NULL; if (Data) subscr=xmlGetText(Data); } _RosterInsertListItem(hList,jid,name,group,subscr,bAdd); } } } } } mir_free(newBuf); SendMessage(hwndDlg, JM_STATUSCHANGED, 0, 0); } static BOOL CALLBACK _RosterNewListProc(HWND hList, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg==WM_MOUSEWHEEL || msg==WM_NCLBUTTONDOWN || msg==WM_NCRBUTTONDOWN) { SetFocus(hList); } if (msg==WM_LBUTTONDOWN) { POINT pt; GetCursorPos(&pt); ScreenToClient(hList, &pt); LVHITTESTINFO lvhti={0}; lvhti.pt=pt; ListView_SubItemHitTest(hList,&lvhti); if (lvhti.flags&LVHT_ONITEM && lvhti.iSubItem !=0) { RECT rc; TCHAR buff[260]; ListView_GetSubItemRect(hList, lvhti.iItem, lvhti.iSubItem, LVIR_BOUNDS,&rc); ListView_GetItemText(hList, lvhti.iItem, lvhti.iSubItem, buff, SIZEOF(buff)); HWND hEditor=CreateWindow(TEXT("EDIT"),buff,WS_CHILD|ES_AUTOHSCROLL,rc.left+3, rc.top+2, rc.right-rc.left-3, rc.bottom - rc.top-3,hList, NULL, hInst, NULL); SendMessage(hEditor,WM_SETFONT,(WPARAM)SendMessage(hList,WM_GETFONT,0,0),0); ShowWindow(hEditor,SW_SHOW); SetWindowText(hEditor, buff); ClientToScreen(hList, &pt); ScreenToClient(hEditor, &pt); mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); ROSTEREDITDAT * edat=(ROSTEREDITDAT *)malloc(sizeof(ROSTEREDITDAT)); edat->OldEditProc=(WNDPROC)GetWindowLongPtr(hEditor, GWLP_WNDPROC); SetWindowLongPtr(hEditor,GWLP_WNDPROC,(LONG_PTR)_RosterItemNewEditProc); edat->hList=hList; edat->index=lvhti.iItem; edat->subindex=lvhti.iSubItem; SetWindowLongPtr(hEditor,GWLP_USERDATA,(LONG_PTR)edat); } } return CallWindowProc(_RosterOldListProc, hList, msg, wParam, lParam); } ///////////////////////////////////////////////////////////////////////////////////////// // JabberRosterOptDlgProc - advanced options dialog procedure static int sttRosterEditorResizer(HWND /*hwndDlg*/, LPARAM, UTILRESIZECONTROL *urc) { switch (urc->wId) { case IDC_HEADERBAR: return RD_ANCHORX_LEFT|RD_ANCHORY_TOP|RD_ANCHORX_WIDTH; case IDC_ROSTER: return RD_ANCHORX_LEFT|RD_ANCHORY_TOP|RD_ANCHORY_HEIGHT|RD_ANCHORX_WIDTH; case IDC_DOWNLOAD: case IDC_UPLOAD: return RD_ANCHORX_LEFT|RD_ANCHORY_BOTTOM; case IDC_EXPORT: case IDC_IMPORT: return RD_ANCHORX_RIGHT|RD_ANCHORY_BOTTOM; // case IDC_STATUSBAR: // return RD_ANCHORX_LEFT|RD_ANCHORX_WIDTH|RD_ANCHORY_BOTTOM; } return RD_ANCHORX_LEFT|RD_ANCHORY_TOP; } static INT_PTR CALLBACK JabberRosterOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CJabberProto* ppro = (CJabberProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case JM_STATUSCHANGED: { int count = ListView_GetItemCount(GetDlgItem(hwndDlg,IDC_ROSTER)); EnableWindow(GetDlgItem(hwndDlg, IDC_DOWNLOAD), ppro->m_bJabberOnline); EnableWindow(GetDlgItem(hwndDlg, IDC_UPLOAD), count && ppro->m_bJabberOnline); EnableWindow(GetDlgItem(hwndDlg, IDC_EXPORT), count > 0); break; } case WM_CLOSE: { DestroyWindow(hwndDlg); break; } case WM_DESTROY: { Utils_SaveWindowPosition(hwndDlg, NULL, ppro->m_szModuleName, "rosterCtrlWnd_"); ppro->rrud.hwndDlg = NULL; WindowFreeIcon(hwndDlg); break; } case WM_INITDIALOG: { ppro = (CJabberProto*)lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); TranslateDialogDefault(hwndDlg); WindowSetIcon(hwndDlg, ppro, "Agents"); Utils_RestoreWindowPosition(hwndDlg, NULL, ppro->m_szModuleName, "rosterCtrlWnd_"); ListView_SetExtendedListViewStyle(GetDlgItem(hwndDlg,IDC_ROSTER), LVS_EX_CHECKBOXES | LVS_EX_BORDERSELECT /*| LVS_EX_FULLROWSELECT*/ | LVS_EX_GRIDLINES /*| LVS_EX_HEADERDRAGDROP*/); _RosterOldListProc=(WNDPROC) GetWindowLongPtr(GetDlgItem(hwndDlg,IDC_ROSTER), GWLP_WNDPROC); SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_ROSTER), GWLP_WNDPROC, (LONG_PTR) _RosterNewListProc); _RosterListClear(hwndDlg); ppro->rrud.hwndDlg = hwndDlg; ppro->rrud.bReadyToDownload = TRUE; ppro->rrud.bReadyToUpload = FALSE; SendMessage(hwndDlg, JM_STATUSCHANGED, 0, 0); return TRUE; } case WM_GETMINMAXINFO: { LPMINMAXINFO lpmmi = (LPMINMAXINFO)lParam; lpmmi->ptMinTrackSize.x = 550; lpmmi->ptMinTrackSize.y = 390; return 0; } case WM_SIZE: { UTILRESIZEDIALOG urd = {0}; urd.cbSize = sizeof(urd); urd.hInstance = hInst; urd.hwndDlg = hwndDlg; urd.lpTemplate = MAKEINTRESOURCEA(IDD_OPT_JABBER3); urd.pfnResizer = sttRosterEditorResizer; CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); break; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_DOWNLOAD: ppro->rrud.bReadyToUpload = FALSE; ppro->rrud.bReadyToDownload = FALSE; SendMessage(ppro->rrud.hwndDlg, JM_STATUSCHANGED,0,0); SetDlgItemText(ppro->rrud.hwndDlg, IDC_DOWNLOAD, TranslateT("Downloading...")); ppro->_RosterSendRequest(hwndDlg, RRA_FILLLIST); break; case IDC_UPLOAD: ppro->rrud.bReadyToUpload = FALSE; SendMessage(ppro->rrud.hwndDlg, JM_STATUSCHANGED, 0, 0); SetDlgItemText(ppro->rrud.hwndDlg, IDC_UPLOAD, TranslateT("Connecting...")); ppro->_RosterSendRequest(hwndDlg, RRA_SYNCROSTER); break; case IDC_EXPORT: ppro->_RosterExportToFile(hwndDlg); break; case IDC_IMPORT: ppro->_RosterImportFromFile(hwndDlg); break; } break; } return FALSE; } INT_PTR __cdecl CJabberProto::OnMenuHandleRosterControl(WPARAM, LPARAM) { if (rrud.hwndDlg && IsWindow(rrud.hwndDlg)) SetForegroundWindow(rrud.hwndDlg); else CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_OPT_JABBER3), NULL, JabberRosterOptDlgProc, (LPARAM)this); return 0; } ///////////////////////////////////////////////////////////////////////////////////////// // JabberOptInit - initializes all options dialogs int CJabberProto::OnOptionsInit(WPARAM wParam, LPARAM) { OPTIONSDIALOGPAGE odp = { 0 }; odp.cbSize = sizeof(odp); odp.hInstance = hInst; odp.ptszGroup = LPGENT("Network"); odp.ptszTitle = m_tszUserName; odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR | ODPF_DONTTRANSLATE; odp.ptszTab = LPGENT("Account"); odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_JABBER); odp.pfnDlgProc = CDlgBase::DynamicDlgProc; odp.dwInitParam = (LPARAM)&OptCreateAccount; OptCreateAccount.create = CDlgOptAccount::Create; OptCreateAccount.param = this; Options_AddPage(wParam, &odp); odp.ptszTab = LPGENT("Conferences"); odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_JABBER4); odp.pfnDlgProc = CDlgBase::DynamicDlgProc; odp.dwInitParam = (LPARAM)&OptCreateGc; OptCreateGc.create = CDlgOptGc::Create; OptCreateGc.param = this; Options_AddPage(wParam, &odp); odp.ptszTab = LPGENT("Advanced"); odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_JABBER2); odp.pfnDlgProc = CDlgBase::DynamicDlgProc; odp.dwInitParam = (LPARAM)&OptCreateAdvanced; OptCreateAdvanced.create = CDlgOptAdvanced::Create; OptCreateAdvanced.param = this; Options_AddPage(wParam, &odp); return 0; } /////////////////////////////////////////////////////////////////////////////// // Account manager UI class CJabberDlgAccMgrUI: public CJabberDlgBase { typedef CJabberDlgBase CSuper; CCtrlCombo m_cbType; CCtrlEditJid m_txtUsername; CCtrlCombo m_cbServer; CCtrlEdit m_txtPassword; CCtrlCheck m_chkSavePassword; CCtrlCheck m_chkUseDomainLogin; CCtrlCombo m_cbResource; CCtrlCheck m_chkManualHost; CCtrlEdit m_txtManualHost; CCtrlEdit m_txtPort; CCtrlButton m_btnRegister; public: CJabberDlgAccMgrUI(CJabberProto *proto, HWND hwndParent): CJabberDlgBase(proto, IDD_ACCMGRUI, hwndParent, false), m_cbType(this, IDC_CB_TYPE), m_txtUsername(this, IDC_EDIT_USERNAME), m_txtPassword(this, IDC_EDIT_PASSWORD), m_chkUseDomainLogin(this, IDC_USEDOMAINLOGIN), m_chkSavePassword(this, IDC_SAVEPASSWORD), m_cbResource(this, IDC_COMBO_RESOURCE), m_cbServer(this, IDC_EDIT_LOGIN_SERVER), m_txtPort(this, IDC_PORT), m_chkManualHost(this, IDC_MANUAL), m_txtManualHost(this, IDC_HOST), m_btnRegister(this, IDC_BUTTON_REGISTER) { CreateLink(m_txtUsername, "LoginName", _T("")); CreateLink(m_chkSavePassword, proto->m_options.SavePassword); CreateLink(m_cbResource, "Resource", _T("Miranda")); CreateLink(m_cbServer, "LoginServer", _T("jabber.org")); CreateLink(m_txtPort, "Port", DBVT_WORD, 5222); CreateLink(m_chkUseDomainLogin, proto->m_options.UseDomainLogin); // Bind events m_cbType.OnChange = Callback(this, &CJabberDlgAccMgrUI::cbType_OnChange); m_cbServer.OnDropdown = Callback(this, &CJabberDlgAccMgrUI::cbServer_OnDropdown); m_chkManualHost.OnChange = Callback(this, &CJabberDlgAccMgrUI::chkManualHost_OnChange); m_chkUseDomainLogin.OnChange = Callback(this, &CJabberDlgAccMgrUI::chkUseDomainLogin_OnChange); m_btnRegister.OnClick = Callback(this, &CJabberDlgAccMgrUI::btnRegister_OnClick); } protected: enum { ACC_PUBLIC, ACC_TLS, ACC_SSL, ACC_GTALK, ACC_LJTALK, ACC_FBOOK, ACC_VK, ACC_SMS }; void OnInitDialog() { CSuper::OnInitDialog(); int i; DBVARIANT dbv; char server[256], manualServer[256]={0}; m_gotservers = false; TCHAR *passw = m_proto->JGetStringCrypt(NULL, "LoginPassword"); if (passw) { m_txtPassword.SetText(passw); mir_free(passw); } m_cbServer.AddString(TranslateT("Loading...")); // fill predefined resources TCHAR* szResources[] = { _T("Home"), _T("Work"), _T("Office"), _T("Miranda") }; for (i = 0; i < SIZEOF(szResources); ++i) m_cbResource.AddString(szResources[i]); // append computer name to the resource list TCHAR szCompName[ MAX_COMPUTERNAME_LENGTH + 1]; DWORD dwCompNameLength = MAX_COMPUTERNAME_LENGTH; if (GetComputerName(szCompName, &dwCompNameLength)) m_cbResource.AddString(szCompName); if ( !DBGetContactSettingTString(NULL, m_proto->m_szModuleName, "Resource", &dbv)) { if (CB_ERR == m_cbResource.FindString(dbv.ptszVal, -1, true)) m_cbResource.AddString(dbv.ptszVal); m_cbResource.SetText(dbv.ptszVal); db_free(&dbv); } else { m_cbResource.SetText(_T("Miranda")); } m_cbType.AddString(TranslateT("Public XMPP Network"), ACC_PUBLIC); m_cbType.AddString(TranslateT("Secure XMPP Network"), ACC_TLS); m_cbType.AddString(TranslateT("Secure XMPP Network (old style)"), ACC_SSL); m_cbType.AddString(TranslateT("Google Talk!"), ACC_GTALK); m_cbType.AddString(TranslateT("LiveJournal Talk"), ACC_LJTALK); m_cbType.AddString(TranslateT("Facebook Chat"), ACC_FBOOK); m_cbType.AddString(TranslateT("Vkontakte"), ACC_VK); m_cbType.AddString(TranslateT("S.ms"), ACC_SMS); m_cbServer.GetTextA(server, SIZEOF(server)); if ( !DBGetContactSettingString(NULL, m_proto->m_szModuleName, "ManualHost", &dbv)) { lstrcpynA(manualServer, dbv.pszVal, SIZEOF(manualServer)); db_free(&dbv); } m_canregister = true; if ( !lstrcmpA(manualServer, "talk.google.com")) { m_cbType.SetCurSel(ACC_GTALK); m_canregister = false; } else if ( !lstrcmpA(server, "livejournal.com")) { m_cbType.SetCurSel(ACC_LJTALK); m_canregister = false; } else if ( !lstrcmpA(server, "chat.facebook.com")) { m_cbType.SetCurSel(ACC_FBOOK); m_canregister = false; } else if ( !lstrcmpA(server, "vk.com")) { m_cbType.SetCurSel(ACC_VK); m_canregister = false; } else if ( !lstrcmpA(server, "S.ms")) { m_cbType.SetCurSel(ACC_SMS); m_canregister = false; } else if (m_proto->m_options.UseSSL) m_cbType.SetCurSel(ACC_SSL); else if (m_proto->m_options.UseTLS) { m_cbType.SetCurSel(ACC_TLS); m_txtPort.SetInt(5222); } else m_cbType.SetCurSel(ACC_PUBLIC); //cbType_OnChange(&m_cbType); if (m_chkManualHost.Enabled()) { if (m_proto->m_options.ManualConnect) { m_chkManualHost.SetState(BST_CHECKED); m_txtManualHost.Enable(); m_txtPort.Enable(); if ( !DBGetContactSettingTString(NULL, m_proto->m_szModuleName, "ManualHost", &dbv)) { m_txtManualHost.SetText(dbv.ptszVal); db_free(&dbv); } m_txtPort.SetInt(m_proto->JGetWord(NULL, "ManualPort", m_txtPort.GetInt())); } else { int defPort = m_txtPort.GetInt(); int port = m_proto->JGetWord(NULL, "Port", defPort); if (port != defPort) { m_chkManualHost.SetState(BST_CHECKED); m_txtManualHost.Enable(); m_txtPort.Enable(); m_txtManualHost.SetTextA(server); m_txtPort.SetInt(port); } else { m_chkManualHost.SetState(BST_UNCHECKED); m_txtManualHost.Disable(); m_txtPort.Disable(); } } } if (m_proto->m_options.UseDomainLogin) chkUseDomainLogin_OnChange(&m_chkUseDomainLogin); CheckRegistration(); } void OnApply() { // clear saved password *m_proto->m_savedPassword = 0; BOOL bUseHostnameAsResource = FALSE; TCHAR szCompName[MAX_COMPUTERNAME_LENGTH + 1], szResource[MAX_COMPUTERNAME_LENGTH + 1]; DWORD dwCompNameLength = MAX_COMPUTERNAME_LENGTH; if (GetComputerName(szCompName, &dwCompNameLength)) { m_cbResource.GetText(szResource, SIZEOF(szResource)); if ( !lstrcmp(szCompName, szResource)) bUseHostnameAsResource = TRUE; } m_proto->m_options.HostNameAsResource = bUseHostnameAsResource; if (m_chkSavePassword.GetState() == BST_CHECKED) { TCHAR *text = m_txtPassword.GetText(); m_proto->JSetStringCrypt(NULL, "LoginPassword", text); mir_free(text); } else { m_proto->JDeleteSetting(NULL, "LoginPassword"); } switch (m_cbType.GetItemData(m_cbType.GetCurSel())) { case ACC_FBOOK: m_proto->m_options.IgnoreRosterGroups = TRUE; case ACC_VK: case ACC_PUBLIC: m_proto->m_options.UseSSL = m_proto->m_options.UseTLS = FALSE; break; case ACC_GTALK: m_proto->JSetWord(NULL, "Priority", 24); { int port = m_txtPort.GetInt(); if (port == 443 || port == 5223) { m_proto->m_options.UseSSL = TRUE; m_proto->m_options.UseTLS = FALSE; } else if (port == 5222) { m_proto->m_options.UseSSL = FALSE; m_proto->m_options.UseTLS = TRUE; } } break; case ACC_TLS: case ACC_LJTALK: case ACC_SMS: m_proto->m_options.UseSSL = FALSE; m_proto->m_options.UseTLS = TRUE; break; case ACC_SSL: m_proto->m_options.UseSSL = TRUE; m_proto->m_options.UseTLS = FALSE; break; } char server[256]; char manualServer[256]; m_cbServer.GetTextA(server, SIZEOF(server)); m_txtManualHost.GetTextA(manualServer, SIZEOF(manualServer)); if ((m_chkManualHost.GetState() == BST_CHECKED) && lstrcmpA(server, manualServer)) { m_proto->m_options.ManualConnect = TRUE; m_proto->JSetString(NULL, "ManualHost", manualServer); m_proto->JSetWord(NULL, "ManualPort", m_txtPort.GetInt()); m_proto->JSetWord(NULL, "Port", m_txtPort.GetInt()); } else { m_proto->m_options.ManualConnect = FALSE; m_proto->JDeleteSetting(NULL, "ManualHost"); m_proto->JDeleteSetting(NULL, "ManualPort"); m_proto->JSetWord(NULL, "Port", m_txtPort.GetInt()); } sttStoreJidFromUI(m_proto, m_txtUsername, m_cbServer); if (m_proto->m_bJabberOnline) { if (m_cbType.IsChanged() || m_txtPassword.IsChanged() || m_cbResource.IsChanged() || m_cbServer.IsChanged() || m_txtPort.IsChanged() || m_txtManualHost.IsChanged()) { MessageBox(m_hwnd, TranslateT("Some changes will take effect the next time you connect to the Jabber network."), TranslateT("Jabber Protocol Option"), MB_OK|MB_SETFOREGROUND); } m_proto->SendPresence(m_proto->m_iStatus, true); } } void OnChange(CCtrlBase*) { if (m_initialized) CheckRegistration(); } INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_JABBER_REFRESH: RefreshServers((HXML)lParam); break; } return CSuper::DlgProc(msg, wParam, lParam); } private: bool m_gotservers; bool m_canregister; void btnRegister_OnClick(CCtrlButton *) { TCHAR buf[512] = _T(""), pass[512]; if ( !m_proto->EnterString(buf, SIZEOF(buf), TranslateT("Confirm password"), JES_PASSWORD)) return; m_txtPassword.GetText(pass, SIZEOF(pass)); if (lstrcmp(buf, pass)) { MessageBox(m_hwnd, TranslateT("Passwords do not match."), _T("Miranda NG"), MB_ICONSTOP|MB_OK); return; } ThreadData regInfo(m_proto, JABBER_SESSION_NORMAL); m_txtUsername.GetText(regInfo.username, SIZEOF(regInfo.username)); m_txtPassword.GetText(regInfo.password, SIZEOF(regInfo.password)); m_cbServer.GetTextA(regInfo.server, SIZEOF(regInfo.server)); regInfo.port = (WORD)m_txtPort.GetInt(); if (m_chkManualHost.GetState() == BST_CHECKED) { m_txtManualHost.GetTextA(regInfo.manualHost, SIZEOF(regInfo.manualHost)); } else { regInfo.manualHost[0] = '\0'; } if (regInfo.username[0] && regInfo.password[0] && regInfo.server[0] && regInfo.port>0 && ((m_chkManualHost.GetState() != BST_CHECKED) || regInfo.manualHost[0])) { CJabberDlgRegister dlg(m_proto, m_hwnd, ®Info); dlg.DoModal(); // DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_OPT_REGISTER), m_hwnd, JabberRegisterDlgProc, (LPARAM)®Info); } } void cbServer_OnDropdown(CCtrlCombo*) { if ( !m_gotservers) mir_forkthread(QueryServerListThread, this); } void cbType_OnChange(CCtrlData *sender) { CCtrlCombo *chk = (CCtrlCombo *)sender; setupConnection(chk->GetItemData(chk->GetCurSel())); CheckRegistration(); } void chkUseDomainLogin_OnChange(CCtrlData *sender) { CCtrlCheck *chk = (CCtrlCheck *)sender; BOOL checked = chk->GetState() == BST_CHECKED; m_txtPassword.Enable(!checked); m_txtUsername.Enable(!checked); m_chkSavePassword.Enable(!checked); if (checked) { m_txtPassword.SetText(_T("")); m_txtUsername.SetText(_T("")); m_chkSavePassword.SetState(BST_CHECKED); } } void chkManualHost_OnChange(CCtrlData *sender) { CCtrlCheck *chk = (CCtrlCheck *)sender; if (chk->GetState() == BST_CHECKED) { char buf[256]; m_cbServer.GetTextA(buf, SIZEOF(buf)); m_txtManualHost.SetTextA(buf); m_txtPort.SetInt(5222); m_txtManualHost.Enable(); m_txtPort.Enable(); } else { m_txtManualHost.Disable(); m_txtPort.Disable(); } } void CheckRegistration(); void setupConnection(int type); void setupPublic(); void setupSecure(); void setupSecureSSL(); void setupGoogle(); void setupLJ(); void setupFB(); void setupVK(); void setupSMS(); void RefreshServers(HXML node); static void QueryServerListThread(void *arg); }; void CJabberDlgAccMgrUI::CheckRegistration() { if ( !m_canregister) { m_btnRegister.Disable(); return; } ThreadData regInfo(m_proto, JABBER_SESSION_NORMAL); m_txtUsername.GetText(regInfo.username, SIZEOF(regInfo.username)); m_txtPassword.GetText(regInfo.password, SIZEOF(regInfo.password)); m_cbServer.GetTextA(regInfo.server, SIZEOF(regInfo.server)); regInfo.port = (WORD)m_txtPort.GetInt(); if (m_chkManualHost.GetState() == BST_CHECKED) m_txtManualHost.GetTextA(regInfo.manualHost, SIZEOF(regInfo.manualHost)); else regInfo.manualHost[0] = '\0'; if (regInfo.username[0] && regInfo.password[0] && regInfo.server[0] && regInfo.port > 0 && ((m_chkManualHost.GetState() != BST_CHECKED) || regInfo.manualHost[0])) m_btnRegister.Enable(); else m_btnRegister.Disable(); } void CJabberDlgAccMgrUI::setupConnection(int type) { switch (type) { case ACC_PUBLIC: setupPublic(); break; case ACC_TLS: setupSecure(); break; case ACC_SSL: setupSecureSSL(); break; case ACC_GTALK: setupGoogle(); break; case ACC_LJTALK: setupLJ(); break; case ACC_FBOOK: setupFB(); break; case ACC_VK: setupVK(); break; case ACC_SMS: setupSMS(); break; } } void CJabberDlgAccMgrUI::setupPublic() { m_canregister = true; m_gotservers = false; m_chkManualHost.SetState(BST_UNCHECKED); m_txtManualHost.SetTextA(""); m_txtPort.SetInt(5222); m_cbServer.Enable(); m_chkManualHost.Enable(); m_txtManualHost.Disable(); m_txtPort.Disable(); m_btnRegister.Enable(); } void CJabberDlgAccMgrUI::setupSecure() { m_canregister = true; m_gotservers = false; m_chkManualHost.SetState(BST_UNCHECKED); m_txtManualHost.SetTextA(""); m_txtPort.SetInt(5222); m_cbServer.Enable(); m_chkManualHost.Enable(); m_txtManualHost.Disable(); m_txtPort.Disable(); m_btnRegister.Enable(); } void CJabberDlgAccMgrUI::setupSecureSSL() { m_canregister = true; m_gotservers = false; m_chkManualHost.SetState(BST_UNCHECKED); m_txtManualHost.SetTextA(""); m_txtPort.SetInt(5223); m_cbServer.Enable(); m_chkManualHost.Enable(); m_txtManualHost.Disable(); m_txtPort.Disable(); m_btnRegister.Enable(); } void CJabberDlgAccMgrUI::setupGoogle() { m_canregister = false; m_gotservers = true; m_cbServer.ResetContent(); m_cbServer.AddStringA("gmail.com"); m_cbServer.AddStringA("googlemail.com"); m_cbServer.SetTextA("gmail.com"); m_chkManualHost.SetState(BST_CHECKED); m_txtManualHost.SetTextA("talk.google.com"); m_txtPort.SetInt(443); m_cbServer.Enable(); m_chkManualHost.Disable(); m_txtManualHost.Disable(); //m_txtPort.Disable(); m_btnRegister.Disable(); } void CJabberDlgAccMgrUI::setupLJ() { m_canregister = false; m_gotservers = true; m_cbServer.ResetContent(); m_cbServer.SetTextA("livejournal.com"); m_cbServer.AddStringA("livejournal.com"); m_chkManualHost.SetState(BST_UNCHECKED); m_txtManualHost.SetTextA(""); m_txtPort.SetInt(5222); m_cbServer.Disable(); m_chkManualHost.Disable(); m_txtManualHost.Disable(); m_txtPort.Disable(); m_btnRegister.Disable(); } void CJabberDlgAccMgrUI::setupFB() { m_canregister = false; m_gotservers = true; m_cbServer.ResetContent(); m_cbServer.SetTextA("chat.facebook.com"); m_cbServer.AddStringA("chat.facebook.com"); m_chkManualHost.SetState(BST_UNCHECKED); m_txtManualHost.SetTextA(""); m_txtPort.SetInt(443); m_cbServer.Disable(); m_chkManualHost.Disable(); m_txtManualHost.Disable(); m_txtPort.Disable(); m_btnRegister.Disable(); } void CJabberDlgAccMgrUI::setupVK() { m_canregister = false; m_gotservers = true; m_cbServer.ResetContent(); m_cbServer.SetTextA("VK.com"); m_cbServer.AddStringA("VK.com"); m_chkManualHost.SetState(BST_UNCHECKED); m_txtManualHost.SetTextA(""); m_txtPort.SetInt(5222); m_cbServer.Disable(); m_chkManualHost.Disable(); m_txtManualHost.Disable(); m_txtPort.Disable(); m_btnRegister.Disable(); } void CJabberDlgAccMgrUI::setupSMS() { m_canregister = false; m_gotservers = true; m_cbServer.ResetContent(); m_cbServer.SetTextA("S.ms"); m_cbServer.AddStringA("S.ms"); m_chkManualHost.SetState(BST_UNCHECKED); m_txtManualHost.SetTextA(""); m_txtPort.SetInt(5222); m_cbServer.Disable(); m_chkManualHost.Disable(); m_txtManualHost.Disable(); m_txtPort.Disable(); m_btnRegister.Disable(); // m_cbResource.Disable(); } void CJabberDlgAccMgrUI::RefreshServers(HXML node) { m_gotservers = node != NULL; TCHAR *server = m_cbServer.GetText(); bool bDropdown = m_cbServer.GetDroppedState(); if (bDropdown) m_cbServer.ShowDropdown(false); m_cbServer.ResetContent(); if (node) { for (int i = 0; ; ++i) { HXML n = xmlGetChild(node, i); if ( !n) break; if ( !lstrcmp(xmlGetName(n), _T("item"))) if (const TCHAR *jid = xmlGetAttrValue(n, _T("jid"))) if (m_cbServer.FindString(jid, -1, true) == CB_ERR) m_cbServer.AddString(jid); } } m_cbServer.SetText(server); if (bDropdown) m_cbServer.ShowDropdown(); mir_free(server); } void CJabberDlgAccMgrUI::QueryServerListThread(void *arg) { CDlgOptAccount *wnd = (CDlgOptAccount *)arg; HWND hwnd = wnd->GetHwnd(); bool bIsError = true; NETLIBHTTPREQUEST request = {0}; request.cbSize = sizeof(request); request.requestType = REQUEST_GET; request.flags = NLHRF_GENERATEHOST|NLHRF_SMARTREMOVEHOST|NLHRF_SMARTAUTHHEADER|NLHRF_HTTP11; request.szUrl = "http://xmpp.org/services/services.xml"; NETLIBHTTPREQUEST *result = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)wnd->GetProto()->m_hNetlibUser, (LPARAM)&request); if (result && IsWindow(hwnd)) { if ((result->resultCode == 200) && result->dataLength && result->pData) { TCHAR* ptszText = mir_a2t(result->pData); XmlNode node(ptszText, NULL, NULL); if (node) { HXML queryNode = xmlGetChild(node, _T("query")); if (queryNode && IsWindow(hwnd)) { SendMessage(hwnd, WM_JABBER_REFRESH, 0, (LPARAM)queryNode); bIsError = false; } } mir_free(ptszText); } } if (result) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)result); if (bIsError) SendMessage(hwnd, WM_JABBER_REFRESH, 0, 0); } INT_PTR CJabberProto::SvcCreateAccMgrUI(WPARAM, LPARAM lParam) { CJabberDlgAccMgrUI *dlg = new CJabberDlgAccMgrUI(this, (HWND)lParam); dlg->Show(); return (INT_PTR)dlg->GetHwnd(); } void CJabberProto::JabberUpdateDialogs(BOOL) { if (rrud.hwndDlg) SendMessage(rrud.hwndDlg, JM_STATUSCHANGED, 0,0); } INT_PTR __cdecl CJabberProto::OnMenuOptions(WPARAM, LPARAM) { OPENOPTIONSDIALOG ood = {0}; ood.cbSize = sizeof(ood); ood.pszGroup = "Network"; ood.pszPage = mir_t2a(m_tszUserName); ood.pszTab = "Account"; Options_Open(&ood); mir_free((void*)ood.pszPage); return 0; } int CJabberProto::OnModernOptInit(WPARAM, LPARAM) {/* static int iBoldControls[] = { IDC_TITLE1, MODERNOPT_CTRL_LAST }; MODERNOPTOBJECT obj = {0}; obj.cbSize = sizeof(obj); obj.dwFlags = MODEROPT_FLG_TCHAR; obj.hIcon = LoadIconEx("main"); obj.hInstance = hInst; obj.iSection = MODERNOPT_PAGE_ACCOUNTS; obj.iType = MODERNOPT_TYPE_SUBSECTIONPAGE; obj.lptzSubsection = mir_a2t(m_szModuleName); // title!!!!!!!!!!! obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT); obj.iBoldControls = iBoldControls; obj.pfnDlgProc = JabberWizardDlgProc; obj.lpszClassicGroup = "Network"; obj.lpszClassicPage = m_szModuleName; // title!!!!!!!!!!! obj.lpszHelpUrl = "http://forums.miranda-im.org/showthread.php?t=14294"; CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); mir_free(obj.lptzSubsection); */ return 0; }