/* Copyright (C) 2006-2010 Ricardo Pescuma Domenecci This is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this file; see the file license.txt. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "stdafx.h" static LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK AddReplacementDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); struct Data { Dictionary *dict; std::wstring find; std::wstring replace; BOOL useVariables; BOOL modal; BOOL findReadOnly; AutoReplaceDialogCallback callback; void *param; }; BOOL ShowAutoReplaceDialog(HWND parent, BOOL modal, Dictionary *dict, const wchar_t *find, const wchar_t *replace, BOOL useVariables, BOOL findReadOnly, AutoReplaceDialogCallback callback, void *param) { Data *data = new Data(); data->dict = dict; data->useVariables = useVariables; data->modal = modal; data->findReadOnly = findReadOnly; data->callback = callback; data->param = param; if (find != nullptr) data->find = find; if (replace != nullptr) data->replace = replace; if (modal) return DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ADD_REPLACEMENT), parent, AddReplacementDlgProc, (LPARAM)data); HWND hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ADD_REPLACEMENT), parent, AddReplacementDlgProc, (LPARAM)data); SetForegroundWindow(hwnd); SetFocus(hwnd); SetFocus(GetDlgItem(hwnd, IDC_NEW)); ShowWindow(hwnd, SW_SHOW); return TRUE; } static LRESULT CALLBACK OnlyCharsEditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { Data *data = (Data *)GetWindowLongPtr(hwnd, GWLP_USERDATA); switch (msg) { case WM_CHAR: if (wParam == VK_BACK) break; if (lParam & (1 << 28)) // ALT key break; if (GetKeyState(VK_CONTROL) & 0x8000) // CTRL key break; { wchar_t c = (wchar_t)wParam; if (!data->dict->autoReplace->isWordChar(c)) return 1; wchar_t tmp[2] = { c, 0 }; CharLower(tmp); wParam = tmp[0]; break; } } LRESULT ret = mir_callNextSubclass(hwnd, OnlyCharsEditProc, msg, wParam, lParam); switch (msg) { case EM_PASTESPECIAL: case WM_PASTE: wchar_t text[256]; GetWindowText(hwnd, text, _countof(text)); scoped_free dest = data->dict->autoReplace->filterText(text); SetWindowText(hwnd, dest); break; } return ret; } static BOOL CenterParent(HWND hwnd) { HWND hwndParent = GetParent(hwnd); if (hwndParent == nullptr) return FALSE; RECT rect, rectP; GetWindowRect(hwnd, &rect); GetWindowRect(hwndParent, &rectP); int width = rect.right - rect.left; int height = rect.bottom - rect.top; int x = ((rectP.right - rectP.left) - width) / 2 + rectP.left; int y = ((rectP.bottom - rectP.top) - height) / 2 + rectP.top; int screenwidth = GetSystemMetrics(SM_CXSCREEN); int screenheight = GetSystemMetrics(SM_CYSCREEN); if (x + width > screenwidth) x = screenwidth - width; if (y + height > screenheight) y = screenheight - height; if (x < 0) x = 0; if (y < 0) y = 0; MoveWindow(hwnd, x, y, width, height, FALSE); return TRUE; } static void Close(HWND hwndDlg, int ret) { Data *data = (Data *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); if (!ret) data->callback(TRUE, data->dict, data->find.c_str(), data->replace.c_str(), data->useVariables, data->find.c_str(), data->param); if (data->modal) EndDialog(hwndDlg, ret); else DestroyWindow(hwndDlg); delete data; } static INT_PTR CALLBACK AddReplacementDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); { Data *data = (Data *)lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)data); SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_OLD), GWLP_USERDATA, (LONG_PTR)data); mir_subclassWindow(GetDlgItem(hwndDlg, IDC_OLD), OnlyCharsEditProc); Window_SetIcon_IcoLib(hwndDlg, IcoLib_GetIconHandle("spellchecker_enabled")); SendDlgItemMessage(hwndDlg, IDC_OLD, EM_LIMITTEXT, 256, 0); SendDlgItemMessage(hwndDlg, IDC_NEW, EM_LIMITTEXT, 256, 0); if (!data->find.empty()) { scoped_free tmp = data->dict->autoReplace->filterText(data->find.c_str()); SetDlgItemText(hwndDlg, IDC_OLD, tmp); } if (!data->replace.empty()) SetDlgItemText(hwndDlg, IDC_NEW, data->replace.c_str()); CheckDlgButton(hwndDlg, IDC_VARIABLES, data->useVariables ? BST_CHECKED : BST_UNCHECKED); if (data->findReadOnly) { SendDlgItemMessage(hwndDlg, IDC_OLD, EM_SETREADONLY, TRUE, 0); EnableWindow(GetDlgItem(hwndDlg, IDC_OLD_PS), FALSE); } if (!variables_enabled) { ShowWindow(GetDlgItem(hwndDlg, IDC_VARIABLES), FALSE); ShowWindow(GetDlgItem(hwndDlg, IDC_VAR_HELP), FALSE); RECT rc_old; GetWindowRect(GetDlgItem(hwndDlg, IDC_OLD), &rc_old); RECT rc_new; GetWindowRect(GetDlgItem(hwndDlg, IDC_NEW), &rc_new); rc_new.right = rc_old.right; SetWindowPos(GetDlgItem(hwndDlg, IDC_NEW), nullptr, 0, 0, rc_new.right - rc_new.left, rc_new.bottom - rc_new.top, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOZORDER); } else { variables_skin_helpbutton(hwndDlg, IDC_VAR_HELP); EnableWindow(GetDlgItem(hwndDlg, IDC_VAR_HELP), IsDlgButtonChecked(hwndDlg, IDC_VARIABLES)); } CenterParent(hwndDlg); } return TRUE; case WM_COMMAND: switch (wParam) { case IDOK: { Data *data = (Data *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); wchar_t find[256]; if (data->findReadOnly) mir_wstrncpy(find, data->find.c_str(), _countof(find)); else { GetDlgItemText(hwndDlg, IDC_OLD, find, _countof(find)); lstrtrim(find); } wchar_t replace[256]; GetDlgItemText(hwndDlg, IDC_NEW, replace, _countof(replace)); lstrtrim(replace); if (!data->findReadOnly && find[0] == 0) MessageBox(hwndDlg, TranslateT("The wrong word can't be empty!"), TranslateT("Wrong Correction"), MB_OK | MB_ICONERROR); else if (replace[0] == 0) MessageBox(hwndDlg, TranslateT("The correction can't be empty!"), TranslateT("Wrong Correction"), MB_OK | MB_ICONERROR); else if (mir_wstrcmp(find, replace) == 0) MessageBox(hwndDlg, TranslateT("The correction can't be equal to the wrong word!"), TranslateT("Wrong Correction"), MB_OK | MB_ICONERROR); else { data->callback(FALSE, data->dict, find, replace, IsDlgButtonChecked(hwndDlg, IDC_VARIABLES), data->find.c_str(), data->param); Close(hwndDlg, 1); } } break; case IDCANCEL: Close(hwndDlg, 0); break; case IDC_VARIABLES: EnableWindow(GetDlgItem(hwndDlg, IDC_VAR_HELP), IsDlgButtonChecked(hwndDlg, IDC_VARIABLES)); break; case IDC_VAR_HELP: variables_showhelp(hwndDlg, IDC_NEW, VHF_FULLDLG, nullptr, "The wrong word typed by the user"); break; } break; case WM_CLOSE: Close(hwndDlg, 0); break; } return FALSE; }