1 /* AbiWord
2 * Copyright (C) 1998 AbiSource, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA.
18 */
19
20 //////////////////////////////////////////////////////////////////
21 // THIS CODE RUNS BOTH THE "Find" AND THE "Find-Replace" DIALOGS.
22 //////////////////////////////////////////////////////////////////
23
24 #include <windows.h>
25
26 #include "ut_string.h"
27 #include "ut_assert.h"
28 #include "ut_debugmsg.h"
29
30 #include "xap_Win32App.h"
31 #include "xap_Win32FrameImpl.h"
32
33 #include "ap_Strings.h"
34 #include "ap_Dialog_Id.h"
35 #include "ap_Dialog_Replace.h"
36 #include "ap_Win32Dialog_Replace.h"
37 #include "xap_Win32DialogHelper.h"
38 #include "ap_Win32Resources.rc2"
39 #include "ap_Win32App.h"
40
41 /*****************************************************************/
static_constructor(XAP_DialogFactory * pFactory,XAP_Dialog_Id id)42 XAP_Dialog * AP_Win32Dialog_Replace::static_constructor(XAP_DialogFactory * pFactory,
43 XAP_Dialog_Id id)
44 {
45 AP_Win32Dialog_Replace * p = new AP_Win32Dialog_Replace(pFactory,id);
46 return p;
47 }
48
AP_Win32Dialog_Replace(XAP_DialogFactory * pDlgFactory,XAP_Dialog_Id id)49 AP_Win32Dialog_Replace::AP_Win32Dialog_Replace(XAP_DialogFactory * pDlgFactory,
50 XAP_Dialog_Id id)
51 : AP_Dialog_Replace(pDlgFactory,id)
52 {
53
54 }
55
~AP_Win32Dialog_Replace(void)56 AP_Win32Dialog_Replace::~AP_Win32Dialog_Replace(void)
57 {
58 }
59
activate(void)60 void AP_Win32Dialog_Replace::activate(void)
61 {
62 int iResult;
63 UT_Win32LocaleString findstr;
64
65 // Update the caption
66 ConstructWindowName();
67 setDialogTitle(m_WindowName);
68
69 SetFocus( GetDlgItem( m_hDlg,AP_RID_DIALOG_REPLACE_COMBO_FIND) );
70
71 iResult = ShowWindow( m_hDlg, SW_SHOW );
72
73 iResult = BringWindowToTop( m_hDlg );
74
75 UT_return_if_fail ((iResult != 0));
76
77 {
78 UT_UCSChar * bufferUnicode = getFindString();
79 findstr.fromUCS4 (bufferUnicode);
80 if (!findstr.empty())
81 {
82 SetDlgItemTextW(m_hDlg, AP_RID_DIALOG_REPLACE_COMBO_FIND,findstr.c_str());
83 SendMessageW(GetDlgItem(m_hDlg,AP_RID_DIALOG_REPLACE_COMBO_FIND), CB_SETEDITSEL, 0, MAKELONG (0, -1));
84 }
85 FREEP(bufferUnicode);
86 }
87
88 if (m_id == AP_DIALOG_ID_REPLACE)
89 {
90
91 UT_UCSChar * bufferUnicode = getReplaceString();
92 findstr.fromUCS4 (bufferUnicode);
93 if (!findstr.empty())
94 {
95 SetDlgItemTextW(m_hDlg,AP_RID_DIALOG_REPLACE_COMBO_REPLACE,findstr.c_str());
96 SendMessageW(GetDlgItem(m_hDlg,AP_RID_DIALOG_REPLACE_COMBO_FIND), CB_SETEDITSEL, 0, MAKELONG (0, -1));
97 }
98 FREEP(bufferUnicode);
99 }
100 }
101
102
destroy(void)103 void AP_Win32Dialog_Replace::destroy(void)
104 {
105 UT_DebugOnly<int> iResult = DestroyWindow( m_hDlg );
106
107 UT_ASSERT_HARMLESS((iResult != 0));
108
109 modeless_cleanup();
110 }
111
notifyActiveFrame(XAP_Frame * pFrame)112 void AP_Win32Dialog_Replace::notifyActiveFrame(XAP_Frame *pFrame)
113 {
114 if((HWND)GetWindowLongPtrW(m_hDlg, GWLP_HWNDPARENT) != static_cast<XAP_Win32FrameImpl*>(pFrame->getFrameImpl())->getTopLevelWindow())
115 {
116 // Update the caption
117 ConstructWindowName();
118 setDialogTitle(m_WindowName);
119
120 SetWindowLongPtrW(m_hDlg, GWLP_HWNDPARENT, (LONG_PTR)static_cast<XAP_Win32FrameImpl*>(pFrame->getFrameImpl())->getTopLevelWindow());
121 SetWindowPos(m_hDlg, NULL, 0, 0, 0, 0,
122 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
123 }
124 }
125
notifyCloseFrame(XAP_Frame * pFrame)126 void AP_Win32Dialog_Replace::notifyCloseFrame(XAP_Frame *pFrame)
127 {
128 if((HWND)GetWindowLongPtrW(m_hDlg, GWLP_HWNDPARENT) == static_cast<XAP_Win32FrameImpl*>(pFrame->getFrameImpl())->getTopLevelWindow())
129 {
130 SetWindowLongPtrW(m_hDlg, GWLP_HWNDPARENT, 0);
131 SetWindowPos(m_hDlg, NULL, 0, 0, 0, 0,
132 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
133 }
134 }
135
runModeless(XAP_Frame * pFrame)136 void AP_Win32Dialog_Replace::runModeless(XAP_Frame * pFrame)
137 {
138 LPCWSTR lpTemplate = NULL;
139 if (m_id == AP_DIALOG_ID_REPLACE)
140 lpTemplate = MAKEINTRESOURCEW(AP_RID_DIALOG_REPLACE);
141 else if (m_id == AP_DIALOG_ID_FIND)
142 lpTemplate = MAKEINTRESOURCEW(AP_RID_DIALOG_FIND);
143 else
144 {
145 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
146 return;
147 }
148
149 setView(static_cast<FV_View *> (pFrame->getCurrentView()) );
150 createModeless(pFrame, lpTemplate);
151
152 // Save dialog the ID number and pointer to the widget
153 m_pApp->rememberModelessId(/* (UT_sint32)*/ getDialogId(), (XAP_Dialog_Modeless *) m_pDialog);
154
155 // Update the caption
156 ConstructWindowName();
157 setDialogTitle(m_WindowName);
158
159 ShowWindow( m_hDlg, SW_SHOW );
160 m_pView->focusChange(AV_FOCUS_MODELESS);
161 }
162
_initButtons(HWND hWnd)163 void AP_Win32Dialog_Replace::_initButtons(HWND hWnd)
164 {
165 HWND hWndEditFind = GetDlgItem(hWnd,AP_RID_DIALOG_REPLACE_COMBO_FIND);
166 // HWND hWndEditReplace = GetDlgItem(hWnd,AP_RID_DIALOG_REPLACE_COMBO_REPLACE);
167 DWORD lenFind = GetWindowTextLengthW(hWndEditFind);
168 // DWORD lenReplace = GetWindowTextLengthW(hWndEditReplace);
169
170 BOOL bEnableFind = (lenFind > 0);
171 EnableWindow(GetDlgItem(hWnd,AP_RID_DIALOG_REPLACE_BTN_FINDNEXT),bEnableFind);
172
173
174 if (m_id == AP_DIALOG_ID_REPLACE)
175 {
176
177 BOOL bEnableReplace = bEnableFind;
178 EnableWindow(GetDlgItem(hWnd,AP_RID_DIALOG_REPLACE_BTN_REPLACE),bEnableReplace);
179 EnableWindow(GetDlgItem(hWnd,AP_RID_DIALOG_REPLACE_BTN_REPLACEALL),bEnableReplace);
180 }
181
182 CheckDlgButton(hWnd,AP_RID_DIALOG_REPLACE_CHECK_MATCHCASE,
183 ((getMatchCase()) ? BST_CHECKED : BST_UNCHECKED));
184
185 CheckDlgButton(hWnd,AP_RID_DIALOG_REPLACE_CHECK_WHOLEWORD,
186 ((getWholeWord()) ? BST_CHECKED : BST_UNCHECKED));
187
188 CheckDlgButton(hWnd,AP_RID_DIALOG_REPLACE_CHECK_REVERSEFIND,
189 ((getReverseFind()) ? BST_CHECKED : BST_UNCHECKED));
190
191 return;
192 }
193
194 #define _DS(c,s) setDlgItemText(AP_RID_DIALOG_##c,pSS->getValue(AP_STRING_ID_##s))
195 #define _DSX(c,s) setDlgItemText(AP_RID_DIALOG_##c,pSS->getValue(XAP_STRING_ID_##s))
196
_onInitDialog(HWND hWnd,WPARAM,LPARAM)197 BOOL AP_Win32Dialog_Replace::_onInitDialog(HWND hWnd, WPARAM /*wParam*/, LPARAM /*lParam*/)
198 {
199
200 const XAP_StringSet * pSS = m_pApp->getStringSet();
201
202 if (m_id == AP_DIALOG_ID_FIND)
203 setDialogTitle(pSS->getValue(AP_STRING_ID_DLG_FR_FindTitle));
204 else
205 setDialogTitle(pSS->getValue(AP_STRING_ID_DLG_FR_ReplaceTitle));
206
207 // localize controls shared across dialogs
208 _DS(REPLACE_BTN_FINDNEXT, DLG_FR_FindNextButton);
209 _DS(REPLACE_TEXT_FIND, DLG_FR_FindLabel);
210 _DS(REPLACE_CHECK_MATCHCASE, DLG_FR_MatchCase);
211 _DS(REPLACE_CHECK_REVERSEFIND, DLG_FR_ReverseFind);
212 _DS(REPLACE_CHECK_WHOLEWORD, DLG_FR_WholeWord);
213
214 _DSX(REPLACE_BTN_CLOSE, DLG_Cancel);
215
216
217 if (m_id == AP_DIALOG_ID_REPLACE)
218 {
219
220 // localize replace-specific controls
221 _DS(REPLACE_BTN_REPLACE, DLG_FR_ReplaceButton);
222 _DS(REPLACE_BTN_REPLACEALL, DLG_FR_ReplaceAllButton);
223 _DS(REPLACE_TEXT_REPLACE, DLG_FR_ReplaceWithLabel);
224 }
225
226 _initButtons(hWnd);
227
228 SetFocus( GetDlgItem(hWnd,AP_RID_DIALOG_REPLACE_COMBO_FIND) );
229
230 centerDialog();
231
232 return 0; // 0 == we did call SetFocus()
233 }
234
_onCommand(HWND hWnd,WPARAM wParam,LPARAM)235 BOOL AP_Win32Dialog_Replace::_onCommand(HWND hWnd, WPARAM wParam, LPARAM /*lParam*/)
236 {
237 WORD wId = LOWORD(wParam);
238
239 // before doing anything else, make sure that the main window is not entirely
240 // without focus
241 m_pView->focusChange(AV_FOCUS_MODELESS);
242 xxx_UT_DEBUGMSG(("s_dlgProc: wId 0x%x\n",wId));
243
244 switch (wId)
245 {
246 case AP_RID_DIALOG_REPLACE_COMBO_FIND:
247 case AP_RID_DIALOG_REPLACE_COMBO_REPLACE:
248 xxx_UT_DEBUGMSG(("_onCommand: edit control\n"));
249 _initButtons(hWnd);
250 return 0;
251
252 case AP_RID_DIALOG_REPLACE_CHECK_MATCHCASE:
253 setMatchCase((IsDlgButtonChecked(hWnd,AP_RID_DIALOG_REPLACE_CHECK_MATCHCASE)==BST_CHECKED));
254 return 1;
255
256 case AP_RID_DIALOG_REPLACE_CHECK_WHOLEWORD:
257 setWholeWord((IsDlgButtonChecked(hWnd,AP_RID_DIALOG_REPLACE_CHECK_WHOLEWORD)==BST_CHECKED));
258 return 1;
259
260 case AP_RID_DIALOG_REPLACE_CHECK_REVERSEFIND:
261 {
262 bool currentVal = (IsDlgButtonChecked(hWnd,AP_RID_DIALOG_REPLACE_CHECK_REVERSEFIND)==BST_CHECKED);
263 setReverseFind(currentVal);
264
265 if (!m_pView->isSelectionEmpty())
266 {
267 // if there's a selection, clear it
268 UT_UCS4Char * pSelection;
269 m_pView->getSelectionText(pSelection);
270
271 if ( pSelection != NULL)
272 {
273 PT_DocPosition pt = m_pView->getSelectionAnchor();
274 PT_DocPosition ln = UT_UCS4_strlen (pSelection);
275 if (currentVal)
276 {
277 m_pView->moveInsPtTo(pt);
278 }
279 else
280 {
281 m_pView->moveInsPtTo(pt+ln);
282 }
283 m_pView->cmdUnselectSelection();
284 }
285
286 FREEP(pSelection);
287 }
288
289 m_pView->findSetStartAtInsPoint();
290
291 return 1;
292 }
293 case AP_RID_DIALOG_REPLACE_BTN_FINDNEXT:
294 return _onBtn_Find(hWnd, find_FIND_NEXT);
295
296 case AP_RID_DIALOG_REPLACE_BTN_REPLACE:
297 return _onBtn_Find(hWnd, find_REPLACE);
298
299 case AP_RID_DIALOG_REPLACE_BTN_REPLACEALL:
300 return _onBtn_Find(hWnd, find_REPLACE_ALL);
301
302 case IDCANCEL: // also AP_RID_DIALOG_REPLACE_BTN_CLOSE
303 EndDialog(hWnd,0);
304 return 1;
305
306 default: // we did not handle this notification
307 UT_DEBUGMSG(("WM_Command for id %ld\n",wId));
308 return 0; // return zero to let windows take care of it.
309 }
310 }
311
_onBtn_Find(HWND hWnd,tFindType tFindType)312 BOOL AP_Win32Dialog_Replace::_onBtn_Find(HWND hWnd, tFindType tFindType)
313 {
314 wchar_t * pBufFromDialogFind = NULL;
315 wchar_t * pBufFromDialogReplace = NULL;
316 UT_UCSChar * pUCSReplace = NULL;
317 UT_Win32LocaleString findstr;
318 UT_Win32LocaleString replacestr;
319
320 // Check find string
321 HWND hWndEditFind = GetDlgItem(hWnd,AP_RID_DIALOG_REPLACE_COMBO_FIND);
322 DWORD lenFind = GetWindowTextLengthW(hWndEditFind);
323 if (!lenFind)
324 return 1;
325
326 pBufFromDialogFind = new wchar_t [lenFind + 1];
327 if (!pBufFromDialogFind)
328 goto FreeMemory;
329 GetWindowTextW(hWndEditFind,pBufFromDialogFind,lenFind+1);
330
331 UT_DEBUGMSG(("Find entry contents: [%s]\n",pBufFromDialogFind));
332
333 findstr.fromLocale (pBufFromDialogFind);
334
335 setFindString(findstr.ucs4_str().ucs4_str());
336
337 if (m_id == AP_DIALOG_ID_REPLACE)
338 {
339 // Check Replace string
340 HWND hWndEditReplace = GetDlgItem(hWnd,AP_RID_DIALOG_REPLACE_COMBO_REPLACE);
341 DWORD lenReplace = GetWindowTextLengthW(hWndEditReplace);
342
343 pBufFromDialogReplace = new wchar_t [lenReplace + 1];
344 if (!pBufFromDialogReplace)
345 goto FreeMemory;
346 GetWindowTextW(hWndEditReplace,pBufFromDialogReplace,lenReplace+1);
347
348 UT_DEBUGMSG(("Replace entry contents: [%s]\n",pBufFromDialogReplace));
349
350 replacestr.fromLocale (pBufFromDialogReplace);
351 setReplaceString(replacestr.ucs4_str().ucs4_str());
352 }
353
354 if (tFindType == find_REPLACE_ALL)
355 {
356 UT_return_val_if_fail ((m_id == AP_DIALOG_ID_REPLACE),0); //should never happen in Find dialog
357 findReplaceAll();
358 }
359 else if (tFindType == find_REPLACE)
360 {
361 UT_return_val_if_fail ((m_id == AP_DIALOG_ID_REPLACE),0); //should never happen in Find dialog
362 if (!getReverseFind())
363 findReplace();
364 else
365 findReplaceReverse();
366 }
367 else if (tFindType == find_FIND_NEXT)
368 {
369 if (!getReverseFind())
370 findNext();
371 else
372 findPrev();
373 }
374
375 FreeMemory:
376 DELETEP(pBufFromDialogFind);
377 DELETEP(pBufFromDialogReplace);
378 FREEP(pUCSReplace);
379 return 1;
380 }
381
_updateLists()382 void AP_Win32Dialog_Replace::_updateLists()
383 {
384 _updateList(GetDlgItem(m_hDlg, AP_RID_DIALOG_REPLACE_COMBO_FIND), &m_findList);
385 _updateList(GetDlgItem(m_hDlg, AP_RID_DIALOG_REPLACE_COMBO_REPLACE), &m_replaceList);
386 }
387
_updateList(HWND hWnd,UT_GenericVector<UT_UCS4Char * > * list)388 void AP_Win32Dialog_Replace::_updateList(HWND hWnd, UT_GenericVector<UT_UCS4Char*> *list)
389 {
390 UT_DEBUGMSG(("AP_Win32Dialog_Replace::_updateList\n"));
391
392 UT_Win32LocaleString str;
393
394 SendMessageW(hWnd, CB_RESETCONTENT, 0,0);
395
396 for (UT_sint32 i = 0; i < list->getItemCount(); i++)
397 {
398 // leaving the size 0 causes the string class to determine the length itself
399 str.fromUCS4 ((UT_UCS4Char*)list->getNthItem(i));
400 SendMessageW(hWnd, CB_ADDSTRING, 0, (LPARAM) str.c_str());
401 }
402
403 SendMessageW(hWnd, CB_SETCURSEL, 0,0);
404 }
405
406