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