Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <string>
21 :
22 : #include <boost/scoped_ptr.hpp>
23 :
24 : #include <hintids.hxx>
25 :
26 : #include <com/sun/star/util/SearchOptions.hpp>
27 : #include <svl/cjkoptions.hxx>
28 : #include <svl/ctloptions.hxx>
29 : #include <svx/pageitem.hxx>
30 : #include <svl/whiter.hxx>
31 : #include <sfx2/dispatch.hxx>
32 : #include <svl/stritem.hxx>
33 : #include <unotools/textsearch.hxx>
34 : #include <svl/itempool.hxx>
35 : #include <svl/eitem.hxx>
36 : #include <svl/srchitem.hxx>
37 : #include <sal/macros.h>
38 : #include <sfx2/request.hxx>
39 : #include <svx/srchdlg.hxx>
40 : #include <svx/dialmgr.hxx>
41 : #include <svx/dialogs.hrc>
42 : #include <vcl/layout.hxx>
43 : #include <vcl/msgbox.hxx>
44 : #include <vcl/wrkwin.hxx>
45 : #include "editeng/unolingu.hxx"
46 : #include <swmodule.hxx>
47 : #include <swwait.hxx>
48 : #include <workctrl.hxx>
49 : #include <view.hxx>
50 : #include <wrtsh.hxx>
51 : #include <swundo.hxx>
52 : #include <uitool.hxx>
53 : #include <cmdid.h>
54 : #include <docsh.hxx>
55 : #include <doc.hxx>
56 : #include <unocrsr.hxx>
57 :
58 : #include <view.hrc>
59 : #include <SwRewriter.hxx>
60 : #include <comcore.hrc>
61 :
62 : #include "PostItMgr.hxx"
63 :
64 : using namespace com::sun::star;
65 : using namespace ::com::sun::star::i18n;
66 : using namespace ::com::sun::star::lang;
67 : using namespace ::com::sun::star::util;
68 :
69 : //Search Parameter
70 :
71 : struct SwSearchOptions
72 : {
73 : SwDocPositions eStart, eEnd;
74 : sal_Bool bDontWrap;
75 :
76 : SwSearchOptions( SwWrtShell* pSh, sal_Bool bBackward );
77 : };
78 :
79 0 : static Window* GetParentWindow( SvxSearchDialog* pSrchDlg )
80 : {
81 0 : return pSrchDlg && pSrchDlg->IsVisible() ? pSrchDlg : 0;
82 : }
83 :
84 0 : void SwView::ExecSearch(SfxRequest& rReq, sal_Bool bNoMessage)
85 : {
86 0 : const SfxItemSet* pArgs = rReq.GetArgs();
87 0 : const SfxPoolItem* pItem = 0;
88 0 : sal_Bool bQuiet = sal_False;
89 0 : if(pArgs && SFX_ITEM_SET == pArgs->GetItemState(SID_SEARCH_QUIET, false, &pItem))
90 0 : bQuiet = ((const SfxBoolItem*) pItem)->GetValue();
91 :
92 0 : sal_Bool bApi = bQuiet | bNoMessage;
93 :
94 0 : sal_uInt16 nSlot = rReq.GetSlot();
95 0 : if (nSlot == FN_REPEAT_SEARCH && !m_pSrchItem)
96 : {
97 0 : if(bApi)
98 : {
99 0 : rReq.SetReturnValue(SfxBoolItem(nSlot, false));
100 0 : nSlot = 0;
101 : }
102 : }
103 0 : if( m_pWrtShell->IsBlockMode() )
104 0 : m_pWrtShell->LeaveBlockMode();
105 0 : switch (nSlot)
106 : {
107 : // for now do nothing
108 : case SID_SEARCH_ITEM:
109 : {
110 0 : delete m_pSrchItem;
111 0 : m_pSrchItem = (SvxSearchItem*) pArgs->Get(SID_SEARCH_ITEM).Clone();
112 : }
113 0 : break;
114 :
115 : case FID_SEARCH_ON:
116 0 : m_bJustOpened = true;
117 0 : GetViewFrame()->GetBindings().Invalidate(SID_SEARCH_ITEM);
118 0 : break;
119 :
120 : case FID_SEARCH_OFF:
121 0 : if(pArgs)
122 : {
123 : // Unregister dialog
124 0 : delete m_pSrchItem;
125 0 : m_pSrchItem = (SvxSearchItem*) pArgs->Get(SID_SEARCH_ITEM).Clone();
126 :
127 0 : DELETEZ( m_pSrchList );
128 0 : DELETEZ( m_pReplList );
129 :
130 0 : m_pSrchDlg = GetSearchDialog();
131 0 : if (m_pSrchDlg)
132 : {
133 : // We will remember the search-/replace items.
134 0 : const SearchAttrItemList* pList = m_pSrchDlg->GetSearchItemList();
135 0 : if( pList && pList->Count() )
136 0 : m_pSrchList = new SearchAttrItemList( *pList );
137 :
138 0 : if( 0 != (pList = m_pSrchDlg->GetReplaceItemList() ) &&
139 0 : pList->Count() )
140 0 : m_pReplList = new SearchAttrItemList( *pList );
141 : }
142 : }
143 0 : break;
144 :
145 : case FN_REPEAT_SEARCH:
146 : case FID_SEARCH_NOW:
147 : {
148 : {
149 0 : if(FID_SEARCH_NOW == nSlot && !rReq.IsAPI())
150 0 : SwView::SetMoveType(NID_SRCH_REP);
151 : }
152 :
153 0 : m_pSrchDlg = GetSearchDialog();
154 0 : if (m_pSrchDlg)
155 : {
156 0 : DELETEZ( m_pSrchList );
157 0 : DELETEZ( m_pReplList );
158 :
159 0 : const SearchAttrItemList* pList = m_pSrchDlg->GetSearchItemList();
160 0 : if( pList && pList->Count() )
161 0 : m_pSrchList = new SearchAttrItemList( *pList );
162 :
163 0 : if( 0 != (pList = m_pSrchDlg->GetReplaceItemList() ) &&
164 0 : pList->Count() )
165 0 : m_pReplList = new SearchAttrItemList( *pList );
166 : }
167 :
168 0 : if (nSlot == FN_REPEAT_SEARCH)
169 : {
170 : OSL_ENSURE(m_pSrchItem, "SearchItem missing");
171 0 : if( !m_pSrchItem )
172 0 : m_pSrchItem = new SvxSearchItem(SID_SEARCH_ITEM);
173 : }
174 : else
175 : {
176 : // Get SearchItem from request
177 : OSL_ENSURE(pArgs, "Args missing");
178 0 : if ( pArgs )
179 : {
180 0 : delete m_pSrchItem;
181 0 : m_pSrchItem = (SvxSearchItem*) pArgs->Get(SID_SEARCH_ITEM).Clone();
182 : }
183 : }
184 0 : switch (m_pSrchItem->GetCommand())
185 : {
186 : case SVX_SEARCHCMD_FIND:
187 : {
188 0 : sal_Bool bRet = SearchAndWrap(bApi);
189 0 : if( bRet )
190 0 : Scroll(m_pWrtShell->GetCharRect().SVRect());
191 0 : rReq.SetReturnValue(SfxBoolItem(nSlot, bRet));
192 : {
193 0 : const sal_uInt16 nChildId = SvxSearchDialogWrapper::GetChildWindowId();
194 0 : SvxSearchDialogWrapper *pDlgWrp = (SvxSearchDialogWrapper*)GetViewFrame()->GetChildWindow(nChildId);
195 0 : if ( pDlgWrp )
196 : {
197 0 : m_pSrchDlg = (SvxSearchDialog*)(pDlgWrp->GetWindow());
198 0 : m_pSrchDlg->SetDocWin( (Window*)m_pEditWin);
199 0 : m_pSrchDlg->SetSrchFlag();
200 : }
201 : }
202 : }
203 0 : break;
204 : case SVX_SEARCHCMD_FIND_ALL:
205 : {
206 0 : sal_Bool bRet = SearchAll();
207 0 : if( !bRet )
208 : {
209 0 : if( !bApi )
210 0 : SvxSearchDialogWrapper::SetSearchLabel(SL_NotFound);
211 0 : m_bFound = sal_False;
212 : }
213 0 : rReq.SetReturnValue(SfxBoolItem(nSlot, bRet));
214 : {
215 0 : const sal_uInt16 nChildId = SvxSearchDialogWrapper::GetChildWindowId();
216 0 : SvxSearchDialogWrapper *pDlgWrp = (SvxSearchDialogWrapper*)GetViewFrame()->GetChildWindow(nChildId);
217 :
218 0 : if ( pDlgWrp )
219 : {
220 0 : m_pSrchDlg = (SvxSearchDialog*)(pDlgWrp->GetWindow());
221 0 : m_pSrchDlg->SetDocWin( (Window*)m_pEditWin);
222 0 : m_pSrchDlg->SetSrchFlag();
223 : }
224 : }
225 : }
226 0 : break;
227 : case SVX_SEARCHCMD_REPLACE:
228 : {
229 :
230 : // 1) Replace selection (Not if only attributes should be replaced)
231 : //JP 27.04.95: Why ?
232 : // what if you only want to assign attributes to the found??
233 :
234 0 : sal_uInt16 nCmd = SVX_SEARCHCMD_FIND;
235 0 : if( !m_pSrchItem->GetReplaceString().isEmpty() ||
236 0 : !m_pReplList )
237 : {
238 : // Prevent, that the replaced string will be found again
239 : // if the replacement string is containing the search string.
240 0 : sal_Bool bBack = m_pSrchItem->GetBackward();
241 0 : if (bBack)
242 0 : m_pWrtShell->Push();
243 0 : OUString aReplace( m_pSrchItem->GetReplaceString() );
244 0 : SearchOptions aTmp( m_pSrchItem->GetSearchOptions() );
245 0 : OUString *pBackRef = ReplaceBackReferences( aTmp, m_pWrtShell->GetCrsr() );
246 0 : if( pBackRef )
247 0 : m_pSrchItem->SetReplaceString( *pBackRef );
248 0 : Replace();
249 0 : if( pBackRef )
250 : {
251 0 : m_pSrchItem->SetReplaceString( aReplace );
252 0 : delete pBackRef;
253 : }
254 0 : if (bBack)
255 : {
256 0 : m_pWrtShell->Pop();
257 0 : m_pWrtShell->SwapPam();
258 0 : }
259 : }
260 0 : else if( m_pReplList )
261 0 : nCmd = SVX_SEARCHCMD_REPLACE;
262 :
263 : // 2) Search further (without replacing!)
264 :
265 0 : sal_uInt16 nOldCmd = m_pSrchItem->GetCommand();
266 0 : m_pSrchItem->SetCommand( nCmd );
267 0 : sal_Bool bRet = SearchAndWrap(bApi);
268 0 : if( bRet )
269 0 : Scroll( m_pWrtShell->GetCharRect().SVRect());
270 0 : m_pSrchItem->SetCommand( nOldCmd );
271 0 : rReq.SetReturnValue(SfxBoolItem(nSlot, bRet));
272 : }
273 : {
274 0 : const sal_uInt16 nChildId = SvxSearchDialogWrapper::GetChildWindowId();
275 0 : SvxSearchDialogWrapper *pDlgWrp = (SvxSearchDialogWrapper*)GetViewFrame()->GetChildWindow(nChildId);
276 :
277 0 : if ( pDlgWrp )
278 : {
279 0 : m_pSrchDlg = (SvxSearchDialog*)(pDlgWrp->GetWindow());
280 0 : m_pSrchDlg->SetDocWin( (Window*)m_pEditWin);
281 0 : m_pSrchDlg->SetSrchFlag();
282 : }
283 : }
284 0 : break;
285 :
286 : case SVX_SEARCHCMD_REPLACE_ALL:
287 : {
288 0 : SwSearchOptions aOpts( m_pWrtShell, m_pSrchItem->GetBackward() );
289 0 : m_bExtra = false;
290 : sal_uLong nFound;
291 :
292 : { //Scope for SwWait-Object
293 0 : SwWait aWait( *GetDocShell(), true );
294 0 : m_pWrtShell->StartAllAction();
295 0 : if (!m_pSrchItem->GetSelection())
296 : {
297 : // if we don't want to search in the selection...
298 0 : m_pWrtShell->KillSelection(0, false);
299 : // i#8288 "replace all" should not change cursor
300 : // position, so save current cursor
301 0 : m_pWrtShell->Push();
302 0 : if (DOCPOS_START == aOpts.eEnd)
303 : {
304 0 : m_pWrtShell->EndDoc();
305 : }
306 : else
307 : {
308 0 : m_pWrtShell->SttDoc();
309 : }
310 : }
311 0 : nFound = FUNC_Search( aOpts );
312 0 : if (!m_pSrchItem->GetSelection())
313 : {
314 : // create it just to overwrite it with stack cursor
315 0 : m_pWrtShell->CreateCrsr();
316 : // i#8288 restore the original cursor position
317 0 : m_pWrtShell->Pop(false);
318 : }
319 0 : m_pWrtShell->EndAllAction();
320 : }
321 :
322 0 : rReq.SetReturnValue(SfxBoolItem(nSlot, nFound != 0 && ULONG_MAX != nFound));
323 0 : if( !nFound )
324 : {
325 0 : if( !bApi )
326 0 : SvxSearchDialogWrapper::SetSearchLabel(SL_NotFound);
327 0 : m_bFound = sal_False;
328 0 : return;
329 : }
330 :
331 0 : if( !bApi && ULONG_MAX != nFound)
332 : {
333 0 : OUString aText( SW_RES( STR_NB_REPLACED ) );
334 0 : aText = aText.replaceFirst("XX", OUString::number( nFound ));
335 0 : Window* pParentWindow = GetParentWindow( m_pSrchDlg );
336 0 : InfoBox( pParentWindow, aText ).Execute();
337 : }
338 : }
339 0 : const sal_uInt16 nChildId = SvxSearchDialogWrapper::GetChildWindowId();
340 0 : SvxSearchDialogWrapper *pDlgWrp = (SvxSearchDialogWrapper*)GetViewFrame()->GetChildWindow(nChildId);
341 :
342 0 : if ( pDlgWrp )
343 : {
344 0 : m_pSrchDlg = (SvxSearchDialog*)(pDlgWrp->GetWindow());
345 0 : m_pSrchDlg->SetDocWin( (Window*)m_pEditWin);
346 0 : m_pSrchDlg->SetSrchFlag();
347 : }
348 0 : break;
349 : }
350 :
351 : uno::Reference< frame::XDispatchRecorder > xRecorder =
352 0 : GetViewFrame()->GetBindings().GetRecorder();
353 : //prevent additional dialogs in recorded macros
354 0 : if ( xRecorder.is() )
355 0 : rReq.AppendItem(SfxBoolItem(SID_SEARCH_QUIET, true));
356 :
357 0 : rReq.Done();
358 : }
359 0 : break;
360 : case FID_SEARCH_SEARCHSET:
361 : case FID_SEARCH_REPLACESET:
362 : {
363 : static const sal_uInt16 aNormalAttr[] =
364 : {
365 : /* 0 */ RES_CHRATR_CASEMAP, RES_CHRATR_CASEMAP,
366 : /* 2 */ RES_CHRATR_COLOR, RES_CHRATR_POSTURE,
367 : /* 4 */ RES_CHRATR_SHADOWED, RES_CHRATR_WORDLINEMODE,
368 : /* 6 */ RES_CHRATR_BLINK, RES_CHRATR_BLINK,
369 : /* 8 */ RES_CHRATR_BACKGROUND, RES_CHRATR_BACKGROUND,
370 : /*10 */ RES_CHRATR_ROTATE, RES_CHRATR_ROTATE,
371 : /*12 */ RES_CHRATR_SCALEW, RES_CHRATR_RELIEF,
372 : // insert position for CJK/CTL attributes!
373 : /*14 */ RES_PARATR_LINESPACING, RES_PARATR_HYPHENZONE,
374 : /*16 */ RES_PARATR_REGISTER, RES_PARATR_REGISTER,
375 : /*18 */ RES_PARATR_VERTALIGN, RES_PARATR_VERTALIGN,
376 : /*20 */ RES_LR_SPACE, RES_UL_SPACE,
377 : /*22 */ SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP,
378 : /*24 */ 0
379 : };
380 :
381 : static const sal_uInt16 aCJKAttr[] =
382 : {
383 : RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_WEIGHT,
384 : RES_CHRATR_EMPHASIS_MARK, RES_CHRATR_TWO_LINES,
385 : RES_PARATR_SCRIPTSPACE, RES_PARATR_FORBIDDEN_RULES
386 : };
387 : static const sal_uInt16 aCTLAttr[] =
388 : {
389 : RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_WEIGHT
390 : };
391 :
392 0 : std::vector<sal_uInt16> aArr;
393 : aArr.insert( aArr.begin(), aNormalAttr,
394 0 : aNormalAttr + SAL_N_ELEMENTS( aNormalAttr ));
395 0 : if( SW_MOD()->GetCTLOptions().IsCTLFontEnabled() )
396 : {
397 : aArr.insert( aArr.begin() + 14, aCTLAttr,
398 0 : aCTLAttr + SAL_N_ELEMENTS( aCTLAttr ));
399 : }
400 0 : SvtCJKOptions aCJKOpt;
401 0 : if( aCJKOpt.IsAnyEnabled() )
402 : {
403 : aArr.insert( aArr.begin() + 14, aCJKAttr,
404 0 : aCJKAttr + SAL_N_ELEMENTS( aCJKAttr ));
405 : }
406 :
407 0 : SfxItemSet aSet( m_pWrtShell->GetAttrPool(), &aArr[0] );
408 0 : sal_uInt16 nWhich = SID_SEARCH_SEARCHSET;
409 :
410 0 : if ( FID_SEARCH_REPLACESET == nSlot )
411 : {
412 0 : nWhich = SID_SEARCH_REPLACESET;
413 :
414 0 : if ( m_pReplList )
415 : {
416 0 : m_pReplList->Get( aSet );
417 0 : DELETEZ( m_pReplList );
418 : }
419 : }
420 0 : else if ( m_pSrchList )
421 : {
422 0 : m_pSrchList->Get( aSet );
423 0 : DELETEZ( m_pSrchList );
424 : }
425 0 : rReq.SetReturnValue( SvxSetItem( nWhich, aSet ) );
426 : }
427 0 : break;
428 : default:
429 : #if OSL_DEBUG_LEVEL > 1
430 : if(nSlot)
431 : {
432 : OString sStr("nSlot: " + OString::number(nSlot) + " wrong Dispatcher (viewsrch.cxx)");
433 : OSL_FAIL(sStr.getStr());
434 : }
435 : #endif
436 0 : return;
437 : }
438 : }
439 :
440 0 : sal_Bool SwView::SearchAndWrap(sal_Bool bApi)
441 : {
442 0 : SwSearchOptions aOpts( m_pWrtShell, m_pSrchItem->GetBackward() );
443 :
444 : // Remember starting position of the search for wraparound
445 : // Start- / EndAction perhaps because existing selections of 'search all'
446 0 : m_pWrtShell->StartAllAction();
447 0 : m_pWrtShell->Push();
448 :
449 : // fdo#65014 : Ensure that the point of the cursor is at the extremity of the
450 : // selection closest to the end being searched to as to exclude the selected
451 : // region from the search. (This doesn't work in the case of multiple
452 : // selected regions as the cursor doesn't mark the selection in that case.)
453 0 : m_pWrtShell->GetCrsr()->Normalize( m_pSrchItem->GetBackward() );
454 :
455 : // If you want to search in selected areas, they must not be unselected.
456 0 : if (!m_pSrchItem->GetSelection())
457 0 : m_pWrtShell->KillSelection(0, false);
458 :
459 0 : boost::scoped_ptr<SwWait> pWait(new SwWait( *GetDocShell(), true ));
460 0 : if( FUNC_Search( aOpts ) )
461 : {
462 0 : m_bFound = sal_True;
463 0 : if(m_pWrtShell->IsSelFrmMode())
464 : {
465 0 : m_pWrtShell->UnSelectFrm();
466 0 : m_pWrtShell->LeaveSelFrmMode();
467 : }
468 0 : m_pWrtShell->Pop();
469 0 : m_pWrtShell->EndAllAction();
470 0 : return sal_True;
471 : }
472 0 : pWait.reset();
473 :
474 : // Search in the specialized areas when no search is present in selections.
475 : // When searching selections will already searched in these special areas.
476 0 : bool bHasSrchInOther = m_bExtra;
477 0 : if (!m_pSrchItem->GetSelection() && !m_bExtra )
478 : {
479 0 : m_bExtra = true;
480 0 : if( FUNC_Search( aOpts ) )
481 : {
482 0 : m_bFound = sal_True;
483 0 : m_pWrtShell->Pop();
484 0 : m_pWrtShell->EndAllAction();
485 0 : return sal_True;
486 : }
487 0 : m_bExtra = false;
488 : }
489 : else
490 0 : m_bExtra = !m_bExtra;
491 :
492 : // If starting position is at the end or beginning of the document.
493 0 : if (aOpts.bDontWrap)
494 : {
495 0 : m_pWrtShell->EndAllAction();
496 0 : if( !bApi )
497 0 : SvxSearchDialogWrapper::SetSearchLabel(SL_NotFound);
498 0 : m_bFound = sal_False;
499 0 : m_pWrtShell->Pop();
500 0 : return sal_False;
501 : }
502 0 : m_pWrtShell->EndAllAction();
503 : // Try again with WrapAround?
504 :
505 0 : m_pWrtShell->StartAllAction();
506 0 : m_pWrtShell->Pop(sal_False);
507 0 : pWait.reset(new SwWait( *GetDocShell(), true ));
508 :
509 0 : bool bSrchBkwrd = DOCPOS_START == aOpts.eEnd;
510 :
511 0 : aOpts.eEnd = bSrchBkwrd ? DOCPOS_START : DOCPOS_END;
512 0 : aOpts.eStart = bSrchBkwrd ? DOCPOS_END : DOCPOS_START;
513 :
514 0 : if (bHasSrchInOther)
515 : {
516 0 : m_pWrtShell->ClearMark();
517 0 : if (bSrchBkwrd)
518 0 : m_pWrtShell->EndDoc();
519 : else
520 0 : m_pWrtShell->SttDoc();
521 : }
522 :
523 0 : m_bFound = bool(FUNC_Search( aOpts ));
524 0 : m_pWrtShell->EndAllAction();
525 0 : pWait.reset();
526 :
527 0 : if (m_bFound)
528 0 : SvxSearchDialogWrapper::SetSearchLabel(SL_End);
529 0 : else if(!bApi)
530 0 : SvxSearchDialogWrapper::SetSearchLabel(SL_NotFound);
531 0 : return m_bFound;
532 : }
533 :
534 0 : sal_Bool SwView::SearchAll(sal_uInt16* pFound)
535 : {
536 0 : SwWait aWait( *GetDocShell(), true );
537 0 : m_pWrtShell->StartAllAction();
538 :
539 0 : SwSearchOptions aOpts( m_pWrtShell, m_pSrchItem->GetBackward() );
540 :
541 0 : if (!m_pSrchItem->GetSelection())
542 : {
543 : // Cancel existing selections, if should not be sought in selected areas.
544 0 : m_pWrtShell->KillSelection(0, false);
545 :
546 0 : if( DOCPOS_START == aOpts.eEnd )
547 0 : m_pWrtShell->EndDoc();
548 : else
549 0 : m_pWrtShell->SttDoc();
550 : }
551 0 : m_bExtra = false;
552 0 : sal_uInt16 nFound = (sal_uInt16)FUNC_Search( aOpts );
553 0 : if(pFound)
554 0 : *pFound = nFound;
555 0 : m_bFound = 0 != nFound;
556 :
557 0 : m_pWrtShell->EndAllAction();
558 0 : return m_bFound;
559 : }
560 :
561 0 : void SwView::Replace()
562 : {
563 0 : SwWait aWait( *GetDocShell(), true );
564 :
565 0 : m_pWrtShell->StartAllAction();
566 :
567 0 : if( m_pSrchItem->GetPattern() ) // Templates?
568 : {
569 0 : SwRewriter aRewriter;
570 0 : aRewriter.AddRule(UndoArg1, m_pSrchItem->GetSearchString());
571 0 : aRewriter.AddRule(UndoArg2, SW_RESSTR(STR_YIELDS));
572 0 : aRewriter.AddRule(UndoArg3, m_pSrchItem->GetReplaceString());
573 :
574 0 : m_pWrtShell->StartUndo(UNDO_UI_REPLACE_STYLE, &aRewriter);
575 :
576 : m_pWrtShell->SetTxtFmtColl( m_pWrtShell->GetParaStyle(
577 : m_pSrchItem->GetReplaceString(),
578 0 : SwWrtShell::GETSTYLE_CREATESOME ));
579 :
580 0 : m_pWrtShell->EndUndo();
581 : }
582 : else
583 : {
584 0 : if (GetPostItMgr()->HasActiveSidebarWin())
585 0 : GetPostItMgr()->Replace(m_pSrchItem);
586 :
587 0 : sal_Bool bReqReplace = true;
588 :
589 0 : if(m_pWrtShell->HasSelection())
590 : {
591 : /* check that the selection match the search string*/
592 : //save state
593 0 : SwPosition aStartPos = (* m_pWrtShell->GetSwCrsr()->Start());
594 0 : SwPosition aEndPos = (* m_pWrtShell->GetSwCrsr()->End());
595 0 : sal_Bool bHasSelection = m_pSrchItem->GetSelection();
596 0 : sal_uInt16 nOldCmd = m_pSrchItem->GetCommand();
597 :
598 : //set state for checking if current selection has a match
599 0 : m_pSrchItem->SetCommand( SVX_SEARCHCMD_FIND );
600 0 : m_pSrchItem->SetSelection(true);
601 :
602 : //check if it matchs
603 0 : SwSearchOptions aOpts( m_pWrtShell, m_pSrchItem->GetBackward() );
604 0 : if( ! FUNC_Search(aOpts) )
605 : {
606 :
607 : //no matching therefore should not replace selection
608 : // => remove selection
609 :
610 0 : if(! m_pSrchItem->GetBackward() )
611 : {
612 0 : (* m_pWrtShell->GetSwCrsr()->Start()) = aStartPos;
613 0 : (* m_pWrtShell->GetSwCrsr()->End()) = aEndPos;
614 : }
615 : else
616 : {
617 0 : (* m_pWrtShell->GetSwCrsr()->Start()) = aEndPos;
618 0 : (* m_pWrtShell->GetSwCrsr()->End()) = aStartPos;
619 : }
620 0 : bReqReplace = false;
621 : }
622 :
623 : //set back old search state
624 0 : m_pSrchItem->SetCommand( nOldCmd );
625 0 : m_pSrchItem->SetSelection(bHasSelection);
626 : }
627 : /*
628 : * remove current selection
629 : * otherwise it is always replaced
630 : * no matter if the search string exists or not in the selection
631 : * Now the selection is removed and the next matching string is selected
632 : */
633 :
634 0 : if( bReqReplace )
635 : {
636 :
637 : sal_Bool bReplaced = m_pWrtShell->SwEditShell::Replace( m_pSrchItem->GetReplaceString(),
638 0 : m_pSrchItem->GetRegExp());
639 0 : if( bReplaced && m_pReplList && m_pReplList->Count() && m_pWrtShell->HasSelection() )
640 : {
641 0 : SfxItemSet aReplSet( m_pWrtShell->GetAttrPool(),
642 0 : aTxtFmtCollSetRange );
643 0 : if( m_pReplList->Get( aReplSet ).Count() )
644 : {
645 0 : ::SfxToSwPageDescAttr( *m_pWrtShell, aReplSet );
646 0 : m_pWrtShell->SwEditShell::SetAttrSet( aReplSet );
647 0 : }
648 : }
649 : }
650 : }
651 :
652 0 : m_pWrtShell->EndAllAction();
653 0 : }
654 :
655 0 : SwSearchOptions::SwSearchOptions( SwWrtShell* pSh, sal_Bool bBackward )
656 : {
657 0 : eStart = DOCPOS_CURR;
658 0 : if( bBackward )
659 : {
660 0 : eEnd = DOCPOS_START;
661 0 : bDontWrap = pSh->IsEndOfDoc();
662 : }
663 : else
664 : {
665 0 : eEnd = DOCPOS_END;
666 0 : bDontWrap = pSh->IsStartOfDoc();
667 : }
668 0 : }
669 :
670 0 : sal_uLong SwView::FUNC_Search( const SwSearchOptions& rOptions )
671 : {
672 0 : SvxSearchDialogWrapper::SetSearchLabel(SL_Empty);
673 :
674 0 : sal_Bool bDoReplace = m_pSrchItem->GetCommand() == SVX_SEARCHCMD_REPLACE ||
675 0 : m_pSrchItem->GetCommand() == SVX_SEARCHCMD_REPLACE_ALL;
676 :
677 0 : int eRanges = m_pSrchItem->GetSelection() ?
678 0 : FND_IN_SEL : m_bExtra ? FND_IN_OTHER : FND_IN_BODY;
679 0 : if (m_pSrchItem->GetCommand() == SVX_SEARCHCMD_FIND_ALL ||
680 0 : m_pSrchItem->GetCommand() == SVX_SEARCHCMD_REPLACE_ALL)
681 0 : eRanges |= FND_IN_SELALL;
682 :
683 0 : m_pWrtShell->SttSelect();
684 :
685 : static const sal_uInt16 aSearchAttrRange[] = {
686 : RES_FRMATR_BEGIN, RES_FRMATR_END-1,
687 : RES_CHRATR_BEGIN, RES_CHRATR_END-1,
688 : RES_PARATR_BEGIN, RES_PARATR_END-1,
689 : SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP,
690 : 0 };
691 :
692 0 : SfxItemSet aSrchSet( m_pWrtShell->GetAttrPool(), aSearchAttrRange);
693 0 : if( m_pSrchList && m_pSrchList->Count() )
694 : {
695 0 : m_pSrchList->Get( aSrchSet );
696 :
697 : // -- Page break with page template
698 0 : ::SfxToSwPageDescAttr( *m_pWrtShell, aSrchSet );
699 : }
700 :
701 0 : SfxItemSet* pReplSet = 0;
702 0 : if( bDoReplace && m_pReplList && m_pReplList->Count() )
703 : {
704 0 : pReplSet = new SfxItemSet( m_pWrtShell->GetAttrPool(),
705 0 : aSearchAttrRange );
706 0 : m_pReplList->Get( *pReplSet );
707 :
708 : // -- Page break with page template
709 0 : ::SfxToSwPageDescAttr( *m_pWrtShell, *pReplSet );
710 :
711 0 : if( !pReplSet->Count() ) // too bad, we don't know
712 0 : DELETEZ( pReplSet ); // the attributes
713 : }
714 :
715 : // build SearchOptions to be used
716 :
717 0 : SearchOptions aSearchOpt( m_pSrchItem->GetSearchOptions() );
718 0 : aSearchOpt.Locale = GetAppLanguageTag().getLocale();
719 0 : if( !bDoReplace )
720 0 : aSearchOpt.replaceString = OUString();
721 :
722 : sal_uLong nFound;
723 0 : if( aSrchSet.Count() || ( pReplSet && pReplSet->Count() ))
724 : {
725 : nFound = m_pWrtShell->SearchAttr(
726 : aSrchSet,
727 0 : !m_pSrchItem->GetPattern(),
728 : rOptions.eStart,
729 : rOptions.eEnd,
730 : FindRanges(eRanges),
731 0 : !m_pSrchItem->GetSearchString().isEmpty() ? &aSearchOpt : 0,
732 0 : pReplSet );
733 : }
734 0 : else if( m_pSrchItem->GetPattern() )
735 : {
736 : // Searching (and replacing) templates
737 0 : const OUString sRplStr( m_pSrchItem->GetReplaceString() );
738 : nFound = m_pWrtShell->SearchTempl( m_pSrchItem->GetSearchString(),
739 : rOptions.eStart,
740 : rOptions.eEnd,
741 : FindRanges(eRanges),
742 0 : bDoReplace ? &sRplStr : 0 );
743 : }
744 : else
745 : {
746 : // Normal search
747 0 : nFound = m_pWrtShell->SearchPattern(aSearchOpt, m_pSrchItem->GetNotes(),
748 : rOptions.eStart,
749 : rOptions.eEnd,
750 : FindRanges(eRanges),
751 0 : bDoReplace );
752 : }
753 0 : m_pWrtShell->EndSelect();
754 0 : return nFound;
755 : }
756 :
757 0 : SvxSearchDialog* SwView::GetSearchDialog()
758 : {
759 0 : const sal_uInt16 nId = SvxSearchDialogWrapper::GetChildWindowId();
760 0 : SvxSearchDialogWrapper *pWrp = (SvxSearchDialogWrapper*) SfxViewFrame::Current()->GetChildWindow(nId);
761 0 : m_pSrchDlg = pWrp ? pWrp->getDialog () : 0;
762 0 : return m_pSrchDlg;
763 : }
764 :
765 0 : void SwView::StateSearch(SfxItemSet &rSet)
766 : {
767 0 : SfxWhichIter aIter(rSet);
768 0 : sal_uInt16 nWhich = aIter.FirstWhich();
769 :
770 0 : while(nWhich)
771 : {
772 0 : switch(nWhich)
773 : {
774 : case SID_SEARCH_OPTIONS:
775 : {
776 0 : sal_uInt16 nOpt = 0xFFFF;
777 0 : if( GetDocShell()->IsReadOnly() )
778 : nOpt &= ~( SEARCH_OPTIONS_REPLACE |
779 0 : SEARCH_OPTIONS_REPLACE_ALL );
780 0 : rSet.Put( SfxUInt16Item( SID_SEARCH_OPTIONS, nOpt));
781 : }
782 0 : break;
783 : case SID_SEARCH_ITEM:
784 : {
785 0 : if ( !m_pSrchItem )
786 : {
787 0 : m_pSrchItem = new SvxSearchItem( SID_SEARCH_ITEM );
788 0 : m_pSrchItem->SetFamily(SFX_STYLE_FAMILY_PARA);
789 0 : m_pSrchItem->SetSearchString( m_pWrtShell->GetSelTxt() );
790 : }
791 :
792 0 : if( m_bJustOpened && m_pWrtShell->IsSelection() )
793 : {
794 0 : OUString aTxt;
795 0 : if( 1 == m_pWrtShell->GetCrsrCnt() &&
796 0 : !( aTxt = m_pWrtShell->SwCrsrShell::GetSelTxt() ).isEmpty() )
797 : {
798 0 : m_pSrchItem->SetSearchString( aTxt );
799 0 : m_pSrchItem->SetSelection( false );
800 : }
801 : else
802 0 : m_pSrchItem->SetSelection( true );
803 : }
804 :
805 0 : m_bJustOpened = false;
806 0 : rSet.Put( *m_pSrchItem );
807 : }
808 0 : break;
809 : }
810 0 : nWhich = aIter.NextWhich();
811 0 : }
812 0 : }
813 :
814 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|