Skip to content

Commit 5c9f45d

Browse files
committed
Fix #76
1 parent 46dd39c commit 5c9f45d

8 files changed

+126
-95
lines changed

Dictionary.cpp

+82
Original file line numberDiff line numberDiff line change
@@ -584,3 +584,85 @@ void XgSelectDict(HWND hwnd, size_t iDict)
584584
xg_vMarkedCands.clear();
585585
xg_iMarkedCand = -1;
586586
}
587+
588+
// カギを使って辞書を更新する。
589+
BOOL XgUpdateDictionaryUsingClues(HWND hwnd, const XGStringW& dict_name)
590+
{
591+
// カギがなければ失敗。
592+
if (!xg_bSolved || xg_vecHorzHints.empty() || xg_vecVertHints.empty())
593+
return FALSE;
594+
595+
// 辞書名がなければ失敗。
596+
if (dict_name.empty())
597+
return FALSE;
598+
599+
// 単語からヒントへの写像を作成する。
600+
std::map<XGStringW, XGStringW> word_to_hint_map;
601+
for (auto& hint : xg_vecHorzHints) {
602+
word_to_hint_map[XgNormalizeString(hint.m_strWord)] = hint.m_strHint;
603+
}
604+
for (auto& hint : xg_vecVertHints) {
605+
word_to_hint_map[XgNormalizeString(hint.m_strWord)] = hint.m_strHint;
606+
}
607+
608+
// 辞書ファイルをすべて読み込む。
609+
XGStringW str;
610+
if (!XgReadTextFileAll(dict_name.c_str(), str))
611+
return FALSE;
612+
613+
// 改行コードを正規化。
614+
xg_str_replace_all(str, L"\r\n", L"\n");
615+
616+
// 行で分割する。
617+
std::vector<XGStringW> lines;
618+
mstr_split(lines, str, L"\n");
619+
620+
// 一行ずつ処理する。
621+
for (auto& line : lines) {
622+
if (line[0] == L'#')
623+
continue;
624+
625+
// タブで分割する。
626+
std::vector<XGStringW> fields;
627+
mstr_split(fields, line, L"\t");
628+
629+
if (fields.empty())
630+
continue;
631+
632+
auto strWord = XgNormalizeString(fields[0]);
633+
auto strNormalized = XgNormalizeString(strWord);
634+
635+
auto it = word_to_hint_map.find(strNormalized);
636+
if (it != word_to_hint_map.end()) {
637+
fields[1] = it->second;
638+
word_to_hint_map.erase(it);
639+
line = mstr_join(fields, L"\t");
640+
}
641+
}
642+
643+
for (auto& pair : word_to_hint_map) {
644+
XGStringW line = XgNormalizeStringEx(pair.first, TRUE, TRUE);
645+
line += L'\t';
646+
line += pair.second;
647+
line += L'\n';
648+
lines.push_back(line);
649+
}
650+
651+
// 辞書ファイルに書き込む。
652+
FILE *fp = _wfopen(dict_name.c_str(), L"w");
653+
if (!fp)
654+
return FALSE;
655+
656+
fprintf(fp, "\xEF\xBB\xBF"); // UTF-8 BOM
657+
658+
for (auto& line : lines) {
659+
auto psz = XgUnicodeToUtf8(line).c_str();
660+
if (!*psz)
661+
continue;
662+
fprintf(fp, "%s\n", psz);
663+
}
664+
665+
fclose(fp);
666+
667+
return TRUE;
668+
}

Dictionary.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,5 @@ BOOL XgLoadDictsAll(void);
217217
void XgSelectDict(HWND hwnd, size_t iDict);
218218
// 辞書からタイトルを取得。
219219
XGStringW XgLoadTitleFromDict(LPCWSTR pszPath);
220+
// カギを使って辞書を更新する。
221+
BOOL XgUpdateDictionaryUsingClues(HWND hwnd, const XGStringW& dict_name);

HISTORY.txt

+2
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@
321321
- Added a function to display the dictionary update date and time.
322322
- The "Jump" dialog has been made modeless.
323323
- Added "Jump to letter or word" function.
324+
- Added the function "Update the dictionary file using the clues" to the "Advanced" settings.
324325

325326
# 開発履歴 (Japanese)
326327

@@ -961,3 +962,4 @@
961962
- 辞書の更新日時を表示する機能を追加。
962963
- 「ジャンプ」ダイアログをモードレス化した。
963964
- 「文字または単語にジャンプ」機能を追加。
965+
- 「上級者向け」設定に「問題のカギを使って辞書ファイルを更新する」機能を追加。

XG_HiddenDialog.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class XG_HiddenDialog
2020
{
2121
case psh1: // PAT.txtに追加。
2222
if (codeNotify == BN_CLICKED) {
23+
HCURSOR hOldCursor = ::SetCursor(::LoadCursor(NULL, IDC_WAIT));
2324
if (XgPatEdit(hwnd, TRUE)) {
2425
// 成功メッセージ。
2526
XgCenterMessageBoxW(hwnd, XgLoadStringDx1(IDS_WROTEPAT),
@@ -29,10 +30,12 @@ class XG_HiddenDialog
2930
XgCenterMessageBoxW(hwnd, XgLoadStringDx1(IDS_CANTWRITEPAT),
3031
nullptr, MB_ICONERROR);
3132
}
33+
::SetCursor(hOldCursor);
3234
}
3335
break;
3436
case psh2: // PAT.txtから削除。
3537
if (codeNotify == BN_CLICKED) {
38+
HCURSOR hOldCursor = ::SetCursor(::LoadCursor(NULL, IDC_WAIT));
3639
if (XgPatEdit(hwnd, FALSE)) {
3740
// 成功メッセージ。
3841
XgCenterMessageBoxW(hwnd, XgLoadStringDx1(IDS_WROTEPAT),
@@ -42,6 +45,7 @@ class XG_HiddenDialog
4245
XgCenterMessageBoxW(hwnd, XgLoadStringDx1(IDS_CANTWRITEPAT),
4346
nullptr, MB_ICONERROR);
4447
}
48+
::SetCursor(hOldCursor);
4549
}
4650
break;
4751
case psh3: // アプリのフォルダを開く。
@@ -51,6 +55,26 @@ class XG_HiddenDialog
5155
PathRemoveFileSpecW(szPath);
5256
ShellExecuteW(hwnd, NULL, szPath, NULL, NULL, SW_SHOWNORMAL);
5357
}
58+
break;
59+
case psh4: // カギを使って辞書を更新する。
60+
if (codeNotify == BN_CLICKED) {
61+
WCHAR szText[MAX_PATH * 2];
62+
HCURSOR hOldCursor = ::SetCursor(::LoadCursor(NULL, IDC_WAIT));
63+
XG_HintsWnd::UpdateHintData(); // ヒントに変更があれば、更新する。
64+
if (XgUpdateDictionaryUsingClues(hwnd, xg_dict_name)) {
65+
// 成功メッセージ。
66+
StringCchPrintfW(szText, _countof(szText), XgLoadStringDx1(IDS_UPDATEDICTOK),
67+
PathFindFileNameW(xg_dict_name.c_str()));
68+
XgCenterMessageBoxW(hwnd, szText, XgLoadStringDx2(IDS_APPNAME), MB_ICONINFORMATION);
69+
} else {
70+
// 失敗メッセージ。
71+
StringCchPrintfW(szText, _countof(szText), XgLoadStringDx1(IDS_UPDATEDICTFAIL),
72+
PathFindFileNameW(xg_dict_name.c_str()));
73+
XgCenterMessageBoxW(hwnd, szText, nullptr, MB_ICONERROR);
74+
}
75+
::SetCursor(hOldCursor);
76+
}
77+
break;
5478
}
5579
}
5680

XG_HiddenDialog.hpp

-87
This file was deleted.

lang/en_US.rc

+7-4
Original file line numberDiff line numberDiff line change
@@ -1572,14 +1572,15 @@ FONT 9, "Tahoma"
15721572
PUSHBUTTON "&Theme...", psh5, 115, 175, 105, 20
15731573
}
15741574

1575-
IDD_HIDDEN DIALOG 0, 0, 275, 170
1575+
IDD_HIDDEN DIALOG 0, 0, 275, 220
15761576
CAPTION "Advanced"
15771577
STYLE DS_CENTER | DS_MODALFRAME | WS_POPUPWINDOW | WS_CAPTION
15781578
FONT 9, "Tahoma"
15791579
{
1580-
PUSHBUTTON "&Add the current pattern to PAT.txt", psh1, 40, 10, 185, 40
1581-
PUSHBUTTON "&Remove the current pattern from PAT.txt", psh2, 40, 60, 185, 40
1582-
PUSHBUTTON "&Open app folder", psh3, 40, 110, 185, 40
1580+
PUSHBUTTON "&Add the current pattern to PAT.txt", psh1, 40, 10, 185, 40, BS_MULTILINE
1581+
PUSHBUTTON "&Remove the current pattern from PAT.txt", psh2, 40, 60, 185, 40, BS_MULTILINE
1582+
PUSHBUTTON "&Open app folder", psh3, 40, 110, 185, 40, BS_MULTILINE
1583+
PUSHBUTTON "&Update the current dictionary using the clues of the current problem", psh4, 40, 160, 185, 40, BS_MULTILINE
15831584
}
15841585

15851586
//////////////////////////////////////////////////////////////////////////////
@@ -1828,6 +1829,8 @@ STRINGTABLE
18281829
IDS_FILENAME, "Filename"
18291830
IDS_DISPLAYNAME, "Display Name"
18301831
IDS_UPDATEDTIME, "Updated Time"
1832+
IDS_UPDATEDICTOK, "Successfully wrote to dictionary file ""%s""."
1833+
IDS_UPDATEDICTFAIL, "Failed to write to dictionary file ""%s"". The folder may not be writable."
18311834
IDS_TT_NEW, "New crossword"
18321835
IDS_TT_GENERATE, "Generate crossword"
18331836
IDS_TT_OPEN, "Open crossword"

lang/ja_JP.rc

+7-4
Original file line numberDiff line numberDiff line change
@@ -1576,14 +1576,15 @@ FONT 9, "MS UI Gothic"
15761576
PUSHBUTTON "テーマ(&T)...", psh5, 115, 175, 105, 20
15771577
}
15781578

1579-
IDD_HIDDEN DIALOG 0, 0, 275, 170
1579+
IDD_HIDDEN DIALOG 0, 0, 275, 220
15801580
CAPTION "上級者向け"
15811581
STYLE DS_CENTER | DS_MODALFRAME | WS_POPUPWINDOW | WS_CAPTION
15821582
FONT 9, "MS UI Gothic"
15831583
{
1584-
PUSHBUTTON "現在の黒マスパターンをPAT.txtに追加する(&A)", psh1, 40, 10, 185, 40
1585-
PUSHBUTTON "現在の黒マスパターンをPAT.txtから削除する(&D)", psh2, 40, 60, 185, 40
1586-
PUSHBUTTON "アプリのフォルダを開く(&O)", psh3, 40, 110, 185, 40
1584+
PUSHBUTTON "現在の黒マスパターンをPAT.txtに追加する(&A)", psh1, 40, 10, 185, 40, BS_MULTILINE
1585+
PUSHBUTTON "現在の黒マスパターンをPAT.txtから削除する(&D)", psh2, 40, 60, 185, 40, BS_MULTILINE
1586+
PUSHBUTTON "アプリのフォルダを開く(&O)", psh3, 40, 110, 185, 40, BS_MULTILINE
1587+
PUSHBUTTON "現在の問題のカギを使って現在の辞書を更新する(&U)", psh4, 40, 160, 185, 40, BS_MULTILINE
15871588
}
15881589

15891590
//////////////////////////////////////////////////////////////////////////////
@@ -1832,6 +1833,8 @@ STRINGTABLE
18321833
IDS_FILENAME, "ファイル名"
18331834
IDS_DISPLAYNAME, "表示名"
18341835
IDS_UPDATEDTIME, "更新日時"
1836+
IDS_UPDATEDICTOK, "辞書ファイル「%s」への書き込みに成功しました。"
1837+
IDS_UPDATEDICTFAIL, "辞書ファイル「%s」への書き込みに失敗しました。書き込めないフォルダの可能性があります。"
18351838
IDS_TT_NEW, "新規作成"
18361839
IDS_TT_GENERATE, "問題を自動生成する"
18371840
IDS_TT_OPEN, "問題を開く"

resource.h

+2
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@
255255
#define IDS_FILENAME 332
256256
#define IDS_DISPLAYNAME 333
257257
#define IDS_UPDATEDTIME 334
258+
#define IDS_UPDATEDICTOK 335
259+
#define IDS_UPDATEDICTFAIL 336
258260
#define IDS_TT_NEW 10100
259261
#define IDS_TT_GENERATE 10101
260262
#define IDS_TT_OPEN 10102

0 commit comments

Comments
 (0)