501 lines
13 KiB
C++
501 lines
13 KiB
C++
#include "stdafx.h"
|
|
#include "AICloudSettingDlg.h"
|
|
#include "earthwormdef.h"
|
|
#include "askaipaletteset.h"
|
|
#include "aisettingdlg.h"
|
|
|
|
using namespace SHAI;
|
|
using namespace AIJSON;
|
|
|
|
#define SHAI_CONFIG_FILE _T("\\shai.json")
|
|
|
|
namespace
|
|
{
|
|
bool readAiCloudConfig(AICloud &cloud)
|
|
{
|
|
CString sJsonPath(FilePath::GetSysDir() + SHAI_CONFIG_FILE);
|
|
if (_taccess(sJsonPath, 0x0) != 0x0) return false;
|
|
|
|
Document8 doc;
|
|
if (!file2Json(sJsonPath, doc)) return false;
|
|
|
|
CMIt8 itAiCloud = doc.FindMember("ai_cloud");
|
|
if (itAiCloud == doc.MemberEnd()) return false;
|
|
|
|
if (!itAiCloud->value.IsArray()) return false;
|
|
|
|
std::string name, api_key, api_url, model;
|
|
bool bSelect(false);
|
|
const CArr8 &ar = itAiCloud->value.GetArray();
|
|
CVIt8 itAr = ar.Begin();
|
|
for (; itAr != ar.End(); ++itAr)
|
|
{
|
|
if (!itAr->IsObject()) continue;
|
|
if (!parseValue<std::string>(*itAr, "name", name)) continue;
|
|
|
|
if (name == cloud.cloudName())
|
|
{
|
|
if (parseValue<std::string>(*itAr, "api_key", api_key)
|
|
&& parseValue<std::string>(*itAr, "api_url", api_url)
|
|
&& parseValue<std::string>(*itAr, "model", model)
|
|
&& parseValue<bool>(*itAr, "select", bSelect)
|
|
)
|
|
{
|
|
cloud.setApiKey(api_key.c_str());
|
|
cloud.setEndpoint(api_url.c_str());
|
|
cloud.setCurrentModel(model.c_str());
|
|
cloud.setCurrentSelect(bSelect);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool readAllCloudConfig(std::vector<SHAI::AICloud*> &clouds)
|
|
{
|
|
CString sJsonPath(FilePath::GetSysDir() + SHAI_CONFIG_FILE);
|
|
if (_taccess(sJsonPath, 0x0) != 0x0) return false;
|
|
|
|
Document8 doc;
|
|
if (!file2Json(sJsonPath, doc)) return false;
|
|
|
|
CMIt8 itAiCloud = doc.FindMember("ai_cloud");
|
|
if (itAiCloud == doc.MemberEnd()) return false;
|
|
|
|
if (!itAiCloud->value.IsArray()) return false;
|
|
|
|
std::string name, api_key, api_url, model;
|
|
bool bSelect(false);
|
|
const CArr8 &ar = itAiCloud->value.GetArray();
|
|
CVIt8 itAr = ar.Begin();
|
|
for (; itAr != ar.End(); ++itAr)
|
|
{
|
|
if (!itAr->IsObject()) continue;
|
|
if (!parseValue<std::string>(*itAr, "name", name)) continue;
|
|
if (!parseValue<std::string>(*itAr, "api_key", api_key)) continue;
|
|
if (!parseValue<std::string>(*itAr, "api_url", api_url)) continue;
|
|
if (!parseValue<std::string>(*itAr, "model", model)) continue;
|
|
if (!parseValue<bool>(*itAr, "select", bSelect)) continue;
|
|
|
|
AICloud *pCloud = AICloud::createCloud(name.c_str());
|
|
if (pCloud)
|
|
{
|
|
pCloud->setCloudName(name.c_str());
|
|
pCloud->setApiKey(api_key.c_str());
|
|
pCloud->setEndpoint(api_url.c_str());
|
|
pCloud->setCurrentModel(model.c_str());
|
|
pCloud->setCurrentSelect(bSelect);
|
|
if (AICloud::IsCustomCloud(pCloud))
|
|
{
|
|
pCloud->insertModel(model.c_str());
|
|
}
|
|
clouds.push_back(pCloud);
|
|
}
|
|
}
|
|
return !clouds.empty();
|
|
}
|
|
|
|
bool writeAiCloudConfig(const AICloud &cloud)
|
|
{
|
|
CString sJsonPath(FilePath::GetSysDir() + SHAI_CONFIG_FILE);
|
|
if (_taccess(sJsonPath, 0x0) != 0x0)
|
|
{
|
|
CFile file(sJsonPath, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
|
|
if (file.m_hFile)
|
|
{
|
|
std::string s("{}");
|
|
file.Write(s.c_str(), (UINT)(sizeof(char) * s.size()));
|
|
file.Close();
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
Document8 doc;
|
|
if (!file2Json(sJsonPath, doc)) return false;
|
|
|
|
MIt8 itCloud = doc.FindMember("ai_cloud");
|
|
if (itCloud == doc.MemberEnd())
|
|
{
|
|
Value8 vAiCloud, vItem;
|
|
vAiCloud.SetArray();
|
|
|
|
addMember(vItem, "name", cloud.cloudName().c_str());
|
|
addMember(vItem, "api_key", cloud.apiKey().c_str());
|
|
addMember(vItem, "api_url", cloud.endpoint().c_str());
|
|
addMember(vItem, "model", cloud.currentModel().c_str());
|
|
addMember(vItem, "select", cloud.currentSelect());
|
|
|
|
pushBack(vAiCloud, vItem);
|
|
|
|
addMember(doc, "ai_cloud", vAiCloud);
|
|
}
|
|
else
|
|
{
|
|
if (!itCloud->value.IsArray()) return false;
|
|
|
|
std::string name, api_key, api_url, model;
|
|
const Arr8 &ar = itCloud->value.GetArray();
|
|
VIt8 itAr = ar.Begin();
|
|
for (; itAr != ar.End(); ++itAr)
|
|
{
|
|
if (!itAr->IsObject()) continue;
|
|
if (!parseValue<std::string>(*itAr, "name", name)) continue;
|
|
|
|
if (name == cloud.cloudName())
|
|
{
|
|
if (itAr->HasMember("api_key"))
|
|
(*itAr)["api_key"].SetString(cloud.apiKey().c_str(), getJsonAllocator());
|
|
else
|
|
addMember(*itAr, "api_key", cloud.apiKey().c_str());
|
|
|
|
if (itAr->HasMember("api_url"))
|
|
(*itAr)["api_url"].SetString(cloud.endpoint().c_str(), getJsonAllocator());
|
|
else
|
|
addMember(*itAr, "api_url", cloud.endpoint().c_str());
|
|
|
|
if (itAr->HasMember("model"))
|
|
(*itAr)["model"].SetString(cloud.currentModel().c_str(), getJsonAllocator());
|
|
else
|
|
addMember(*itAr, "model", cloud.currentModel().c_str());
|
|
|
|
if (itAr->HasMember("select"))
|
|
(*itAr)["select"].SetBool(cloud.currentSelect());
|
|
else
|
|
addMember(*itAr, "select", cloud.currentSelect());
|
|
|
|
return json2File(sJsonPath, doc, true);;
|
|
}
|
|
}
|
|
// 走到这里,说明没有找到,需要添加
|
|
Value8 vItem;
|
|
addMember(vItem, "name", cloud.cloudName().c_str());
|
|
addMember(vItem, "api_key", cloud.apiKey().c_str());
|
|
addMember(vItem, "api_url", cloud.endpoint().c_str());
|
|
addMember(vItem, "model", cloud.currentModel().c_str());
|
|
addMember(vItem, "select", cloud.currentSelect());
|
|
pushBack(itCloud->value, vItem);
|
|
|
|
}
|
|
return json2File(sJsonPath, doc, true);
|
|
}
|
|
|
|
bool deleteAICloudConfig(LPCSTR cloudName)
|
|
{
|
|
CString sJsonPath(FilePath::GetSysDir() + SHAI_CONFIG_FILE);
|
|
if (_taccess(sJsonPath, 0x0) != 0x0) return false;
|
|
|
|
Document8 doc;
|
|
if (!file2Json(sJsonPath, doc)) return false;
|
|
|
|
MIt8 itCloud = doc.FindMember("ai_cloud");
|
|
if (itCloud == doc.MemberEnd()) return false;
|
|
|
|
if (!itCloud->value.IsArray()) return false;
|
|
|
|
bool bFind(false);
|
|
std::string name, api_key, api_url, model;
|
|
const Arr8 &ar = itCloud->value.GetArray();
|
|
VIt8 itAr = ar.Begin();
|
|
for (; itAr != ar.End(); ++itAr)
|
|
{
|
|
if (!itAr->IsObject()) continue;
|
|
if (!parseValue<std::string>(*itAr, "name", name)) continue;
|
|
|
|
if (name == cloudName)
|
|
{
|
|
ar.Erase(itAr);
|
|
bFind = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bFind)
|
|
return json2File(sJsonPath, doc, true);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#pragma region CAICloudSettingDlg
|
|
|
|
IMPLEMENT_DYNAMIC(CAICloudSettingDlg, CDialog)
|
|
|
|
CAICloudSettingDlg::CAICloudSettingDlg(CWnd* pParent )
|
|
: CDialog(IDD_AI_CLOUD_SETTING, pParent)
|
|
, m_sApiKey(_T(""))
|
|
, m_sApiEndPoint(_T(""))
|
|
, m_bCurrent(FALSE)
|
|
, m_pCurrentCloud(NULL)
|
|
{
|
|
if (!readAllCloudConfig(m_clouds))
|
|
AfxMessageBox(_T("未找到配置文件。"));
|
|
}
|
|
|
|
CAICloudSettingDlg::~CAICloudSettingDlg()
|
|
{
|
|
for (size_t i = 0; i < m_clouds.size(); ++i)
|
|
{
|
|
if (m_clouds[i])
|
|
delete m_clouds[i];
|
|
}
|
|
m_clouds.clear();
|
|
}
|
|
|
|
void CAICloudSettingDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
DDX_Text(pDX, IDC_EDIT_API_KEY, m_sApiKey);
|
|
DDX_Text(pDX, IDC_EDIT_API_URL, m_sApiEndPoint);
|
|
DDX_CBIndex(pDX, IDC_COMBO_MODEL, m_iSelectModelIdx);
|
|
DDX_Control(pDX, IDC_LIST_CLOUD, m_wndListCloud);
|
|
DDX_Check(pDX, IDC_CHECK_CURRENT, m_bCurrent);
|
|
DDX_Control(pDX, IDC_COMBO_MODEL, m_wndComboxModels);
|
|
}
|
|
|
|
BOOL CAICloudSettingDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
int idx(-1), iCurrent(0);
|
|
for (size_t i = 0; i < m_clouds.size(); ++i)
|
|
{
|
|
idx = m_wndListCloud.InsertString((int)i, utf2w(m_clouds[i]->cloudName()).c_str());
|
|
m_wndListCloud.SetItemData(idx, (DWORD_PTR)m_clouds[i]);
|
|
if (m_clouds[i]->currentSelect())
|
|
iCurrent = (int)i;
|
|
}
|
|
|
|
m_pCurrentCloud = m_clouds[iCurrent];
|
|
m_wndListCloud.SetCurSel(iCurrent);
|
|
|
|
m_sApiKey = utf2w(m_pCurrentCloud->apiKey()).c_str();
|
|
m_sApiEndPoint = utf2w(m_pCurrentCloud->endpoint()).c_str();
|
|
|
|
m_bCurrent = m_pCurrentCloud->currentSelect();
|
|
|
|
initModelsCombox();
|
|
|
|
UpdateData(FALSE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CAICloudSettingDlg, CDialog)
|
|
ON_BN_CLICKED(IDOK, &CAICloudSettingDlg::OnBnClickedOk)
|
|
ON_BN_CLICKED(IDC_BTN_ADD, &CAICloudSettingDlg::OnBnClickedAdd)
|
|
ON_BN_CLICKED(IDC_BTN_DEL, &CAICloudSettingDlg::OnBnClickedDel)
|
|
ON_LBN_SELCHANGE(IDC_LIST_CLOUD, &CAICloudSettingDlg::OnLbnSelchangeListCloud)
|
|
ON_CBN_SELCHANGE(IDC_COMBO_MODEL, &CAICloudSettingDlg::OnCbnSelchangeComboModel)
|
|
END_MESSAGE_MAP()
|
|
|
|
void CAICloudSettingDlg::OnBnClickedOk()
|
|
{
|
|
if (!UpdateData(TRUE)) return;
|
|
saveCurrentCloud();
|
|
|
|
bool bHasCurrent(false);
|
|
for (size_t i(0); i < m_clouds.size(); ++i)
|
|
{
|
|
bHasCurrent = m_clouds[i]->currentSelect();
|
|
if (bHasCurrent)
|
|
break;
|
|
}
|
|
|
|
if (!bHasCurrent)
|
|
{
|
|
AfxMessageBox(_T("没有设置当前模型。"));
|
|
return;
|
|
}
|
|
|
|
for (size_t i(0); i < m_clouds.size(); ++i)
|
|
{
|
|
writeAiCloudConfig(*m_clouds[i]);
|
|
}
|
|
|
|
g_aiPaletteSet::instance().refreshAiCloud();
|
|
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
void CAICloudSettingDlg::OnBnClickedAdd()
|
|
{
|
|
CAiSettingDlg dlg;
|
|
if (dlg.DoModal() != IDOK) return;
|
|
|
|
CustomCloud *pNew = new CustomCloud(AIJSON::w2utf(dlg.m_sName).c_str()
|
|
, AIJSON::w2utf(dlg.m_sApiKey).c_str()
|
|
, AIJSON::w2utf(dlg.m_sApiUrl).c_str());
|
|
|
|
if (std::find_if(m_clouds.begin(), m_clouds.end(), AICloud::IS_EQUAL(pNew)) != m_clouds.end())
|
|
{
|
|
AfxMessageBox(_T("配置已经存在。"));
|
|
return;
|
|
}
|
|
|
|
pNew->insertModel(AIJSON::w2utf(dlg.m_sModel).c_str());
|
|
pNew->setCurrentModel(AIJSON::w2utf(dlg.m_sModel).c_str());
|
|
|
|
m_clouds.push_back(pNew);
|
|
|
|
int idx = m_wndListCloud.InsertString(m_wndListCloud.GetCount(), utf2w(pNew->cloudName()).c_str());
|
|
if (idx != -1)
|
|
m_wndListCloud.SetItemData(idx, (DWORD_PTR)pNew);
|
|
|
|
writeAiCloudConfig(*pNew);
|
|
|
|
m_wndListCloud.SetCurSel(idx);
|
|
OnLbnSelchangeListCloud();
|
|
}
|
|
|
|
void CAICloudSettingDlg::OnBnClickedDel()
|
|
{
|
|
if (AfxMessageBox(_T("确定删除?"), MB_YESNO) != IDYES)
|
|
return;
|
|
|
|
int idx = m_wndListCloud.GetCurSel();
|
|
if (idx == -1) return;
|
|
|
|
AICloud *pCloud = (SHAI::AICloud*)m_wndListCloud.GetItemData(idx);
|
|
if (!pCloud) return;
|
|
|
|
if (!AICloud::IsCustomCloud(pCloud))
|
|
{
|
|
AfxMessageBox(_T("只可以删除自定义配置。"));
|
|
return;
|
|
}
|
|
|
|
std::vector<AICloud*>::iterator it = std::find_if(m_clouds.begin(), m_clouds.end(), AICloud::IS_EQUAL(pCloud));
|
|
if (it == m_clouds.end())
|
|
return;
|
|
|
|
m_clouds.erase(it);
|
|
|
|
deleteAICloudConfig(pCloud->cloudName().c_str());
|
|
|
|
m_wndListCloud.DeleteString(idx);
|
|
DELETE_PTR(pCloud);
|
|
|
|
int count = m_wndListCloud.GetCount();
|
|
if (count > 0)
|
|
{
|
|
m_pCurrentCloud = NULL;
|
|
m_wndListCloud.SetCurSel(0);
|
|
OnLbnSelchangeListCloud();
|
|
}
|
|
}
|
|
|
|
void CAICloudSettingDlg::OnLbnSelchangeListCloud()
|
|
{
|
|
// 保存上一个
|
|
if (m_pCurrentCloud)
|
|
{
|
|
saveCurrentCloud();
|
|
writeAiCloudConfig(*m_pCurrentCloud);
|
|
}
|
|
|
|
int idx = m_wndListCloud.GetCurSel();
|
|
m_pCurrentCloud = (SHAI::AICloud*)m_wndListCloud.GetItemData(idx);
|
|
|
|
m_sApiKey = utf2w(m_pCurrentCloud->apiKey()).c_str();
|
|
m_sApiEndPoint = utf2w(m_pCurrentCloud->endpoint()).c_str();
|
|
m_bCurrent = m_pCurrentCloud->currentSelect();
|
|
|
|
initModelsCombox();
|
|
|
|
UpdateData(FALSE);
|
|
|
|
}
|
|
|
|
void CAICloudSettingDlg::OnCbnSelchangeComboModel()
|
|
{
|
|
int idx(m_wndComboxModels.GetCurSel());
|
|
if (idx == -1) return;
|
|
CString str;
|
|
m_wndComboxModels.GetLBText(idx, str);
|
|
m_pCurrentCloud->setCurrentModel(w2utf(str).c_str());
|
|
}
|
|
|
|
void CAICloudSettingDlg::initModelsCombox()
|
|
{
|
|
m_pCurrentCloud->getModels();
|
|
m_wndComboxModels.ResetContent();
|
|
for (size_t i(0); i < m_pCurrentCloud->models().size(); i++)
|
|
{
|
|
m_wndComboxModels.AddString(utf2w(m_pCurrentCloud->models()[i]).c_str());
|
|
}
|
|
if (!m_pCurrentCloud->currentModel().empty())
|
|
{
|
|
if (m_wndComboxModels.GetCount() > 0)
|
|
{
|
|
m_iSelectModelIdx = m_wndComboxModels.FindString(0
|
|
, utf2w(m_pCurrentCloud->currentModel()).c_str());
|
|
if (m_iSelectModelIdx == -1)
|
|
m_iSelectModelIdx = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_wndComboxModels.GetCount() > 0)
|
|
m_iSelectModelIdx = 0;
|
|
}
|
|
}
|
|
|
|
void CAICloudSettingDlg::saveCurrentCloud()
|
|
{
|
|
if (!m_pCurrentCloud) return;
|
|
UpdateData(TRUE);
|
|
|
|
m_pCurrentCloud->setApiKey(w2utf(m_sApiKey).c_str());
|
|
m_pCurrentCloud->setEndpoint(w2utf(m_sApiEndPoint).c_str());
|
|
CString str;
|
|
m_wndComboxModels.GetWindowText(str);
|
|
m_pCurrentCloud->setCurrentModel(w2utf(str).c_str());
|
|
m_pCurrentCloud->setCurrentSelect(m_bCurrent == FALSE ? false : true);
|
|
|
|
if (m_bCurrent)
|
|
{
|
|
for (size_t i(0); i < m_clouds.size(); ++i)
|
|
{
|
|
if (m_pCurrentCloud == m_clouds[i])
|
|
continue;
|
|
m_clouds[i]->setCurrentSelect(false);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
bool CAICloudSettingDlg::getActiveAIClouds(AICloud *&pCloud)
|
|
{
|
|
std::vector<AICloud*> clouds;
|
|
readAllCloudConfig(clouds);
|
|
if (clouds.empty()) return false;
|
|
|
|
bool bRel(false);
|
|
for (size_t i(0); i < clouds.size(); ++i)
|
|
{
|
|
AICloud *p(clouds[i]);
|
|
if (p->currentSelect())
|
|
{
|
|
pCloud = AICloud::createCloud(p->cloudName().c_str());
|
|
if (pCloud)
|
|
{
|
|
pCloud->setCloudName(p->cloudName().c_str());
|
|
pCloud->setApiKey(p->apiKey().c_str());
|
|
pCloud->setEndpoint(p->endpoint().c_str());
|
|
pCloud->setCurrentModel(p->currentModel().c_str());
|
|
pCloud->setCurrentSelect(p->currentSelect());
|
|
pCloud->setModels(p->models());
|
|
bRel = true;
|
|
}
|
|
}
|
|
DELETE_PTR(p);
|
|
}
|
|
|
|
return bRel;
|
|
}
|
|
|