Replace the single-line, semicolon-separated keyword field with a taller multi-line edit box (with a vertical scrollbar) where each keyword goes on its own line. The stored format stays semicolon-separated, so existing notify.ini files remain valid; load/save convert between newlines and semicolons, trimming each keyword and skipping empty lines. Also decode the stored matchPattern as UTF-8 when loading the dialog, so non-ASCII keywords round-trip correctly (matching the CP_UTF8 encoding used on save). Co-Authored-By: deepseek-v4-pro
305 lines
11 KiB
C++
305 lines
11 KiB
C++
#include "stdafx.h"
|
|
#include "NotifySettingsDlg.h"
|
|
#include "NotifyManager.h"
|
|
#include "context.h"
|
|
|
|
NotifySettingsDlg::NotifySettingsDlg(CWnd* pParent)
|
|
: CDialogLangEx(IDD_DIALOG_NOTIFY_SETTINGS, pParent)
|
|
, m_powerShellAvailable(false)
|
|
{
|
|
}
|
|
|
|
NotifySettingsDlg::~NotifySettingsDlg()
|
|
{
|
|
}
|
|
|
|
void NotifySettingsDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialogLangEx::DoDataExchange(pDX);
|
|
|
|
DDX_Control(pDX, IDC_EDIT_SMTP_SERVER, m_editSmtpServer);
|
|
DDX_Control(pDX, IDC_EDIT_SMTP_PORT, m_editSmtpPort);
|
|
DDX_Control(pDX, IDC_CHECK_SMTP_SSL, m_checkSmtpSSL);
|
|
DDX_Control(pDX, IDC_EDIT_SMTP_USER, m_editSmtpUser);
|
|
DDX_Control(pDX, IDC_EDIT_SMTP_PASS, m_editSmtpPass);
|
|
DDX_Control(pDX, IDC_EDIT_SMTP_RECIPIENT, m_editSmtpRecipient);
|
|
|
|
DDX_Control(pDX, IDC_CHECK_NOTIFY_ENABLED, m_checkNotifyEnabled);
|
|
DDX_Control(pDX, IDC_COMBO_NOTIFY_TYPE, m_comboNotifyType);
|
|
DDX_Control(pDX, IDC_COMBO_NOTIFY_COLUMN, m_comboNotifyColumn);
|
|
DDX_Control(pDX, IDC_EDIT_NOTIFY_PATTERN, m_editNotifyPattern);
|
|
|
|
DDX_Control(pDX, IDC_STATIC_NOTIFY_WARNING, m_staticWarning);
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(NotifySettingsDlg, CDialogLangEx)
|
|
ON_BN_CLICKED(IDC_BTN_TEST_EMAIL, &NotifySettingsDlg::OnBnClickedBtnTestEmail)
|
|
ON_BN_CLICKED(IDC_CHECK_NOTIFY_ENABLED, &NotifySettingsDlg::OnBnClickedCheckNotifyEnabled)
|
|
END_MESSAGE_MAP()
|
|
|
|
BOOL NotifySettingsDlg::OnInitDialog()
|
|
{
|
|
CDialogLangEx::OnInitDialog();
|
|
|
|
// Set translatable text for static controls
|
|
SetDlgItemText(IDC_GROUP_SMTP, _TR(_T("SMTP 配置")));
|
|
SetDlgItemText(IDC_STATIC_SMTP_SERVER, _TR(_T("服务器:")));
|
|
SetDlgItemText(IDC_STATIC_SMTP_PORT, _TR(_T("端口:")));
|
|
SetDlgItemText(IDC_CHECK_SMTP_SSL, _TR(_T("使用 SSL/TLS")));
|
|
SetDlgItemText(IDC_STATIC_SMTP_USER, _TR(_T("用户名:")));
|
|
SetDlgItemText(IDC_STATIC_SMTP_PASS, _TR(_T("密码:")));
|
|
SetDlgItemText(IDC_STATIC_SMTP_HINT, _TR(_T("(Gmail 需使用应用专用密码)")));
|
|
SetDlgItemText(IDC_STATIC_SMTP_RECIPIENT, _TR(_T("收件人:")));
|
|
SetDlgItemText(IDC_BTN_TEST_EMAIL, _TR(_T("测试")));
|
|
SetDlgItemText(IDC_GROUP_NOTIFY_RULE, _TR(_T("通知规则")));
|
|
SetDlgItemText(IDC_CHECK_NOTIFY_ENABLED, _TR(_T("启用通知")));
|
|
SetDlgItemText(IDC_STATIC_TRIGGER, _TR(_T("触发条件:")));
|
|
SetDlgItemText(IDC_STATIC_MATCH_COLUMN, _TR(_T("匹配列:")));
|
|
SetDlgItemText(IDC_STATIC_KEYWORDS, _TR(_T("关键词:")));
|
|
SetDlgItemText(IDC_STATIC_KEYWORDS_HINT, _TR(_T("(每行一个关键词,匹配任一项即触发通知)")));
|
|
SetDlgItemText(IDC_STATIC_NOTIFY_TIP, _TR(_T("提示: 同一主机 60 分钟内仅通知一次")));
|
|
SetDlgItemText(IDOK, _TR("确定"));
|
|
SetDlgItemText(IDCANCEL, _TR("取消"));
|
|
SetWindowText(_TR("通知设置"));
|
|
|
|
// Check PowerShell availability
|
|
m_powerShellAvailable = GetNotifyManager().IsPowerShellAvailable();
|
|
|
|
// Show warning if PowerShell is not available
|
|
if (!m_powerShellAvailable) {
|
|
m_staticWarning.SetWindowText(_T("Warning: Requires Windows 10 or later with PowerShell 5.1+"));
|
|
// Disable all controls except OK/Cancel
|
|
GetDlgItem(IDC_EDIT_SMTP_SERVER)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_EDIT_SMTP_PORT)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_CHECK_SMTP_SSL)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_EDIT_SMTP_USER)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_EDIT_SMTP_PASS)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_EDIT_SMTP_RECIPIENT)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_BTN_TEST_EMAIL)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_CHECK_NOTIFY_ENABLED)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_COMBO_NOTIFY_TYPE)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_COMBO_NOTIFY_COLUMN)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_EDIT_NOTIFY_PATTERN)->EnableWindow(FALSE);
|
|
} else {
|
|
m_staticWarning.SetWindowText(_T(""));
|
|
}
|
|
|
|
PopulateComboBoxes();
|
|
LoadSettings();
|
|
UpdateControlStates();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void NotifySettingsDlg::PopulateComboBoxes()
|
|
{
|
|
// Trigger type combo (currently only "Host Online")
|
|
m_comboNotifyType.ResetContent();
|
|
m_comboNotifyType.AddString(_TR("主机上线"));
|
|
m_comboNotifyType.SetItemData(0, NOTIFY_TRIGGER_HOST_ONLINE);
|
|
m_comboNotifyType.SetCurSel(0);
|
|
|
|
// Column combo - use translatable strings
|
|
m_comboNotifyColumn.ResetContent();
|
|
struct { int id; const TCHAR* name; } columns[] = {
|
|
{ ONLINELIST_IP, _T("IP地址") },
|
|
{ ONLINELIST_ADDR, _T("地址") },
|
|
{ ONLINELIST_LOCATION, _T("地理位置") },
|
|
{ ONLINELIST_COMPUTER_NAME,_T("计算机名") },
|
|
{ ONLINELIST_OS, _T("操作系统") },
|
|
{ ONLINELIST_CPU, _T("CPU") },
|
|
{ ONLINELIST_VIDEO, _T("摄像头") },
|
|
{ ONLINELIST_PING, _T("延迟") },
|
|
{ ONLINELIST_VERSION, _T("版本") },
|
|
{ ONLINELIST_INSTALLTIME, _T("安装时间") },
|
|
{ ONLINELIST_LOGINTIME, _T("活动窗口") },
|
|
{ ONLINELIST_CLIENTTYPE, _T("客户端类型") },
|
|
{ ONLINELIST_PRIVILEGE, _T("权限") },
|
|
};
|
|
for (const auto& col : columns) {
|
|
CString item;
|
|
item.Format(_T("%d - %s"), col.id, _TR(col.name));
|
|
m_comboNotifyColumn.AddString(item);
|
|
m_comboNotifyColumn.SetItemData(m_comboNotifyColumn.GetCount() - 1, col.id);
|
|
}
|
|
m_comboNotifyColumn.SetCurSel(ONLINELIST_COMPUTER_NAME); // Default to computer name
|
|
}
|
|
|
|
void NotifySettingsDlg::LoadSettings()
|
|
{
|
|
// Get current config from manager
|
|
m_config = GetNotifyManager().GetConfig();
|
|
|
|
// SMTP settings
|
|
m_editSmtpServer.SetWindowText(CString(m_config.smtp.server.c_str()));
|
|
|
|
CString portStr;
|
|
portStr.Format(_T("%d"), m_config.smtp.port);
|
|
m_editSmtpPort.SetWindowText(portStr);
|
|
|
|
m_checkSmtpSSL.SetCheck(m_config.smtp.useSSL ? BST_CHECKED : BST_UNCHECKED);
|
|
m_editSmtpUser.SetWindowText(CString(m_config.smtp.username.c_str()));
|
|
m_editSmtpPass.SetWindowText(CString(m_config.smtp.password.c_str()));
|
|
m_editSmtpRecipient.SetWindowText(CString(m_config.smtp.recipient.c_str()));
|
|
|
|
// Rule settings
|
|
const NotifyRule& rule = m_config.GetRule();
|
|
m_checkNotifyEnabled.SetCheck(rule.enabled ? BST_CHECKED : BST_UNCHECKED);
|
|
|
|
// Set trigger type (currently only one option)
|
|
m_comboNotifyType.SetCurSel(0);
|
|
|
|
// Set column
|
|
if (rule.columnIndex >= 0 && rule.columnIndex < m_comboNotifyColumn.GetCount()) {
|
|
m_comboNotifyColumn.SetCurSel(rule.columnIndex);
|
|
}
|
|
|
|
// Display stored semicolon-separated keywords as one keyword per line.
|
|
{
|
|
CString pattern;
|
|
const CString stored(CA2T(rule.matchPattern.c_str(), CP_UTF8));
|
|
int start = 0;
|
|
for (;;) {
|
|
const int pos = stored.Find(_T(';'), start);
|
|
CString kw = (pos < 0) ? stored.Mid(start) : stored.Mid(start, pos - start);
|
|
kw.Trim();
|
|
if (!kw.IsEmpty()) {
|
|
if (!pattern.IsEmpty()) pattern += _T("\r\n");
|
|
pattern += kw;
|
|
}
|
|
if (pos < 0) break;
|
|
start = pos + 1;
|
|
}
|
|
m_editNotifyPattern.SetWindowText(pattern);
|
|
}
|
|
}
|
|
|
|
void NotifySettingsDlg::SaveSettings()
|
|
{
|
|
CString str;
|
|
|
|
// SMTP settings
|
|
m_editSmtpServer.GetWindowText(str);
|
|
m_config.smtp.server = CT2A(str, CP_UTF8);
|
|
|
|
m_editSmtpPort.GetWindowText(str);
|
|
m_config.smtp.port = _ttoi(str);
|
|
|
|
m_config.smtp.useSSL = (m_checkSmtpSSL.GetCheck() == BST_CHECKED);
|
|
|
|
m_editSmtpUser.GetWindowText(str);
|
|
m_config.smtp.username = CT2A(str, CP_UTF8);
|
|
|
|
m_editSmtpPass.GetWindowText(str);
|
|
m_config.smtp.password = CT2A(str, CP_UTF8);
|
|
|
|
m_editSmtpRecipient.GetWindowText(str);
|
|
m_config.smtp.recipient = CT2A(str, CP_UTF8);
|
|
|
|
// Rule settings
|
|
NotifyRule& rule = m_config.GetRule();
|
|
rule.enabled = (m_checkNotifyEnabled.GetCheck() == BST_CHECKED);
|
|
|
|
int sel = m_comboNotifyType.GetCurSel();
|
|
rule.triggerType = (sel >= 0) ? (NotifyTriggerType)m_comboNotifyType.GetItemData(sel) : NOTIFY_TRIGGER_HOST_ONLINE;
|
|
|
|
sel = m_comboNotifyColumn.GetCurSel();
|
|
rule.columnIndex = (sel >= 0) ? (int)m_comboNotifyColumn.GetItemData(sel) : ONLINELIST_COMPUTER_NAME;
|
|
|
|
// Normalize one-keyword-per-line input back to semicolon-separated storage.
|
|
m_editNotifyPattern.GetWindowText(str);
|
|
str.Replace(_T("\r\n"), _T("\n"));
|
|
str.Replace(_T('\r'), _T('\n'));
|
|
{
|
|
CString joined;
|
|
int start = 0;
|
|
for (;;) {
|
|
const int pos = str.Find(_T('\n'), start);
|
|
CString kw = (pos < 0) ? str.Mid(start) : str.Mid(start, pos - start);
|
|
kw.Trim();
|
|
if (!kw.IsEmpty()) {
|
|
if (!joined.IsEmpty()) joined += _T(';');
|
|
joined += kw;
|
|
}
|
|
if (pos < 0) break;
|
|
start = pos + 1;
|
|
}
|
|
rule.matchPattern = CT2A(joined, CP_UTF8);
|
|
}
|
|
|
|
// Update manager config and save
|
|
GetNotifyManager().SetConfig(m_config);
|
|
GetNotifyManager().SaveConfig();
|
|
}
|
|
|
|
void NotifySettingsDlg::UpdateControlStates()
|
|
{
|
|
if (!m_powerShellAvailable) return;
|
|
|
|
BOOL enabled = (m_checkNotifyEnabled.GetCheck() == BST_CHECKED);
|
|
m_comboNotifyType.EnableWindow(enabled);
|
|
m_comboNotifyColumn.EnableWindow(enabled);
|
|
m_editNotifyPattern.EnableWindow(enabled);
|
|
}
|
|
|
|
void NotifySettingsDlg::OnOK()
|
|
{
|
|
SaveSettings();
|
|
CDialogLangEx::OnOK();
|
|
}
|
|
|
|
void NotifySettingsDlg::OnBnClickedBtnTestEmail()
|
|
{
|
|
// Temporarily save current UI values to config for testing
|
|
CString str;
|
|
|
|
m_editSmtpServer.GetWindowText(str);
|
|
m_config.smtp.server = CT2A(str, CP_UTF8);
|
|
|
|
m_editSmtpPort.GetWindowText(str);
|
|
m_config.smtp.port = _ttoi(str);
|
|
|
|
m_config.smtp.useSSL = (m_checkSmtpSSL.GetCheck() == BST_CHECKED);
|
|
|
|
m_editSmtpUser.GetWindowText(str);
|
|
m_config.smtp.username = CT2A(str, CP_UTF8);
|
|
|
|
m_editSmtpPass.GetWindowText(str);
|
|
m_config.smtp.password = CT2A(str, CP_UTF8);
|
|
|
|
m_editSmtpRecipient.GetWindowText(str);
|
|
m_config.smtp.recipient = CT2A(str, CP_UTF8);
|
|
|
|
// Update manager config temporarily
|
|
NotifyConfig backup = GetNotifyManager().GetConfig();
|
|
NotifyConfig tempConfig = backup;
|
|
tempConfig.smtp = m_config.smtp;
|
|
GetNotifyManager().SetConfig(tempConfig);
|
|
|
|
// Disable button during test
|
|
GetDlgItem(IDC_BTN_TEST_EMAIL)->EnableWindow(FALSE);
|
|
SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
// Send test email (synchronous)
|
|
std::string result = GetNotifyManager().SendTestEmail();
|
|
|
|
// Restore config
|
|
GetNotifyManager().SetConfig(backup);
|
|
|
|
// Re-enable button
|
|
GetDlgItem(IDC_BTN_TEST_EMAIL)->EnableWindow(TRUE);
|
|
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
|
|
|
// Show result
|
|
if (result == "success") {
|
|
MessageBox(_TR(_T("测试邮件发送成功!")), _TR(_T("测试邮件")), MB_OK | MB_ICONINFORMATION);
|
|
} else {
|
|
MessageBox(_TR(_T("测试邮件发送失败,请检查SMTP配置")), _TR(_T("测试邮件")), MB_OK | MB_ICONWARNING);
|
|
}
|
|
}
|
|
|
|
void NotifySettingsDlg::OnBnClickedCheckNotifyEnabled()
|
|
{
|
|
UpdateControlStates();
|
|
}
|