doc_and_tools/tools/apps/hgjson/CDlgLang.cpp

1096 lines
27 KiB
C++

// CDlgLang.cpp: 实现文件
//
#include "stdafx.h"
#include "hgjson.h"
#include "afxdialogex.h"
#include "CDlgLang.h"
#include "DlgInput.h"
#include "DlgAddWords.h"
#include <file/file_util.h>
#include <coding/coding.h>
#include <algorithm>
#include <map>
#define RESERVED_STR 600
namespace sdk_util
{
INTER_MODULE_CALLBACK(got_str)
{
*((std::string*)param) += std::string(data, len);
return inter_module_data::SET_RESULT_CONTINUE;
}
INTER_MODULE_CALLBACK(got_wstr)
{
*((std::wstring*)param) += std::wstring((const wchar_t*)data, len / 2);
return inter_module_data::SET_RESULT_CONTINUE;
}
uint32_t make_string_id(const wchar_t* str, bool(*is_repeat)(uint32_t, void*), void* param)
{
uint32_t crc = coding_util::crc_32(str, lstrlenW(str) * 2);
crc &= 0x0ffff;
if (crc <= RESERVED_STR)
crc = RESERVED_STR + 1;
while (is_repeat(crc, param))
crc++;
return crc;
}
void trim_left(std::wstring& str)
{
int i = 0;
while (str[i] == L' ' || str[i] == L'\t')
i++;
str.erase(0, i);
}
void trim_right(std::wstring& str)
{
int i = str.length() - 1;
while (i >= 0)
{
if (str[i] == L' ' || str[i] == L'\t')
i--;
else
break;
}
str.erase(i + 1);
}
unsigned pick_number(const wchar_t* str, const wchar_t** end, int type)
{
int off = 0;
unsigned val = 0;
if (type == coding_util::NUM_FMT_HEX)
{
for (; off < 4; ++off)
{
val <<= 4;
if (str[off] >= L'0' && str[off] <= L'9')
{
val += str[off] - L'0';
}
else if (str[off] >= L'a' && str[off] <= L'f')
{
val += str[off] - L'a' + 10;
}
else if (str[off] >= L'A' && str[off] <= L'A')
{
val += str[off] - L'A' + 10;
}
else
{
val >>= 4;
break;
}
}
}
else if (type == coding_util::NUM_FMT_OCT)
{
for (; off < 3; ++off)
{
val <<= 3;
if (str[off] >= L'0' && str[off] <= L'7')
{
val += str[off] - L'0';
}
else
{
val >>= 3;
break;
}
}
}
if (end)
*end = str + off;
return val;
}
void convert_unicode(std::wstring& str)
{
std::wstring conv(L"");
for (int i = 0; i < str.length(); ++i)
{
if (str[i] == L'\\')
{
const wchar_t* end = NULL;
if (str[i + 1] == L'u')
{
unsigned val = (unsigned)sdk_util::pick_number(str.c_str() + i + 2, &end, coding_util::NUM_FMT_HEX);
if (end - str.c_str() == i + 6)
{
conv.append(1, val);
i += 5;
continue;
}
}
else if (iswdigit(str[i + 1]))
{
char val[4] = { 0 };
val[0] = (char)sdk_util::pick_number(str.c_str() + i + 1, &end, coding_util::NUM_FMT_OCT);
if (end - str.c_str() == i + 4 && *end == L'\\' && iswdigit(end[1]))
{
val[1] = (char)sdk_util::pick_number(str.c_str() + i + 5, &end, coding_util::NUM_FMT_OCT);
if (end - str.c_str() == i + 8)
{
int off = 8;
if ((val[0] & 0x20) && *end == L'\\' && iswdigit(end[1]))
{
val[2] = (char)sdk_util::pick_number(str.c_str() + i + 9, &end, coding_util::NUM_FMT_OCT);
off += 4;
}
if (end - str.c_str() == i + off)
{
std::wstring oct(L"");
coding_util::utf8_2_unicode(val, got_wstr, &oct);
conv += oct;
i += off - 1;
continue;
}
}
}
}
}
conv.append(1, str[i]);
}
str = std::move(conv);
}
static LANGID g_reserve[] = { {1, 936, "\344\270\255\346\226\207\357\274\210\347\256\200\344\275\223\357\274\211"} // 中文(简体)
, {2, 950, "\344\270\255\346\226\207\357\274\210\347\271\201\344\275\223\357\274\211"} // 中文(繁体)
, {10, 20127, "\350\213\261\350\257\255"} // 英语
, {20, 855, "\344\277\204\350\257\255"} // 俄语
, {30, 863, "\346\263\225\350\257\255"} // 法语
, {40, 1141, "\345\276\267\350\257\255"} // 德语
, {50, 1144, "\346\204\217\345\244\247\345\210\251\350\257\255"} // 意大利语
, {60, 932, "\346\227\245\350\257\255"} // 日语
, {70, 949, "\351\237\251\346\226\207"} // 韩文
, {80, 1258, "\350\266\212\345\215\227\350\257\255"} // 越南语
};
LANGID* lang_info_from_cp(int cp)
{
for (auto& v : g_reserve)
{
if (v.cp == cp)
return &v;
}
return NULL;
}
LANGID* lang_info_from_ID(int id)
{
for (auto& v : g_reserve)
{
if (v.id == id)
return &v;
}
return NULL;
}
LANGID* lang_info_from_name(const char* utf8)
{
for (auto& v : g_reserve)
{
if (v.utf8 == utf8)
return &v;
}
return NULL;
}
int save_2_lang_pak(HWND owner, std::vector<LANGID>& items, int cp, std::string* raw_data, bool to_file)
{
uint32_t len = 0,
crc = 0,
ver = MAKELPARAM(0, 1),
cps[] = { cp, -1},
self_id = g_reserve[0].id,
off = sizeof(len) + sizeof(crc) + sizeof(ver) + sizeof(cps) + sizeof(self_id),
*ptr = NULL,
repeat = 0,
tmp = 0;
LANGID *info = lang_info_from_cp(cp);
std::string cont(""), str("");
std::vector<int> known;
if (!info)
return ERROR_NOT_SUPPORTED;
self_id = info->id;
#define APPEND_INT(str, n) \
str += std::string((char*)&n, sizeof(n))
#define APPEND_ARRAY(str, n) \
str += std::string((char*)n, sizeof(n))
APPEND_INT(cont, len);
APPEND_INT(cont, crc);
APPEND_INT(cont, ver);
APPEND_ARRAY(cont, cps);
APPEND_INT(cont, self_id);
cont += std::string(info->utf8.c_str(), info->utf8.length() + 1);
if (cont.length() % 16)
cont.append(16 - (cont.length() % 16), '\0'); // ENDING address align 16 before
len = cont.length();
off = (items.size() + _countof(g_reserve) + 1) * sizeof(len) * 2;
for (const auto& v : g_reserve)
{
APPEND_INT(cont, v.id);
APPEND_INT(cont, off);
std::vector<LANGID>::iterator it = std::find(items.begin(), items.end(), v.id);
if (it == items.end())
{
str += std::string(v.utf8.c_str(), v.utf8.length() + 1);
off += v.utf8.length() + 1;
}
else
{
str += std::string(it->utf8.c_str(), it->utf8.length() + 1);
off += it->utf8.length() + 1;
}
known.push_back(v.id);
}
for (const auto& v : items)
{
if (std::find(known.begin(), known.end(), v.id) == known.end())
{
APPEND_INT(cont, v.id);
APPEND_INT(cont, off);
str += std::string(v.utf8.c_str(), v.utf8.length() + 1);
off += v.utf8.length() + 1;
}
else
repeat++;
}
len = -1;
APPEND_INT(cont, len);
APPEND_INT(cont, len);
for (int i = 0; i < repeat; ++i)
{
APPEND_INT(cont, len);
APPEND_INT(cont, len);
}
cont += std::string(str.c_str(), str.length());
ptr = (uint32_t*)&cont[0];
*ptr++ = cont.length();
*ptr = coding_util::crc_32((const void*)(ptr + 1), cont.length() - 8);
file_util::PATHFILE file = { 0 };
tmp = 0;
if (to_file && file_util::browser_file(owner, &file, L"Language pack(*.pak)\0\0", false))
{
tmp = file_util::save_2_file(cont.c_str(), cont.length(), file.path);
}
if (raw_data)
*raw_data = std::move(cont);
return tmp;
}
bool parse_pak_digest(uint8_t* data, int* id)
{
uint32_t ver = *(uint32_t*)data,
val = 0,
name_id = 0,
* cps = (uint32_t*)(data + sizeof(uint32_t) * 3);
std::vector<uint32_t> code_pages;
std::wstring name(L"");
if (id)
*id = *cps;
while (*cps != -1)
{
code_pages.push_back(*cps++);
}
if (code_pages.empty())
return false;
cps++;
name_id = *cps++;
val = (uint8_t*)cps - data;
coding_util::utf8_2_unicode((char*)data + val, got_wstr, &name);
return name.length() ? true : false;
}
bool parse_pak(uint8_t* data, std::vector<LANGIDW>& items)
{
uint32_t ver = *(uint32_t*)data,
val = 0,
* cps = (uint32_t*)(data + sizeof(uint32_t) * 3);
while (*cps++ != -1);
cps++;
val = (uint8_t*)cps - data;
val += strlen((char*)data + val) + 1;
val += 15;
val /= 16;
val *= 16;
struct
{
uint32_t id;
uint32_t off;
}*go = nullptr;
*((void**)&go) = (void*)(data + val);
while (go->id != -1)
{
LANGIDW l;
l.id = go->id;
coding_util::utf8_2_unicode((char*)data + go->off + val, got_wstr, &l.unic);
items.push_back(l);
go++;
}
return true;
}
bool load_lang_pak(const wchar_t* file, std::vector<LANGIDW>& items, int* id)
{
std::string cont(""), name("");
bool ret = false;
FILE* src = _wfopen(file, L"rb");
if (src)
{
int len = 0;
uint8_t* buf = nullptr;
fseek(src, 0, SEEK_END);
len = ftell(src);
fseek(src, 0, SEEK_SET);
if (len)
{
buf = new uint8_t[len + 4];
if (buf)
{
memset(buf, 0, len + 4);
len = fread(buf, 1, len, src);
if (len == *(uint32_t*)buf && coding_util::crc_32(buf + sizeof(uint32_t) * 2, len - sizeof(uint32_t) * 2) == ((uint32_t*)buf)[1])
{
cont = std::string((char*)buf, len);
}
delete[] buf;
}
}
fclose(src);
}
if (cont.length())
{
parse_pak_digest((uint8_t*)&cont[0], id);
ret = parse_pak((uint8_t*)&cont[0], items);
}
return ret;
}
std::wstring get_wnd_text(HWND wnd)
{
int l = GetWindowTextLengthW(wnd);
wchar_t* buf = new wchar_t[l + 4];
std::wstring ret(L"");
l = GetWindowTextW(wnd, buf, l + 1);
buf[l] = 0;
ret = buf;
delete[] buf;
return std::move(ret);
}
std::wstring get_wnd_text(HWND dlg, UINT id)
{
return get_wnd_text(GetDlgItem(dlg, id));
}
std::wstring load_file(const wchar_t* file, int* bom)
{
std::string raw("");
std::wstring unic(L"");
file_util::load_file(file, got_str, &raw);
if (bom)
{
if (coding_util::bom::is_unicode(raw.c_str(), NULL))
*bom = BOM_UNICODE;
else if (coding_util::bom::is_utf8(raw.c_str()))
*bom = BOM_UTF8;
else
*bom = BOM_ANSI;
}
coding_util::bom::to_unicode(raw.c_str(), raw.length(), got_wstr, &unic);
return std::move(unic);
}
int save_file(const wchar_t* file, std::wstring& cont, int bom)
{
if (bom == BOM_UTF8)
{
std::string raw(""), bomd("");
coding_util::unicode_2_utf8(cont.c_str(), got_str, &raw);
coding_util::bom::from_utf8(raw.c_str(), raw.length(), got_str, &bomd);
return file_util::save_2_file(bomd.c_str(), bomd.length(), file);
}
else if (bom == BOM_UNICODE)
{
std::string raw("");
coding_util::bom::from_unicode(cont.c_str(), cont.length() * 2, got_str, &raw);
return file_util::save_2_file(raw.c_str(), raw.length(), file);
}
else
{
std::string raw("");
coding_util::unicode_2_ansi(cont.c_str(), got_str, &raw);
return file_util::save_2_file(raw.c_str(), raw.length(), file);
}
}
}
// CDlgLang 对话框
IMPLEMENT_DYNAMIC(CDlgLang, CDialogEx)
CDlgLang::CDlgLang(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_LANGUAGE, pParent)
, cur_cp_(936)
{
std::vector<sdk_util::LANGIDW> langs;
//sdk_util::load_lang_pak(L"D:\\boxroom\\Dingding\\chinese.pak", langs);
langs.clear();
}
CDlgLang::~CDlgLang()
{
}
void CDlgLang::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_COMBO1, lang_);
DDX_Control(pDX, IDC_LIST1, list_);
}
BOOL CDlgLang::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
int ind = 0;
list_.InsertColumn(ind++, TEXT("No."), 0, 48);
list_.InsertColumn(ind++, TEXT("ID"), 0, 60);
list_.InsertColumn(ind++, TEXT("Text"), 0, 350);
list_.SetExtendedStyle(list_.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP);
list_.ModifyStyle(0, LVS_SINGLESEL);
for (const auto& v : sdk_util::g_reserve)
{
std::wstring unic(L"");
coding_util::utf8_2_unicode(v.utf8.c_str(), sdk_util::got_wstr, &unic);
ind = lang_.AddString(unic.c_str());
lang_.SetItemData(ind, (DWORD_PTR)v.cp);
}
select_code_page(936);
return TRUE; // return TRUE unless you set the focus to a control
}
bool CDlgLang::select_code_page(int cp)
{
bool found = false;
for (int i = 0; i < lang_.GetCount(); ++i)
{
if ((int)lang_.GetItemData(i) == cp)
{
lang_.SetCurSel(i);
found = true;
break;
}
}
return found;
}
void CDlgLang::add_2_list(void* lang_list, int id, bool unic)
{
if (unic)
{
std::vector<sdk_util::LANGIDW>* data = (std::vector<sdk_util::LANGIDW>*)lang_list;
for (const auto& v : *data)
{
std::wstring text(L"");
int ind = find_list_item_by_ID(v.id);
if (ind == -1)
{
ind = list_.InsertItem(list_.GetItemCount(), std::to_wstring(list_.GetItemCount() + 1).c_str());
list_.SetItemText(ind, 1, std::to_wstring(v.id).c_str());
}
list_.SetItemText(ind, 2, v.unic.c_str());
}
}
else
{
std::vector<sdk_util::LANGID>* data = (std::vector<sdk_util::LANGID>*)lang_list;
for (const auto& v : *data)
{
std::wstring text(L"");
int ind = find_list_item_by_ID(v.id);
if (ind == -1)
{
ind = list_.InsertItem(list_.GetItemCount(), std::to_wstring(list_.GetItemCount() + 1).c_str());
list_.SetItemText(ind, 1, std::to_wstring(v.id).c_str());
}
coding_util::utf8_2_unicode(v.utf8.c_str(), sdk_util::got_wstr, &text);
list_.SetItemText(ind, 2, text.c_str());
}
}
}
int CDlgLang::insert_item_2_list(const wchar_t* str, uint32_t id)
{
int item = 0;
bool ok = false;
wchar_t buf[40] = { 0 };
for (; item < list_.GetItemCount(); ++item)
{
list_.GetItemText(item, 1, buf, _countof(buf) - 1);
if (_wtoi(buf) > id)
{
item = list_.InsertItem(item, std::to_wstring(item + 1).c_str());
ok = true;
break;
}
}
if (ok)
{
for (int i = item + 1; i < list_.GetItemCount(); ++i)
list_.SetItemText(i, 0, std::to_wstring(i + 1).c_str());
}
else
item = list_.InsertItem(list_.GetItemCount(), std::to_wstring(list_.GetItemCount() + 1).c_str());
list_.SetItemText(item, 1, std::to_wstring(id).c_str());
list_.SetItemText(item, 2, str);
list_.EnsureVisible(item, FALSE);
list_.SetItemState(item, LVNI_FOCUSED | LVIS_SELECTED, LVNI_FOCUSED | LVIS_SELECTED);
GotoDlgCtrl(&list_);
return item;
}
int CDlgLang::find_hz_ID(const wchar_t* hz)
{
for (const auto& v : hz_)
{
if (v.hz == hz)
return v.id;
}
return -1;
}
int CDlgLang::find_list_item_by_ID(int id)
{
for (int i = 0; i < list_.GetItemCount(); ++i)
{
TCHAR val[40] = { 0 };
list_.GetItemText(i, 1, val, _countof(val) - 1);
if (_ttoi(val) == id)
return i;
}
return -1;
}
void CDlgLang::on_hz_pak_initialized(bool success)
{
lang_.EnableWindow(success);
list_.EnableWindow(success);
GetDlgItem(IDC_BUTTON_SAVE)->EnableWindow(success);
GetDlgItem(IDC_BUTTON_SAVE_EXPORT)->EnableWindow(success);
GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(cur_cp_ == 936);
GetDlgItem(IDC_BUTTON_ADD_FILE)->EnableWindow(cur_cp_ == 936);
}
bool CDlgLang::find_repeat_in_vector(uint32_t val, void* param)
{
std::vector<int>* vec = (std::vector<int>*)param;
return std::find(vec->begin(), vec->end(), val) != vec->end();
}
bool CDlgLang::find_repeat_in_list(uint32_t val, void* param)
{
CListCtrl* lst = (CListCtrl*)param;
wchar_t buf[40] = { 0 };
for (int i = 0; i < lst->GetItemCount(); ++i)
{
lst->GetItemText(i, 1, buf, _countof(buf) - 1);
if (_wtoi(buf) == val)
return true;
}
return false;
}
BEGIN_MESSAGE_MAP(CDlgLang, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON_INIT_ID, &CDlgLang::OnBnClickedButtonInitId)
ON_CBN_SELCHANGE(IDC_COMBO1, &CDlgLang::OnCbnSelchangeLanguage)
ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CDlgLang::OnNMDblclkList1)
ON_BN_CLICKED(IDC_BUTTON_SAVE, &CDlgLang::OnBnClickedButtonSave)
ON_BN_CLICKED(IDC_BUTTON_ADD, &CDlgLang::OnBnClickedButtonAdd)
ON_BN_CLICKED(IDC_BUTTON_ADD_FILE, &CDlgLang::OnBnClickedButtonAddFile)
ON_BN_CLICKED(IDC_BUTTON_SAVE_EXPORT, &CDlgLang::OnBnClickedButtonSaveExport)
ON_BN_CLICKED(IDC_BUTTON_BATCH_ADD, &CDlgLang::OnBnClickedButtonBatchAdd)
END_MESSAGE_MAP()
// CDlgLang 消息处理程序
void CDlgLang::OnBnClickedButtonInitId()
{
// TODO: 在此添加控件通知处理程序代码
file_util::PATHFILE file = { 0 };
std::vector<sdk_util::LANGID> items;
if (file_util::browser_file(m_hWnd, &file, L"Language Pack (*.pak)\0All Files (*.*)\0\0"))
{
hz_.clear();
{
file_util::PATHFILE ext = { 0 };
file_util::file_extension(file.path, &ext);
if (wcsicmp(ext.path, L"pak") == 0)
{
std::vector<sdk_util::LANGIDW> lans;
int id = 0;
sdk_util::load_lang_pak(file.path, lans, &id);
if (id != 936)
{
::MessageBoxW(m_hWnd, L"\u8BF7\u9009\u62E9\u201C\u4E2D\u6587\uFF08\u7B80\u4F53\uFF09\u201D\u7684\u8BED\u8A00\u5305\u4F5C\u4E3A\u521D\u59CB\u5316\u8BED\u8A00\u5305\uFF01", L"\u91CD\u65B0\u9009\u62E9", MB_OK | MB_ICONINFORMATION);
return;
}
cur_cp_ = id;
for (auto& v : lans)
{
HZMAP hm;
hm.id = v.id;
hm.hz = v.unic;
hz_.push_back(hm);
}
list_.DeleteAllItems();
add_2_list(&lans, cur_cp_, true);
select_code_page(cur_cp_);
on_hz_pak_initialized(true);
return;
}
}
std::string bom(""), utf8("");
std::wstring cont(L""), line(L""), save(L"");
size_t pos = -1;
int cur = 0, next = 0;
std::vector<int> ids;
file_util::load_file(file.path, sdk_util::got_str, &bom);
coding_util::bom::to_unicode(bom.c_str(), bom.length(), sdk_util::got_wstr, &cont);
bom.clear();
coding_util::pick_line(cont.c_str(), sdk_util::got_wstr, &line, &next);
while (next || !line.empty())
{
std::wstring cpy(line + L"\r\n");
if (!line.empty())
{
sdk_util::trim_left(line);
pos = line.find(L"//");
if (pos)
{
pos = line.find(L"#define");
if (pos == 0)
{
line.erase(0, 7);
sdk_util::trim_left(line);
pos = line.find(L" ");
if(pos == std::wstring::npos)
pos = line.find(L"\t");
if (pos != std::wstring::npos)
{
std::wstring name = line.substr(0, pos);
line.erase(0, pos + 1);
sdk_util::trim_left(line);
if (line[0] == L'\"')
{
int bgn = 0, end = 0;
if (coding_util::pick_value(line.c_str(), L"\"", L"\"", &bgn, &end))
{
line.erase(end + 1);
line.erase(0, bgn);
cpy.insert(0, L"// ");
sdk_util::convert_unicode(line);
bgn = sdk_util::make_string_id(line.c_str(), &CDlgLang::find_repeat_in_vector, &ids);
ids.push_back(bgn);
cpy += L"#define ID_" + name + L" " + std::to_wstring(bgn) + L"\r\n\r\n";
sdk_util::LANGID li;
li.id = bgn;
coding_util::unicode_2_utf8(line.c_str(), sdk_util::got_str, &li.utf8);
items.push_back(li);
HZMAP hm;
hm.id = li.id;
hm.hz = line;
hz_.push_back(hm);
}
}
}
}
}
}
save += cpy;
cur += next;
line.clear();
coding_util::pick_line(cont.c_str() + cur, sdk_util::got_wstr, &line, &next);
}
coding_util::unicode_2_utf8(save.c_str(), sdk_util::got_str, &utf8);
save.clear();
coding_util::bom::from_utf8(utf8.c_str(), utf8.length(), sdk_util::got_str, &bom);
utf8.clear();
file_util::save_2_file(bom.c_str(), bom.length(), file.path);
std::sort(items.begin(), items.end());
list_.DeleteAllItems();
cur_cp_ = 936;
add_2_list(&items, cur_cp_, false);
select_code_page(cur_cp_);
on_hz_pak_initialized(true);
//sdk_util::save_2_lang_pak(m_hWnd, items);
}
}
void CDlgLang::OnCbnSelchangeLanguage()
{
file_util::PATHFILE file = { 0 };
int lang_cp = (int)lang_.GetItemData(lang_.GetCurSel());
if (file_util::browser_file(m_hWnd, &file))
{
{
file_util::PATHFILE ext = { 0 };
file_util::file_extension(file.path, &ext);
if (wcsicmp(ext.path, L"pak") == 0)
{
std::vector<sdk_util::LANGIDW> lans;
int cp = 0;
sdk_util::load_lang_pak(file.path, lans, &cp);
if (cp != lang_cp)
{
sdk_util::LANGID* inf = sdk_util::lang_info_from_cp(lang_cp);
std::wstring unic(L"");
coding_util::utf8_2_unicode(inf->utf8.c_str(), sdk_util::got_wstr, &unic);
unic.insert(0, L"\u8BF7\u9009\u62E9\u201C");
unic += L"\u201D\u8BED\u8A00\u5305\uFF01";
::MessageBoxW(m_hWnd, unic.c_str(), L"Error", MB_OK | MB_ICONSTOP);
select_code_page(cur_cp_);
GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(cur_cp_ == 936);
GetDlgItem(IDC_BUTTON_ADD_FILE)->EnableWindow(cur_cp_ == 936);
return;
}
// list_.DeleteAllItems();
cur_cp_ = cp;
add_2_list(&lans, cur_cp_, true);
select_code_page(cur_cp_);
GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(cur_cp_ == 936);
GetDlgItem(IDC_BUTTON_ADD_FILE)->EnableWindow(cur_cp_ == 936);
return;
}
}
::MessageBoxW(m_hWnd, L"\u7EAF\u6587\u672C\u7FFB\u8BD1\u5BF9\u7167\uFF0C\u8BF7\u4EE5\u4E2D\u6587\uFF08\u7B80\u4F53\uFF09\u8BED\u8A00\u5728\u7B2C\u4E00\u5217\uFF08\u5982\u6709\u7A7A\u683C\u8BF7\u52A0\u82F1\u6587\u53CC\u5F15\u53F7\uFF09\uFF0C\u5176\u5B83\u8BED\u8A00\u4E3A\u7A7A\u683C\u4EE5\u540E\u7684\u7B2C\u4E8C\u5217\u3002", L"\u63D0\u793A", MB_OK | MB_ICONINFORMATION);
std::string bom("");
std::wstring cont(L""), line(L""), hz(L""), lan(L"");
size_t pos = -1;
int cur = 1, next = -1;
std::vector<int> ids;
std::map<std::wstring, std::wstring> lost;
cur_cp_ = lang_cp;
file_util::load_file(file.path, sdk_util::got_str, &bom);
coding_util::bom::to_unicode(bom.c_str(), bom.length(), sdk_util::got_wstr, &cont);
bom.clear();
while (next || !line.empty())
{
cur += next;
line.clear();
coding_util::pick_line(cont.c_str() + cur, sdk_util::got_wstr, &line, &next);
if (line.empty())
continue;
sdk_util::trim_left(line);
if (line.empty())
continue;
if (line[0] == L'\"')
{
int bgn = 0, end = 0;
coding_util::pick_value(line.c_str(), L"\"", L"\"", &bgn, &end);
if (end <= bgn)
continue;
hz = line.substr(bgn, end - bgn + 1);
line.erase(0, end + 2);
}
else
{
pos = line.find(L" ");
if (pos > line.find(L"\t"))
pos = line.find(L"\t");
if (pos == std::wstring::npos)
continue;
hz = line.substr(0, pos);
line.erase(0, pos + 1);
}
sdk_util::trim_left(line);
if (line.empty())
continue;
lan = line;
int id = find_hz_ID(hz.c_str()),
item = id == -1 ? -1 : find_list_item_by_ID(id);
if (item == -1)
lost[hz] = lan;
else
list_.SetItemText(item, 2, lan.c_str());
}
cont.clear();
if (lost.size())
{
for (auto& v : lost)
cont += L" " + v.first + L" <---> " + v.second + L"\r\n";
file_util::set_clipboard(cont.c_str(), cont.length() * 2, CF_UNICODETEXT);
cont.insert(0, L"下列语言条目,没有找到中文原版,请在中文(简体)语言包中补充完整(内容已经拷贝到剪贴板):\r\n");
::MessageBoxW(m_hWnd, cont.c_str(), L"Lost", MB_OK | MB_ICONERROR);
}
}
else if (lang_cp == 936)
{
cur_cp_ = lang_cp;
list_.DeleteAllItems();
lang_cp = 1;
for (const auto& v : hz_)
{
int item = list_.InsertItem(list_.GetItemCount(), std::to_wstring(lang_cp++).c_str());
list_.SetItemText(item, 1, std::to_wstring(v.id).c_str());
list_.SetItemText(item, 2, v.hz.c_str());
}
}
else
{
select_code_page(cur_cp_);
}
GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(cur_cp_ == 936);
GetDlgItem(IDC_BUTTON_ADD_FILE)->EnableWindow(cur_cp_ == 936);
}
void CDlgLang::OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
*pResult = 0;
// TODO: 在此添加控件通知处理程序代码
POINT pos = { 0 };
int item = -1;
GetCursorPos(&pos);
list_.ScreenToClient(&pos);
item = list_.HitTest(pos);
if (item != -1)
{
int size = 4 * 1024;
wchar_t* buf = new wchar_t[size];
CDlgInput dlg;
memset(buf, 0, size * sizeof(buf[0]));
list_.GetItemText(item, 2, buf, size - 1);
dlg.value_ = buf;
dlg.type_ = CDlgInput::INPUT_FOR_STRING;
delete[] buf;
if (dlg.DoModal() == IDOK)
{
list_.SetItemText(item, 2, dlg.value_);
}
}
}
void CDlgLang::OnBnClickedButtonSave()
{
// TODO: 在此添加控件通知处理程序代码
std::vector<sdk_util::LANGID> items;
int cp = (int)lang_.GetItemData(lang_.GetCurSel()), size = 1024;
wchar_t* buf = new wchar_t[size];
memset(buf, 0, size * sizeof(buf[0]));
for (int i = 0; i < list_.GetItemCount(); ++i)
{
sdk_util::LANGID lan;
list_.GetItemText(i, 1, buf, size - 1);
lan.id = _wtoi(buf);
list_.GetItemText(i, 2, buf, size - 1);
coding_util::unicode_2_utf8(buf, sdk_util::got_str, &lan.utf8);
lan.cp = cp;
items.push_back(std::move(lan));
}
delete[] buf;
if (items.empty())
{
MessageBox(TEXT("No items need save"));
return;
}
if (sdk_util::save_2_lang_pak(m_hWnd, items, cp))
::MessageBoxW(m_hWnd, L"\u8BF7\u68C0\u67E5\u8DEF\u5F84\u53CA\u6743\u9650\u662F\u5426\u6B63\u5E38?", L"\u4FDD\u5B58\u5931\u8D25", MB_OK);
}
void CDlgLang::OnBnClickedButtonAdd()
{
// TODO: 在此添加控件通知处理程序代码
CDlgInput dlg;
dlg.type_ = CDlgInput::INPUT_FOR_STRING;
if (dlg.DoModal() == IDOK)
{
HZMAP h;
h.hz = dlg.value_.GetBuffer();
dlg.value_.ReleaseBuffer();
h.id = find_hz_ID(h.hz.c_str());
if (h.id == -1)
{
h.id = sdk_util::make_string_id(h.hz.c_str(), &CDlgLang::find_repeat_in_list, &list_);
insert_item_2_list(h.hz.c_str(), h.id);
hz_.push_back(h);
}
else
{
MessageBox(TEXT("Existing already."));
h.id = find_list_item_by_ID(h.id);
list_.EnsureVisible(h.id, FALSE);
list_.SetItemState(h.id, LVNI_FOCUSED | LVIS_SELECTED, LVNI_FOCUSED | LVIS_SELECTED);
GotoDlgCtrl(&list_);
}
}
}
void CDlgLang::OnBnClickedButtonAddFile()
{
// TODO: 在此添加控件通知处理程序代码
file_util::PATHFILE file = { 0 };
if (file_util::browser_file(m_hWnd, &file, L"Text File(*.txt)\0\0"))
{
std::string bom("");
std::wstring unic(L""), line(L"");
int id = 0, next = 0, same = 0, added = 0, off = 0;
file_util::load_file(file.path, sdk_util::got_str, &bom);
coding_util::bom::to_unicode(bom.c_str(), bom.length(), sdk_util::got_wstr, &unic);
bom.clear();
coding_util::pick_line(unic.c_str(), sdk_util::got_wstr, &line, &next);
while (next)
{
if (!line.empty())
{
id = find_hz_ID(line.c_str());
if (id == -1)
{
HZMAP h;
h.hz = std::move(line);
h.id = sdk_util::make_string_id(h.hz.c_str(), &CDlgLang::find_repeat_in_list, &list_);
insert_item_2_list(h.hz.c_str(), h.id);
hz_.push_back(h);
added++;
}
else
{
same++;
}
}
off += next;
line = L"";
coding_util::pick_line(unic.c_str() + off, sdk_util::got_wstr, &line, &next);
}
::MessageBoxW(m_hWnd, (std::wstring(L"新增加 ") + std::to_wstring(added) + L" 个词条,有" + std::to_wstring(same) + L" 个词条重复。").c_str(), L"OK", MB_OK);
}
}
void CDlgLang::OnBnClickedButtonSaveExport()
{
// TODO: 在此添加控件通知处理程序代码
if (list_.GetItemCount())
{
std::wstring text(L"");
for (int i = 0; i < list_.GetItemCount(); ++i)
{
TCHAR buf[512] = { 0 };
std::wstring l(L"");
list_.GetItemText(i, 1, buf, _countof(buf) - 1);
l = buf;
if (l.length() < 5)
l.insert(0, 5 - l.length(), L' ');
l += L"\t\t";
text += l;
list_.GetItemText(i, 2, buf, _countof(buf) - 1);
text += buf;
text += L"\r\n";
}
file_util::set_clipboard(text.c_str(), text.length() * 2, CF_UNICODETEXT);
::MessageBoxW(m_hWnd, L"文本内容已经拷贝到剪贴板", L"Ok", MB_OK);
}
}
void CDlgLang::OnBnClickedButtonBatchAdd()
{
// TODO: 在此添加控件通知处理程序代码
CDlgAddWords dlg;
dlg.DoModal();
}