doc_and_tools/tools/apps/hgjson/DlgCondition.cpp

307 lines
7.3 KiB
C++

// DlgCondition.cpp: 实现文件
//
#include "stdafx.h"
#include "hgjson.h"
#include "DlgCondition.h"
#include "afxdialogex.h"
#include "resource.h"
#include "../../../../code_device/hgdriver/hgdev/simple_logic.h"
#include "opt_ui/DlgPage.h" // for u2a
// CDlgCondition 对话框
IMPLEMENT_DYNAMIC(CDlgCondition, CDialogEx)
CDlgCondition::CDlgCondition(const wchar_t* name, CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_CONDITION, pParent)
, name_(name ? name : L"")
{
}
CDlgCondition::~CDlgCondition()
{
}
std::wstring CDlgCondition::get_item_text(UINT id)
{
int l = GetDlgItem(id)->GetWindowTextLengthW();
wchar_t* buf = new wchar_t[l + 4];
l = GetDlgItem(id)->GetWindowTextW(buf, l + 2);
buf[l] = 0;
std::wstring ret(buf);
delete[] buf;
return std::move(ret);
}
std::wstring CDlgCondition::get_value(int range, bool first)
{
if (range == SANE_CONSTRAINT_STRING_LIST || range == SANE_CONSTRAINT_WORD_LIST)
{
return get_item_text(first ? IDC_COMBO_VALUE : IDC_COMBO_VALUE2);
}
else
{
return get_item_text(first ? IDC_EDIT_VALUE : IDC_EDIT_VALUE2);
}
}
void CDlgCondition::enable_value_controls(bool enable, int range, bool second)
{
int cmd = enable ? SW_SHOW : SW_HIDE;
if (second)
{
GetDlgItem(IDC_STATIC_AND)->ShowWindow(cmd);
if (range == SANE_CONSTRAINT_STRING_LIST || range == SANE_CONSTRAINT_WORD_LIST)
{
GetDlgItem(IDC_EDIT_VALUE2)->ShowWindow(SW_HIDE);
value2_.ShowWindow(cmd);
}
else
{
GetDlgItem(IDC_EDIT_VALUE2)->ShowWindow(cmd);
value2_.ShowWindow(SW_HIDE);
}
}
else
{
if (range == SANE_CONSTRAINT_STRING_LIST || range == SANE_CONSTRAINT_WORD_LIST)
{
GetDlgItem(IDC_EDIT_VALUE)->ShowWindow(SW_HIDE);
value_.ShowWindow(cmd);
}
else
{
GetDlgItem(IDC_EDIT_VALUE)->ShowWindow(cmd);
value_.ShowWindow(SW_HIDE);
}
}
}
void CDlgCondition::clear_items(void)
{
for (int i = 0; i < items_.GetCount(); ++i)
{
LPOPTITEM opt = (LPOPTITEM)items_.GetItemData(i);
if (opt)
delete opt;
}
items_.ResetContent();
}
void CDlgCondition::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_COMBO_ITEM, items_);
DDX_Control(pDX, IDC_COMBO_LOGIC, oper_);
DDX_Control(pDX, IDC_COMBO_VALUE, value_);
DDX_Control(pDX, IDC_COMBO_VALUE2, value2_);
}
BOOL CDlgCondition::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
enable_value_controls(false, 0);
LPOPTITEM data = new OPTITEM;
int index = 0;
clear_items();
while (!(data->title = item_all_(index++, &data->type, &data->range, &data->name)).empty())
{
if (data->type != SANE_TYPE_GROUP)
{
int ind = items_.AddString(data->name.c_str());
items_.SetItemData(ind, (DWORD_PTR)data);
data = new OPTITEM;
}
}
delete data;
value_.ResetContent();
SetDlgItemText(IDC_EDIT_CONDITION, condition_.c_str());
return TRUE; // return TRUE unless you set the focus to a control
}
BEGIN_MESSAGE_MAP(CDlgCondition, CDialogEx)
ON_BN_CLICKED(IDOK, &CDlgCondition::OnBnClickedOk)
ON_BN_CLICKED(IDC_BUTTON1, &CDlgCondition::OnBnClickedButton1)
ON_BN_CLICKED(IDCANCEL, &CDlgCondition::OnBnClickedCancel)
ON_CBN_SELCHANGE(IDC_COMBO_ITEM, &CDlgCondition::OnCbnSelchangeComboItem)
ON_CBN_SELCHANGE(IDC_COMBO_LOGIC, &CDlgCondition::OnCbnSelchangeComboLogic)
END_MESSAGE_MAP()
// CDlgCondition 消息处理程序
void CDlgCondition::init_data(std::function<std::wstring(int/*index*/, int*/*type*/, int*/*range type*/, std::wstring* /*name*/)> item, std::function < std::wstring(const wchar_t*/*name*/, int/*index*/)> value, const wchar_t* data0)
{
item_all_ = item;
item_val_ = value;
condition_ = data0 ? data0 : L"";
}
std::wstring CDlgCondition::get_condition(void)
{
return condition_;
}
void CDlgCondition::OnCbnSelchangeComboItem()
{
// TODO: 在此添加控件通知处理程序代码
LPOPTITEM opt = (LPOPTITEM)items_.GetItemData(items_.GetCurSel());
if (opt->name == name_)
{
MessageBox(TEXT("Condition can't contains self!"));
if (items_.GetCurSel() == 0)
items_.SetCurSel(1);
else
items_.SetCurSel(items_.GetCurSel() - 1);
GotoDlgCtrl(&items_);
return;
}
if (opt->range == SANE_CONSTRAINT_STRING_LIST || opt->range == SANE_CONSTRAINT_WORD_LIST ||
opt->range == SANE_CONSTRAINT_RANGE)
{
std::wstring val(L"");
int ind = 0;
value_.ResetContent();
value2_.ResetContent();
while (!(val = item_val_(opt->name.c_str(), ind++)).empty())
{
value_.AddString(val.c_str());
value2_.AddString(val.c_str());
}
}
std::wstring lg(get_item_text(IDC_COMBO_LOGIC));
enable_value_controls(lg != L"enabled" && lg != L"!enabled", opt->range, false);
}
void CDlgCondition::OnCbnSelchangeComboLogic()
{
// TODO: 在此添加控件通知处理程序代码
std::wstring oper(get_item_text(IDC_COMBO_LOGIC));
LPOPTITEM opt = (LPOPTITEM)items_.GetItemData(items_.GetCurSel());
if (oper == L"enabled" || oper == L"!enabled")
{
enable_value_controls(false, opt->range, false);
enable_value_controls(false, opt->range);
}
else
{
enable_value_controls(true, opt->range, false);
if (oper == L"between" || oper == L"out of")
enable_value_controls(true, opt->range);
}
}
void CDlgCondition::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
std::wstring name(get_item_text(IDC_COMBO_ITEM)),
logic(get_item_text(IDC_COMBO_LOGIC)),
val(L""), val2(L"");
LPOPTITEM opt = (LPOPTITEM)items_.GetItemData(items_.GetCurSel());
if (logic == L"enabled" || logic == L"!enabled")
{
name = opt->name + L"." + logic;
}
else
{
val = get_value(opt->range, true);
if (logic == L"between" || logic == L"out of")
{
val2 = get_value(opt->range, false);
name = opt->name;
if (logic == L"between")
name += L"==[";
else
name += L"!=[";
name += val + L"," + val2 + L"]";
}
else
{
name = opt->name + logic + val;
}
if (opt->range == SANE_CONSTRAINT_RANGE)
{
wchar_t buf[128] = { 0 };
value_.GetLBText(0, buf);
if (val < buf)
{
logic = buf;
swprintf_s(buf, _countof(buf) - 1, L"value must not less than '%s'", logic.c_str());
MessageBox(buf);
return;
}
value_.GetLBText(1, buf);
if (val2 > buf)
{
logic = buf;
swprintf_s(buf, _countof(buf) - 1, L"value must not greate than '%s'", logic.c_str());
MessageBox(buf);
return;
}
}
}
val = get_item_text(IDC_EDIT_CONDITION);
if (!val.empty())
name.insert(0, val + L" || ");
SetDlgItemText(IDC_EDIT_CONDITION, name.c_str());
}
void CDlgCondition::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
std::string utf8("");
simple_logic logic;
int pos = 0;
condition_ = get_item_text(IDC_EDIT_CONDITION);
utf8 = local_trans::u2a(condition_.c_str(), CP_UTF8);
if (!logic.parse(utf8.c_str(), &pos))
{
wchar_t info[128] = { 0 };
swprintf_s(info, _countof(info) - 1, L"Failed at pos %d ('%c')!", pos, utf8[pos]);
MessageBox(info, L"Invalid expression", MB_OK);
utf8.erase(pos);
std::wstring pre(local_trans::a2u(utf8.c_str(), CP_UTF8));
::SendMessage(GetDlgItem(IDC_EDIT_CONDITION)->m_hWnd, EM_SETSEL, (WPARAM)pre.length(), (LPARAM)pre.length() + 1);
condition_ = L"";
return;
}
clear_items();
CDialogEx::OnOK();
}
void CDlgCondition::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码
clear_items();
CDialogEx::OnCancel();
}