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() );
122
123 pWrtShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload);
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());
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());
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<
423/*24 */ SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP
424 >);
425
426 SfxItemSet aSet(m_pWrtShell->GetAttrPool(), aNormalAttr);
427
429 {
431 }
433 {
437 }
438
439 TypedWhichId<SvxSetItem> nWhich = SID_SEARCH_SEARCHSET;
440
441 if ( FID_SEARCH_REPLACESET == nSlot )
442 {
443 nWhich = SID_SEARCH_REPLACESET;
444
445 if ( s_xReplaceList )
446 {
447 s_xReplaceList->Get( aSet );
448 s_xReplaceList.reset();
449 }
450 }
451 else if ( s_xSearchList )
452 {
453 s_xSearchList->Get( aSet );
454 s_xSearchList.reset();
455 }
456 rReq.SetReturnValue( SvxSetItem( nWhich, aSet ) );
457 }
458 break;
459 default:
460 SAL_WARN_IF( nSlot, "sw", "nSlot: " << nSlot << " wrong Dispatcher (viewsrch.cxx)" );
461 return;
462 }
463}
464
466{
468
469 // Remember starting position of the search for wraparound
470 // Start- / EndAction perhaps because existing selections of 'search all'
471 m_pWrtShell->StartAllAction();
472 m_pWrtShell->Push();
473
474 // After a search all action we place the cursor at the beginning of
475 // the document so that the single search selects the first matching
476 // occurrence in the document instead of the second.
477 if( m_eLastSearchCommand == SvxSearchCmd::FIND_ALL )
478 {
479 if( SwDocPositions::Start == aOpts.eEnd )
480 m_pWrtShell->EndOfSection();
481 else
482 m_pWrtShell->StartOfSection();
483 }
484
485 // fdo#65014 : Ensure that the point of the cursor is at the extremity of the
486 // selection closest to the end being searched to as to exclude the selected
487 // region from the search. (This doesn't work in the case of multiple
488 // selected regions as the cursor doesn't mark the selection in that case.)
489 m_pWrtShell->GetCursor()->Normalize( s_pSrchItem->GetBackward() );
490
491 if (!m_pWrtShell->HasSelection() && (s_pSrchItem->HasStartPoint()))
492 {
493 // No selection -> but we have a start point (top left corner of the
494 // current view), start searching from there, not from the current
495 // cursor position.
496 SwEditShell& rShell = GetWrtShell();
498 rShell.SetCursor(aPosition);
499 }
500
501 // If you want to search in selected areas, they must not be unselected.
503 m_pWrtShell->KillSelection(nullptr, false);
504
505 std::optional<SwWait> oWait( std::in_place, *GetDocShell(), true );
506 if( FUNC_Search( aOpts ) )
507 {
508 s_bFound = true;
509 if(m_pWrtShell->IsSelFrameMode())
510 {
511 m_pWrtShell->UnSelectFrame();
512 m_pWrtShell->LeaveSelFrameMode();
513 }
514 m_pWrtShell->Pop();
515 m_pWrtShell->EndAllAction();
516 return true;
517 }
518 oWait.reset();
519
520 // Search in the specialized areas when no search is present in selections.
521 // When searching selections will already searched in these special areas.
522 bool bHasSrchInOther = s_bExtra;
523 if (!s_pSrchItem->GetSelection() && !s_bExtra )
524 {
525 s_bExtra = true;
526 if( FUNC_Search( aOpts ) )
527 {
528 s_bFound = true;
529 m_pWrtShell->Pop();
530 m_pWrtShell->EndAllAction();
531 return true;
532 }
533 s_bExtra = false;
534 }
535 else
537
538 // If starting position is at the end or beginning of the document.
539 if (aOpts.bDontWrap)
540 {
541 m_pWrtShell->EndAllAction();
542 if( !bApi )
543 {
544#if HAVE_FEATURE_DESKTOP
545 m_pWrtShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_SEARCH_NOT_FOUND, s_pSrchItem->GetSearchString().toUtf8());
546 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::NotFound);
547#endif
548 }
549 s_bFound = false;
550 m_pWrtShell->Pop();
551 return false;
552 }
553 m_pWrtShell->EndAllAction();
554 // Try again with WrapAround?
555
556 m_pWrtShell->StartAllAction();
558 oWait.emplace( *GetDocShell(), true );
559
560 bool bSrchBkwrd = SwDocPositions::Start == aOpts.eEnd;
561
562 aOpts.eEnd = bSrchBkwrd ? SwDocPositions::Start : SwDocPositions::End;
563 aOpts.eStart = bSrchBkwrd ? SwDocPositions::End : SwDocPositions::Start;
564
565 if (bHasSrchInOther)
566 {
567 m_pWrtShell->ClearMark();
568 // Select the start or the end of the entire document
569 if (bSrchBkwrd)
570 m_pWrtShell->SttEndDoc(false);
571 else
572 m_pWrtShell->SttEndDoc(true);
573 }
574
575 s_bFound = bool(FUNC_Search( aOpts ));
576
577 // If WrapAround found no matches in the body text, search in the special
578 // sections, too.
580 {
581 s_bExtra = true;
582 if (FUNC_Search(aOpts))
583 s_bFound = true;
584 else
585 s_bExtra = false;
586 }
587
588 m_pWrtShell->EndAllAction();
589 oWait.reset();
590#if HAVE_FEATURE_DESKTOP
591 if (s_bFound)
592 {
593 if (!bSrchBkwrd)
595 else
596 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::Start);
597 }
598 else if(!bApi)
599 {
600 m_pWrtShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_SEARCH_NOT_FOUND, s_pSrchItem->GetSearchString().toUtf8());
601 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::NotFound);
602 }
603#endif
604 return s_bFound;
605}
606
608{
609 SwWait aWait( *GetDocShell(), true );
610 m_pWrtShell->StartAllAction();
611
613
615 {
616 // Cancel existing selections, if should not be sought in selected areas.
617 m_pWrtShell->KillSelection(nullptr, false);
618
619 if( SwDocPositions::Start == aOpts.eEnd )
620 m_pWrtShell->EndOfSection();
621 else
622 m_pWrtShell->StartOfSection();
623 }
624 s_bExtra = false;
625 sal_uInt16 nFound = o3tl::narrowing<sal_uInt16>(FUNC_Search( aOpts ));
626 s_bFound = 0 != nFound;
627
628 m_pWrtShell->EndAllAction();
629 return nFound;
630}
631
633{
634 SwWait aWait( *GetDocShell(), true );
635
636 m_pWrtShell->StartAllAction();
637
638 if( s_pSrchItem->GetPattern() ) // Templates?
639 {
640 SwRewriter aRewriter;
642 aRewriter.AddRule(UndoArg2, SwResId(STR_YIELDS));
644
645 m_pWrtShell->StartUndo(SwUndoId::UI_REPLACE_STYLE, &aRewriter);
646
647 m_pWrtShell->SetTextFormatColl( m_pWrtShell->GetParaStyle(
650
651 m_pWrtShell->EndUndo();
652 }
653 else
654 {
655 if (GetPostItMgr()->HasActiveSidebarWin())
657
658 bool bReqReplace = true;
659
660 if(m_pWrtShell->HasSelection())
661 {
662 /* check that the selection match the search string*/
663 //save state
664 SwPosition aStartPos = * m_pWrtShell->GetCursor()->Start();
665 SwPosition aEndPos = * m_pWrtShell->GetCursor()->End();
666 bool bHasSelection = s_pSrchItem->GetSelection();
668
669 //set state for checking if current selection has a match
670 s_pSrchItem->SetCommand( SvxSearchCmd::FIND );
672
673 //check if it matches
675 if( ! FUNC_Search(aOpts) )
676 {
677
678 //no matching therefore should not replace selection
679 // => remove selection
680
681 if(! s_pSrchItem->GetBackward() )
682 {
683 (* m_pWrtShell->GetCursor()->Start()) = aStartPos;
684 (* m_pWrtShell->GetCursor()->End()) = aEndPos;
685 }
686 else
687 {
688 (* m_pWrtShell->GetCursor()->Start()) = aEndPos;
689 (* m_pWrtShell->GetCursor()->End()) = aStartPos;
690 }
691 bReqReplace = false;
692 }
693
694 //set back old search state
695 s_pSrchItem->SetCommand( nOldCmd );
696 s_pSrchItem->SetSelection(bHasSelection);
697 }
698 /*
699 * remove current selection
700 * otherwise it is always replaced
701 * no matter if the search string exists or not in the selection
702 * Now the selection is removed and the next matching string is selected
703 */
704
705 if( bReqReplace )
706 {
707
708 bool bReplaced = m_pWrtShell->SwEditShell::Replace( s_pSrchItem->GetReplaceString(),
710 if( bReplaced && s_xReplaceList && s_xReplaceList->Count() && m_pWrtShell->HasSelection() )
711 {
712 SfxItemSet aReplSet( m_pWrtShell->GetAttrPool(),
714 if( s_xReplaceList->Get( aReplSet ).Count() )
715 {
717 m_pWrtShell->SwEditShell::SetAttrSet( aReplSet );
718 }
719 }
720 }
721 }
722
723 m_pWrtShell->EndAllAction();
724}
725
726SwSearchOptions::SwSearchOptions( SwWrtShell const * pSh, bool bBackward )
727 : eStart(SwDocPositions::Curr)
728{
729 if( bBackward )
730 {
732 bDontWrap = pSh->IsEndOfDoc();
733 }
734 else
735 {
737 bDontWrap = pSh->IsStartOfDoc();
738 }
739}
740
742{
743#if HAVE_FEATURE_DESKTOP
744 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::Empty);
745#endif
746 bool bDoReplace = s_pSrchItem->GetCommand() == SvxSearchCmd::REPLACE ||
747 s_pSrchItem->GetCommand() == SvxSearchCmd::REPLACE_ALL;
748
751 : s_bExtra
753 if (s_pSrchItem->GetCommand() == SvxSearchCmd::FIND_ALL ||
754 s_pSrchItem->GetCommand() == SvxSearchCmd::REPLACE_ALL)
755 eRanges |= FindRanges::InSelAll;
756
757 m_pWrtShell->SttSelect();
758
759 static const WhichRangesContainer aSearchAttrRange(svl::Items<
763 SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP
764 >);
765
766 SfxItemSet aSrchSet( m_pWrtShell->GetAttrPool(), aSearchAttrRange);
767 if( s_xSearchList && s_xSearchList->Count() )
768 {
769 s_xSearchList->Get( aSrchSet );
770
771 // -- Page break with page template
773 }
774
775 std::optional<SfxItemSet> xReplSet;
776 if( bDoReplace && s_xReplaceList && s_xReplaceList->Count() )
777 {
778 xReplSet.emplace( m_pWrtShell->GetAttrPool(), aSearchAttrRange );
779 s_xReplaceList->Get( *xReplSet );
780
781 // -- Page break with page template
782 ::SfxToSwPageDescAttr( *m_pWrtShell, *xReplSet );
783
784 if( !xReplSet->Count() ) // too bad, we don't know
785 xReplSet.reset(); // the attributes
786 }
787
788 // build SearchOptions to be used
789
791 aSearchOpt.Locale = GetAppLanguageTag().getLocale();
792 if( !bDoReplace )
793 aSearchOpt.replaceString.clear();
794
795 sal_Int32 nFound;
796 if( aSrchSet.Count() || ( xReplSet && xReplSet->Count() ))
797 {
798 nFound = m_pWrtShell->SearchAttr(
799 aSrchSet,
801 rOptions.eStart,
802 rOptions.eEnd,
803 eRanges,
804 !s_pSrchItem->GetSearchString().isEmpty() ? &aSearchOpt : nullptr,
805 xReplSet ? &*xReplSet : nullptr );
806 }
807 else if( s_pSrchItem->GetPattern() )
808 {
809 // Searching (and replacing) templates
810 const OUString& sRplStr( s_pSrchItem->GetReplaceString() );
811 nFound = m_pWrtShell->SearchTempl( s_pSrchItem->GetSearchString(),
812 rOptions.eStart,
813 rOptions.eEnd,
814 eRanges,
815 bDoReplace ? &sRplStr : nullptr );
816 }
817 else
818 {
819 // Normal search
820 nFound = m_pWrtShell->SearchPattern(aSearchOpt, s_pSrchItem->GetNotes(),
821 rOptions.eStart,
822 rOptions.eEnd,
823 eRanges,
824 bDoReplace );
825 }
826 m_pWrtShell->EndSelect();
827 return nFound;
828}
829
831{
832#if HAVE_FEATURE_DESKTOP
833 const sal_uInt16 nId = SvxSearchDialogWrapper::GetChildWindowId();
835 if (!pViewFrm)
836 return nullptr;
837 SvxSearchDialogWrapper *pWrp = static_cast<SvxSearchDialogWrapper*>(pViewFrm->GetChildWindow(nId));
838 if (!pWrp)
839 return nullptr;
840 return pWrp->getDialog();
841#else
842 return nullptr;
843#endif
844}
845
847{
848 SfxWhichIter aIter(rSet);
849 sal_uInt16 nWhich = aIter.FirstWhich();
850
851 while(nWhich)
852 {
853 switch(nWhich)
854 {
855 case SID_SEARCH_OPTIONS:
856 {
857 SearchOptionFlags nOpt = SearchOptionFlags::ALL;
858 if( GetDocShell()->IsReadOnly() )
859 nOpt &= ~SearchOptionFlags( SearchOptionFlags::REPLACE |
860 SearchOptionFlags::REPLACE_ALL );
861 rSet.Put( SfxUInt16Item( SID_SEARCH_OPTIONS, static_cast<sal_uInt16>(nOpt) ));
862 }
863 break;
864 case SID_SEARCH_ITEM:
865 {
866 if ( !s_pSrchItem )
867 {
868 s_pSrchItem = new SvxSearchItem( SID_SEARCH_ITEM );
869 s_pSrchItem->SetFamily(SfxStyleFamily::Para);
870 s_pSrchItem->SetSearchString( m_pWrtShell->GetSelText() );
871 }
872
873 if( s_bJustOpened && m_pWrtShell->IsSelection() )
874 {
875 OUString aText;
876 if( 1 == m_pWrtShell->GetCursorCnt() &&
877 !( aText = m_pWrtShell->SwCursorShell::GetSelText() ).isEmpty() )
878 {
880 s_pSrchItem->SetSelection( false );
881 }
882 else
883 s_pSrchItem->SetSelection( true );
884 }
885
886 s_bJustOpened = false;
887 rSet.Put( *s_pSrchItem );
888 }
889 break;
890 }
891 nWhich = aIter.NextWhich();
892 }
893}
894
895/* 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 SAL_WARN_UNUSED_RESULT SfxViewFrame * Current()
SfxBindings & GetBindings()
SfxChildWindow * GetChildWindow(sal_uInt16)
virtual void libreOfficeKitViewCallback(int nType, const OString &pPayload) const override
SfxViewFrame & GetViewFrame() const
sal_uInt16 FirstWhich()
sal_uInt16 NextWhich()
static bool IsCTLFontEnabled()
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:1047
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
bool IsStartOfDoc() const
Definition: crsrsh.cxx:3070
bool IsEndOfDoc() const
Definition: crsrsh.cxx:3082
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
sal_uInt16 Replace(SvxSearchItem const *pItem)
Definition: PostItMgr.cxx:2300
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:470
SvxSearchCmd m_eLastSearchCommand
Definition: view.hxx:235
static SvxSearchItem * s_pSrchItem
Definition: view.hxx:165
SwWrtShell & GetWrtShell() const
Definition: view.hxx:423
SAL_DLLPRIVATE sal_uInt16 SearchAll()
Definition: viewsrch.cxx:607
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:465
std::unique_ptr< SwWrtShell > m_pWrtShell
Definition: view.hxx:194
SAL_DLLPRIVATE sal_uLong FUNC_Search(const SwSearchOptions &rOptions)
Definition: viewsrch.cxx:741
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:650
static SvxSearchDialog * GetSearchDialog()
Definition: viewsrch.cxx:830
static bool s_bExtra
Definition: view.hxx:170
static bool s_bFound
Definition: view.hxx:171
SwDocShell * GetDocShell()
Definition: view.cxx:1193
void StateSearch(SfxItemSet &)
Definition: viewsrch.cxx:846
static sal_uInt16 GetMoveType()
Definition: viewmdi.cxx:734
SAL_DLLPRIVATE void Replace()
Definition: viewsrch.cxx:632
static void SetMoveType(sal_uInt16 nSet)
Definition: viewmdi.cxx:739
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:1869
@ GETSTYLE_CREATESOME
Definition: wrtsh.hxx:362
ring_container GetRingContainer()
Definition: ring.hxx:240
#define FN_REPEAT_SEARCH
Definition: cmdid.h:112
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_CHRATR_END(46)
constexpr TypedWhichId< SvxForbiddenRuleItem > RES_PARATR_FORBIDDEN_RULES(75)
constexpr sal_uInt16 RES_PARATR_BEGIN(RES_TXTATR_END)
constexpr TypedWhichId< SvxFirstLineIndentItem > RES_MARGIN_FIRSTLINE(91)
constexpr TypedWhichId< SvxShadowedItem > RES_CHRATR_SHADOWED(13)
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_CTL_FONT(27)
constexpr sal_uInt16 RES_FRMATR_END(141)
constexpr TypedWhichId< SvxWeightItem > RES_CHRATR_CTL_WEIGHT(31)
constexpr TypedWhichId< SvxHyphenZoneItem > RES_PARATR_HYPHENZONE(69)
constexpr TypedWhichId< SvxCharReliefItem > RES_CHRATR_RELIEF(36)
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< SvxRightMarginItem > RES_MARGIN_RIGHT(93)
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< SvxColorItem > RES_CHRATR_COLOR(3)
constexpr TypedWhichId< SvxULSpaceItem > RES_UL_SPACE(98)
const LanguageTag & GetAppLanguageTag()
Definition: init.cxx:748
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:1108
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:38
SwDocPositions eStart
Definition: viewsrch.cxx:66
SwSearchOptions(SwWrtShell const *pSh, bool bBackward)
Definition: viewsrch.cxx:726
SwDocPositions eEnd
Definition: viewsrch.cxx:66
css::lang::Locale Locale
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:168
@ UI_REPLACE_STYLE
void SfxToSwPageDescAttr(const SwWrtShell &rShell, SfxItemSet &rSet)
Definition: uitool.cxx:656
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