307 lines
7.3 KiB
C++
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/sdk/sane_opt_json/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->title.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();
|
|
}
|