LibreOffice Module sw (master) 1
viewsrch.cxx
Go to the documentation of this file.
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 <memory>
23#include <boost/property_tree/json_parser.hpp>
24
25#include <hintids.hxx>
26
27#include <sal/log.hxx>
28#include <svl/cjkoptions.hxx>
29#include <svl/ctloptions.hxx>
30#include <svx/pageitem.hxx>
31#include <svl/whiter.hxx>
32#include <sfx2/viewfrm.hxx>
33#include <svl/eitem.hxx>
34#include <svl/srchitem.hxx>
35#include <sfx2/bindings.hxx>
36#include <sfx2/request.hxx>
37#include <sfx2/lokhelper.hxx>
38#include <svx/srchdlg.hxx>
39#include <swmodule.hxx>
40#include <swwait.hxx>
41#include <workctrl.hxx>
42#include <view.hxx>
43#include <wrtsh.hxx>
44#include <swundo.hxx>
45#include <uitool.hxx>
46#include <cmdid.h>
47#include <docsh.hxx>
48#include <LibreOfficeKit/LibreOfficeKitEnums.h>
49#include <comphelper/lok.hxx>
50#include <comphelper/string.hxx>
51
52#include <strings.hrc>
53#include <SwRewriter.hxx>
54
55#include <PostItMgr.hxx>
56
57using namespace com::sun::star;
58using namespace ::com::sun::star::i18n;
59using namespace ::com::sun::star::lang;
60using namespace ::com::sun::star::util;
61
62//Search Parameter
63
65{
68
69 SwSearchOptions( SwWrtShell const * pSh, bool bBackward );
70};
71
73static void lcl_addContainerToJson(boost::property_tree::ptree& rTree, const OString& rKey, const std::vector<OString>& rMatches)
74{
75 boost::property_tree::ptree aChildren;
76
77 for (const OString& rMatch : rMatches)
78 {
79 boost::property_tree::ptree aChild;
80 aChild.put("part", "0");
81 aChild.put("rectangles", rMatch.getStr());
82 aChildren.push_back(std::make_pair("", aChild));
83 }
84
85 rTree.add_child(rKey.getStr(), aChildren);
86}
87
89static void lcl_emitSearchResultCallbacks(SvxSearchItem const * pSearchItem, SwWrtShell const * pWrtShell, bool bHighlightAll)
90{
91 // Emit a callback also about the selection rectangles, grouped by matches.
92 SwPaM* pPaM = pWrtShell->GetCursor();
93 if (!pPaM)
94 return;
95
96 std::vector<OString> aMatches;
97 for (SwPaM& rPaM : pPaM->GetRingContainer())
98 {
99 if (SwShellCursor* pShellCursor = dynamic_cast<SwShellCursor*>(&rPaM))
100 {
101 std::vector<OString> aSelectionRectangles;
102 pShellCursor->SwSelPaintRects::Show(&aSelectionRectangles);
103 std::vector<OString> aRect;
104 for (const OString & rSelectionRectangle : aSelectionRectangles)
105 {
106 if (rSelectionRectangle.isEmpty())
107 continue;
108 aRect.push_back(rSelectionRectangle);
109 }
110 OString sRect = comphelper::string::join("; ", aRect);
111 aMatches.push_back(sRect);
112 }
113 }
114 boost::property_tree::ptree aTree;
115 aTree.put("searchString", pSearchItem->GetSearchString().toUtf8().getStr());
116 aTree.put("highlightAll", bHighlightAll);
117 lcl_addContainerToJson(aTree, "searchResultSelection", aMatches);
118
119 std::stringstream aStream;
120 boost::property_tree::write_json(aStream, aTree);
121 OString aPayload = aStream.str().c_str();
122
123 pWrtShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload.getStr());
124
125 if(bHighlightAll)
126 { // FindAll disables this during find, do it once when done.
127 SfxLokHelper::notifyUpdate(pWrtShell->GetSfxViewShell(),LOK_CALLBACK_TEXT_SELECTION);
128 SfxLokHelper::notifyOtherViewsUpdatePerViewId(pWrtShell->GetSfxViewShell(), LOK_CALLBACK_TEXT_VIEW_SELECTION);
129 }
130}
131
133{
135
136 const SfxItemSet* pArgs = rReq.GetArgs();
137 const SfxPoolItem* pItem = nullptr;
138 bool bQuiet = false;
139 if(pArgs && SfxItemState::SET == pArgs->GetItemState(SID_SEARCH_QUIET, false, &pItem))
140 bQuiet = static_cast<const SfxBoolItem*>( pItem)->GetValue();
141
142 sal_uInt16 nSlot = rReq.GetSlot();
143 if (nSlot == FN_REPEAT_SEARCH && !s_pSrchItem)
144 {
145 if(bQuiet)
146 {
147 rReq.SetReturnValue(SfxBoolItem(nSlot, false));
148 nSlot = 0;
149 }
150 }
151 if( m_pWrtShell->IsBlockMode() )
152 m_pWrtShell->LeaveBlockMode();
153 switch (nSlot)
154 {
155 // for now do nothing
156 case SID_SEARCH_ITEM:
157 {
158 delete s_pSrchItem;
159 s_pSrchItem = pArgs->Get(SID_SEARCH_ITEM).Clone();
160 }
161 break;
162
163 case FID_SEARCH_ON:
164 s_bJustOpened = true;
165 GetViewFrame()->GetBindings().Invalidate(SID_SEARCH_ITEM);
166 break;
167
168 case FID_SEARCH_OFF:
169 if(pArgs)
170 {
171 // Unregister dialog
172 delete s_pSrchItem;
173 s_pSrchItem = pArgs->Get(SID_SEARCH_ITEM).Clone();
174
175 s_xSearchList.reset();
176 s_xReplaceList.reset();
177
178 SvxSearchDialog *const pSrchDlg(GetSearchDialog());
179 if (pSrchDlg)
180 {
181 // We will remember the search-/replace items.
182 const SearchAttrItemList* pList = pSrchDlg->GetSearchItemList();
183 if( nullptr != pList && pList->Count() )
184 s_xSearchList.reset(new SearchAttrItemList( *pList ));
185
186 pList = pSrchDlg->GetReplaceItemList();
187 if (nullptr != pList && pList->Count())
188 s_xReplaceList.reset(new SearchAttrItemList( *pList ));
189 }
190 }
191 break;
192
193 case FN_REPEAT_SEARCH:
194 case FID_SEARCH_NOW:
195 {
196 sal_uInt16 nMoveType = SwView::GetMoveType();
197 {
198 if(FID_SEARCH_NOW == nSlot && !rReq.IsAPI())
200 }
201
202 SvxSearchDialog * pSrchDlg(GetSearchDialog());
203 if (pSrchDlg)
204 {
205 s_xSearchList.reset();
206 s_xReplaceList.reset();
207
208 const SearchAttrItemList* pList = pSrchDlg->GetSearchItemList();
209 if( nullptr != pList && pList->Count() )
210 s_xSearchList.reset(new SearchAttrItemList( *pList ));
211
212 pList = pSrchDlg->GetReplaceItemList();
213 if (nullptr != pList && pList->Count())
214 s_xReplaceList.reset(new SearchAttrItemList( *pList ));
215 }
216
217 if (nSlot == FN_REPEAT_SEARCH)
218 {
219 OSL_ENSURE(s_pSrchItem, "SearchItem missing");
220 if( !s_pSrchItem )
221 s_pSrchItem = new SvxSearchItem(SID_SEARCH_ITEM);
222 }
223 else
224 {
225 // Get SearchItem from request
226 OSL_ENSURE(pArgs, "Args missing");
227 if ( pArgs )
228 {
229 delete s_pSrchItem;
230 s_pSrchItem = pArgs->Get(SID_SEARCH_ITEM).Clone();
231 }
232 }
233 SvxSearchCmd eCommand = s_pSrchItem->GetCommand();
234 switch (eCommand)
235 {
236 case SvxSearchCmd::FIND:
237 {
238 bool bRet = SearchAndWrap(bQuiet);
239 if( bRet )
240 {
241 Scroll(m_pWrtShell->GetCharRect().SVRect());
243 lcl_emitSearchResultCallbacks(s_pSrchItem, m_pWrtShell.get(), /* bHighlightAll = */ false);
244 }
245 rReq.SetReturnValue(SfxBoolItem(nSlot, bRet));
246
247 GetDocShell()->Broadcast(SfxHint(SfxHintId::SwNavigatorUpdateTracking));
248 }
249 break;
250 case SvxSearchCmd::FIND_ALL:
251 {
252 // Disable LOK selection notifications during search.
253 m_pWrtShell->GetSfxViewShell()->setTiledSearching(true);
254 const auto nFound = SearchAll();
255 m_pWrtShell->GetSfxViewShell()->setTiledSearching(false);
256
257 GetDocShell()->Broadcast(
258 SfxHint(SfxHintId::SwNavigatorUpdateTracking));
259 GetDocShell()->Broadcast(
260 SfxHint(SfxHintId::SwNavigatorSelectOutlinesWithSelections));
261
262 if (nFound == 0)
263 {
264#if HAVE_FEATURE_DESKTOP
265 if( !bQuiet )
266 {
267 m_pWrtShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_SEARCH_NOT_FOUND, s_pSrchItem->GetSearchString().toUtf8().getStr());
268 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::NotFound);
269 }
270#endif
271 s_bFound = false;
272 }
273 else
274 {
276 lcl_emitSearchResultCallbacks(s_pSrchItem, m_pWrtShell.get(), /* bHighlightAll = */ true);
277 if (!bQuiet)
278 {
279 OUString sText(SwResId(STR_SEARCH_KEY_FOUND_TIMES));
280 sText = sText.replaceFirst("%1", OUString::number(nFound));
282 }
283 }
284 rReq.SetReturnValue(SfxBoolItem(nSlot, nFound != 0));
285 }
286 break;
287 case SvxSearchCmd::REPLACE:
288 {
289
290 // 1) Replace selection (Not if only attributes should be replaced)
291//JP 27.04.95: Why?
292// what if you only want to assign attributes to the found??
293
294 SvxSearchCmd nCmd = SvxSearchCmd::FIND;
295 if( !s_pSrchItem->GetReplaceString().isEmpty() ||
297 {
298 // Prevent, that the replaced string will be found again
299 // if the replacement string is containing the search string.
300 bool bBack = s_pSrchItem->GetBackward();
301 if (bBack)
302 m_pWrtShell->Push();
303 OUString aReplace( s_pSrchItem->GetReplaceString() );
305 std::optional<OUString> xBackRef = sw::ReplaceBackReferences(aTmp,
306 m_pWrtShell->GetCursor(), m_pWrtShell->GetLayout());
307 if( xBackRef )
308 s_pSrchItem->SetReplaceString( *xBackRef );
309 Replace();
310 if( xBackRef )
311 {
312 s_pSrchItem->SetReplaceString( aReplace );
313 }
314 if (bBack)
315 {
316 m_pWrtShell->Pop();
317 m_pWrtShell->SwapPam();
318 }
319 }
320 else if( s_xReplaceList )
321 nCmd = SvxSearchCmd::REPLACE;
322
323 // 2) Search further (without replacing!)
324
326 s_pSrchItem->SetCommand( nCmd );
327 bool bRet = SearchAndWrap(bQuiet);
328 if( bRet )
329 Scroll( m_pWrtShell->GetCharRect().SVRect());
330 s_pSrchItem->SetCommand( nOldCmd );
331 rReq.SetReturnValue(SfxBoolItem(nSlot, bRet));
332 }
333 break;
334
335 case SvxSearchCmd::REPLACE_ALL:
336 {
338 s_bExtra = false;
339 sal_uLong nFound;
340
341 { //Scope for SwWait-Object
342 SwWait aWait( *GetDocShell(), true );
343 m_pWrtShell->StartAllAction();
344
345 // i#8288 "replace all" should not change cursor
346 // position, so save current cursor
347 m_pWrtShell->Push();
348
350 {
351 // if we don't want to search in the selection...
352 m_pWrtShell->KillSelection(nullptr, false);
353 if (SwDocPositions::Start == aOpts.eEnd)
354 {
355 m_pWrtShell->EndOfSection();
356 }
357 else
358 {
359 m_pWrtShell->StartOfSection();
360 }
361 }
362 nFound = FUNC_Search( aOpts );
363 // create it just to overwrite it with stack cursor
364 m_pWrtShell->CreateCursor();
365 // i#8288 restore the original cursor position
367 m_pWrtShell->EndAllAction();
368 }
369
370 rReq.SetReturnValue(SfxBoolItem(nSlot, nFound != 0 && ULONG_MAX != nFound));
371 if( !nFound )
372 {
373#if HAVE_FEATURE_DESKTOP
374 if( !bQuiet )
375 {
376 m_pWrtShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_SEARCH_NOT_FOUND, s_pSrchItem->GetSearchString().toUtf8().getStr());
377 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::NotFound);
378 }
379#endif
380 s_bFound = false;
381 SwView::SetMoveType(nMoveType);
382 return;
383 }
384
385 if( !bQuiet && ULONG_MAX != nFound)
386 {
387 OUString sText( SwResId( STR_NB_REPLACED ) );
388 sText = sText.replaceFirst("XX", OUString::number( nFound ));
390 }
391 }
392 break;
393 }
394
395 uno::Reference< frame::XDispatchRecorder > xRecorder =
397 //prevent additional dialogs in recorded macros
398 if ( xRecorder.is() )
399 rReq.AppendItem(SfxBoolItem(SID_SEARCH_QUIET, true));
400
401 rReq.Done();
403 SwView::SetMoveType(nMoveType);
404 }
405 break;
406 case FID_SEARCH_SEARCHSET:
407 case FID_SEARCH_REPLACESET:
408 {
409 static const WhichRangesContainer aNormalAttr(svl::Items<
422/*24 */ SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP
423 >);
424
425 SfxItemSet aSet(m_pWrtShell->GetAttrPool(), aNormalAttr);
426
427 if( SW_MOD()->GetCTLOptions().IsCTLFontEnabled() )
428 {
430 }
432 {
436 }
437
438 TypedWhichId<SvxSetItem> nWhich = SID_SEARCH_SEARCHSET;
439
440 if ( FID_SEARCH_REPLACESET == nSlot )
441 {
442 nWhich = SID_SEARCH_REPLACESET;
443
444 if ( s_xReplaceList )
445 {
446 s_xReplaceList->Get( aSet );
447 s_xReplaceList.reset();
448 }
449 }
450 else if ( s_xSearchList )
451 {
452 s_xSearchList->Get( aSet );
453 s_xSearchList.reset();
454 }
455 rReq.SetReturnValue( SvxSetItem( nWhich, aSet ) );
456 }
457 break;
458 default:
459 SAL_WARN_IF( nSlot, "sw", "nSlot: " << nSlot << " wrong Dispatcher (viewsrch.cxx)" );
460 return;
461 }
462}
463
465{
467
468 // Remember starting position of the search for wraparound
469 // Start- / EndAction perhaps because existing selections of 'search all'
470 m_pWrtShell->StartAllAction();
471 m_pWrtShell->Push();
472
473 // After a search all action we place the cursor at the beginning of
474 // the document so that the single search selects the first matching
475 // occurrence in the document instead of the second.
476 if( m_eLastSearchCommand == SvxSearchCmd::FIND_ALL )
477 {
478 if( SwDocPositions::Start == aOpts.eEnd )
479 m_pWrtShell->EndOfSection();
480 else
481 m_pWrtShell->StartOfSection();
482 }
483
484 // fdo#65014 : Ensure that the point of the cursor is at the extremity of the
485 // selection closest to the end being searched to as to exclude the selected
486 // region from the search. (This doesn't work in the case of multiple
487 // selected regions as the cursor doesn't mark the selection in that case.)
488 m_pWrtShell->GetCursor()->Normalize( s_pSrchItem->GetBackward() );
489
490 if (!m_pWrtShell->HasSelection() && (s_pSrchItem->HasStartPoint()))
491 {
492 // No selection -> but we have a start point (top left corner of the
493 // current view), start searching from there, not from the current
494 // cursor position.
495 SwEditShell& rShell = GetWrtShell();
497 rShell.SetCursor(aPosition);
498 }
499
500 // If you want to search in selected areas, they must not be unselected.
502 m_pWrtShell->KillSelection(nullptr, false);
503
504 std::optional<SwWait> oWait( std::in_place, *GetDocShell(), true );
505 if( FUNC_Search( aOpts ) )
506 {
507 s_bFound = true;
508 if(m_pWrtShell->IsSelFrameMode())
509 {
510 m_pWrtShell->UnSelectFrame();
511 m_pWrtShell->LeaveSelFrameMode();
512 }
513 m_pWrtShell->Pop();
514 m_pWrtShell->EndAllAction();
515 return true;
516 }
517 oWait.reset();
518
519 // Search in the specialized areas when no search is present in selections.
520 // When searching selections will already searched in these special areas.
521 bool bHasSrchInOther = s_bExtra;
522 if (!s_pSrchItem->GetSelection() && !s_bExtra )
523 {
524 s_bExtra = true;
525 if( FUNC_Search( aOpts ) )
526 {
527 s_bFound = true;
528 m_pWrtShell->Pop();
529 m_pWrtShell->EndAllAction();
530 return true;
531 }
532 s_bExtra = false;
533 }
534 else
536
537 // If starting position is at the end or beginning of the document.
538 if (aOpts.bDontWrap)
539 {
540 m_pWrtShell->EndAllAction();
541 if( !bApi )
542 {
543#if HAVE_FEATURE_DESKTOP
544 m_pWrtShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_SEARCH_NOT_FOUND, s_pSrchItem->GetSearchString().toUtf8().getStr());
545 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::NotFound);
546#endif
547 }
548 s_bFound = false;
549 m_pWrtShell->Pop();
550 return false;
551 }
552 m_pWrtShell->EndAllAction();
553 // Try again with WrapAround?
554
555 m_pWrtShell->StartAllAction();
557 oWait.emplace( *GetDocShell(), true );
558
559 bool bSrchBkwrd = SwDocPositions::Start == aOpts.eEnd;
560
561 aOpts.eEnd = bSrchBkwrd ? SwDocPositions::Start : SwDocPositions::End;
562 aOpts.eStart = bSrchBkwrd ? SwDocPositions::End : SwDocPositions::Start;
563
564 if (bHasSrchInOther)
565 {
566 m_pWrtShell->ClearMark();
567 // Select the start or the end of the entire document
568 if (bSrchBkwrd)
569 m_pWrtShell->SttEndDoc(false);
570 else
571 m_pWrtShell->SttEndDoc(true);
572 }
573
574 s_bFound = bool(FUNC_Search( aOpts ));
575
576 // If WrapAround found no matches in the body text, search in the special
577 // sections, too.
579 {
580 s_bExtra = true;
581 if (FUNC_Search(aOpts))
582 s_bFound = true;
583 else
584 s_bExtra = false;
585 }
586
587 m_pWrtShell->EndAllAction();
588 oWait.reset();
589#if HAVE_FEATURE_DESKTOP
590 if (s_bFound)
591 {
592 if (!bSrchBkwrd)
594 else
595 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::Start);
596 }
597 else if(!bApi)
598 {
599 m_pWrtShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_SEARCH_NOT_FOUND, s_pSrchItem->GetSearchString().toUtf8().getStr());
600 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::NotFound);
601 }
602#endif
603 return s_bFound;
604}
605
607{
608 SwWait aWait( *GetDocShell(), true );
609 m_pWrtShell->StartAllAction();
610
612
614 {
615 // Cancel existing selections, if should not be sought in selected areas.
616 m_pWrtShell->KillSelection(nullptr, false);
617
618 if( SwDocPositions::Start == aOpts.eEnd )
619 m_pWrtShell->EndOfSection();
620 else
621 m_pWrtShell->StartOfSection();
622 }
623 s_bExtra = false;
624 sal_uInt16 nFound = o3tl::narrowing<sal_uInt16>(FUNC_Search( aOpts ));
625 s_bFound = 0 != nFound;
626
627 m_pWrtShell->EndAllAction();
628 return nFound;
629}
630
632{
633 SwWait aWait( *GetDocShell(), true );
634
635 m_pWrtShell->StartAllAction();
636
637 if( s_pSrchItem->GetPattern() ) // Templates?
638 {
639 SwRewriter aRewriter;
641 aRewriter.AddRule(UndoArg2, SwResId(STR_YIELDS));
643
644 m_pWrtShell->StartUndo(SwUndoId::UI_REPLACE_STYLE, &aRewriter);
645
646 m_pWrtShell->SetTextFormatColl( m_pWrtShell->GetParaStyle(
649
650 m_pWrtShell->EndUndo();
651 }
652 else
653 {
654 if (GetPostItMgr()->HasActiveSidebarWin())
656
657 bool bReqReplace = true;
658
659 if(m_pWrtShell->HasSelection())
660 {
661 /* check that the selection match the search string*/
662 //save state
663 SwPosition aStartPos = * m_pWrtShell->GetCursor()->Start();
664 SwPosition aEndPos = * m_pWrtShell->GetCursor()->End();
665 bool bHasSelection = s_pSrchItem->GetSelection();
667
668 //set state for checking if current selection has a match
669 s_pSrchItem->SetCommand( SvxSearchCmd::FIND );
671
672 //check if it matches
674 if( ! FUNC_Search(aOpts) )
675 {
676
677 //no matching therefore should not replace selection
678 // => remove selection
679
680 if(! s_pSrchItem->GetBackward() )
681 {
682 (* m_pWrtShell->GetCursor()->Start()) = aStartPos;
683 (* m_pWrtShell->GetCursor()->End()) = aEndPos;
684 }
685 else
686 {
687 (* m_pWrtShell->GetCursor()->Start()) = aEndPos;
688 (* m_pWrtShell->GetCursor()->End()) = aStartPos;
689 }
690 bReqReplace = false;
691 }
692
693 //set back old search state
694 s_pSrchItem->SetCommand( nOldCmd );
695 s_pSrchItem->SetSelection(bHasSelection);
696 }
697 /*
698 * remove current selection
699 * otherwise it is always replaced
700 * no matter if the search string exists or not in the selection
701 * Now the selection is removed and the next matching string is selected
702 */
703
704 if( bReqReplace )
705 {
706
707 bool bReplaced = m_pWrtShell->SwEditShell::Replace( s_pSrchItem->GetReplaceString(),
709 if( bReplaced && s_xReplaceList && s_xReplaceList->Count() && m_pWrtShell->HasSelection() )
710 {
711 SfxItemSet aReplSet( m_pWrtShell->GetAttrPool(),
713 if( s_xReplaceList->Get( aReplSet ).Count() )
714 {
716 m_pWrtShell->SwEditShell::SetAttrSet( aReplSet );
717 }
718 }
719 }
720 }
721
722 m_pWrtShell->EndAllAction();
723}
724
725SwSearchOptions::SwSearchOptions( SwWrtShell const * pSh, bool bBackward )
726 : eStart(SwDocPositions::Curr)
727{
728 if( bBackward )
729 {
731 bDontWrap = pSh->IsEndOfDoc();
732 }
733 else
734 {
736 bDontWrap = pSh->IsStartOfDoc();
737 }
738}
739
741{
742#if HAVE_FEATURE_DESKTOP
743 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::Empty);
744#endif
745 bool bDoReplace = s_pSrchItem->GetCommand() == SvxSearchCmd::REPLACE ||
746 s_pSrchItem->GetCommand() == SvxSearchCmd::REPLACE_ALL;
747
750 : s_bExtra
752 if (s_pSrchItem->GetCommand() == SvxSearchCmd::FIND_ALL ||
753 s_pSrchItem->GetCommand() == SvxSearchCmd::REPLACE_ALL)
754 eRanges |= FindRanges::InSelAll;
755
756 m_pWrtShell->SttSelect();
757
758 static const WhichRangesContainer aSearchAttrRange(svl::Items<
762 SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP
763 >);
764
765 SfxItemSet aSrchSet( m_pWrtShell->GetAttrPool(), aSearchAttrRange);
766 if( s_xSearchList && s_xSearchList->Count() )
767 {
768 s_xSearchList->Get( aSrchSet );
769
770 // -- Page break with page template
772 }
773
774 std::optional<SfxItemSet> xReplSet;
775 if( bDoReplace && s_xReplaceList && s_xReplaceList->Count() )
776 {
777 xReplSet.emplace( m_pWrtShell->GetAttrPool(), aSearchAttrRange );
778 s_xReplaceList->Get( *xReplSet );
779
780 // -- Page break with page template
781 ::SfxToSwPageDescAttr( *m_pWrtShell, *xReplSet );
782
783 if( !xReplSet->Count() ) // too bad, we don't know
784 xReplSet.reset(); // the attributes
785 }
786
787 // build SearchOptions to be used
788
790 aSearchOpt.Locale = GetAppLanguageTag().getLocale();
791 if( !bDoReplace )
792 aSearchOpt.replaceString.clear();
793
794 sal_Int32 nFound;
795 if( aSrchSet.Count() || ( xReplSet && xReplSet->Count() ))
796 {
797 nFound = m_pWrtShell->SearchAttr(
798 aSrchSet,
800 rOptions.eStart,
801 rOptions.eEnd,
802 eRanges,
803 !s_pSrchItem->GetSearchString().isEmpty() ? &aSearchOpt : nullptr,
804 xReplSet ? &*xReplSet : nullptr );
805 }
806 else if( s_pSrchItem->GetPattern() )
807 {
808 // Searching (and replacing) templates
809 const OUString& sRplStr( s_pSrchItem->GetReplaceString() );
810 nFound = m_pWrtShell->SearchTempl( s_pSrchItem->GetSearchString(),
811 rOptions.eStart,
812 rOptions.eEnd,
813 eRanges,
814 bDoReplace ? &sRplStr : nullptr );
815 }
816 else
817 {
818 // Normal search
819 nFound = m_pWrtShell->SearchPattern(aSearchOpt, s_pSrchItem->GetNotes(),
820 rOptions.eStart,
821 rOptions.eEnd,
822 eRanges,
823 bDoReplace );
824 }
825 m_pWrtShell->EndSelect();
826 return nFound;
827}
828
830{
831#if HAVE_FEATURE_DESKTOP
832 const sal_uInt16 nId = SvxSearchDialogWrapper::GetChildWindowId();
834 auto pSrchDlg = pWrp ? pWrp->getDialog() : nullptr;
835 return pSrchDlg;
836#else
837 return nullptr;
838#endif
839}
840
842{
843 SfxWhichIter aIter(rSet);
844 sal_uInt16 nWhich = aIter.FirstWhich();
845
846 while(nWhich)
847 {
848 switch(nWhich)
849 {
850 case SID_SEARCH_OPTIONS:
851 {
852 SearchOptionFlags nOpt = SearchOptionFlags::ALL;
853 if( GetDocShell()->IsReadOnly() )
854 nOpt &= ~SearchOptionFlags( SearchOptionFlags::REPLACE |
855 SearchOptionFlags::REPLACE_ALL );
856 rSet.Put( SfxUInt16Item( SID_SEARCH_OPTIONS, static_cast<sal_uInt16>(nOpt) ));
857 }
858 break;
859 case SID_SEARCH_ITEM:
860 {
861 if ( !s_pSrchItem )
862 {
863 s_pSrchItem = new SvxSearchItem( SID_SEARCH_ITEM );
864 s_pSrchItem->SetFamily(SfxStyleFamily::Para);
865 s_pSrchItem->SetSearchString( m_pWrtShell->GetSelText() );
866 }
867
868 if( s_bJustOpened && m_pWrtShell->IsSelection() )
869 {
870 OUString aText;
871 if( 1 == m_pWrtShell->GetCursorCnt() &&
872 !( aText = m_pWrtShell->SwCursorShell::GetSelText() ).isEmpty() )
873 {
875 s_pSrchItem->SetSelection( false );
876 }
877 else
878 s_pSrchItem->SetSelection( true );
879 }
880
881 s_bJustOpened = false;
882 rSet.Put( *s_pSrchItem );
883 }
884 break;
885 }
886 nWhich = aIter.NextWhich();
887 }
888}
889
890/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ UndoArg1
Definition: SwRewriter.hxx:29
@ UndoArg3
Definition: SwRewriter.hxx:31
@ UndoArg2
Definition: SwRewriter.hxx:30
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
sal_uInt16 Count() const
void Invalidate(sal_uInt16 nId)
const css::uno::Reference< css::frame::XDispatchRecorder > & GetRecorder() const
sal_uInt16 Count() const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
void MergeRange(sal_uInt16 nFrom, sal_uInt16 nTo)
static void notifyUpdate(SfxViewShell const *pViewShell, int nType)
static void notifyOtherViewsUpdatePerViewId(SfxViewShell const *pViewShell, int nType)
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const=0
sal_uInt16 GetSlot() const
const SfxItemSet * GetArgs() const
void AppendItem(const SfxPoolItem &)
void SetReturnValue(const SfxPoolItem &)
bool IsAPI() const
void Done(bool bRemove=false)
static SfxViewFrame * Current()
SfxBindings & GetBindings()
SfxChildWindow * GetChildWindow(sal_uInt16)
SfxViewFrame * GetViewFrame() const
virtual void libreOfficeKitViewCallback(int nType, const char *pPayload) const override
sal_uInt16 FirstWhich()
sal_uInt16 NextWhich()
SvxSearchDialog * getDialog()
static void SetSearchLabel(const SearchLabel &rSL)
const SearchAttrItemList * GetReplaceItemList() const
const SearchAttrItemList * GetSearchItemList() const
bool HasStartPoint() const
void SetReplaceString(const OUString &rNewString)
const OUString & GetSearchString() const
SvxSearchCmd GetCommand() const
void SetSelection(bool bNewSelection)
const OUString & GetReplaceString() const
bool GetNotes() const
const i18nutil::SearchOptions2 & GetSearchOptions() const
bool GetSelection() const
void SetCommand(SvxSearchCmd nNewCommand)
void SetSearchString(const OUString &rNewString)
sal_Int32 GetStartPointX() const
bool GetBackward() const
void SetFamily(SfxStyleFamily eNewFamily)
bool GetRegExp() const
bool GetPattern() const
sal_Int32 GetStartPointY() const
int SetCursor(const Point &rPt, bool bOnlyText=false, bool bBlock=true)
Definition: crsrsh.cxx:761
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
bool IsStartOfDoc() const
Definition: crsrsh.cxx:2767
bool IsEndOfDoc() const
Definition: crsrsh.cxx:2779
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
sal_uInt16 Replace(SvxSearchItem const *pItem)
Definition: PostItMgr.cxx:2306
void AddRule(SwUndoArg eWhat, const OUString &rWith)
Definition: SwRewriter.cxx:25
Represents the current text cursor of one opened edit window.
Definition: viscrs.hxx:140
SfxViewShell * GetSfxViewShell() const
Definition: viewsh.hxx:451
SvxSearchCmd m_eLastSearchCommand
Definition: view.hxx:235
static SvxSearchItem * s_pSrchItem
Definition: view.hxx:165
SwWrtShell & GetWrtShell() const
Definition: view.hxx:416
SAL_DLLPRIVATE sal_uInt16 SearchAll()
Definition: viewsrch.cxx:606
void Scroll(const tools::Rectangle &rRect, sal_uInt16 nRangeX=USHRT_MAX, sal_uInt16 nRangeY=USHRT_MAX)
Definition: viewport.cxx:393
SAL_DLLPRIVATE bool SearchAndWrap(bool bApi)
Definition: viewsrch.cxx:464
std::unique_ptr< SwWrtShell > m_pWrtShell
Definition: view.hxx:194
SAL_DLLPRIVATE sal_uLong FUNC_Search(const SwSearchOptions &rOptions)
Definition: viewsrch.cxx:740
static std::unique_ptr< SearchAttrItemList > s_xReplaceList
Definition: view.hxx:175
static std::unique_ptr< SearchAttrItemList > s_xSearchList
Definition: view.hxx:174
SwPostItMgr * GetPostItMgr()
Definition: view.hxx:642
static SvxSearchDialog * GetSearchDialog()
Definition: viewsrch.cxx:829
static bool s_bExtra
Definition: view.hxx:170
static bool s_bFound
Definition: view.hxx:171
SwDocShell * GetDocShell()
Definition: view.cxx:1160
void StateSearch(SfxItemSet &)
Definition: viewsrch.cxx:841
static sal_uInt16 GetMoveType()
Definition: viewmdi.cxx:707
SAL_DLLPRIVATE void Replace()
Definition: viewsrch.cxx:631
static void SetMoveType(sal_uInt16 nSet)
Definition: viewmdi.cxx:712
void ExecSearch(SfxRequest &)
Definition: viewsrch.cxx:132
static bool s_bJustOpened
Definition: view.hxx:172
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
void addCurrentPosition()
Definition: wrtsh1.cxx:1852
@ GETSTYLE_CREATESOME
Definition: wrtsh.hxx:362
ring_container GetRingContainer()
Definition: ring.hxx:240
#define FN_REPEAT_SEARCH
Definition: cmdid.h:110
SwDocPositions
Definition: cshtyp.hxx:104
FindRanges
Definition: cshtyp.hxx:91
@ InSel
Find in selections.
@ InSelAll
All (only in non-body and selections).
@ InOther
Find "all" in Footer/Header/Fly...
@ InBody
Find "one" only in body text.
constexpr OUStringLiteral IsReadOnly(u"IsReadOnly")
constexpr sal_uInt16 RES_FRMATR_BEGIN(RES_PARATR_LIST_END)
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_CJK_FONT(22)
constexpr sal_uInt16 RES_FRMATR_END(133)
constexpr sal_uInt16 RES_CHRATR_END(46)
constexpr TypedWhichId< SvxForbiddenRuleItem > RES_PARATR_FORBIDDEN_RULES(75)
constexpr sal_uInt16 RES_PARATR_BEGIN(RES_TXTATR_END)
constexpr TypedWhichId< SvxShadowedItem > RES_CHRATR_SHADOWED(13)
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_CTL_FONT(27)
constexpr TypedWhichId< SvxWeightItem > RES_CHRATR_CTL_WEIGHT(31)
constexpr TypedWhichId< SvxHyphenZoneItem > RES_PARATR_HYPHENZONE(69)
constexpr TypedWhichId< SvxCharReliefItem > RES_CHRATR_RELIEF(36)
constexpr TypedWhichId< SvxULSpaceItem > RES_UL_SPACE(92)
constexpr sal_uInt16 RES_PARATR_END(82)
constexpr TypedWhichId< SvxCharScaleWidthItem > RES_CHRATR_SCALEW(35)
constexpr TypedWhichId< SvxBrushItem > RES_CHRATR_BACKGROUND(21)
constexpr TypedWhichId< SvxCaseMapItem > RES_CHRATR_CASEMAP(RES_CHRATR_BEGIN)
constexpr TypedWhichId< SvxLineSpacingItem > RES_PARATR_LINESPACING(RES_PARATR_BEGIN)
constexpr sal_uInt16 RES_CHRATR_BEGIN(HINT_BEGIN)
constexpr TypedWhichId< SvxEmphasisMarkItem > RES_CHRATR_EMPHASIS_MARK(33)
constexpr TypedWhichId< SvxPostureItem > RES_CHRATR_POSTURE(11)
constexpr TypedWhichId< SvxBlinkItem > RES_CHRATR_BLINK(18)
constexpr TypedWhichId< SvxOverlineItem > RES_CHRATR_OVERLINE(38)
constexpr TypedWhichId< SvxParaVertAlignItem > RES_PARATR_VERTALIGN(76)
constexpr TypedWhichId< SvxCharRotateItem > RES_CHRATR_ROTATE(32)
constexpr TypedWhichId< SvxScriptSpaceItem > RES_PARATR_SCRIPTSPACE(73)
constexpr TypedWhichId< SvxWordLineModeItem > RES_CHRATR_WORDLINEMODE(16)
constexpr TypedWhichId< SvxWeightItem > RES_CHRATR_CJK_WEIGHT(26)
constexpr TypedWhichId< SvxTwoLinesItem > RES_CHRATR_TWO_LINES(34)
constexpr TypedWhichId< SwRegisterItem > RES_PARATR_REGISTER(71)
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
constexpr TypedWhichId< SvxColorItem > RES_CHRATR_COLOR(3)
const LanguageTag & GetAppLanguageTag()
Definition: init.cxx:732
WhichRangesContainer const aTextFormatCollSetRange(svl::Items< RES_CHRATR_BEGIN, RES_CHRATR_END-1, RES_PARATR_BEGIN, RES_PARATR_END-1, RES_PARATR_LIST_LEVEL, RES_PARATR_LIST_LEVEL, RES_FRMATR_BEGIN, RES_FRMATR_END-1, RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, XATTR_FILL_FIRST, XATTR_FILL_LAST >)
#define SAL_WARN_IF(condition, area, stream)
bool IsAnyEnabled()
OString join(std::string_view rSeparator, const std::vector< OString > &rSequence)
static constexpr auto Items
std::optional< OUString > ReplaceBackReferences(const i18nutil::SearchOptions2 &rSearchOpt, SwPaM *const pPam, SwRootFrame const *const pLayout)
Helperfunction to resolve backward references in regular expressions.
Definition: findtxt.cxx:1107
sal_Int16 nId
const char GetValue[]
static SfxItemSet & rSet
sal_uIntPtr sal_uLong
SearchOptionFlags
SvxSearchCmd
Marks a position in the document model.
Definition: pam.hxx:37
SwDocPositions eStart
Definition: viewsrch.cxx:66
SwSearchOptions(SwWrtShell const *pSh, bool bBackward)
Definition: viewsrch.cxx:725
SwDocPositions eEnd
Definition: viewsrch.cxx:66
css::lang::Locale Locale
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:165
#define SW_MOD()
Definition: swmodule.hxx:256
@ UI_REPLACE_STYLE
void SfxToSwPageDescAttr(const SwWrtShell &rShell, SfxItemSet &rSet)
Definition: uitool.cxx:655
static void lcl_emitSearchResultCallbacks(SvxSearchItem const *pSearchItem, SwWrtShell const *pWrtShell, bool bHighlightAll)
Emits LOK callbacks (count, selection) for search results.
Definition: viewsrch.cxx:89
static void lcl_addContainerToJson(boost::property_tree::ptree &rTree, const OString &rKey, const std::vector< OString > &rMatches)
Adds rMatches using rKey as a key to the rTree tree.
Definition: viewsrch.cxx:73
#define NID_SRCH_REP
Definition: workctrl.hxx:49