/* IRC plugin for Miranda IM Copyright (C) 2003-05 Jurgen Persson Copyright (C) 2007-09 George Hazan 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 "stdafx.h" static void removeSpaces(wchar_t* p) { while (*p) { if (*p == ' ') memmove(p, p + 1, sizeof(wchar_t)*mir_wstrlen(p)); p++; } } ///////////////////////////////////////////////////////////////////////////////////////// void CIrcProto::ReadSettings(TDbSetting *sets, int count) { uint8_t *base = (uint8_t *)this; DBVARIANT dbv; for (int i = 0; i < count; i++) { TDbSetting *p = &sets[i]; uint8_t *ptr = base + p->offset; switch (p->type) { case DBVT_BYTE: *(uint8_t*)ptr = getByte(p->name, p->defValue); break; case DBVT_WORD: *(uint16_t*)ptr = getWord(p->name, p->defValue); break; case DBVT_DWORD: *(uint32_t*)ptr = getDword(p->name, p->defValue); break; case DBVT_ASCIIZ: if (!getString(p->name, &dbv)) { if (p->size != -1) { size_t len = min(p->size - 1, mir_strlen(dbv.pszVal)); memcpy(ptr, dbv.pszVal, len); ptr[len] = 0; } else *(char**)ptr = mir_strdup(dbv.pszVal); db_free(&dbv); } else { if (p->size != -1) *ptr = 0; else *(char**)ptr = nullptr; } break; case DBVT_WCHAR: if (!getWString(p->name, &dbv)) { if (p->size != -1) { size_t len = min(p->size - 1, mir_wstrlen(dbv.pwszVal)); memcpy(ptr, dbv.pszVal, len * sizeof(wchar_t)); *(wchar_t*)&ptr[len * sizeof(wchar_t)] = 0; } else *(wchar_t**)ptr = mir_wstrdup(dbv.pwszVal); db_free(&dbv); } else { if (p->size != -1) { if (p->defStr == nullptr) *ptr = 0; else mir_wstrncpy((wchar_t*)ptr, p->defStr, (int)p->size); } else *(wchar_t**)ptr = mir_wstrdup(p->defStr); } break; } } } void CIrcProto::WriteSettings(TDbSetting *sets, int count) { uint8_t *base = (uint8_t*)this; for (int i = 0; i < count; i++) { TDbSetting *p = &sets[i]; uint8_t *ptr = base + p->offset; switch (p->type) { case DBVT_BYTE: setByte(p->name, *(uint8_t*)ptr); break; case DBVT_WORD: setWord(p->name, *(uint16_t*)ptr); break; case DBVT_DWORD: setDword(p->name, *(uint32_t*)ptr); break; case DBVT_ASCIIZ: if (p->size == -1) setString(p->name, *(char**)ptr); else setString(p->name, (char*)ptr); break; case DBVT_WCHAR: if (p->size == -1) setWString(p->name, *(wchar_t**)ptr); else setWString(p->name, (wchar_t*)ptr); break; } } } ///////////////////////////////////////////////////////////////////////////////////////// // add icons to the skinning module static IconItem iconList[] = { { LPGEN("Main"), "main", IDI_MAIN, 0 }, { LPGEN("Add"), "add", IDI_ADD, 0 }, { LPGEN("Apply"), "apply", IDI_APPLY, 0 }, { LPGEN("Rename"), "rename", IDI_RENAME, 0 }, { LPGEN("Edit"), "edit", IDI_EDIT, 0 }, { LPGEN("Cancel"), "delete", IDI_DELETE, 0 }, { LPGEN("Ignore"), "block", IDI_BLOCK, 0 }, { LPGEN("Channel list"), "list", IDI_LIST, 0 }, { LPGEN("Channel manager"), "manager", IDI_MANAGER, 0 }, { LPGEN("Server window"), "server", IDI_SERVER, 0 }, { LPGEN("Show channel"), "show", IDI_SHOW, 0 }, { LPGEN("Question"), "question",IDI_IRCQUESTION, 0 }, { LPGEN("WhoIs"), "whois", IDI_WHOIS, 0 }, { LPGEN("Incoming DCC Chat"), "dcc", IDI_DCC, 0 }, { LPGEN("Logo (48x48)"), "logo", IDI_LOGO, 48 } }; void InitIcons(void) { g_plugin.registerIcon("Protocols/IRC", iconList, "IRC"); } ///////////////////////////////////////////////////////////////////////////////////////// // code page handler struct { UINT cpId; wchar_t *cpName; } static cpTable[] = { { 874, LPGENW("Thai") }, { 932, LPGENW("Japanese") }, { 936, LPGENW("Simplified Chinese") }, { 949, LPGENW("Korean") }, { 950, LPGENW("Traditional Chinese") }, { 1250, LPGENW("Central European") }, { 1251, LPGENW("Cyrillic (Windows)") }, { 20866, LPGENW("Cyrillic (KOI8R)") }, { 1252, LPGENW("Latin I") }, { 1253, LPGENW("Greek") }, { 1254, LPGENW("Turkish") }, { 1255, LPGENW("Hebrew") }, { 1256, LPGENW("Arabic") }, { 1257, LPGENW("Baltic") }, { 1258, LPGENW("Vietnamese") }, { 1361, LPGENW("Korean (Johab)") } }; static CCtrlCombo *sttCombo; static BOOL CALLBACK sttLangAddCallback(wchar_t *str) { UINT cp = _wtoi(str); CPINFOEX cpinfo; if (GetCPInfoEx(cp, 0, &cpinfo)) { wchar_t *b = wcschr(cpinfo.CodePageName, '('); if (b) { wchar_t *e = wcsrchr(cpinfo.CodePageName, ')'); if (e) { *e = 0; sttCombo->AddString(b + 1, cp); } else sttCombo->AddString(cpinfo.CodePageName, cp); } else sttCombo->AddString(cpinfo.CodePageName, cp); } return TRUE; } ///////////////////////////////////////////////////////////////////////////////////////// // 'Connect preferences' dialog static TDbSetting ConnectSettings[] = { { FIELD_OFFSET(CIrcProto, m_userID), "UserID", DBVT_WCHAR, _countof(CIrcProto::m_userID) }, { FIELD_OFFSET(CIrcProto, m_identSystem), "IdentSystem", DBVT_WCHAR, _countof(CIrcProto::m_identSystem) }, { FIELD_OFFSET(CIrcProto, m_identPort), "IdentPort", DBVT_WCHAR, _countof(CIrcProto::m_identPort) }, { FIELD_OFFSET(CIrcProto, m_serverName), "ServerName", DBVT_ASCIIZ, _countof(CIrcProto::m_serverName) }, { FIELD_OFFSET(CIrcProto, m_portStart), "PortStart", DBVT_ASCIIZ, _countof(CIrcProto::m_portStart) }, { FIELD_OFFSET(CIrcProto, m_portEnd), "PortEnd", DBVT_ASCIIZ, _countof(CIrcProto::m_portEnd) }, { FIELD_OFFSET(CIrcProto, m_password), "Password", DBVT_ASCIIZ, _countof(CIrcProto::m_password) }, { FIELD_OFFSET(CIrcProto, m_joinOnInvite), "JoinOnInvite", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_iSSL), "UseSSL", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_onlineNotificationTime) , "OnlineNotificationTime", DBVT_WORD, 0, 30 }, { FIELD_OFFSET(CIrcProto, m_onlineNotificationLimit) , "OnlineNotificationLimit", DBVT_WORD, 0, 50 }, { FIELD_OFFSET(CIrcProto, m_channelAwayNotification), "ChannelAwayNotification", DBVT_BYTE, 0, 1 }, { FIELD_OFFSET(CIrcProto, m_nick), "Nick", DBVT_WCHAR, _countof(CIrcProto::m_nick) }, { FIELD_OFFSET(CIrcProto, m_pNick), "PNick", DBVT_WCHAR, _countof(CIrcProto::m_pNick) }, { FIELD_OFFSET(CIrcProto, m_alternativeNick), "AlernativeNick", DBVT_WCHAR, _countof(CIrcProto::m_alternativeNick) }, { FIELD_OFFSET(CIrcProto, m_name), "Name", DBVT_WCHAR, _countof(CIrcProto::m_name) }, { FIELD_OFFSET(CIrcProto, m_ident), "Ident", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_identTimer), "IdentTimer", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_forceVisible), "ForceVisible", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_disableErrorPopups), "DisableErrorPopups", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_rejoinChannels), "RejoinChannels", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_rejoinIfKicked), "RejoinIfKicked", DBVT_BYTE, 0, 1 }, { FIELD_OFFSET(CIrcProto, m_showAddresses), "ShowAddresses", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_oldStyleModes), "OldStyleModes", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_useServer), "UseServer", DBVT_BYTE, 0, 1 }, { FIELD_OFFSET(CIrcProto, m_bUseSASL), "UseSASL", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_hideServerWindow), "HideServerWindow", DBVT_BYTE, 0, 1 }, { FIELD_OFFSET(CIrcProto, m_sendKeepAlive), "SendKeepAlive", DBVT_BYTE, 0, 1 }, { FIELD_OFFSET(CIrcProto, m_autoOnlineNotification), "AutoOnlineNotification", DBVT_BYTE }, }; class CConnectPrefsDlg : public CIrcBaseDlg { CCtrlEdit m_server, m_port, m_port2, m_pass; CCtrlEdit m_nick, m_nick2, m_name, m_userID; CCtrlCombo m_ssl; CCtrlCheck m_ident, m_identTimer; CCtrlEdit m_identSystem, m_identPort; CCtrlCheck m_forceVisible, m_rejoinOnKick, m_rejoinChannels, m_disableError; CCtrlCheck m_address, m_useServer, m_showServer, m_keepAlive, m_autoJoin; CCtrlCheck m_oldStyle, m_onlineNotif, m_channelAway, m_useSasl; CCtrlEdit m_onlineTimer, m_limit; CCtrlSpin m_spin1, m_spin2; public: CConnectPrefsDlg::CConnectPrefsDlg(CIrcProto *_pro) : CIrcBaseDlg(_pro, IDD_PREFS_CONNECT), m_server(this, IDC_SERVER), m_port(this, IDC_PORT), m_port2(this, IDC_PORT2), m_pass(this, IDC_PASS), m_nick(this, IDC_NICK), m_nick2(this, IDC_NICK2), m_name(this, IDC_NAME), m_userID(this, IDC_USERID), m_ident(this, IDC_IDENT), m_identSystem(this, IDC_IDENTSYSTEM), m_identPort(this, IDC_IDENTPORT), m_identTimer(this, IDC_IDENT_TIMED), m_forceVisible(this, IDC_FORCEVISIBLE), m_rejoinOnKick(this, IDC_REJOINONKICK), m_rejoinChannels(this, IDC_REJOINCHANNELS), m_disableError(this, IDC_DISABLEERROR), m_address(this, IDC_ADDRESS), m_useServer(this, IDC_USESERVER), m_showServer(this, IDC_SHOWSERVER), m_keepAlive(this, IDC_KEEPALIVE), m_autoJoin(this, IDC_AUTOJOIN), m_oldStyle(this, IDC_OLDSTYLE), m_useSasl(this, IDC_SASL), m_onlineNotif(this, IDC_ONLINENOTIF), m_channelAway(this, IDC_CHANNELAWAY), m_onlineTimer(this, IDC_ONLINETIMER), m_limit(this, IDC_LIMIT), m_spin1(this, IDC_SPIN1, 999, 20), m_spin2(this, IDC_SPIN2, 200), m_ssl(this, IDC_SSL) { m_ident.OnChange = Callback(this, &CConnectPrefsDlg::OnIdent); m_useServer.OnChange = Callback(this, &CConnectPrefsDlg::OnUseServer); m_onlineNotif.OnChange = Callback(this, &CConnectPrefsDlg::OnOnlineNotif); m_channelAway.OnChange = Callback(this, &CConnectPrefsDlg::OnChannelAway); } bool OnInitDialog() override { m_proto->m_hwndConnect = m_hwnd; m_server.SetTextA(m_proto->m_serverName); m_port.SetTextA(m_proto->m_portStart); m_port2.SetTextA(m_proto->m_portEnd); m_pass.SetTextA(m_proto->m_password); m_useSasl.SetState(m_proto->m_bUseSASL); m_ssl.AddString(TranslateT("Off"), 0); m_ssl.AddString(TranslateT("Auto"), 1); m_ssl.AddString(TranslateT("On"), 2); m_ssl.SelectData(m_proto->m_iSSL); m_spin1.SetPosition(m_proto->m_onlineNotificationTime); m_spin2.SetPosition(m_proto->m_onlineNotificationLimit); m_nick.SetText(m_proto->m_nick); m_nick2.SetText(m_proto->m_alternativeNick); m_userID.SetText(m_proto->m_userID); m_name.SetText(m_proto->m_name); m_identSystem.SetText(m_proto->m_identSystem); m_identPort.SetText(m_proto->m_identPort); m_address.SetState(m_proto->m_showAddresses); m_oldStyle.SetState(m_proto->m_oldStyleModes); m_channelAway.SetState(m_proto->m_channelAwayNotification); m_onlineNotif.SetState(m_proto->m_autoOnlineNotification); m_ident.SetState(m_proto->m_ident); m_identTimer.SetState(m_proto->m_identTimer); m_disableError.SetState(m_proto->m_disableErrorPopups); m_forceVisible.SetState(m_proto->m_forceVisible); m_rejoinChannels.SetState(m_proto->m_rejoinChannels); m_rejoinOnKick.SetState(m_proto->m_rejoinIfKicked); m_keepAlive.SetState(m_proto->m_sendKeepAlive); m_useServer.SetState(m_proto->m_useServer); m_showServer.SetState(!m_proto->m_hideServerWindow); m_showServer.Enable(m_proto->m_useServer); m_autoJoin.SetState(m_proto->m_joinOnInvite); return true; } bool OnApply() override { // Save the setting in the CONNECT dialog m_server.GetTextA(m_proto->m_serverName, _countof(m_proto->m_serverName)); m_port.GetTextA(m_proto->m_portStart, _countof(m_proto->m_portStart)); m_port2.GetTextA(m_proto->m_portEnd, _countof(m_proto->m_portEnd)); m_pass.GetTextA(m_proto->m_password, _countof(m_proto->m_password)); m_proto->m_iSSL = m_ssl.GetCurData(); m_proto->m_bUseSASL = m_useSasl.GetState(); m_proto->m_onlineNotificationTime = SendDlgItemMessage(m_hwnd, IDC_SPIN1, UDM_GETPOS, 0, 0); m_proto->m_onlineNotificationLimit = SendDlgItemMessage(m_hwnd, IDC_SPIN2, UDM_GETPOS, 0, 0); m_proto->m_channelAwayNotification = m_channelAway.GetState(); m_nick.GetText(m_proto->m_nick, _countof(m_proto->m_nick)); removeSpaces(m_proto->m_nick); wcsncpy_s(m_proto->m_pNick, m_proto->m_nick, _TRUNCATE); m_nick2.GetText(m_proto->m_alternativeNick, _countof(m_proto->m_alternativeNick)); removeSpaces(m_proto->m_alternativeNick); m_userID.GetText(m_proto->m_userID, _countof(m_proto->m_userID)); removeSpaces(m_proto->m_userID); m_name.GetText(m_proto->m_name, _countof(m_proto->m_name)); m_identSystem.GetText(m_proto->m_identSystem, _countof(m_proto->m_identSystem)); m_identPort.GetText(m_proto->m_identPort, _countof(m_proto->m_identPort)); m_proto->m_ident = m_ident.GetState(); m_proto->m_identTimer = m_identTimer.GetState(); m_proto->m_forceVisible = m_forceVisible.GetState(); m_proto->m_disableErrorPopups = m_disableError.GetState(); m_proto->m_rejoinChannels = m_rejoinChannels.GetState(); m_proto->m_rejoinIfKicked = m_rejoinOnKick.GetState(); m_proto->m_showAddresses = m_address.GetState(); m_proto->m_oldStyleModes = m_oldStyle.GetState(); m_proto->m_useServer = m_useServer.GetState(); Menu_EnableItem(m_proto->hMenuServer, m_proto->m_useServer != 0); m_proto->m_joinOnInvite = m_autoJoin.GetState(); m_proto->m_hideServerWindow = !m_showServer.GetState(); if (m_proto->m_sendKeepAlive = m_keepAlive.GetState()) m_proto->SetChatTimer(m_proto->KeepAliveTimer, 60 * 1000, KeepAliveTimerProc); else m_proto->KillChatTimer(m_proto->KeepAliveTimer); m_proto->m_autoOnlineNotification = m_onlineNotif.GetState(); if (m_proto->m_autoOnlineNotification) { if (!m_proto->bTempDisableCheck) { m_proto->SetChatTimer(m_proto->OnlineNotifTimer, 500, OnlineNotifTimerProc); if (m_proto->m_channelAwayNotification) m_proto->SetChatTimer(m_proto->OnlineNotifTimer3, 1500, OnlineNotifTimerProc3); } } else if (!m_proto->bTempForceCheck) { m_proto->KillChatTimer(m_proto->OnlineNotifTimer); m_proto->KillChatTimer(m_proto->OnlineNotifTimer3); } m_proto->WriteSettings(ConnectSettings, _countof(ConnectSettings)); return true; } void OnIdent(CCtrlData *) { m_identSystem.Enable(m_ident.GetState()); m_identPort.Enable(m_ident.GetState()); m_identTimer.Enable(m_ident.GetState()); } void OnUseServer(CCtrlData *) { EnableWindow(GetDlgItem(m_hwnd, IDC_SHOWSERVER), m_useServer.GetState()); } void OnOnlineNotif(CCtrlData *) { m_channelAway.Enable(m_onlineNotif.GetState()); m_onlineTimer.Enable(m_onlineNotif.GetState()); m_spin1.Enable(m_onlineNotif.GetState()); m_spin2.Enable(m_onlineNotif.GetState()); m_limit.Enable(m_onlineNotif.GetState() && m_channelAway.GetState()); } void OnChannelAway(CCtrlData *) { m_spin2.Enable(m_onlineNotif.GetState() && m_channelAway.GetState()); m_limit.Enable(m_onlineNotif.GetState() && m_channelAway.GetState()); } }; ///////////////////////////////////////////////////////////////////////////////////////// // 'CTCP preferences' dialog static TDbSetting CtcpSettings[] = { { FIELD_OFFSET(CIrcProto, m_userInfo), "UserInfo", DBVT_WCHAR, _countof(CIrcProto::m_userInfo) }, { FIELD_OFFSET(CIrcProto, m_DCCPacketSize), "DccPacketSize", DBVT_WORD, 0, 4096 }, { FIELD_OFFSET(CIrcProto, m_DCCPassive), "DccPassive", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_DCCMode), "DCCMode", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_manualHost), "ManualHost", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_IPFromServer), "IPFromServer", DBVT_BYTE, 0, 1 }, { FIELD_OFFSET(CIrcProto, m_disconnectDCCChats), "DisconnectDCCChats", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_mySpecifiedHost), "SpecHost", DBVT_ASCIIZ, _countof(CIrcProto::m_mySpecifiedHost) }, { FIELD_OFFSET(CIrcProto, m_DCCChatAccept), "CtcpChatAccept", DBVT_BYTE, 0, 1 }, { FIELD_OFFSET(CIrcProto, m_sendNotice), "SendNotice", DBVT_BYTE, 0, 1 } }; class CCtcpPrefsDlg : public CIrcBaseDlg { CCtrlCombo m_combo; CCtrlCheck m_slow, m_fast, m_disc, m_passive, m_sendNotice, m_enableIP, m_fromServer; CCtrlEdit m_ip, m_userInfo; CCtrlCheck m_radio1, m_radio2, m_radio3; public: CCtcpPrefsDlg(CIrcProto *_pro) : CIrcBaseDlg(_pro, IDD_PREFS_CTCP), m_enableIP(this, IDC_ENABLEIP), m_fromServer(this, IDC_FROMSERVER), m_combo(this, IDC_COMBO), m_slow(this, IDC_SLOW), m_fast(this, IDC_FAST), m_disc(this, IDC_DISC), m_passive(this, IDC_PASSIVE), m_sendNotice(this, IDC_SENDNOTICE), m_ip(this, IDC_IP), m_userInfo(this, IDC_USERINFO), m_radio1(this, IDC_RADIO1), m_radio2(this, IDC_RADIO2), m_radio3(this, IDC_RADIO3) { m_enableIP.OnChange = Callback(this, &CCtcpPrefsDlg::OnClicked); m_fromServer.OnChange = Callback(this, &CCtcpPrefsDlg::OnClicked); } bool OnInitDialog() override { m_userInfo.SetText(m_proto->m_userInfo); m_slow.SetState(m_proto->m_DCCMode == 0); m_fast.SetState(m_proto->m_DCCMode == 1); m_disc.SetState(m_proto->m_disconnectDCCChats); m_passive.SetState(m_proto->m_DCCPassive); m_sendNotice.SetState(m_proto->m_sendNotice); m_combo.AddStringA("256"); m_combo.AddStringA("512"); m_combo.AddStringA("1024"); m_combo.AddStringA("2048"); m_combo.AddStringA("4096"); m_combo.AddStringA("8192"); wchar_t szTemp[10]; mir_snwprintf(szTemp, L"%u", m_proto->m_DCCPacketSize); int i = m_combo.SelectString(szTemp); if (i == CB_ERR) m_combo.SelectString(L"4096"); if (m_proto->m_DCCChatAccept == 1) m_radio1.SetState(true); if (m_proto->m_DCCChatAccept == 2) m_radio2.SetState(true); if (m_proto->m_DCCChatAccept == 3) m_radio3.SetState(true); m_fromServer.SetState(m_proto->m_IPFromServer); m_enableIP.SetState(m_proto->m_manualHost); m_ip.Enable(m_proto->m_manualHost); m_fromServer.Enable(!m_proto->m_manualHost); if (m_proto->m_manualHost) m_ip.SetTextA(m_proto->m_mySpecifiedHost); else { if (m_proto->m_IPFromServer) { if (m_proto->m_myHost[0]) { CMStringW s = (CMStringW)TranslateT("m_myHost) + L">"; m_ip.SetText(s.c_str()); } else m_ip.SetText(TranslateT("")); } else { if (m_proto->m_myLocalHost[0]) { CMStringW s = (CMStringW)TranslateT("m_myLocalHost) + L">"; m_ip.SetText(s.c_str()); } else m_ip.SetText(TranslateT("")); } } return true; } bool OnApply() override { m_userInfo.GetText(m_proto->m_userInfo, _countof(m_proto->m_userInfo)); m_proto->m_DCCPacketSize = m_combo.GetInt(); m_proto->m_DCCPassive = m_passive.GetState(); m_proto->m_sendNotice = m_sendNotice.GetState(); m_proto->m_DCCMode = m_fast.GetState(); m_proto->m_manualHost = m_enableIP.GetState(); m_proto->m_IPFromServer = m_fromServer.GetState(); m_proto->m_disconnectDCCChats = m_disc.GetState(); if (m_enableIP.GetState()) { char szTemp[500]; m_ip.GetTextA(szTemp, sizeof(szTemp)); mir_strncpy(m_proto->m_mySpecifiedHost, GetWord(szTemp, 0).c_str(), 499); if (mir_strlen(m_proto->m_mySpecifiedHost)) m_proto->ForkThread(&CIrcProto::ResolveIPThread, new IPRESOLVE(m_proto->m_mySpecifiedHost, IP_MANUAL)); } else m_proto->m_mySpecifiedHost[0] = 0; if (m_radio1.GetState()) m_proto->m_DCCChatAccept = 1; if (m_radio2.GetState()) m_proto->m_DCCChatAccept = 2; if (m_radio3.GetState()) m_proto->m_DCCChatAccept = 3; m_proto->WriteSettings(CtcpSettings, _countof(CtcpSettings)); return true; } void OnClicked(CCtrlData *) { m_ip.Enable(m_enableIP.GetState()); m_fromServer.Enable(!m_enableIP.GetState()); if (m_enableIP.GetState()) m_ip.SetTextA(m_proto->m_mySpecifiedHost); else { if (m_fromServer.GetState()) { if (m_proto->m_myHost[0]) { CMStringW s = (CMStringW)TranslateT("m_myHost) + L">"; m_ip.SetText(s.c_str()); } else m_ip.SetText(TranslateT("")); } else { if (m_proto->m_myLocalHost[0]) { CMStringW s = (CMStringW)TranslateT("m_myLocalHost) + L">"; m_ip.SetText(s.c_str()); } else m_ip.SetText(TranslateT("")); } } } }; ///////////////////////////////////////////////////////////////////////////////////////// // 'Advanced preferences' dialog static TDbSetting OtherSettings[] = { { FIELD_OFFSET(CIrcProto, m_quitMessage), "QuitMessage", DBVT_WCHAR, _countof(CIrcProto::m_quitMessage) }, { FIELD_OFFSET(CIrcProto, m_alias), "Alias", DBVT_WCHAR, (size_t)-1 }, { FIELD_OFFSET(CIrcProto, m_codepage), "Codepage", DBVT_DWORD, 0, CP_ACP }, { FIELD_OFFSET(CIrcProto, m_utfAutodetect), "UtfAutodetect", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_perform), "Perform", DBVT_BYTE }, }; static char* sttPerformEvents[] = { LPGEN("Event: Connect"), LPGEN("Event: Available"), LPGEN("Event: Away"), LPGEN("Event: Not available"), LPGEN("Event: Occupied"), LPGEN("Event: Do not disturb"), LPGEN("Event: Free for chat"), LPGEN("Event: Disconnect") }; static LRESULT CALLBACK EditSubclassProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_CHAR: if (wParam == 21 || wParam == 11 || wParam == 2) { char w[2]; w[1] = 0; if (wParam == 11) w[0] = 3; if (wParam == 2) w[0] = 2; if (wParam == 21) w[0] = 31; SendMessage(hwndDlg, EM_REPLACESEL, false, (LPARAM)w); SendMessage(hwndDlg, EM_SCROLLCARET, 0, 0); return 0; } break; } return mir_callNextSubclass(hwndDlg, EditSubclassProc, msg, wParam, lParam); } class COtherPrefsDlg : public CIrcBaseDlg { bool m_performlistModified; CCtrlButton m_url; CCtrlMButton m_add, m_delete; CCtrlCombo m_performCombo, m_codepage; CCtrlEdit m_pertormEdit, m_quitMessage, m_alias; CCtrlCheck m_perform, m_autodetect; public: COtherPrefsDlg(CIrcProto *_pro) : CIrcBaseDlg(_pro, IDD_PREFS_OTHER), m_url(this, IDC_CUSTOM), m_performCombo(this, IDC_PERFORMCOMBO), m_codepage(this, IDC_CODEPAGE), m_pertormEdit(this, IDC_PERFORMEDIT), m_perform(this, IDC_PERFORM), m_autodetect(this, IDC_UTF_AUTODETECT), m_quitMessage(this, IDC_QUITMESSAGE), m_alias(this, IDC_ALIASEDIT), m_add(this, IDC_ADD, g_plugin.getIcon(IDI_ADD), LPGEN("Click to set commands that will be performed for this event")), m_delete(this, IDC_DELETE, g_plugin.getIcon(IDI_DELETE), LPGEN("Click to delete the commands for this event")), m_performlistModified(false) { m_performCombo.OnChange = Callback(this, &COtherPrefsDlg::OnPerformCombo); m_codepage.OnChange = Callback(this, &COtherPrefsDlg::OnCodePage); m_pertormEdit.OnChange = Callback(this, &COtherPrefsDlg::OnPerformEdit); m_perform.OnChange = Callback(this, &COtherPrefsDlg::OnPerform); m_add.OnClick = Callback(this, &COtherPrefsDlg::OnAdd); m_delete.OnClick = Callback(this, &COtherPrefsDlg::OnDelete); } bool OnInitDialog() { mir_subclassWindow(m_alias.GetHwnd(), EditSubclassProc); mir_subclassWindow(m_quitMessage.GetHwnd(), EditSubclassProc); mir_subclassWindow(m_pertormEdit.GetHwnd(), EditSubclassProc); m_alias.SetText(m_proto->m_alias); m_quitMessage.SetText(m_proto->m_quitMessage); m_perform.SetState(m_proto->m_perform); m_performCombo.Enable(m_proto->m_perform); m_pertormEdit.Enable(m_proto->m_perform); m_add.Enable(m_proto->m_perform); m_delete.Enable(m_proto->m_perform); m_codepage.AddString(TranslateT("Default ANSI codepage"), CP_ACP); sttCombo = &m_codepage; EnumSystemCodePages(sttLangAddCallback, CP_INSTALLED); for (int i = m_codepage.GetCount(); i >= 0; i--) { if (m_codepage.GetItemData(i) == m_proto->m_codepage) { m_codepage.SetCurSel(i); break; } } if (m_proto->m_codepage == CP_UTF8) m_autodetect.Disable(); for (auto &it: sttPerformEvents) { CMStringA sSetting = CMStringA("PERFORM:") + it; sSetting.MakeUpper(); PERFORM_INFO *pPref = new PERFORM_INFO(sSetting.c_str(), m_proto->getMStringW(sSetting.c_str())); m_performCombo.AddString(_A2T(Translate(it)), (LPARAM)pPref); } m_performCombo.SetCurSel(0); OnPerformCombo(nullptr); m_autodetect.SetState(m_proto->m_utfAutodetect); return true; } bool OnApply() override { mir_free(m_proto->m_alias); m_proto->m_alias = m_alias.GetText(); m_quitMessage.GetText(m_proto->m_quitMessage, _countof(m_proto->m_quitMessage)); m_proto->m_codepage = m_codepage.GetCurData(); if (m_proto->IsConnected()) m_proto->setCodepage(m_proto->m_codepage); m_proto->m_utfAutodetect = m_autodetect.GetState(); m_proto->m_perform = m_perform.GetState(); if (m_add.Enabled()) OnAdd(nullptr); if (m_performlistModified) { int count = m_performCombo.GetCount(); for (int i = 0; i < count; i++) { PERFORM_INFO *pPerf = (PERFORM_INFO *)m_performCombo.GetItemData(i); if ((INT_PTR)pPerf == CB_ERR) continue; if (pPerf->mText.IsEmpty()) m_proto->delSetting(pPerf->mSetting.c_str()); else m_proto->setWString(pPerf->mSetting.c_str(), pPerf->mText.c_str()); } } m_proto->WriteSettings(OtherSettings, _countof(OtherSettings)); return true; } void OnDestroy() override { int i = m_performCombo.GetCount(); if (i != CB_ERR && i != 0) { for (int index = 0; index < i; index++) { PERFORM_INFO *pPerf = (PERFORM_INFO *)m_performCombo.GetItemData(index); if ((INT_PTR)pPerf != CB_ERR && pPerf != nullptr) delete pPerf; } } } void OnPerformCombo(CCtrlData *) { PERFORM_INFO *pPerf = (PERFORM_INFO *)m_performCombo.GetCurData(); if (pPerf == INVALID_HANDLE_VALUE) return; if (pPerf == nullptr) m_pertormEdit.SetTextA(""); else m_pertormEdit.SetText(pPerf->mText.c_str()); m_add.Disable(); if (GetWindowTextLength(m_pertormEdit.GetHwnd()) != 0) m_delete.Enable(); else m_delete.Disable(); } void OnCodePage(CCtrlData *) { m_autodetect.Enable(m_codepage.GetCurData() != CP_UTF8); } void OnPerformEdit(CCtrlData *) { m_add.Enable(); if (GetWindowTextLength(m_pertormEdit.GetHwnd()) != 0) m_delete.Enable(); else m_delete.Disable(); } void OnPerform(CCtrlData *) { m_performCombo.Enable(m_perform.GetState()); m_pertormEdit.Enable(m_perform.GetState()); m_add.Enable(m_perform.GetState()); m_delete.Enable(m_perform.GetState()); } void OnAdd(CCtrlButton *) { ptrW temp(m_pertormEdit.GetText()); if (mir_wstrstri(temp, L"/away")) MessageBox(nullptr, TranslateT("The usage of /AWAY in your perform buffer is restricted\n as IRC sends this command automatically."), TranslateT("IRC Error"), MB_OK); else { PERFORM_INFO *pPerf = (PERFORM_INFO *)m_performCombo.GetCurData(); if (pPerf == INVALID_HANDLE_VALUE) return; if (pPerf != nullptr) pPerf->mText = temp; m_add.Disable(); m_performlistModified = true; } } void OnDelete(CCtrlButton *) { PERFORM_INFO *pPerf = (PERFORM_INFO *)m_performCombo.GetCurData(); if (pPerf == INVALID_HANDLE_VALUE) return; if (pPerf != nullptr) { pPerf->mText = L""; m_pertormEdit.SetTextA(""); m_delete.Disable(); m_add.Disable(); } m_performlistModified = true; } }; ///////////////////////////////////////////////////////////////////////////////////////// // 'add ignore' preferences dialog struct CAddIgnoreDlg : public CIrcBaseDlg { wchar_t szOldMask[500]; CAddIgnoreDlg::CAddIgnoreDlg(CIrcProto *_pro, const wchar_t *mask, CDlgBase *_owner) : CIrcBaseDlg(_pro, IDD_ADDIGNORE) { m_hwndParent = _owner->GetHwnd(); if (mask == nullptr) szOldMask[0] = 0; else wcsncpy(szOldMask, mask, _countof(szOldMask)); } bool OnInitDialog() override { if (szOldMask[0] == 0) { CheckDlgButton(m_hwnd, IDC_Q, BST_CHECKED); CheckDlgButton(m_hwnd, IDC_N, BST_CHECKED); CheckDlgButton(m_hwnd, IDC_I, BST_CHECKED); CheckDlgButton(m_hwnd, IDC_D, BST_CHECKED); CheckDlgButton(m_hwnd, IDC_C, BST_CHECKED); } return true; } bool OnApply() override { wchar_t szMask[500]; CMStringW flags; if (IsDlgButtonChecked(m_hwnd, IDC_Q) == BST_CHECKED) flags += 'q'; if (IsDlgButtonChecked(m_hwnd, IDC_N) == BST_CHECKED) flags += 'n'; if (IsDlgButtonChecked(m_hwnd, IDC_I) == BST_CHECKED) flags += 'i'; if (IsDlgButtonChecked(m_hwnd, IDC_D) == BST_CHECKED) flags += 'd'; if (IsDlgButtonChecked(m_hwnd, IDC_C) == BST_CHECKED) flags += 'c'; if (IsDlgButtonChecked(m_hwnd, IDC_M) == BST_CHECKED) flags += 'm'; GetDlgItemText(m_hwnd, IDC_MASK, szMask, _countof(szMask)); CMStringW Mask = GetWord(szMask, 0); if (Mask.GetLength() != 0) { if (!wcschr(Mask.c_str(), '!') && !wcschr(Mask.c_str(), '@')) Mask += L"!*@*"; if (!flags.IsEmpty()) { if (*szOldMask) m_proto->RemoveIgnore(szOldMask); m_proto->AddIgnore(Mask.c_str(), flags.c_str()); } } return true; } }; ///////////////////////////////////////////////////////////////////////////////////////// // 'Ignore' preferences dialog static TDbSetting IgnoreSettings[] = { { FIELD_OFFSET(CIrcProto, m_DCCFileEnabled), "EnableCtcpFile", DBVT_BYTE, 0, 1 }, { FIELD_OFFSET(CIrcProto, m_DCCChatEnabled), "EnableCtcpChat", DBVT_BYTE, 0, 1 }, { FIELD_OFFSET(CIrcProto, m_DCCChatIgnore), "CtcpChatIgnore", DBVT_BYTE, 0, 1 }, { FIELD_OFFSET(CIrcProto, m_ignore), "Ignore", DBVT_BYTE }, { FIELD_OFFSET(CIrcProto, m_ignoreChannelDefault), "IgnoreChannelDefault", DBVT_BYTE }, }; static LRESULT CALLBACK ListviewSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_KEYUP: if (ListView_GetSelectionMark(GetDlgItem(GetParent(hwnd), IDC_LIST)) != -1) { EnableWindow(GetDlgItem(GetParent(hwnd), IDC_EDIT), true); EnableWindow(GetDlgItem(GetParent(hwnd), IDC_DELETE), true); } else { EnableWindow(GetDlgItem(GetParent(hwnd), IDC_EDIT), false); EnableWindow(GetDlgItem(GetParent(hwnd), IDC_DELETE), false); } if (wParam == VK_DELETE) SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_DELETE, BN_CLICKED), 0); if (wParam == VK_SPACE) SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_EDIT, BN_CLICKED), 0); break; } return mir_callNextSubclass(hwnd, ListviewSubclassProc, msg, wParam, lParam); } // Callback for the 'Add ignore' dialog void CIrcProto::InitIgnore(void) { wchar_t szTemp[MAX_PATH]; mir_snwprintf(szTemp, L"%%miranda_path%%\\Plugins\\%S_ignore.ini", m_szModuleName); wchar_t *szLoadFileName = Utils_ReplaceVarsW(szTemp); char* pszIgnoreData = IrcLoadFile(szLoadFileName); if (pszIgnoreData != nullptr) { char *p1 = pszIgnoreData; while (*p1 != 0) { while (*p1 == '\r' || *p1 == '\n') p1++; if (*p1 == 0) break; char* p2 = strstr(p1, "\r\n"); if (!p2) p2 = strchr(p1, 0); char* pTemp = p2; while (pTemp > p1 && (*pTemp == '\r' || *pTemp == '\n' || *pTemp == 0 || *pTemp == ' ')) pTemp--; *++pTemp = 0; CMStringA mask = GetWord(p1, 0); CMStringA flags = GetWord(p1, 1); if (!mask.IsEmpty()) m_ignoreItems.insert(new CIrcIgnoreItem(getCodepage(), mask.c_str(), flags.c_str())); p1 = p2; } RewriteIgnoreSettings(); delete[] pszIgnoreData; ::_wremove(szLoadFileName); } mir_free(szLoadFileName); int idx = 0; char settingName[40]; for (;;) { mir_snprintf(settingName, "IGNORE:%d", idx++); DBVARIANT dbv; if (getWString(settingName, &dbv)) break; CMStringW mask = GetWord(dbv.pwszVal, 0); CMStringW flags = GetWord(dbv.pwszVal, 1); m_ignoreItems.insert(new CIrcIgnoreItem(mask.c_str(), flags.c_str())); db_free(&dbv); } } void CIrcProto::RewriteIgnoreSettings(void) { char settingName[40]; int i = 0; for (;;) { mir_snprintf(settingName, "IGNORE:%d", i++); if (db_unset(0, m_szModuleName, settingName)) break; } for (i = 0; i < m_ignoreItems.getCount(); i++) { mir_snprintf(settingName, "IGNORE:%d", i); CIrcIgnoreItem &C = m_ignoreItems[i]; setWString(settingName, (C.mask + L" " + C.flags).c_str()); } } class CIgnorePrefsDlg : public CIrcBaseDlg { void FixButtons() { m_add.Enable(m_enable.GetState()); if (m_list.GetSelectionMark() != -1) { m_edit.Enable(); m_del.Enable(); } else { m_edit.Disable(); m_del.Disable(); } } static int CALLBACK IgnoreListSort(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { CIgnorePrefsDlg *hwndDlg = (CIgnorePrefsDlg*)lParamSort; if (!hwndDlg->GetHwnd()) return 1; wchar_t temp1[512]; wchar_t temp2[512]; LVITEM lvm; lvm.mask = LVIF_TEXT; lvm.iSubItem = 0; lvm.cchTextMax = _countof(temp1); lvm.iItem = lParam1; lvm.pszText = temp1; hwndDlg->m_list.GetItem(&lvm); lvm.iItem = lParam2; lvm.pszText = temp2; hwndDlg->m_list.GetItem(&lvm); if (temp1[0] && temp2[0]) return mir_wstrcmpi(temp1, temp2); return (temp1[0] == 0) ? 1 : -1; } void RebuildList() { m_list.DeleteAllItems(); for (auto &C : m_proto->m_ignoreItems) { if (C->mask.IsEmpty() || C->flags[0] != '+') continue; LVITEM lvItem; lvItem.iItem = m_list.GetItemCount(); lvItem.iSubItem = 0; lvItem.mask = LVIF_TEXT | LVIF_PARAM; lvItem.lParam = lvItem.iItem; lvItem.pszText = (wchar_t *)C->mask.c_str(); lvItem.iItem = m_list.InsertItem(&lvItem); lvItem.iSubItem = 1; lvItem.mask = LVIF_TEXT; lvItem.pszText = (wchar_t *)C->flags.c_str(); m_list.SetItem(&lvItem); } UpdateList(); m_list.SortItems(IgnoreListSort, (LPARAM)this); UpdateList(); FixButtons(); } void UpdateList() { int j = m_list.GetItemCount(); if (j > 0) { LVITEM lvm; lvm.mask = LVIF_PARAM; lvm.iSubItem = 0; for (int i = 0; i < j; i++) { lvm.iItem = i; lvm.lParam = i; m_list.SetItem(&lvm); } } } CCtrlMButton m_add, m_edit, m_del; CCtrlCheck m_enable, m_ignoreChat, m_ignoreFile, m_ignoreChannel, m_ignoreUnknown; CCtrlListView m_list; public: CIgnorePrefsDlg(CIrcProto *_pro) : CIrcBaseDlg(_pro, IDD_PREFS_IGNORE), m_list(this, IDC_LIST), m_add(this, IDC_ADD, g_plugin.getIcon(IDI_ADD), LPGEN("Add new ignore")), m_edit(this, IDC_EDIT, g_plugin.getIcon(IDI_EDIT), LPGEN("Edit this ignore")), m_del(this, IDC_DELETE, g_plugin.getIcon(IDI_DELETE), LPGEN("Delete this ignore")), m_enable(this, IDC_ENABLEIGNORE), m_ignoreChat(this, IDC_IGNORECHAT), m_ignoreFile(this, IDC_IGNOREFILE), m_ignoreChannel(this, IDC_IGNORECHANNEL), m_ignoreUnknown(this, IDC_IGNOREUNKNOWN) { m_enable.OnChange = Callback(this, &CIgnorePrefsDlg::OnEnableIgnore); m_ignoreChat.OnChange = Callback(this, &CIgnorePrefsDlg::OnIgnoreChat); m_add.OnClick = Callback(this, &CIgnorePrefsDlg::OnAdd); m_list.OnDoubleClick = m_edit.OnClick = Callback(this, &CIgnorePrefsDlg::OnEdit); m_del.OnClick = Callback(this, &CIgnorePrefsDlg::OnDelete); m_list.OnColumnClick = Callback(this, &CIgnorePrefsDlg::List_OnColumnClick); } bool OnInitDialog() override { m_proto->m_ignoreDlg = this; mir_subclassWindow(m_list.GetHwnd(), ListviewSubclassProc); m_enable.SetState(m_proto->m_ignore); m_ignoreFile.SetState(!m_proto->m_DCCFileEnabled); m_ignoreChat.SetState(!m_proto->m_DCCChatEnabled); m_ignoreChannel.SetState(m_proto->m_ignoreChannelDefault); if (m_proto->m_DCCChatIgnore == 2) m_ignoreUnknown.SetState(BST_CHECKED); m_ignoreUnknown.Enable(m_proto->m_DCCChatEnabled); m_list.Enable(m_proto->m_ignore); m_ignoreChannel.Enable(m_proto->m_ignore); m_add.Enable(m_proto->m_ignore); LV_COLUMN lvC; lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvC.fmt = LVCFMT_LEFT; lvC.iSubItem = 0; lvC.cx = 235; lvC.pszText = TranslateT("Ignore mask"); ListView_InsertColumn(GetDlgItem(m_hwnd, IDC_INFO_LISTVIEW), 0, &lvC); lvC.iSubItem = 1; lvC.cx = 100; lvC.pszText = TranslateT("Flags"); ListView_InsertColumn(GetDlgItem(m_hwnd, IDC_INFO_LISTVIEW), 1, &lvC); ListView_SetExtendedListViewStyle(GetDlgItem(m_hwnd, IDC_INFO_LISTVIEW), LVS_EX_FULLROWSELECT); RebuildList(); return true; } bool OnApply() override { m_proto->m_DCCFileEnabled = !m_ignoreFile.GetState(); m_proto->m_DCCChatEnabled = !m_ignoreChat.GetState(); m_proto->m_ignore = m_enable.GetState(); m_proto->m_ignoreChannelDefault = m_ignoreChannel.GetState(); m_proto->m_DCCChatIgnore = m_ignoreUnknown.GetState() ? 2 : 1; m_proto->WriteSettings(IgnoreSettings, _countof(IgnoreSettings)); return true; } void OnDestroy() override { m_proto->m_ignoreDlg = nullptr; m_proto->m_ignoreItems.destroy(); int i = m_list.GetItemCount(); for (int j = 0; j < i; j++) { wchar_t szMask[512], szFlags[40]; m_list.GetItemText(j, 0, szMask, _countof(szMask)); m_list.GetItemText(j, 1, szFlags, _countof(szFlags)); m_proto->m_ignoreItems.insert(new CIrcIgnoreItem(szMask, szFlags)); } m_proto->RewriteIgnoreSettings(); } INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override { switch (msg) { case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case IDC_LIST: switch (((NMHDR *)lParam)->code) { case NM_CLICK: case NM_RCLICK: if (m_list.GetSelectionMark() != -1) FixButtons(); break; } } break; } return CDlgBase::DlgProc(msg, wParam, lParam); } void Update() override { RebuildList(); } void OnEnableIgnore(CCtrlData *) { m_ignoreChannel.Enable(m_enable.GetState()); m_list.Enable(m_enable.GetState()); m_add.Enable(m_enable.GetState()); } void OnIgnoreChat(CCtrlData *) { m_ignoreUnknown.Enable(m_ignoreChat.GetState() == BST_UNCHECKED); } void OnAdd(CCtrlButton *) { CAddIgnoreDlg *dlg = new CAddIgnoreDlg(m_proto, nullptr, this); dlg->Show(); SetWindowText(dlg->GetHwnd(), TranslateT("Add ignore")); m_add.Disable(); m_edit.Disable(); m_del.Disable(); } void OnEdit(CCtrlButton *) { if (!m_add.Enabled()) return; wchar_t szMask[512]; wchar_t szFlags[512]; wchar_t szNetwork[512]; int i = m_list.GetSelectionMark(); m_list.GetItemText(i, 0, szMask, 511); m_list.GetItemText(i, 1, szFlags, 511); m_list.GetItemText(i, 2, szNetwork, 511); CAddIgnoreDlg *dlg = new CAddIgnoreDlg(m_proto, szMask, this); dlg->Show(); HWND hWnd = dlg->GetHwnd(); SetWindowText(hWnd, TranslateT("Edit ignore")); if (szFlags[0]) { if (wcschr(szFlags, 'q')) CheckDlgButton(hWnd, IDC_Q, BST_CHECKED); if (wcschr(szFlags, 'n')) CheckDlgButton(hWnd, IDC_N, BST_CHECKED); if (wcschr(szFlags, 'i')) CheckDlgButton(hWnd, IDC_I, BST_CHECKED); if (wcschr(szFlags, 'd')) CheckDlgButton(hWnd, IDC_D, BST_CHECKED); if (wcschr(szFlags, 'c')) CheckDlgButton(hWnd, IDC_C, BST_CHECKED); if (wcschr(szFlags, 'm')) CheckDlgButton(hWnd, IDC_M, BST_CHECKED); } SetDlgItemText(hWnd, IDC_MASK, szMask); m_add.Disable(); m_edit.Disable(); m_del.Disable(); } void OnDelete(CCtrlButton *) { if (!m_del.Enabled()) return; wchar_t szMask[512]; int i = m_list.GetSelectionMark(); m_list.GetItemText(i, 0, szMask, _countof(szMask)); m_proto->RemoveIgnore(szMask); } void List_OnColumnClick(CCtrlListView::TEventInfo *) { m_list.SortItems(IgnoreListSort, (LPARAM)this); UpdateList(); } }; ///////////////////////////////////////////////////////////////////////////////////////// int CIrcProto::OnInitOptionsPages(WPARAM wParam, LPARAM) { OPTIONSDIALOGPAGE odp = {}; odp.szTitle.w = m_tszUserName; odp.szGroup.w = LPGENW("Network"); odp.flags = ODPF_BOLDGROUPS | ODPF_UNICODE | ODPF_DONTTRANSLATE; odp.szTab.w = LPGENW("Account"); odp.pDialog = new CConnectPrefsDlg(this); g_plugin.addOptions(wParam, &odp); odp.szTab.w = LPGENW("DCC and CTCP"); odp.pDialog = new CCtcpPrefsDlg(this); g_plugin.addOptions(wParam, &odp); odp.szTab.w = LPGENW("Advanced"); odp.pDialog = new COtherPrefsDlg(this); g_plugin.addOptions(wParam, &odp); odp.szTab.w = LPGENW("Ignore"); odp.pDialog = new CIgnorePrefsDlg(this); g_plugin.addOptions(wParam, &odp); return 0; } /////////////////////////////////////////////////////////////////////////////// // Account manager UI class CDlgAccMgrUI : public CIrcBaseDlg { CCtrlEdit m_server, m_port, m_port2, m_pass, m_nick, m_nick2, m_name, m_userID; CCtrlCombo m_ssl; public: CDlgAccMgrUI(CIrcProto* _pro, HWND _owner) : CIrcBaseDlg(_pro, IDD_ACCMGRUI), m_server(this, IDC_SERVER), m_port(this, IDC_PORT), m_port2(this, IDC_PORT2), m_pass(this, IDC_PASS), m_nick(this, IDC_NICK), m_nick2(this, IDC_NICK2), m_name(this, IDC_NAME), m_ssl(this, IDC_SSL), m_userID(this, IDC_USERID) { m_hwndParent = _owner; } bool OnInitDialog() override { m_server.SetTextA(m_proto->m_serverName); m_port.SetTextA(m_proto->m_portStart); m_port2.SetTextA(m_proto->m_portEnd); m_pass.SetTextA(m_proto->m_password); m_ssl.AddString(TranslateT("Off"), 0); m_ssl.AddString(TranslateT("Auto"), 1); m_ssl.AddString(TranslateT("On"), 2); m_ssl.SelectData(m_proto->m_iSSL); m_nick.SetText(m_proto->m_nick); m_nick2.SetText(m_proto->m_alternativeNick); m_userID.SetText(m_proto->m_userID); m_name.SetText(m_proto->m_name); return true; } bool OnApply() override { m_server.GetTextA(m_proto->m_serverName, _countof(m_proto->m_serverName)); m_port.GetTextA(m_proto->m_portStart, _countof(m_proto->m_portStart)); m_port2.GetTextA(m_proto->m_portEnd, _countof(m_proto->m_portEnd)); m_pass.GetTextA(m_proto->m_password, _countof(m_proto->m_password)); m_proto->m_iSSL = m_ssl.GetCurData(); m_nick.GetText(m_proto->m_nick, _countof(m_proto->m_nick)); removeSpaces(m_proto->m_nick); wcsncpy_s(m_proto->m_pNick, m_proto->m_nick, _TRUNCATE); m_nick2.GetText(m_proto->m_alternativeNick, _countof(m_proto->m_alternativeNick)); removeSpaces(m_proto->m_alternativeNick); m_userID.GetText(m_proto->m_userID, _countof(m_proto->m_userID)); removeSpaces(m_proto->m_userID); m_name.GetText(m_proto->m_name, _countof(m_proto->m_name)); m_proto->WriteSettings(ConnectSettings, _countof(ConnectSettings)); return true; } }; INT_PTR CIrcProto::SvcCreateAccMgrUI(WPARAM, LPARAM lParam) { CDlgAccMgrUI *dlg = new CDlgAccMgrUI(this, (HWND)lParam); dlg->Show(); return (INT_PTR)dlg->GetHwnd(); } ///////////////////////////////////////////////////////////////////////////////////////// void CIrcProto::InitPrefs(void) { ConnectSettings[0].defStr = L"Miranda"; ConnectSettings[1].defStr = L"UNIX"; ConnectSettings[2].defStr = L"113"; ConnectSettings[3].defStr = L"30"; ConnectSettings[4].defStr = L"10"; CtcpSettings[0].defStr = STR_USERINFO; OtherSettings[0].defStr = STR_QUITMESSAGE; ReadSettings(ConnectSettings, _countof(ConnectSettings)); ReadSettings(CtcpSettings, _countof(CtcpSettings)); ReadSettings(OtherSettings, _countof(OtherSettings)); ReadSettings(IgnoreSettings, _countof(IgnoreSettings)); int x = getDword("SizeOfListBottom", -1); if (x != -1) { db_unset(0, m_szModuleName, "SizeOfListBottom"); setDword("channelList_height", x); } if ((x = getDword("SizeOfListWidth", -1)) != -1) { db_unset(0, m_szModuleName, "SizeOfListWidth"); setDword("channelList_width", x); } if (m_pNick[0] == 0) { if (m_nick[0] != 0) { memcpy(m_pNick, m_nick, sizeof(m_pNick)); setWString("PNick", m_nick); } } else { memcpy(m_nick, m_pNick, sizeof(m_nick)); setWString("Nick", m_nick); } m_mySpecifiedHostIP[0] = 0; if (m_alias == nullptr) m_alias = mir_wstrdup(L"/op /mode ## +ooo $1 $2 $3\r\n/dop /mode ## -ooo $1 $2 $3\r\n/voice /mode ## +vvv $1 $2 $3\r\n/dvoice /mode ## -vvv $1 $2 $3\r\n/j /join #$1 $2-\r\n/p /part ## $1-\r\n/w /whois $1\r\n/k /kick ## $1 $2-\r\n/q /query $1\r\n/logon /log on ##\r\n/logoff /log off ##\r\n/save /log buffer $1\r\n/slap /me slaps $1 around a bit with a large trout"); m_myHost[0] = 0; colors[0] = RGB(255, 255, 255); colors[1] = RGB(0, 0, 0); colors[2] = RGB(0, 0, 127); colors[3] = RGB(0, 147, 0); colors[4] = RGB(255, 0, 0); colors[5] = RGB(127, 0, 0); colors[6] = RGB(156, 0, 156); colors[7] = RGB(252, 127, 0); colors[8] = RGB(255, 255, 0); colors[9] = RGB(0, 252, 0); colors[10] = RGB(0, 147, 147); colors[11] = RGB(0, 255, 255); colors[12] = RGB(0, 0, 252); colors[13] = RGB(255, 0, 255); colors[14] = RGB(127, 127, 127); colors[15] = RGB(210, 210, 210); }