diff --git a/GUI.cpp b/GUI.cpp index 5968636..8ecbea8 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -4574,6 +4574,7 @@ enum I_SYNCED_APPEARANCE, I_SYNCED_RULES, I_SYNCED_GENERATIVE, + I_SYNCED_DICTLIST, I_SYNCED_MAX }; @@ -4586,6 +4587,7 @@ HWND xg_ahSyncedDialogs[I_SYNCED_MAX] = { 0 }; #include "XG_SettingsDialog.cpp" #include "XG_RulePresetDialog.cpp" #include "XgGenerative.cpp" +#include "XgDictList.cpp" // 全般設定。 void XgGeneralSettings(HWND hwnd, INT nStartPage = I_SYNCED_FILE_SETTINGS) @@ -4639,6 +4641,14 @@ void XgGeneralSettings(HWND hwnd, INT nStartPage = I_SYNCED_FILE_SETTINGS) psp.lParam = 0; hpsp[iPage++] = ::CreatePropertySheetPageW(&psp); + // 「辞書」設定。 + psp.pszTemplate = MAKEINTRESOURCEW(IDD_DICTLIST); + psp.pfnDlgProc = XgDictListDlgProc; + psp.dwFlags = PSP_DEFAULT; + psp.hInstance = xg_hInstance; + psp.lParam = 0; + hpsp[iPage++] = ::CreatePropertySheetPageW(&psp); + assert(iPage <= _countof(hpsp)); assert(nStartPage < _countof(hpsp)); diff --git a/HISTORY.txt b/HISTORY.txt index 487f21f..40a535b 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -305,6 +305,7 @@ - The save destination setting is reflected in "Open" and "Save As". - Fixed QString string comparison. - Made "Generated" and "Canceled" display options. + - Added "Generative" and "Dictionaries" settings. # 開発履歴 (Japanese) @@ -926,3 +927,4 @@ - 保存先設定を「開く」や「名前を付けて保存」に反映。 - QStringの文字列比較を修正。 - 「生成しました」「キャンセルしました」の表示をオプションに。 + - 「生成」設定と「辞書」設定を追加。 diff --git a/XgDictList.cpp b/XgDictList.cpp new file mode 100644 index 0000000..5a95f0e --- /dev/null +++ b/XgDictList.cpp @@ -0,0 +1,268 @@ +// リストを再読み込みする。 +void XgDictList_ReloadList(HWND hwnd) +{ + HWND hwndLst1 = GetDlgItem(hwnd, lst1); + + // すべての項目を消去する。 + ListView_DeleteAllItems(hwndLst1); + SendDlgItemMessageW(hwnd, cmb1, CB_RESETCONTENT, 0, 0); + + // リストビューを埋める。 + INT iItem = 0; + for (auto& entry : xg_dicts) { + LV_ITEMW item = { LVIF_TEXT }; + item.pszText = const_cast(PathFindFileNameW(entry.m_filename.c_str())); + item.iItem = iItem; + item.iSubItem = 0; + ListView_InsertItem(hwndLst1, &item); + item.iItem = iItem; + item.iSubItem = 1; + item.pszText = const_cast(entry.m_friendly_name.c_str()); + ListView_SetItem(hwndLst1, &item); + ++iItem; + } + + // コンボボックスを埋める。 + for (auto& item : xg_dicts) { + LPCWSTR pszText = PathFindFileNameW(item.m_filename.c_str()); + ::SendDlgItemMessageW(hwnd, cmb1, CB_ADDSTRING, 0, (LPARAM)pszText); + } + + // コンボボックスの項目を選択する。 + { + LPCWSTR pszText = PathFindFileNameW(xg_dict_name.c_str()); + INT iItem = ::SendDlgItemMessageW(hwnd, cmb1, CB_FINDSTRINGEXACT, -1, (LPARAM)pszText); + if (iItem != CB_ERR) { + ::SendDlgItemMessageW(hwnd, cmb1, CB_SETCURSEL, iItem, 0); + } + } + + // リストビューの項目を選択する。 + LV_FINDINFO Find = { LVFI_STRING, PathFindFileNameW(xg_dict_name.c_str()) }; + iItem = ListView_FindItem(hwndLst1, -1, &Find); + ListView_SetItemState(hwndLst1, iItem, INDEXTOSTATEIMAGEMASK(2), LVIS_STATEIMAGEMASK); + ListView_EnsureVisible(hwndLst1, iItem, FALSE); +} + +// リストビューのチェック位置を取得する。 +INT XgDictList_GetCurSel(HWND hwnd, HWND hwndLst1) +{ + INT cItems = ListView_GetItemCount(hwndLst1); + for (INT iItem = 0; iItem < cItems; ++iItem) { + UINT uState = ListView_GetItemState(hwndLst1, iItem, LVIS_STATEIMAGEMASK); + if (uState & INDEXTOSTATEIMAGEMASK(2)) + return iItem; + } + return -1; +} + +// リストビューのチェック情報を更新する。 +void XgDictList_SetCurSel(HWND hwnd, HWND hwndLst1, INT iSelect) +{ + INT cItems = ListView_GetItemCount(hwndLst1); + for (INT iItem = 0; iItem < cItems; ++iItem) { + if (iItem == iSelect) { + ListView_SetItemState(hwndLst1, iItem, INDEXTOSTATEIMAGEMASK(2), LVIS_STATEIMAGEMASK); + } else { + ListView_SetItemState(hwndLst1, iItem, INDEXTOSTATEIMAGEMASK(1), LVIS_STATEIMAGEMASK); + } + } + + ListView_SetItemState(hwndLst1, iSelect, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + ListView_EnsureVisible(hwndLst1, iSelect, FALSE); +} + +// [辞書]設定。 +INT_PTR CALLBACK +XgDictListDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static INT m_bUpdating = 0; + HWND hwndLst1 = GetDlgItem(hwnd, lst1); + + switch (uMsg) + { + case WM_INITDIALOG: + { + xg_ahSyncedDialogs[I_SYNCED_DICTLIST] = hwnd; + + // 拡張リストビュースタイルを設定。 + ListView_SetExtendedListViewStyle(hwndLst1, + LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES); + + // 辞書リストのヘッダーを初期化。 + LV_COLUMNW column = { LVCF_TEXT | LVCF_WIDTH }; + column.pszText = const_cast(L"Filename"); + column.cx = 200; + ListView_InsertColumn(hwndLst1, 0, &column); + column.pszText = const_cast(L"Display name"); + column.cx = 250; + ListView_InsertColumn(hwndLst1, 1, &column); + + // リストを再読み込みする。 + ++m_bUpdating; + XgDictList_ReloadList(hwnd); + --m_bUpdating; + } + return TRUE; + + case WM_COMMAND: + // 変更があれば「更新」ボタンを有効にする。 + switch (LOWORD(wParam)) + { + case psh1: + if (HIWORD(wParam) == BN_CLICKED) + PropSheet_Changed(GetParent(hwnd), hwnd); + break; + case cmb1: + if (HIWORD(wParam) == CBN_EDITCHANGE || + HIWORD(wParam) == CBN_SELCHANGE || + HIWORD(wParam) == CBN_SELENDOK) + { + PropSheet_Changed(GetParent(hwnd), hwnd); + } + break; + } + // 実際の処理。 + switch (LOWORD(wParam)) + { + case psh1: // ファイルを開く。 + if (HIWORD(wParam) == BN_CLICKED) { + INT iItem = XgDictList_GetCurSel(hwnd, hwndLst1); + + // コンボボックスからテキストを取得。 + WCHAR szText[MAX_PATH]; + szText[0] = 0; + SendDlgItemMessageW(hwnd, cmb1, CB_GETLBTEXT, iItem, (LPARAM)szText); + szText[_countof(szText) - 1] = 0; + + // パスファイル名を構築する。 + WCHAR szPath[MAX_PATH]; + GetModuleFileNameW(NULL, szPath, _countof(szPath)); + PathRemoveFileSpecW(szPath); + PathAppendW(szPath, L"DICT"); + PathAppendW(szPath, szText); + + // シェルで開く。開けなければメモ帳で開く。 + SHELLEXECUTEINFOW info = { sizeof(info), SEE_MASK_FLAG_NO_UI, hwnd }; + info.lpFile = szPath; + if (!ShellExecuteExW(&info)) { + WCHAR szQuotedPath[MAX_PATH]; + StringCchPrintfW(szQuotedPath, _countof(szQuotedPath), L"\"%s\"", szPath); + info.lpFile = L"notepad.exe"; + info.lpParameters = szQuotedPath; + info.nShow = SW_SHOWNORMAL; + ShellExecuteExW(&info); + } + } + break; + case psh2: // フォルダを開く。 + if (HIWORD(wParam) == BN_CLICKED) { + WCHAR szPath[MAX_PATH]; + GetModuleFileNameW(NULL, szPath, _countof(szPath)); + PathRemoveFileSpecW(szPath); + PathAppendW(szPath, L"DICT"); + ShellExecuteW(hwnd, NULL, szPath, NULL, NULL, SW_SHOWNORMAL); + } + break; + case psh4: // 再読み込み。 + XgDictList_ReloadList(hwnd); + break; + case cmb1: + if (HIWORD(wParam) == CBN_EDITCHANGE || + HIWORD(wParam) == CBN_SELCHANGE || + HIWORD(wParam) == CBN_SELENDOK) + { + if (m_bUpdating) + break; + // コンボボックスで現在選択されているテキストを取得。 + INT iItem = (INT)::SendDlgItemMessageW(hwnd, cmb1, CB_GETCURSEL, 0, 0); + if (iItem == CB_ERR) + return 0; + + // コンボボックスからテキストを取得。 + WCHAR szText[MAX_PATH]; + szText[0] = 0; + SendDlgItemMessageW(hwnd, cmb1, CB_GETLBTEXT, iItem, (LPARAM)szText); + szText[_countof(szText) - 1] = 0; + + // リストビューからテキストを探す。 + LV_FINDINFO Find = { LVFI_STRING, szText }; + iItem = ListView_FindItem(hwndLst1, -1, &Find); + + // リストビューの選択を更新する。 + m_bUpdating++; + XgDictList_SetCurSel(hwnd, hwndLst1, iItem); + m_bUpdating--; + } + break; + } + break; + + case WM_NOTIFY: + { + NMHDR *pnmhdr = (NMHDR *)lParam; + auto pListView = (NM_LISTVIEW *)lParam; + switch (pnmhdr->code) { + case PSN_APPLY: // 適用 + { + INT iItem = XgDictList_GetCurSel(hwnd, hwndLst1); + + // コンボボックスからテキストを取得。 + WCHAR szText[MAX_PATH]; + szText[0] = 0; + SendDlgItemMessageW(hwnd, cmb1, CB_GETLBTEXT, iItem, (LPARAM)szText); + szText[_countof(szText) - 1] = 0; + + // パスファイル名を構築する。 + WCHAR szPath[MAX_PATH]; + GetModuleFileNameW(NULL, szPath, _countof(szPath)); + PathRemoveFileSpecW(szPath); + PathAppendW(szPath, L"DICT"); + PathAppendW(szPath, szText); + + // 辞書を指定する。 + xg_dict_name = szPath; + + // 再読み込み。 + XgDictList_ReloadList(hwnd); + } + break; + + case LVN_ITEMCHANGED: + if (pnmhdr->idFrom == lst1 && !m_bUpdating && (pListView->uNewState & LVIS_SELECTED)) { + // リストビューの選択が変わった。 + HWND hwndLst1 = GetDlgItem(hwnd, lst1); + + // テキストを取得。 + WCHAR szText[MAX_PATH]; + LV_ITEMW item = { LVIF_TEXT }; + item.pszText = szText; + item.cchTextMax = _countof(szText); + item.iItem = pListView->iItem; + item.iSubItem = 0; + ListView_GetItem(hwndLst1, &item); + + // リストビューのチェック状態を更新する。 + m_bUpdating++; + XgDictList_SetCurSel(hwnd, hwndLst1, pListView->iItem); + m_bUpdating--; + + // コンボボックスからテキストを探す。 + INT iItem = (INT)::SendDlgItemMessageW(hwnd, cmb1, CB_FINDSTRINGEXACT, -1, (LPARAM)szText); + if (iItem != CB_ERR) { + // コンボボックスの選択を変更する。 + m_bUpdating++; + ::SendDlgItemMessageW(hwnd, cmb1, CB_SETCURSEL, iItem, 0); + m_bUpdating--; + + // 更新ボタンを有効にする。 + PropSheet_Changed(GetParent(hwnd), hwnd); + } + } + break; + } + } + break; + } + return 0; +} diff --git a/XgGenerative.cpp b/XgGenerative.cpp index fdd8c96..827c5a8 100644 --- a/XgGenerative.cpp +++ b/XgGenerative.cpp @@ -2,8 +2,6 @@ INT_PTR CALLBACK XgGenerativeDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - static XGStringW s_strFit; - switch (uMsg) { case WM_INITDIALOG: diff --git a/lang/en_US.rc b/lang/en_US.rc index e949e75..7328d52 100644 --- a/lang/en_US.rc +++ b/lang/en_US.rc @@ -1560,6 +1560,20 @@ FONT 9, "Tahoma" AUTOCHECKBOX "Auto &retry", chx3, 10, 45, 200, 15 } +IDD_DICTLIST DIALOG 0, 0, 269, 203 +CAPTION "Dictionaries" +STYLE DS_CENTER | DS_MODALFRAME | WS_POPUPWINDOW | WS_CAPTION +FONT 9, "Tahoma" +{ + LTEXT "Current &dict:", -1, 5, 10, 70, 15, SS_CENTERIMAGE + COMBOBOX cmb1, 80, 10, 180, 300, CBS_HASSTRINGS | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Dictionary &List:", -1, 5, 30, 110, 15, SS_CENTERIMAGE | NOT WS_GROUP + CONTROL "", lst1, "SysListView32", LVS_REPORT | WS_BORDER | WS_TABSTOP, 5, 50, 255, 95 + PUSHBUTTON "Open &file", psh1, 5, 150, 65, 20 + PUSHBUTTON "&Open folder", psh2, 75, 150, 75, 20 + PUSHBUTTON "&Reload list", psh4, 5, 175, 105, 20 +} + ////////////////////////////////////////////////////////////////////////////// // RT_VERSION diff --git a/lang/ja_JP.rc b/lang/ja_JP.rc index a7337a7..5eb6142 100644 --- a/lang/ja_JP.rc +++ b/lang/ja_JP.rc @@ -1564,6 +1564,20 @@ FONT 9, "MS UI Gothic" AUTOCHECKBOX "自動で再試行(&T)", chx3, 10, 45, 200, 15 } +IDD_DICTLIST DIALOG 0, 0, 269, 203 +CAPTION "辞書" +STYLE DS_CENTER | DS_MODALFRAME | WS_POPUPWINDOW | WS_CAPTION +FONT 9, "MS UI Gothic" +{ + LTEXT "現在の辞書(&D):", -1, 5, 10, 70, 15, SS_CENTERIMAGE + COMBOBOX cmb1, 80, 10, 180, 300, CBS_HASSTRINGS | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "辞書リスト(&L):", -1, 5, 30, 110, 15, SS_CENTERIMAGE | NOT WS_GROUP + CONTROL "", lst1, "SysListView32", LVS_REPORT | WS_BORDER | WS_TABSTOP, 5, 50, 255, 95 + PUSHBUTTON "ファイルを開く(&F)", psh1, 5, 150, 65, 20 + PUSHBUTTON "フォルダを開く(&O)", psh2, 75, 150, 75, 20 + PUSHBUTTON "リスト再読み込み(&R)", psh4, 5, 175, 105, 20 +} + ////////////////////////////////////////////////////////////////////////////// // RT_VERSION diff --git a/resource.h b/resource.h index 8a5e312..ad6de8b 100644 --- a/resource.h +++ b/resource.h @@ -39,6 +39,7 @@ #define IDD_FILESETTINGS 135 #define IDD_VIEWSETTINGS 136 #define IDD_GENERATIVE 137 +#define IDD_DICTLIST 138 #define IDS_VERSION 101 #define IDS_APPNAME 102