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