// RecipeLiseDlg.cpp: 实现文件
|
//
|
|
#include "stdafx.h"
|
#include "BondEq.h"
|
#include "afxdialogex.h"
|
#include "RecipeListDlg.h"
|
#include "InputDialog.h"
|
#include "ToolUnits.h"
|
#include <fstream>
|
#include <sstream>
|
#include <map>
|
|
|
// CRecipeListDlg 对话框
|
|
IMPLEMENT_DYNAMIC(CRecipeListDlg, CDialogEx)
|
|
CRecipeListDlg::CRecipeListDlg(CWnd* pParent /*=nullptr*/)
|
: CDialogEx(IDD_DIALOG_RECIPE_LIST, pParent)
|
{
|
|
}
|
|
CRecipeListDlg::~CRecipeListDlg()
|
{
|
}
|
|
void CRecipeListDlg::InitRecipeLise()
|
{
|
if (m_grid.GetSafeHwnd() == NULL)
|
return;
|
|
int nRows = 1;
|
int nCols = 4;
|
|
int nFixRows = 1;
|
int nFixCols = 0;
|
int nRowIdx = 0;
|
int nColIdx = 0;
|
|
m_grid.DeleteAllItems();
|
m_grid.SetVirtualMode(FALSE);
|
m_grid.GetDefaultCell(TRUE, FALSE)->SetBackClr(g_nGridFixCellColor); // 设置固定行背景色
|
m_grid.GetDefaultCell(FALSE, TRUE)->SetBackClr(g_nGridFixCellColor); // 设置固定列背景色
|
m_grid.GetDefaultCell(FALSE, FALSE)->SetBackClr(g_nGridCellColor); // 设置单元格背景色
|
m_grid.SetFixedTextColor(g_nGridFixFontColor); // 设置固定行列字体颜色
|
|
m_grid.SetRowCount(nRows);
|
m_grid.SetColumnCount(nCols);
|
m_grid.SetFixedRowCount(nFixRows);
|
m_grid.SetFixedColumnCount(nFixCols);
|
|
// Col
|
m_grid.SetColumnWidth(nColIdx, 10);
|
m_grid.SetItemText(nRowIdx, nColIdx++, _T("No."));
|
m_grid.SetColumnWidth(nColIdx, 10);
|
m_grid.SetItemText(nRowIdx, nColIdx++, _T("名称"));
|
m_grid.SetColumnWidth(nColIdx, 50);
|
m_grid.SetItemText(nRowIdx, nColIdx++, _T("描述"));
|
m_grid.SetColumnWidth(nColIdx, 30);
|
m_grid.SetItemText(nRowIdx, nColIdx++, _T("创建时间"));
|
|
m_grid.SetFixedRowSelection(FALSE);
|
m_grid.SetFixedColumnSelection(FALSE);
|
m_grid.SetEditable(TRUE);
|
m_grid.SetRowResize(FALSE);
|
m_grid.SetColumnResize(TRUE);
|
m_grid.ExpandColumnsToFit(TRUE);
|
m_grid.SetListMode(TRUE); // 启用列表模式
|
m_grid.EnableSelection(TRUE); // 启用选择
|
m_grid.SetSingleRowSelection(TRUE); // 自动整行高亮(限制为单行选择)
|
m_grid.ExpandLastColumn(); // 最后一列填充网格
|
|
FillRecipeLise();
|
}
|
|
void CRecipeListDlg::FillRecipeLise()
|
{
|
// 清除数据行,保留表头
|
for (int i = 1; i < m_grid.GetRowCount(); i++) {
|
m_grid.DeleteRow(i);
|
}
|
|
// 1. 遍历文件夹下所有XML文件
|
std::string strRecipePath = CToolUnits::getRecipePath();
|
std::vector<CString> vecFile = CToolUnits::GetFileNamesInDirectory(strRecipePath.c_str(), _T(".xml"));
|
|
// 2. 读取 RecipeList.txt 文件
|
std::map<CString, std::pair<CString, CString>> recipeData; // {配方名, {描述, 创建时间}}
|
std::ifstream inFile(strRecipePath + "\\RecipeList.txt");
|
if (inFile.is_open()) {
|
std::string line;
|
while (std::getline(inFile, line)) {
|
if (line.empty()) continue; // 跳过空行
|
|
std::istringstream ss(line);
|
std::string name, description, createTime;
|
|
// CSV格式解析(逗号分隔)
|
if (std::getline(ss, name, ',') &&
|
std::getline(ss, description, ',') &&
|
std::getline(ss, createTime)) {
|
recipeData[CString(name.c_str())] = std::make_pair(CString(description.c_str()), CString(createTime.c_str()));
|
}
|
}
|
inFile.close();
|
}
|
|
// 3. 更新表格数据
|
int rowIdx = 1;
|
m_grid.SetRowCount(static_cast<int>(vecFile.size()) + 1);
|
for (const auto& fileName : vecFile) {
|
// 从 RecipeList.txt 数据中查找对应的描述和创建时间
|
CString description = _T("");
|
CString createTime = _T("");
|
auto it = recipeData.find(fileName);
|
if (it != recipeData.end()) {
|
description = it->second.first; // 配方描述
|
createTime = it->second.second; // 创建时间
|
}
|
|
// 填充表格数据
|
m_grid.SetItemText(rowIdx, 0, CString(std::to_string(rowIdx).c_str())); // No.
|
m_grid.SetItemText(rowIdx, 1, fileName); // 配方名称
|
m_grid.SetItemText(rowIdx, 2, description); // 配方描述
|
m_grid.SetItemText(rowIdx, 3, createTime); // 创建时间
|
|
m_grid.SetItemState(rowIdx, 0, GVIS_READONLY);
|
m_grid.SetItemState(rowIdx, 1, GVIS_READONLY);
|
m_grid.SetItemState(rowIdx, 3, GVIS_READONLY);
|
|
++rowIdx;
|
}
|
|
m_grid.ExpandColumnsToFit(FALSE);
|
m_grid.ExpandLastColumn();
|
m_grid.Invalidate();
|
m_grid.UpdateWindow();
|
}
|
|
void CRecipeListDlg::DoDataExchange(CDataExchange* pDX)
|
{
|
CDialogEx::DoDataExchange(pDX);
|
DDX_Control(pDX, IDC_CUSTOM_RECIPE_LIST, m_grid);
|
}
|
|
|
BEGIN_MESSAGE_MAP(CRecipeListDlg, CDialogEx)
|
ON_BN_CLICKED(IDC_BUTTON_CREATE_RECIPE, &CRecipeListDlg::OnBnClickedButtonCreateRecipe)
|
ON_BN_CLICKED(IDC_BUTTON_DELETE_RECIPE, &CRecipeListDlg::OnBnClickedButtonDeleteRecipe)
|
END_MESSAGE_MAP()
|
|
|
// CRecipeListDlg 消息处理程序
|
|
|
BOOL CRecipeListDlg::OnInitDialog()
|
{
|
CDialogEx::OnInitDialog();
|
|
// TODO: 在此添加额外的初始化
|
InitRecipeLise();
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
// 异常: OCX 属性页应返回 FALSE
|
}
|
|
void CRecipeListDlg::OnBnClickedButtonCreateRecipe()
|
{
|
// TODO: 在此添加控件通知处理程序代码
|
CInputDialog inputDialog(_T("配方名称"), _T("请输入配方名称:"));
|
if (inputDialog.DoModal() != IDOK) {
|
return;
|
}
|
CString newRecipeName = inputDialog.GetInputText();
|
|
// 验证名称不重复
|
std::string recipePath = CToolUnits::getRecipePath();
|
std::string recipeListPath = recipePath + "\\RecipeList.txt";
|
std::vector<CString> existingFiles = CToolUnits::GetFileNamesInDirectory(recipePath.c_str(), ".xml");
|
|
for (const auto& fileName : existingFiles) {
|
if (newRecipeName.Compare(fileName) == 0) {
|
AfxMessageBox(_T("配方名称已存在,请输入其他名称!"));
|
return;
|
}
|
}
|
|
// 检查是否要复制选中配方
|
CString strCopyRecipe = _T("");
|
for (int i = 1; i < m_grid.GetRowCount(); i++) {
|
if (m_grid.IsCellSelected(i, 1)) {
|
strCopyRecipe = m_grid.GetItemText(i, 1);
|
|
CString strMessage;
|
strMessage.Format(_T("Copy [%s] -> [%s]?"), strCopyRecipe, newRecipeName);
|
if (AfxMessageBox(strMessage, MB_YESNO | MB_ICONQUESTION) != IDYES) {
|
strCopyRecipe = _T("");
|
}
|
break;
|
}
|
}
|
|
// 创建新的XML文件
|
CString newRecipeFile = CString(recipePath.c_str()) + "\\" + newRecipeName + ".xml";
|
if (!strCopyRecipe.IsEmpty()) {
|
CString sourceFile = CString(recipePath.c_str()) + "\\" + strCopyRecipe + ".xml";
|
CopyFile(sourceFile, newRecipeFile, FALSE);
|
}
|
else {
|
// 生成默认XML文件
|
RecipeManager& recipeManager = RecipeManager::getInstance();
|
recipeManager.generateDefaultRecipe();
|
if (!recipeManager.saveRecipe(std::string(CT2A(newRecipeName)))) {
|
AfxMessageBox(_T("创建配方失败!"));
|
return;
|
}
|
}
|
|
// 更新 RecipeList.txt
|
std::ofstream outFile(recipeListPath, std::ios::app); // 追加模式
|
if (outFile.is_open()) {
|
SYSTEMTIME sysTime;
|
GetLocalTime(&sysTime);
|
char buffer[64];
|
sprintf_s(buffer, "%04d-%02d-%02d %02d:%02d:%02d",
|
sysTime.wYear, sysTime.wMonth, sysTime.wDay,
|
sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
|
|
outFile << CT2A(newRecipeName) << ",默认描述," << buffer << std::endl;
|
outFile.close();
|
}
|
|
// 刷新网格控件
|
FillRecipeLise();
|
}
|
|
void CRecipeListDlg::OnBnClickedButtonDeleteRecipe()
|
{
|
// TODO: 在此添加控件通知处理程序代码
|
int nSelect = -1;
|
for (int i = 1; i < m_grid.GetRowCount(); i++) {
|
if (m_grid.IsCellSelected(i, 1)) {
|
nSelect = i;
|
break;
|
}
|
}
|
|
if (nSelect < 0) {
|
AfxMessageBox(_T("请选择要删除的配方!"));
|
return;
|
}
|
|
CString selectedRecipe = m_grid.GetItemText(nSelect, 1);
|
if (selectedRecipe.IsEmpty()) {
|
AfxMessageBox(_T("配方名称无效!"));
|
return;
|
}
|
|
CString message = _T("确定要删除配方 \"") + selectedRecipe + _T("\" 吗?");
|
if (AfxMessageBox(message, MB_YESNO | MB_ICONQUESTION) != IDYES) {
|
return;
|
}
|
|
// 删除XML文件
|
std::string recipePath = CToolUnits::getRecipePath();
|
CString xmlFilePath = CString(recipePath.c_str()) + "\\" + selectedRecipe + ".xml";
|
if (!DeleteFile(xmlFilePath)) {
|
AfxMessageBox(_T("删除XML文件失败!"));
|
return;
|
}
|
|
// 更新RecipeList.txt文件
|
std::string recipeListPath = recipePath + "\\RecipeList.txt";
|
std::ifstream inFile(recipeListPath);
|
std::ofstream outFile(recipeListPath + ".tmp"); // 创建临时文件
|
|
if (inFile.is_open() && outFile.is_open()) {
|
std::string line;
|
while (std::getline(inFile, line)) {
|
std::istringstream ss(line);
|
std::string name;
|
if (std::getline(ss, name, ',')) {
|
if (selectedRecipe != CString(name.c_str())) {
|
outFile << line << std::endl; // 保留不匹配的行
|
}
|
}
|
}
|
inFile.close();
|
outFile.close();
|
|
// 替换文件
|
DeleteFile(CString(recipeListPath.c_str()));
|
MoveFile(CString((recipeListPath + ".tmp").c_str()), CString(recipeListPath.c_str()));
|
}
|
|
// 刷新网格控件
|
FillRecipeLise();
|
}
|