xref: /core/svx/source/dialog/srchdlg.cxx (revision 1e8f0940)
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 <sal/macros.h>
21 #include <osl/diagnose.h>
22 #include <vcl/wrkwin.hxx>
23 #include <vcl/timer.hxx>
24 #include <svl/slstitm.hxx>
25 #include <svl/itemiter.hxx>
26 #include <svl/style.hxx>
27 #include <unotools/intlwrapper.hxx>
28 #include <unotools/moduleoptions.hxx>
29 #include <unotools/searchopt.hxx>
30 #include <sfx2/dispatch.hxx>
31 #include <sfx2/objsh.hxx>
32 #include <sfx2/module.hxx>
33 #include <sfx2/viewsh.hxx>
34 #include <sfx2/basedlgs.hxx>
35 #include <sfx2/viewfrm.hxx>
36 #include <svl/cjkoptions.hxx>
37 #include <svl/ctloptions.hxx>
38 #include <com/sun/star/awt/XWindow.hpp>
39 #include <com/sun/star/accessibility/AccessibleRelation.hpp>
40 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
41 #include <com/sun/star/accessibility/XAccessibleGetAccFlowTo.hpp>
42 #include <com/sun/star/container/XNameAccess.hpp>
43 #include <com/sun/star/frame/XDispatch.hpp>
44 #include <com/sun/star/frame/XDispatchProvider.hpp>
45 #include <com/sun/star/frame/XLayoutManager.hpp>
46 #include <com/sun/star/beans/PropertyValue.hpp>
47 #include <com/sun/star/beans/XPropertySet.hpp>
48 #include <com/sun/star/configuration/theDefaultProvider.hpp>
49 #include <com/sun/star/frame/ModuleManager.hpp>
50 #include <com/sun/star/ui/XUIElement.hpp>
51 #include <comphelper/processfactory.hxx>
52 #include <comphelper/scopeguard.hxx>
53 #include <svl/itempool.hxx>
54 #include <svl/intitem.hxx>
55 
56 #include <sfx2/app.hxx>
57 #include <toolkit/helper/vclunohelper.hxx>
58 
59 #include <svx/srchdlg.hxx>
60 #include <svx/strarray.hxx>
61 
62 #include <svx/strings.hrc>
63 #include <svx/svxids.hrc>
64 #include <svx/svxitems.hrc>
65 
66 #include <svl/srchitem.hxx>
67 #include <svx/pageitem.hxx>
68 #include "srchctrl.hxx"
69 #include <svx/dialmgr.hxx>
70 #include <svx/dlgutil.hxx>
71 #include <editeng/brushitem.hxx>
72 #include <tools/resary.hxx>
73 #include <svx/svxdlg.hxx>
74 #include <vcl/toolbox.hxx>
75 #include <o3tl/typed_flags_set.hxx>
76 #include <vcl/combobox.hxx>
77 
78 #include <cstdlib>
79 #include <memory>
80 
81 #include <svx/xdef.hxx>
82 #include <officecfg/Office/Common.hxx>
83 
84 using namespace com::sun::star::i18n;
85 using namespace com::sun::star::uno;
86 using namespace com::sun::star::accessibility;
87 using namespace com::sun::star;
88 using namespace comphelper;
89 
90 enum class ModifyFlags {
91     NONE         = 0x000000,
92     Search       = 0x000001,
93     Replace      = 0x000002,
94     Word         = 0x000004,
95     Exact        = 0x000008,
96     Backwards    = 0x000010,
97     Selection    = 0x000020,
98     Regexp       = 0x000040,
99     Layout       = 0x000080,
100     Similarity   = 0x000100,
101     Formulas     = 0x000200,
102     Values       = 0x000400,
103     CalcNotes    = 0x000800,
104     Rows         = 0x001000,
105     Columns      = 0x002000,
106     AllTables    = 0x004000,
107     Notes        = 0x008000,
108     Wildcard     = 0x010000
109 };
110 namespace o3tl {
111     template<> struct typed_flags<ModifyFlags> : is_typed_flags<ModifyFlags, 0x01ffff> {};
112 }
113 
114 namespace
115 {
116     bool GetCheckBoxValue(const weld::CheckButton& rBox)
117     {
118         return rBox.get_sensitive() && rBox.get_active();
119     }
120 
121     bool GetNegatedCheckBoxValue(const weld::CheckButton& rBox)
122     {
123         return rBox.get_sensitive() && !rBox.get_active();
124     }
125 }
126 
127 struct SearchDlg_Impl
128 {
129     bool        bSaveToModule  : 1,
130                 bFocusOnSearch : 1;
131     std::unique_ptr<sal_uInt16[]> pRanges;
132     Timer       aSelectionTimer;
133 
134     uno::Reference< frame::XDispatch > xCommand1Dispatch;
135     uno::Reference< frame::XDispatch > xCommand2Dispatch;
136     util::URL   aCommand1URL;
137     util::URL   aCommand2URL;
138 
139     SearchDlg_Impl()
140         : bSaveToModule(true)
141         , bFocusOnSearch(true)
142     {
143         aCommand1URL.Complete = aCommand1URL.Main = "vnd.sun.search:SearchViaComponent1";
144         aCommand1URL.Protocol = "vnd.sun.search:";
145         aCommand1URL.Path = "SearchViaComponent1";
146         aCommand2URL.Complete = aCommand2URL.Main = "vnd.sun.search:SearchViaComponent2";
147         aCommand2URL.Protocol = "vnd.sun.search:";
148         aCommand2URL.Path = "SearchViaComponent2";
149     }
150 };
151 
152 static void ListToStrArr_Impl( sal_uInt16 nId, std::vector<OUString>& rStrLst, weld::ComboBox& rCBox )
153 {
154     const SfxStringListItem* pSrchItem =
155         static_cast<const SfxStringListItem*>(SfxGetpApp()->GetItem( nId ));
156 
157     if (pSrchItem)
158     {
159         std::vector<OUString> aLst = pSrchItem->GetList();
160 
161         for (const OUString & s : aLst)
162         {
163             rStrLst.push_back(s);
164             rCBox.append_text(s);
165         }
166     }
167 }
168 
169 static void StrArrToList_Impl( sal_uInt16 nId, const std::vector<OUString>& rStrLst )
170 {
171     DBG_ASSERT( !rStrLst.empty(), "check in advance");
172     SfxGetpApp()->PutItem( SfxStringListItem( nId, &rStrLst ) );
173 }
174 
175 SearchAttrItemList::SearchAttrItemList( const SearchAttrItemList& rList ) :
176     SrchAttrItemList(rList)
177 {
178     for ( size_t i = 0; i < size(); ++i )
179         if ( !IsInvalidItem( (*this)[i].pItem ) )
180             (*this)[i].pItem = (*this)[i].pItem->Clone();
181 }
182 
183 SearchAttrItemList::~SearchAttrItemList()
184 {
185     Clear();
186 }
187 
188 void SearchAttrItemList::Put( const SfxItemSet& rSet )
189 {
190     if ( !rSet.Count() )
191         return;
192 
193     SfxItemPool* pPool = rSet.GetPool();
194     SfxItemIter aIter( rSet );
195     SearchAttrItem aItem;
196     const SfxPoolItem* pItem = aIter.GetCurItem();
197     sal_uInt16 nWhich;
198 
199     while ( true )
200     {
201         // only test that it is available?
202         if( IsInvalidItem( pItem ) )
203         {
204             nWhich = rSet.GetWhichByPos( aIter.GetCurPos() );
205             aItem.pItem = const_cast<SfxPoolItem*>(pItem);
206         }
207         else
208         {
209             nWhich = pItem->Which();
210             aItem.pItem = pItem->Clone();
211         }
212 
213         aItem.nSlot = pPool->GetSlotId( nWhich );
214         Insert( aItem );
215 
216         if ( aIter.IsAtEnd() )
217             break;
218         pItem = aIter.NextItem();
219     }
220 }
221 
222 
223 SfxItemSet& SearchAttrItemList::Get( SfxItemSet& rSet )
224 {
225     SfxItemPool* pPool = rSet.GetPool();
226 
227     for ( size_t i = 0; i < size(); ++i )
228         if ( IsInvalidItem( (*this)[i].pItem ) )
229             rSet.InvalidateItem( pPool->GetWhich( (*this)[i].nSlot ) );
230         else
231             rSet.Put( *(*this)[i].pItem );
232     return rSet;
233 }
234 
235 
236 void SearchAttrItemList::Clear()
237 {
238     for ( size_t i = 0; i < size(); ++i )
239         if ( !IsInvalidItem( (*this)[i].pItem ) )
240             delete (*this)[i].pItem;
241     SrchAttrItemList::clear();
242 }
243 
244 
245 // Deletes the pointer to the items
246 void SearchAttrItemList::Remove(size_t nPos)
247 {
248     size_t nLen = 1;
249     if ( nPos + nLen > size() )
250         nLen = size() - nPos;
251 
252     for ( size_t i = nPos; i < nPos + nLen; ++i )
253         if ( !IsInvalidItem( (*this)[i].pItem ) )
254             delete (*this)[i].pItem;
255 
256     SrchAttrItemList::erase( begin() + nPos, begin() + nPos + nLen );
257 }
258 
259 SvxSearchDialog::SvxSearchDialog(weld::Window* pParent, SfxChildWindow* pChildWin, SfxBindings& rBind)
260     : SfxModelessDialogController(&rBind, pChildWin, pParent,
261                                   "svx/ui/findreplacedialog.ui", "FindReplaceDialog")
262     , mbSuccess(false)
263     , rBindings(rBind)
264     , bWriter(false)
265     , bSearch(true)
266     , bFormat(false)
267     , bReplaceBackwards(false)
268     , nOptions(SearchOptionFlags::ALL)
269     , bSet(false)
270     , bConstruct(true)
271     , nModifyFlag(ModifyFlags::NONE)
272     , pReplaceList(new SearchAttrItemList)
273     , nTransliterationFlags(TransliterationFlags::NONE)
274     , m_xSearchFrame(m_xBuilder->weld_frame("searchframe"))
275     , m_xSearchLB(m_xBuilder->weld_combo_box("searchterm"))
276     , m_xSearchTmplLB(m_xBuilder->weld_combo_box("searchlist"))
277     , m_xSearchAttrText(m_xBuilder->weld_label("searchdesc"))
278     , m_xSearchLabel(m_xBuilder->weld_label("searchlabel"))
279     , m_xReplaceFrame(m_xBuilder->weld_frame("replaceframe"))
280     , m_xReplaceLB(m_xBuilder->weld_combo_box("replaceterm"))
281     , m_xReplaceTmplLB(m_xBuilder->weld_combo_box("replacelist"))
282     , m_xReplaceAttrText(m_xBuilder->weld_label("replacedesc"))
283     , m_xSearchBtn(m_xBuilder->weld_button("search"))
284     , m_xBackSearchBtn(m_xBuilder->weld_button("backsearch"))
285     , m_xSearchAllBtn(m_xBuilder->weld_button("searchall"))
286     , m_xReplaceBtn(m_xBuilder->weld_button("replace"))
287     , m_xReplaceAllBtn(m_xBuilder->weld_button("replaceall"))
288     , m_xComponentFrame(m_xBuilder->weld_frame("componentframe"))
289     , m_xSearchComponent1PB(m_xBuilder->weld_button("component1"))
290     , m_xSearchComponent2PB(m_xBuilder->weld_button("component2"))
291     , m_xMatchCaseCB(m_xBuilder->weld_check_button("matchcase"))
292     , m_xSearchFormattedCB(m_xBuilder->weld_check_button("searchformatted"))
293     , m_xWordBtn(m_xBuilder->weld_check_button("wholewords"))
294     , m_xCloseBtn(m_xBuilder->weld_button("close"))
295     , m_xIncludeDiacritics(m_xBuilder->weld_check_button("includediacritics"))
296     , m_xIncludeKashida(m_xBuilder->weld_check_button("includekashida"))
297     , m_xOtherOptionsExpander(m_xBuilder->weld_expander("OptionsExpander"))
298     , m_xSelectionBtn(m_xBuilder->weld_check_button("selection"))
299     , m_xRegExpBtn(m_xBuilder->weld_check_button("regexp"))
300     , m_xWildcardBtn(m_xBuilder->weld_check_button("wildcard"))
301     , m_xSimilarityBox(m_xBuilder->weld_check_button("similarity"))
302     , m_xSimilarityBtn(m_xBuilder->weld_button("similaritybtn"))
303     , m_xLayoutBtn(m_xBuilder->weld_check_button("layout"))
304     , m_xNotesBtn(m_xBuilder->weld_check_button("notes"))
305     , m_xJapMatchFullHalfWidthCB(m_xBuilder->weld_check_button("matchcharwidth"))
306     , m_xJapOptionsCB(m_xBuilder->weld_check_button("soundslike"))
307     , m_xReplaceBackwardsCB(m_xBuilder->weld_check_button("replace_backwards"))
308     , m_xJapOptionsBtn(m_xBuilder->weld_button("soundslikebtn"))
309     , m_xAttributeBtn(m_xBuilder->weld_button("attributes"))
310     , m_xFormatBtn(m_xBuilder->weld_button("format"))
311     , m_xNoFormatBtn(m_xBuilder->weld_button("noformat"))
312     , m_xCalcGrid(m_xBuilder->weld_widget("calcgrid"))
313     , m_xCalcSearchInFT(m_xBuilder->weld_label("searchinlabel"))
314     , m_xCalcSearchInLB(m_xBuilder->weld_combo_box("calcsearchin"))
315     , m_xCalcSearchDirFT(m_xBuilder->weld_label("searchdir"))
316     , m_xRowsBtn(m_xBuilder->weld_radio_button("rows"))
317     , m_xColumnsBtn(m_xBuilder->weld_radio_button("cols"))
318     , m_xAllSheetsCB(m_xBuilder->weld_check_button("allsheets"))
319     , m_xCalcStrFT(m_xBuilder->weld_label("entirecells"))
320 {
321     m_xSearchTmplLB->make_sorted();
322     m_xSearchAttrText->hide();
323     m_xSearchLabel->show();
324 
325     m_xReplaceTmplLB->make_sorted();
326     m_xReplaceAttrText->hide();
327 
328     aCalcStr = m_xCalcStrFT->get_label();
329 
330     // m_xSimilarityBtn->set_height_request(m_xSimilarityBox->get_preferred_size().Height());
331     // m_xJapOptionsBtn->set_height_request(m_xJapOptionsCB->get_preferred_size().Height());
332 
333     //tdf#122322
334     nRememberSize = officecfg::Office::Common::Misc::FindReplaceRememberedSearches::get();
335     if (nRememberSize<1)
336         nRememberSize = 1; //0 crashes with no results found
337 
338     auto nTermWidth = m_xSearchLB->get_approximate_digit_width() * 28;
339     m_xSearchLB->set_size_request(nTermWidth, -1);
340     m_xSearchTmplLB->set_size_request(nTermWidth, -1);
341     m_xReplaceLB->set_size_request(nTermWidth, -1);
342     m_xReplaceTmplLB->set_size_request(nTermWidth, -1);
343 
344     Construct_Impl();
345 }
346 
347 void SvxSearchDialog::ChildWinDispose()
348 {
349     rBindings.EnterRegistrations();
350     pSearchController.reset();
351     pOptionsController.reset();
352     pFamilyController.reset();
353     rBindings.LeaveRegistrations();
354     SfxModelessDialogController::ChildWinDispose();
355 }
356 
357 SvxSearchDialog::~SvxSearchDialog()
358 {
359 }
360 
361 void SvxSearchDialog::Construct_Impl()
362 {
363     pImpl.reset( new SearchDlg_Impl() );
364     pImpl->aSelectionTimer.SetTimeout( 500 );
365     pImpl->aSelectionTimer.SetInvokeHandler(
366         LINK( this, SvxSearchDialog, TimeoutHdl_Impl ) );
367     EnableControls_Impl( SearchOptionFlags::NONE );
368 
369     // Store old Text from m_xWordBtn
370     aCalcStr += "#";
371     aCalcStr += m_xWordBtn->get_label();
372 
373     aLayoutStr = SvxResId( RID_SVXSTR_SEARCH_STYLES );
374     aLayoutWriterStr = SvxResId( RID_SVXSTR_WRITER_STYLES );
375     aLayoutCalcStr = SvxResId( RID_SVXSTR_CALC_STYLES );
376     aStylesStr = m_xLayoutBtn->get_label();
377 
378     // Get stored search-strings from the application
379     ListToStrArr_Impl(SID_SEARCHDLG_SEARCHSTRINGS,
380                        aSearchStrings, *m_xSearchLB);
381     ListToStrArr_Impl(SID_SEARCHDLG_REPLACESTRINGS,
382                        aReplaceStrings, *m_xReplaceLB);
383 
384     InitControls_Impl();
385 
386     // Get attribute sets only once in constructor()
387     const SfxPoolItem* ppArgs[] = { pSearchItem.get(), nullptr };
388     const SvxSetItem* pSrchSetItem =
389         static_cast<const SvxSetItem*>( rBindings.GetDispatcher()->Execute( FID_SEARCH_SEARCHSET, SfxCallMode::SLOT, ppArgs ) );
390 
391     if ( pSrchSetItem )
392         InitAttrList_Impl( &pSrchSetItem->GetItemSet(), nullptr );
393 
394     const SvxSetItem* pReplSetItem =
395         static_cast<const SvxSetItem*>( rBindings.GetDispatcher()->Execute( FID_SEARCH_REPLACESET, SfxCallMode::SLOT, ppArgs ) );
396 
397     if ( pReplSetItem )
398         InitAttrList_Impl( nullptr, &pReplSetItem->GetItemSet() );
399 
400     // Create controller and update at once
401     rBindings.EnterRegistrations();
402     pSearchController.reset(
403         new SvxSearchController( SID_SEARCH_ITEM, rBindings, *this ) );
404     pOptionsController.reset(
405         new SvxSearchController( SID_SEARCH_OPTIONS, rBindings, *this ) );
406     rBindings.LeaveRegistrations();
407     rBindings.GetDispatcher()->Execute( FID_SEARCH_ON, SfxCallMode::SLOT, ppArgs );
408     pImpl->aSelectionTimer.Start();
409 
410 
411     SvtCJKOptions aCJKOptions;
412     if(!aCJKOptions.IsJapaneseFindEnabled())
413     {
414         m_xJapOptionsCB->set_active( false );
415         m_xJapOptionsCB->hide();
416         m_xJapOptionsBtn->hide();
417     }
418     if(!aCJKOptions.IsCJKFontEnabled())
419     {
420         m_xJapMatchFullHalfWidthCB->hide();
421     }
422     SvtCTLOptions aCTLOptions;
423     // Do not disable and hide the m_xIncludeDiacritics button.
424     // Include Diacritics == Not Ignore Diacritics => A does not match A-Umlaut (Diaeresis).
425     // Confusingly these have negated names (following the UI) but the actual
426     // transliteration is to *ignore* diacritics if "included" (sensitive) is
427     // _not_ checked.
428     if(!aCTLOptions.IsCTLFontEnabled())
429     {
430         m_xIncludeDiacritics->set_active( true );
431         m_xIncludeKashida->set_active( true );
432         m_xIncludeKashida->hide();
433     }
434     //component extension - show component search buttons if the commands
435     // vnd.sun.star::SearchViaComponent1 and 2 are supported
436     const uno::Reference< frame::XFrame >xFrame = rBindings.GetActiveFrame();
437     const uno::Reference< frame::XDispatchProvider > xDispatchProv(xFrame, uno::UNO_QUERY);
438     OUString sTarget("_self");
439 
440     bool bSearchComponent1 = false;
441     bool bSearchComponent2 = false;
442     if(xDispatchProv.is() &&
443             (pImpl->xCommand1Dispatch = xDispatchProv->queryDispatch(pImpl->aCommand1URL, sTarget, 0)).is())
444     {
445         bSearchComponent1 = true;
446     }
447     if(xDispatchProv.is() &&
448             (pImpl->xCommand2Dispatch = xDispatchProv->queryDispatch(pImpl->aCommand2URL, sTarget, 0)).is())
449     {
450         bSearchComponent2 = true;
451     }
452 
453     if( bSearchComponent1 || bSearchComponent2 )
454     {
455         try
456         {
457             uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider =
458                     configuration::theDefaultProvider::get( comphelper::getProcessComponentContext() );
459             uno::Sequence< uno::Any > aArgs {
460                         Any(OUString( "/org.openoffice.Office.Common/SearchOptions/")) };
461 
462             uno::Reference< uno::XInterface > xIFace = xConfigurationProvider->createInstanceWithArguments(
463                         "com.sun.star.configuration.ConfigurationUpdateAccess",
464                         aArgs);
465             uno::Reference< container::XNameAccess> xDirectAccess(xIFace, uno::UNO_QUERY);
466             if(xDirectAccess.is())
467             {
468                 OUString sTemp;
469                 uno::Any aRet = xDirectAccess->getByName("ComponentSearchGroupLabel");
470                 aRet >>= sTemp;
471                 m_xComponentFrame->set_label(sTemp);
472                 aRet = xDirectAccess->getByName("ComponentSearchCommandLabel1");
473                 aRet >>= sTemp;
474                 m_xSearchComponent1PB->set_label( sTemp );
475                 aRet = xDirectAccess->getByName("ComponentSearchCommandLabel2");
476                 aRet >>= sTemp;
477                 m_xSearchComponent2PB->set_label( sTemp );
478             }
479         }
480         catch(uno::Exception&){}
481 
482         if(!m_xSearchComponent1PB->get_label().isEmpty() && bSearchComponent1 )
483         {
484             m_xComponentFrame->show();
485             m_xSearchComponent1PB->show();
486         }
487         if( !m_xSearchComponent2PB->get_label().isEmpty() )
488         {
489             m_xComponentFrame->show();
490             m_xSearchComponent2PB->show();
491         }
492     }
493 }
494 
495 void SvxSearchDialog::Close()
496 {
497     // remember strings
498     if (!aSearchStrings.empty())
499         StrArrToList_Impl( SID_SEARCHDLG_SEARCHSTRINGS, aSearchStrings );
500 
501     if (!aReplaceStrings.empty())
502         StrArrToList_Impl( SID_SEARCHDLG_REPLACESTRINGS, aReplaceStrings );
503 
504     // save settings to configuration
505     SvtSearchOptions aOpt;
506     aOpt.SetWholeWordsOnly          ( m_xWordBtn->get_active() );
507     aOpt.SetBackwards               ( m_xReplaceBackwardsCB->get_active() );
508     aOpt.SetUseRegularExpression    ( m_xRegExpBtn->get_active() );
509     aOpt.SetUseWildcard             ( m_xWildcardBtn->get_active() );
510     aOpt.SetSearchForStyles         ( m_xLayoutBtn->get_active() );
511     aOpt.SetSimilaritySearch        ( m_xSimilarityBox->get_active() );
512     aOpt.SetUseAsianOptions         ( m_xJapOptionsCB->get_active() );
513     aOpt.SetNotes                   ( m_xNotesBtn->get_active() );
514     aOpt.SetIgnoreDiacritics_CTL    ( !m_xIncludeDiacritics->get_active() );
515     aOpt.SetIgnoreKashida_CTL       ( !m_xIncludeKashida->get_active() );
516     aOpt.SetSearchFormatted         ( m_xSearchFormattedCB->get_active() );
517     aOpt.Commit();
518 
519     if (IsClosing())
520         return;
521 
522     const SfxPoolItem* ppArgs[] = { pSearchItem.get(), nullptr };
523     rBindings.GetDispatcher()->Execute( FID_SEARCH_OFF, SfxCallMode::SLOT, ppArgs );
524     rBindings.Invalidate(SID_SEARCH_DLG);
525 
526     SfxViewFrame* pViewFrame = SfxViewFrame::Current();
527     if (pViewFrame)
528         pViewFrame->ToggleChildWindow(SID_SEARCH_DLG);
529 }
530 
531 TransliterationFlags SvxSearchDialog::GetTransliterationFlags() const
532 {
533     if (!m_xMatchCaseCB->get_active())
534         nTransliterationFlags |=  TransliterationFlags::IGNORE_CASE;
535     else
536         nTransliterationFlags &= ~TransliterationFlags::IGNORE_CASE;
537     if ( !m_xJapMatchFullHalfWidthCB->get_active())
538         nTransliterationFlags |=  TransliterationFlags::IGNORE_WIDTH;
539     else
540         nTransliterationFlags &= ~TransliterationFlags::IGNORE_WIDTH;
541     return nTransliterationFlags;
542 }
543 
544 void SvxSearchDialog::SetSaveToModule(bool b)
545 {
546     pImpl->bSaveToModule = b;
547 }
548 
549 void SvxSearchDialog::SetSearchLabel(const OUString& rStr)
550 {
551     m_xSearchLabel->set_label(rStr);
552 
553     if (rStr == SvxResId(RID_SVXSTR_SEARCH_NOT_FOUND))
554         m_xSearchLB->set_entry_message_type(weld::EntryMessageType::Error);
555 }
556 
557 void SvxSearchDialog::ApplyTransliterationFlags_Impl( TransliterationFlags nSettings )
558 {
559     nTransliterationFlags = nSettings;
560     bool bVal(nSettings & TransliterationFlags::IGNORE_CASE);
561     m_xMatchCaseCB->set_active( !bVal );
562     bVal = bool(nSettings & TransliterationFlags::IGNORE_WIDTH);
563     m_xJapMatchFullHalfWidthCB->set_active( !bVal );
564 }
565 
566 
567 bool SvxSearchDialog::IsOtherOptionsExpanded() const
568 {
569     return m_xReplaceBackwardsCB->get_active() ||
570            m_xSelectionBtn->get_active() ||
571            m_xRegExpBtn->get_active() ||
572            m_xLayoutBtn->get_active() ||
573            m_xSimilarityBox->get_active() ||
574            m_xJapMatchFullHalfWidthCB->get_active() ||
575            m_xJapOptionsCB->get_active() ||
576            m_xWildcardBtn->get_active() ||
577            m_xNotesBtn->get_active() ||
578            m_xIncludeKashida->get_active() ||
579            m_xIncludeDiacritics->get_active();
580 }
581 
582 void SvxSearchDialog::Activate()
583 {
584     // apply possible transliteration changes of the SvxSearchItem member
585     DBG_ASSERT( pSearchItem, "SearchItem missing" );
586     if (pSearchItem)
587     {
588         m_xMatchCaseCB->set_active( pSearchItem->GetExact() );
589         m_xJapMatchFullHalfWidthCB->set_active( !pSearchItem->IsMatchFullHalfWidthForms() );
590     }
591 
592     SfxModelessDialogController::Activate();
593 }
594 
595 void SvxSearchDialog::InitControls_Impl()
596 {
597     // CaseSensitives AutoComplete
598     m_xSearchLB->set_entry_completion( true, true );
599     m_xSearchLB->show();
600     m_xReplaceLB->set_entry_completion( true, true );
601     m_xReplaceLB->show();
602 
603     m_xFormatBtn->set_sensitive(false);
604     m_xAttributeBtn->set_sensitive(false);
605 
606     m_xSearchLB->connect_changed( LINK( this, SvxSearchDialog, ModifyHdl_Impl ) );
607     m_xReplaceLB->connect_changed( LINK( this, SvxSearchDialog, ModifyHdl_Impl ) );
608 
609     Link<weld::Widget&,void> aLink = LINK( this, SvxSearchDialog, FocusHdl_Impl );
610     m_xSearchLB->connect_focus_in( aLink );
611     m_xReplaceLB->connect_focus_in( aLink );
612 
613     aLink = LINK( this, SvxSearchDialog, LoseFocusHdl_Impl );
614     m_xSearchLB->connect_focus_out( aLink );
615     m_xReplaceLB->connect_focus_out( aLink );
616 
617     m_xSearchTmplLB->connect_focus_out( aLink );
618     m_xReplaceTmplLB->connect_focus_out( aLink );
619 
620     Link<weld::Button&,void> aLink2 = LINK( this, SvxSearchDialog, CommandHdl_Impl );
621     m_xSearchBtn->connect_clicked( aLink2 );
622     m_xBackSearchBtn->connect_clicked( aLink2 );
623     m_xSearchAllBtn->connect_clicked( aLink2 );
624     m_xReplaceBtn->connect_clicked( aLink2 );
625     m_xReplaceAllBtn->connect_clicked( aLink2 );
626     m_xCloseBtn->connect_clicked( aLink2 );
627     m_xSimilarityBtn->connect_clicked( aLink2 );
628     m_xJapOptionsBtn->connect_clicked( aLink2 );
629     m_xSearchComponent1PB->connect_clicked( aLink2 );
630     m_xSearchComponent2PB->connect_clicked( aLink2 );
631 
632     aLink2 = LINK( this, SvxSearchDialog, FlagHdl_Impl );
633     m_xReplaceBackwardsCB->connect_clicked( aLink2 );
634     m_xWordBtn->connect_clicked( aLink2 );
635     m_xSelectionBtn->connect_clicked( aLink2 );
636     m_xMatchCaseCB->connect_clicked( aLink2 );
637     m_xRegExpBtn->connect_clicked( aLink2 );
638     m_xWildcardBtn->connect_clicked( aLink2 );
639     m_xNotesBtn->connect_clicked( aLink2 );
640     m_xSimilarityBox->connect_clicked( aLink2 );
641     m_xJapOptionsCB->connect_clicked( aLink2 );
642     m_xJapMatchFullHalfWidthCB->connect_clicked( aLink2 );
643     m_xIncludeDiacritics->connect_clicked( aLink2 );
644     m_xIncludeKashida->connect_clicked( aLink2 );
645     m_xLayoutBtn->connect_clicked( LINK( this, SvxSearchDialog, TemplateHdl_Impl ) );
646     m_xFormatBtn->connect_clicked( LINK( this, SvxSearchDialog, FormatHdl_Impl ) );
647     m_xNoFormatBtn->connect_clicked(
648         LINK( this, SvxSearchDialog, NoFormatHdl_Impl ) );
649     m_xAttributeBtn->connect_clicked(
650         LINK( this, SvxSearchDialog, AttributeHdl_Impl ) );
651 }
652 
653 namespace
654 {
655     SvtModuleOptions::EFactory getModule(SfxBindings const & rBindings)
656     {
657         SvtModuleOptions::EFactory eFactory(SvtModuleOptions::EFactory::UNKNOWN_FACTORY);
658         try
659         {
660             const uno::Reference< frame::XFrame > xFrame =
661                 rBindings.GetActiveFrame();
662             uno::Reference< frame::XModuleManager2 > xModuleManager(
663                 frame::ModuleManager::create(::comphelper::getProcessComponentContext()));
664 
665             OUString aModuleIdentifier = xModuleManager->identify( xFrame );
666             eFactory = SvtModuleOptions::ClassifyFactoryByServiceName(aModuleIdentifier);
667         }
668         catch (const uno::Exception&)
669         {
670         }
671         return eFactory;
672     }
673 }
674 
675 void SvxSearchDialog::ShowOptionalControls_Impl()
676 {
677     DBG_ASSERT( pSearchItem, "no search item" );
678 
679     SvtCJKOptions aCJKOptions;
680     SvtCTLOptions aCTLOptions;
681     SvtModuleOptions::EFactory eFactory = getModule(rBindings);
682     bool bDrawApp = eFactory == SvtModuleOptions::EFactory::DRAW;
683     bool bWriterApp =
684         eFactory == SvtModuleOptions::EFactory::WRITER ||
685         eFactory == SvtModuleOptions::EFactory::WRITERWEB ||
686         eFactory == SvtModuleOptions::EFactory::WRITERGLOBAL;
687     bool bCalcApp = eFactory == SvtModuleOptions::EFactory::CALC;
688 
689     m_xLayoutBtn->set_visible(!bDrawApp);
690     m_xNotesBtn->set_visible(bWriterApp);
691     m_xRegExpBtn->set_visible(!bDrawApp);
692     m_xWildcardBtn->set_visible(bCalcApp); /* TODO:WILDCARD enable for other apps if hey handle it */
693     m_xReplaceBackwardsCB->show();
694     m_xSimilarityBox->show();
695     m_xSimilarityBtn->show();
696     m_xSelectionBtn->show();
697     m_xIncludeDiacritics->show();
698     m_xIncludeKashida->set_visible(aCTLOptions.IsCTLFontEnabled());
699     m_xJapMatchFullHalfWidthCB->set_visible(aCJKOptions.IsCJKFontEnabled());
700     m_xJapOptionsCB->set_visible(aCJKOptions.IsJapaneseFindEnabled());
701     m_xJapOptionsBtn->set_visible(aCJKOptions.IsJapaneseFindEnabled());
702 
703     if (bWriter)
704     {
705         m_xAttributeBtn->show();
706         m_xFormatBtn->show();
707         m_xNoFormatBtn->show();
708     }
709 
710     if (bCalcApp)
711     {
712         m_xCalcSearchInFT->show();
713         m_xCalcSearchInLB->show();
714         m_xCalcSearchDirFT->show();
715         m_xRowsBtn->show();
716         m_xColumnsBtn->show();
717         m_xAllSheetsCB->show();
718         m_xSearchFormattedCB->show();
719     }
720 }
721 
722 
723 namespace {
724 
725 class ToggleSaveToModule
726 {
727 public:
728     ToggleSaveToModule(SvxSearchDialog& rDialog, bool bValue) :
729         mrDialog(rDialog), mbValue(bValue)
730     {
731         mrDialog.SetSaveToModule(mbValue);
732     }
733 
734     ~ToggleSaveToModule()
735     {
736         mrDialog.SetSaveToModule(!mbValue);
737     }
738 private:
739     SvxSearchDialog& mrDialog;
740     bool const mbValue;
741 };
742 
743 }
744 
745 void SvxSearchDialog::Init_Impl( bool bSearchPattern )
746 {
747     DBG_ASSERT( pSearchItem, "SearchItem == 0" );
748 
749     // We don't want to save any intermediate state to the module while the
750     // dialog is being initialized.
751     ToggleSaveToModule aNoModuleSave(*this, false);
752     SvtSearchOptions aOpt;
753 
754     bWriter = ( pSearchItem->GetAppFlag() == SvxSearchApp::WRITER );
755 
756     if ( !( nModifyFlag & ModifyFlags::Word ) )
757          m_xWordBtn->set_active( pSearchItem->GetWordOnly() );
758     if ( !( nModifyFlag & ModifyFlags::Exact ) )
759         m_xMatchCaseCB->set_active( pSearchItem->GetExact() );
760     if ( !( nModifyFlag & ModifyFlags::Backwards ) )
761         m_xReplaceBackwardsCB->set_active( bReplaceBackwards ); //adjustment to replace backwards
762     if ( !( nModifyFlag & ModifyFlags::Notes ) )
763         m_xNotesBtn->set_active( pSearchItem->GetNotes() );
764     if ( !( nModifyFlag & ModifyFlags::Selection ) )
765         m_xSelectionBtn->set_active( pSearchItem->GetSelection() );
766     if ( !( nModifyFlag & ModifyFlags::Regexp ) )
767         m_xRegExpBtn->set_active( pSearchItem->GetRegExp() );
768     if ( !( nModifyFlag & ModifyFlags::Wildcard ) )
769         m_xWildcardBtn->set_active( pSearchItem->GetWildcard() );
770     if ( !( nModifyFlag & ModifyFlags::Layout ) )
771         m_xLayoutBtn->set_active( pSearchItem->GetPattern() );
772     if (m_xNotesBtn->get_active())
773         m_xLayoutBtn->set_sensitive(false);
774     m_xSimilarityBox->set_active( pSearchItem->IsLevenshtein() );
775     if ( m_xJapOptionsCB->get_visible() )
776         m_xJapOptionsCB->set_active( pSearchItem->IsUseAsianOptions() );
777     m_xIncludeDiacritics->set_active( !aOpt.IsIgnoreDiacritics_CTL() );
778     if ( m_xIncludeKashida->get_visible() )
779         m_xIncludeKashida->set_active( !aOpt.IsIgnoreKashida_CTL() );
780     if ( SvxSearchDialog::IsOtherOptionsExpanded() )
781         m_xOtherOptionsExpander->set_expanded( true );
782     ApplyTransliterationFlags_Impl( pSearchItem->GetTransliterationFlags() );
783 
784     ShowOptionalControls_Impl();
785 
786     if ( pSearchItem->GetAppFlag() == SvxSearchApp::CALC )
787     {
788         m_xCalcGrid->show();
789         m_xSearchFormattedCB->set_active( aOpt.IsSearchFormatted() );
790         Link<weld::Button&,void> aLink = LINK( this, SvxSearchDialog, FlagHdl_Impl );
791         m_xCalcSearchInLB->connect_changed( LINK( this, SvxSearchDialog, LBSelectHdl_Impl ) );
792         m_xRowsBtn->connect_clicked( aLink );
793         m_xColumnsBtn->connect_clicked( aLink );
794         m_xAllSheetsCB->connect_clicked( aLink );
795         m_xSearchFormattedCB->connect_clicked( aLink );
796 
797         ModifyFlags nModifyFlagCheck;
798         switch ( pSearchItem->GetCellType() )
799         {
800             case SvxSearchCellType::FORMULA:
801                 nModifyFlagCheck = ModifyFlags::Formulas;
802                 break;
803 
804             case SvxSearchCellType::VALUE:
805                 nModifyFlagCheck = ModifyFlags::Values;
806                 break;
807 
808             case SvxSearchCellType::NOTE:
809                 nModifyFlagCheck = ModifyFlags::CalcNotes;
810                 break;
811 
812             default:
813                 std::abort(); // cannot happen
814         }
815         if ( !(nModifyFlag & nModifyFlagCheck) )
816             m_xCalcSearchInLB->set_active( static_cast<sal_Int32>(pSearchItem->GetCellType()) );
817 
818         m_xWordBtn->set_label( aCalcStr.getToken( 0, '#' ) );
819 
820         if ( pSearchItem->GetRowDirection() &&
821              !( nModifyFlag & ModifyFlags::Rows ) )
822             m_xRowsBtn->set_active(true);
823         else if ( !pSearchItem->GetRowDirection() &&
824                   !( nModifyFlag & ModifyFlags::Columns ) )
825             m_xColumnsBtn->set_active(true);
826 
827         if ( !( nModifyFlag & ModifyFlags::AllTables ) )
828             m_xAllSheetsCB->set_active( pSearchItem->IsAllTables() );
829 
830         // only look for formatting in Writer
831         m_xFormatBtn->hide();
832         m_xNoFormatBtn->hide();
833         m_xAttributeBtn->hide();
834     }
835     else
836     {
837         m_xSearchFormattedCB->hide();
838         m_xWordBtn->set_label( aCalcStr.getToken( 1, '#' ) );
839 
840         if ( pSearchItem->GetAppFlag() == SvxSearchApp::DRAW )
841         {
842             m_xSearchAllBtn->hide();
843 
844             m_xRegExpBtn->hide();
845             m_xWildcardBtn->hide();
846             m_xLayoutBtn->hide();
847 
848             // only look for formatting in Writer
849             m_xFormatBtn->hide();
850             m_xNoFormatBtn->hide();
851             m_xAttributeBtn->hide();
852         }
853         else
854         {
855             m_xWildcardBtn->hide(); /* TODO:WILDCARD do not hide for other apps if they handle it */
856 
857             if ( !pSearchList )
858             {
859                 // Get attribute sets, if it not has been done already
860                 const SfxPoolItem* ppArgs[] = { pSearchItem.get(), nullptr };
861                 const SvxSetItem* pSrchSetItem =
862                     static_cast<const SvxSetItem*>(rBindings.GetDispatcher()->Execute( FID_SEARCH_SEARCHSET, SfxCallMode::SLOT, ppArgs ));
863 
864                 if ( pSrchSetItem )
865                     InitAttrList_Impl( &pSrchSetItem->GetItemSet(), nullptr );
866 
867                 const SvxSetItem* pReplSetItem =
868                     static_cast<const SvxSetItem*>( rBindings.GetDispatcher()->Execute( FID_SEARCH_REPLACESET, SfxCallMode::SLOT, ppArgs ) );
869 
870                 if ( pReplSetItem )
871                     InitAttrList_Impl( nullptr, &pReplSetItem->GetItemSet() );
872             }
873         }
874     }
875 
876     // similarity search?
877     if ( !( nModifyFlag & ModifyFlags::Similarity ) )
878         m_xSimilarityBox->set_active( pSearchItem->IsLevenshtein() );
879     bSet = true;
880 
881     FlagHdl_Impl(*m_xSimilarityBox);
882     FlagHdl_Impl(*m_xJapOptionsCB);
883 
884     bool bDisableSearch = false;
885     SfxViewShell* pViewShell = SfxViewShell::Current();
886 
887     if ( pViewShell )
888     {
889         bool bText = !bSearchPattern;
890 
891         if ( pViewShell->HasSelection( bText ) )
892             EnableControl_Impl(*m_xSelectionBtn);
893         else
894         {
895             m_xSelectionBtn->set_active( false );
896             m_xSelectionBtn->set_sensitive(false);
897         }
898     }
899 
900     // Pattern Search and there were no AttrSets given
901     if ( bSearchPattern )
902     {
903         SfxObjectShell* pShell = SfxObjectShell::Current();
904 
905         if ( pShell && pShell->GetStyleSheetPool() )
906         {
907             // Templates designed
908             m_xSearchTmplLB->clear();
909             m_xReplaceTmplLB->clear();
910             SfxStyleSheetBasePool* pStylePool = pShell->GetStyleSheetPool();
911             pStylePool->SetSearchMask( pSearchItem->GetFamily() );
912             SfxStyleSheetBase* pBase = pStylePool->First();
913 
914             while ( pBase )
915             {
916                 if ( pBase->IsUsed() )
917                     m_xSearchTmplLB->append_text( pBase->GetName() );
918                 m_xReplaceTmplLB->append_text( pBase->GetName() );
919                 pBase = pStylePool->Next();
920             }
921             m_xSearchTmplLB->set_active_text( pSearchItem->GetSearchString() );
922             m_xReplaceTmplLB->set_active_text( pSearchItem->GetReplaceString() );
923 
924         }
925         m_xSearchTmplLB->show();
926 
927         if ( bConstruct )
928             // Grab focus only after creating
929             m_xSearchTmplLB->grab_focus();
930         m_xReplaceTmplLB->show();
931         m_xSearchLB->hide();
932         m_xReplaceLB->hide();
933 
934         m_xWordBtn->set_sensitive(false);
935         m_xRegExpBtn->set_sensitive(false);
936         m_xWildcardBtn->set_sensitive(false);
937         m_xMatchCaseCB->set_sensitive(false);
938 
939         bDisableSearch = !m_xSearchTmplLB->get_count();
940     }
941     else
942     {
943         bool bSetSearch = !( nModifyFlag & ModifyFlags::Search );
944         bool bSetReplace = !( nModifyFlag & ModifyFlags::Replace );
945 
946         if ( !(pSearchItem->GetSearchString().isEmpty()) && bSetSearch )
947             m_xSearchLB->set_entry_text( pSearchItem->GetSearchString() );
948         else if (!aSearchStrings.empty())
949         {
950             bool bAttributes =
951                 ( ( pSearchList && pSearchList->Count() ) ||
952                   ( pReplaceList && pReplaceList->Count() ) );
953 
954             if ( bSetSearch && !bAttributes )
955                 m_xSearchLB->set_entry_text(aSearchStrings[0]);
956 
957             OUString aReplaceTxt = pSearchItem->GetReplaceString();
958 
959             if (!aReplaceStrings.empty())
960                 aReplaceTxt = aReplaceStrings[0];
961 
962             if ( bSetReplace && !bAttributes )
963                 m_xReplaceLB->set_entry_text( aReplaceTxt );
964         }
965         m_xSearchLB->show();
966 
967         if ( bConstruct )
968             // Grab focus only after creating
969             m_xSearchLB->grab_focus();
970         m_xReplaceLB->show();
971         m_xSearchTmplLB->hide();
972         m_xReplaceTmplLB->hide();
973 
974         EnableControl_Impl(*m_xRegExpBtn);
975         EnableControl_Impl(*m_xWildcardBtn);
976         EnableControl_Impl(*m_xMatchCaseCB);
977 
978         if ( m_xRegExpBtn->get_active() )
979             m_xWordBtn->set_sensitive(false);
980         else
981             EnableControl_Impl(*m_xWordBtn);
982 
983         bDisableSearch = m_xSearchLB->get_active_text().isEmpty() &&
984             m_xSearchAttrText->get_label().isEmpty();
985     }
986     FocusHdl_Impl(*m_xSearchLB);
987 
988     if ( bDisableSearch )
989     {
990         m_xSearchBtn->set_sensitive(false);
991         m_xBackSearchBtn->set_sensitive(false);
992         m_xSearchAllBtn->set_sensitive(false);
993         m_xReplaceBtn->set_sensitive(false);
994         m_xReplaceAllBtn->set_sensitive(false);
995         m_xComponentFrame->set_sensitive(false);
996     }
997     else
998     {
999         EnableControl_Impl(*m_xSearchBtn);
1000         EnableControl_Impl(*m_xBackSearchBtn);
1001         EnableControl_Impl(*m_xReplaceBtn);
1002         if (!bWriter || !m_xNotesBtn->get_active())
1003         {
1004             EnableControl_Impl(*m_xSearchAllBtn);
1005             EnableControl_Impl(*m_xReplaceAllBtn);
1006         }
1007         if (bWriter && pSearchItem->GetNotes())
1008         {
1009             m_xSearchAllBtn->set_sensitive(false);
1010             m_xReplaceAllBtn->set_sensitive(false);
1011         }
1012     }
1013 
1014     if (!m_xSearchAttrText->get_label().isEmpty())
1015         EnableControl_Impl(*m_xNoFormatBtn);
1016     else
1017         m_xNoFormatBtn->set_sensitive(false);
1018 
1019     if ( !pSearchList )
1020     {
1021         m_xAttributeBtn->set_sensitive(false);
1022         m_xFormatBtn->set_sensitive(false);
1023     }
1024 
1025     if ( m_xLayoutBtn->get_active() )
1026     {
1027         pImpl->bSaveToModule = false;
1028         TemplateHdl_Impl(*m_xLayoutBtn);
1029         pImpl->bSaveToModule = true;
1030     }
1031 }
1032 
1033 
1034 void SvxSearchDialog::InitAttrList_Impl( const SfxItemSet* pSSet,
1035                                          const SfxItemSet* pRSet )
1036 {
1037     if ( !pSSet && !pRSet )
1038         return;
1039 
1040     if ( !pImpl->pRanges && pSSet )
1041     {
1042         const sal_uInt16* pPtr = pSSet->GetRanges();
1043         const sal_uInt16* pTmp = pPtr;
1044 
1045         while( *pPtr )
1046         {
1047             pPtr += 2;
1048         }
1049         sal_sSize nCnt = pPtr - pTmp + 1;
1050         pImpl->pRanges.reset( new sal_uInt16[nCnt] );
1051         memcpy( pImpl->pRanges.get(), pTmp, sizeof(sal_uInt16) * nCnt );
1052     }
1053 
1054     bool bSetOptimalLayoutSize = false;
1055 
1056     // See to it that are the texts of the attributes are correct
1057     OUString aDesc;
1058 
1059     if ( pSSet )
1060     {
1061         pSearchList.reset(new SearchAttrItemList);
1062 
1063         if ( pSSet->Count() )
1064         {
1065             pSearchList->Put( *pSSet );
1066 
1067             m_xSearchAttrText->set_label( BuildAttrText_Impl( aDesc, true ) );
1068 
1069             if ( !aDesc.isEmpty() )
1070             {
1071                 if (!m_xSearchAttrText->get_visible())
1072                 {
1073                     m_xSearchAttrText->show();
1074                     bSetOptimalLayoutSize = true;
1075                 }
1076                 bFormat |= true;
1077             }
1078         }
1079     }
1080 
1081     if ( pRSet )
1082     {
1083         pReplaceList.reset(new SearchAttrItemList);
1084 
1085         if ( pRSet->Count() )
1086         {
1087             pReplaceList->Put( *pRSet );
1088 
1089             m_xReplaceAttrText->set_label( BuildAttrText_Impl( aDesc, false ) );
1090 
1091             if ( !aDesc.isEmpty() )
1092             {
1093                 if (!m_xReplaceAttrText->get_visible())
1094                 {
1095                     m_xReplaceAttrText->show();
1096                     bSetOptimalLayoutSize = true;
1097                 }
1098                 bFormat |= true;
1099             }
1100         }
1101     }
1102 
1103     if (bSetOptimalLayoutSize)
1104         m_xDialog->resize_to_request();
1105 }
1106 
1107 IMPL_LINK( SvxSearchDialog, LBSelectHdl_Impl, weld::ComboBox&, rCtrl, void )
1108 {
1109     ClickHdl_Impl(&rCtrl);
1110 }
1111 
1112 IMPL_LINK( SvxSearchDialog, FlagHdl_Impl, weld::Button&, rCtrl, void )
1113 {
1114     ClickHdl_Impl(&rCtrl);
1115 }
1116 
1117 void SvxSearchDialog::ClickHdl_Impl(const weld::Widget* pCtrl)
1118 {
1119     if ( pCtrl && !bSet )
1120         SetModifyFlag_Impl(pCtrl);
1121     else
1122         bSet = false;
1123 
1124     if (pCtrl == m_xSimilarityBox.get())
1125     {
1126         bool bIsChecked = m_xSimilarityBox->get_active();
1127 
1128         if ( bIsChecked )
1129         {
1130             m_xSimilarityBtn->set_sensitive(true);
1131             m_xRegExpBtn->set_active( false );
1132             m_xRegExpBtn->set_sensitive(false);
1133             m_xWildcardBtn->set_active( false );
1134             m_xWildcardBtn->set_sensitive(false);
1135             EnableControl_Impl(*m_xWordBtn);
1136 
1137             if ( m_xLayoutBtn->get_active() )
1138             {
1139                 EnableControl_Impl(*m_xMatchCaseCB);
1140                 m_xLayoutBtn->set_active( false );
1141             }
1142             m_xRegExpBtn->set_sensitive(false);
1143             m_xWildcardBtn->set_sensitive(false);
1144             m_xLayoutBtn->set_sensitive(false);
1145             m_xFormatBtn->set_sensitive(false);
1146             m_xNoFormatBtn->set_sensitive(false);
1147             m_xAttributeBtn->set_sensitive(false);
1148         }
1149         else
1150         {
1151             EnableControl_Impl(*m_xRegExpBtn);
1152             EnableControl_Impl(*m_xWildcardBtn);
1153             if (!m_xNotesBtn->get_active())
1154                 EnableControl_Impl(*m_xLayoutBtn);
1155             EnableControl_Impl(*m_xFormatBtn);
1156             EnableControl_Impl(*m_xAttributeBtn);
1157             m_xSimilarityBtn->set_sensitive(false);
1158         }
1159         pSearchItem->SetLevenshtein( bIsChecked );
1160     }
1161     else if (pCtrl == m_xNotesBtn.get())
1162     {
1163         if (m_xNotesBtn->get_active())
1164         {
1165             m_xLayoutBtn->set_sensitive(false);
1166             m_xSearchAllBtn->set_sensitive(false);
1167             m_xReplaceAllBtn->set_sensitive(false);
1168         }
1169         else
1170         {
1171             EnableControl_Impl(*m_xLayoutBtn);
1172             ModifyHdl_Impl(*m_xSearchLB);
1173         }
1174     }
1175     else
1176     {
1177         if ( m_xLayoutBtn->get_active() && !bFormat )
1178         {
1179             m_xWordBtn->set_active( false );
1180             m_xWordBtn->set_sensitive(false);
1181             m_xRegExpBtn->set_active( false );
1182             m_xRegExpBtn->set_sensitive(false);
1183             m_xWildcardBtn->set_active( false );
1184             m_xWildcardBtn->set_sensitive(false);
1185             m_xMatchCaseCB->set_active( false );
1186             m_xMatchCaseCB->set_sensitive(false);
1187             m_xNotesBtn->set_sensitive(false);
1188 
1189             if ( m_xSearchTmplLB->get_count() )
1190             {
1191                 EnableControl_Impl(*m_xSearchBtn);
1192                 EnableControl_Impl(*m_xBackSearchBtn);
1193                 EnableControl_Impl(*m_xSearchAllBtn);
1194                 EnableControl_Impl(*m_xReplaceBtn);
1195                 EnableControl_Impl(*m_xReplaceAllBtn);
1196             }
1197         }
1198         else
1199         {
1200             EnableControl_Impl(*m_xRegExpBtn);
1201             EnableControl_Impl(*m_xWildcardBtn);
1202             EnableControl_Impl(*m_xMatchCaseCB);
1203             EnableControl_Impl(*m_xNotesBtn);
1204 
1205             if ( m_xRegExpBtn->get_active() )
1206             {
1207                 m_xWordBtn->set_active( false );
1208                 m_xWordBtn->set_sensitive(false);
1209                 m_xWildcardBtn->set_active( false );
1210                 m_xWildcardBtn->set_sensitive(false);
1211                 m_xSimilarityBox->set_active( false );
1212                 m_xSimilarityBox->set_sensitive(false);
1213                 m_xSimilarityBtn->set_sensitive(false);
1214             }
1215             else if ( m_xWildcardBtn->get_active() )
1216             {
1217                 m_xRegExpBtn->set_active( false );
1218                 m_xRegExpBtn->set_sensitive(false);
1219                 m_xSimilarityBox->set_active( false );
1220                 m_xSimilarityBox->set_sensitive(false);
1221                 m_xSimilarityBtn->set_sensitive(false);
1222             }
1223             else
1224             {
1225                 EnableControl_Impl(*m_xWordBtn);
1226                 EnableControl_Impl(*m_xSimilarityBox);
1227             }
1228 
1229             // Search-string in place? then enable Buttons
1230             bSet = true;
1231             ModifyHdl_Impl(*m_xSearchLB);
1232         }
1233     }
1234 
1235     if (pCtrl == m_xAllSheetsCB.get())
1236     {
1237         bSet = true;
1238         ModifyHdl_Impl(*m_xSearchLB);
1239     }
1240 
1241     if (pCtrl == m_xJapOptionsCB.get())
1242     {
1243         bool bEnableJapOpt = m_xJapOptionsCB->get_active();
1244         m_xMatchCaseCB->set_sensitive(!bEnableJapOpt );
1245         m_xJapMatchFullHalfWidthCB->set_sensitive(!bEnableJapOpt );
1246         m_xJapOptionsBtn->set_sensitive( bEnableJapOpt );
1247     }
1248 
1249     if ( pImpl->bSaveToModule )
1250         SaveToModule_Impl();
1251 }
1252 
1253 IMPL_LINK(SvxSearchDialog, CommandHdl_Impl, weld::Button&, rBtn, void)
1254 {
1255     bool bInclusive = ( m_xLayoutBtn->get_label() == aLayoutStr );
1256 
1257     if ( ( &rBtn == m_xSearchBtn.get() )   ||
1258          (&rBtn == m_xBackSearchBtn.get())  ||
1259          ( &rBtn == m_xSearchAllBtn.get() )||
1260          ( &rBtn == m_xReplaceBtn.get() )  ||
1261          ( &rBtn == m_xReplaceAllBtn.get() ) )
1262     {
1263         if ( m_xLayoutBtn->get_active() && !bInclusive )
1264         {
1265             pSearchItem->SetSearchString ( m_xSearchTmplLB->get_active_text() );
1266             pSearchItem->SetReplaceString( m_xReplaceTmplLB->get_active_text() );
1267         }
1268         else
1269         {
1270             pSearchItem->SetSearchString ( m_xSearchLB->get_active_text() );
1271             pSearchItem->SetReplaceString( m_xReplaceLB->get_active_text() );
1272 
1273             if ( &rBtn == m_xReplaceBtn.get() )
1274                 Remember_Impl( m_xReplaceLB->get_active_text(), false );
1275             else
1276             {
1277                 Remember_Impl( m_xSearchLB->get_active_text(), true );
1278 
1279                 if ( &rBtn == m_xReplaceAllBtn.get() )
1280                     Remember_Impl( m_xReplaceLB->get_active_text(), false );
1281             }
1282         }
1283 
1284         pSearchItem->SetRegExp( false );
1285         pSearchItem->SetWildcard( false );
1286         pSearchItem->SetLevenshtein( false );
1287         if (GetCheckBoxValue(*m_xRegExpBtn))
1288             pSearchItem->SetRegExp( true );
1289         else if (GetCheckBoxValue(*m_xWildcardBtn))
1290             pSearchItem->SetWildcard( true );
1291         else if (GetCheckBoxValue(*m_xSimilarityBox))
1292             pSearchItem->SetLevenshtein( true );
1293 
1294         pSearchItem->SetWordOnly(GetCheckBoxValue(*m_xWordBtn));
1295 
1296         bool bSetBackwards = false;
1297         if( &rBtn == m_xBackSearchBtn.get())
1298         {
1299             bSetBackwards = true;
1300         }
1301         else if( &rBtn == m_xReplaceBtn.get())
1302         {
1303             bSetBackwards = GetCheckBoxValue(*m_xReplaceBackwardsCB);
1304             bReplaceBackwards = GetCheckBoxValue(*m_xReplaceBackwardsCB);
1305         }
1306 
1307         pSearchItem->SetBackward(bSetBackwards);
1308 
1309         pSearchItem->SetNotes(GetCheckBoxValue(*m_xNotesBtn));
1310         pSearchItem->SetPattern(GetCheckBoxValue(*m_xLayoutBtn));
1311         pSearchItem->SetSelection(GetCheckBoxValue(*m_xSelectionBtn));
1312         pSearchItem->SetUseAsianOptions(GetCheckBoxValue(*m_xJapOptionsCB));
1313         TransliterationFlags nFlags = GetTransliterationFlags();
1314         if( !pSearchItem->IsUseAsianOptions())
1315             nFlags &= TransliterationFlags::IGNORE_CASE |
1316                       TransliterationFlags::IGNORE_WIDTH;
1317         if (GetNegatedCheckBoxValue(*m_xIncludeDiacritics))
1318             nFlags |= TransliterationFlags::IGNORE_DIACRITICS_CTL;
1319         if (GetNegatedCheckBoxValue(*m_xIncludeKashida))
1320             nFlags |= TransliterationFlags::IGNORE_KASHIDA_CTL;
1321         pSearchItem->SetTransliterationFlags( nFlags );
1322 
1323         if ( !bWriter )
1324         {
1325             if ( m_xCalcSearchInLB->get_active() != -1)
1326                 pSearchItem->SetCellType( static_cast<SvxSearchCellType>(m_xCalcSearchInLB->get_active()) );
1327 
1328             pSearchItem->SetRowDirection( m_xRowsBtn->get_active() );
1329             pSearchItem->SetAllTables( m_xAllSheetsCB->get_active() );
1330             pSearchItem->SetSearchFormatted( m_xSearchFormattedCB->get_active() );
1331         }
1332 
1333         if ((&rBtn == m_xSearchBtn.get()) ||  (&rBtn == m_xBackSearchBtn.get()))
1334             pSearchItem->SetCommand( SvxSearchCmd::FIND );
1335         else if ( &rBtn == m_xSearchAllBtn.get() )
1336             pSearchItem->SetCommand( SvxSearchCmd::FIND_ALL );
1337         else if ( &rBtn == m_xReplaceBtn.get() )
1338             pSearchItem->SetCommand( SvxSearchCmd::REPLACE );
1339         else if ( &rBtn == m_xReplaceAllBtn.get() )
1340             pSearchItem->SetCommand( SvxSearchCmd::REPLACE_ALL );
1341 
1342         // when looking for templates, delete format lists
1343         if ( !bFormat && pSearchItem->GetPattern() )
1344         {
1345             if ( pSearchList )
1346                 pSearchList->Clear();
1347 
1348             if ( pReplaceList )
1349                 pReplaceList->Clear();
1350         }
1351         nModifyFlag = ModifyFlags::NONE;
1352         const SfxPoolItem* ppArgs[] = { pSearchItem.get(), nullptr };
1353         rBindings.ExecuteSynchron( FID_SEARCH_NOW, ppArgs );
1354     }
1355     else if ( &rBtn == m_xCloseBtn.get() )
1356     {
1357         if ( !m_xLayoutBtn->get_active() || bInclusive )
1358         {
1359             OUString aStr( m_xSearchLB->get_active_text() );
1360 
1361             if ( !aStr.isEmpty() )
1362                 Remember_Impl( aStr, true );
1363             aStr = m_xReplaceLB->get_active_text();
1364 
1365             if ( !aStr.isEmpty() )
1366                 Remember_Impl( aStr, false );
1367         }
1368         SaveToModule_Impl();
1369         Close();
1370     }
1371     else if (&rBtn == m_xSimilarityBtn.get())
1372     {
1373         SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1374         ScopedVclPtr<AbstractSvxSearchSimilarityDialog> pDlg(pFact->CreateSvxSearchSimilarityDialog(m_xDialog.get(),
1375                                                                     pSearchItem->IsLEVRelaxed(),
1376                                                                     pSearchItem->GetLEVOther(),
1377                                                                     pSearchItem->GetLEVShorter(),
1378                                                                     pSearchItem->GetLEVLonger() ));
1379         if ( executeSubDialog(pDlg.get()) == RET_OK )
1380         {
1381             pSearchItem->SetLEVRelaxed( pDlg->IsRelaxed() );
1382             pSearchItem->SetLEVOther( pDlg->GetOther() );
1383             pSearchItem->SetLEVShorter( pDlg->GetShorter() );
1384             pSearchItem->SetLEVLonger( pDlg->GetLonger() );
1385             SaveToModule_Impl();
1386         }
1387     }
1388     else if (&rBtn == m_xJapOptionsBtn.get())
1389     {
1390         SfxItemSet aSet( SfxGetpApp()->GetPool() );
1391         pSearchItem->SetTransliterationFlags( GetTransliterationFlags() );
1392         SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1393         ScopedVclPtr<AbstractSvxJSearchOptionsDialog> aDlg(pFact->CreateSvxJSearchOptionsDialog(m_xDialog.get(), aSet,
1394                 pSearchItem->GetTransliterationFlags() ));
1395         int nRet = executeSubDialog(aDlg.get());
1396         if (RET_OK == nRet) //! true only if FillItemSet of SvxJSearchOptionsPage returns true
1397         {
1398             TransliterationFlags nFlags = aDlg->GetTransliterationFlags();
1399             pSearchItem->SetTransliterationFlags( nFlags );
1400             ApplyTransliterationFlags_Impl( nFlags );
1401         }
1402     }
1403     else if (&rBtn == m_xSearchComponent1PB.get() || &rBtn == m_xSearchComponent2PB.get())
1404     {
1405         uno::Sequence < beans::PropertyValue > aArgs(2);
1406         beans::PropertyValue* pArgs = aArgs.getArray();
1407         pArgs[0].Name = "SearchString";
1408         pArgs[0].Value <<= m_xSearchLB->get_active_text();
1409         pArgs[1].Name = "ParentWindow";
1410         pArgs[1].Value <<= m_xDialog->GetXWindow();
1411         if (&rBtn == m_xSearchComponent1PB.get())
1412         {
1413             if ( pImpl->xCommand1Dispatch.is() )
1414                 pImpl->xCommand1Dispatch->dispatch(pImpl->aCommand1URL, aArgs);
1415         }
1416         else
1417         {
1418             if ( pImpl->xCommand2Dispatch.is() )
1419                 pImpl->xCommand2Dispatch->dispatch(pImpl->aCommand2URL, aArgs);
1420         }
1421     }
1422 }
1423 
1424 
1425 IMPL_LINK( SvxSearchDialog, ModifyHdl_Impl, weld::ComboBox&, rEd, void )
1426 {
1427     if ( !bSet )
1428         SetModifyFlag_Impl( &rEd );
1429     else
1430         bSet = false;
1431 
1432     // Calc allows searching for empty cells.
1433     bool bAllowEmptySearch = (pSearchItem->GetAppFlag() == SvxSearchApp::CALC);
1434 
1435     if (&rEd == m_xSearchLB.get() || &rEd == m_xReplaceLB.get())
1436     {
1437         sal_Int32 nSrchTxtLen = m_xSearchLB->get_active_text().getLength();
1438         sal_Int32 nReplTxtLen = 0;
1439         if (bAllowEmptySearch)
1440             nReplTxtLen = m_xReplaceLB->get_active_text().getLength();
1441         sal_Int32 nAttrTxtLen = m_xSearchAttrText->get_label().getLength();
1442 
1443         if (nSrchTxtLen || nReplTxtLen || nAttrTxtLen)
1444         {
1445             EnableControl_Impl(*m_xSearchBtn);
1446             EnableControl_Impl(*m_xBackSearchBtn);
1447             EnableControl_Impl(*m_xReplaceBtn);
1448             if (!bWriter || !m_xNotesBtn->get_active())
1449             {
1450                 EnableControl_Impl(*m_xSearchAllBtn);
1451                 EnableControl_Impl(*m_xReplaceAllBtn);
1452             }
1453         }
1454         else
1455         {
1456             m_xComponentFrame->set_sensitive(false);
1457             m_xSearchBtn->set_sensitive(false);
1458             m_xBackSearchBtn->set_sensitive(false);
1459             m_xSearchAllBtn->set_sensitive(false);
1460             m_xReplaceBtn->set_sensitive(false);
1461             m_xReplaceAllBtn->set_sensitive(false);
1462         }
1463     }
1464 }
1465 
1466 IMPL_LINK_NOARG(SvxSearchDialog, TemplateHdl_Impl, weld::Button&, void)
1467 {
1468     if ( pImpl->bSaveToModule )
1469         SaveToModule_Impl();
1470 
1471     if ( bFormat )
1472         return;
1473     OUString sDesc;
1474 
1475     if ( m_xLayoutBtn->get_active() )
1476     {
1477         if ( !pFamilyController )
1478         {
1479             sal_uInt16 nId = 0;
1480 
1481             // Enable templates controller
1482             switch ( pSearchItem->GetFamily() )
1483             {
1484                 case SfxStyleFamily::Char:
1485                     nId = SID_STYLE_FAMILY1; break;
1486 
1487                 case SfxStyleFamily::Para:
1488                     nId = SID_STYLE_FAMILY2; break;
1489 
1490                 case SfxStyleFamily::Frame:
1491                     nId = SID_STYLE_FAMILY3; break;
1492 
1493                 case SfxStyleFamily::Page:
1494                     nId = SID_STYLE_FAMILY4; break;
1495 
1496                 case SfxStyleFamily::All:
1497                     break;
1498 
1499                 default:
1500                     OSL_FAIL( "StyleSheetFamily was changed?" );
1501             }
1502 
1503             rBindings.EnterRegistrations();
1504             pFamilyController.reset(
1505                 new SvxSearchController( nId, rBindings, *this ) );
1506             rBindings.LeaveRegistrations();
1507             m_xSearchTmplLB->clear();
1508             m_xReplaceTmplLB->clear();
1509 
1510             m_xSearchTmplLB->show();
1511             m_xReplaceTmplLB->show();
1512             m_xSearchLB->hide();
1513             m_xReplaceLB->hide();
1514 
1515             m_xSearchAttrText->set_label( sDesc );
1516             m_xReplaceAttrText->set_label( sDesc );
1517 
1518             if(!sDesc.isEmpty())
1519             {
1520                 if (!m_xReplaceAttrText->get_visible() || !m_xReplaceAttrText->get_visible())
1521                 {
1522                     m_xSearchAttrText->show();
1523                     m_xReplaceAttrText->show();
1524                     m_xDialog->resize_to_request();
1525                 }
1526             }
1527         }
1528         m_xFormatBtn->set_sensitive(false);
1529         m_xNoFormatBtn->set_sensitive(false);
1530         m_xAttributeBtn->set_sensitive(false);
1531         m_xSimilarityBox->set_sensitive(false);
1532         m_xSimilarityBtn->set_sensitive(false);
1533     }
1534     else
1535     {
1536         // Disable templates controller
1537         rBindings.EnterRegistrations();
1538         pFamilyController.reset();
1539         rBindings.LeaveRegistrations();
1540 
1541         m_xSearchLB->show();
1542         m_xReplaceLB->show();
1543         m_xSearchTmplLB->hide();
1544         m_xReplaceTmplLB->hide();
1545 
1546         m_xSearchAttrText->set_label( BuildAttrText_Impl( sDesc, true ) );
1547         m_xReplaceAttrText->set_label( BuildAttrText_Impl( sDesc, false ) );
1548 
1549         if(!sDesc.isEmpty())
1550         {
1551             if (!m_xReplaceAttrText->get_visible() || !m_xReplaceAttrText->get_visible())
1552             {
1553                 m_xSearchAttrText->show();
1554                 m_xReplaceAttrText->show();
1555                 m_xDialog->resize_to_request();
1556             }
1557         }
1558 
1559         EnableControl_Impl(*m_xFormatBtn);
1560         EnableControl_Impl(*m_xAttributeBtn);
1561         EnableControl_Impl(*m_xSimilarityBox);
1562 
1563         FocusHdl_Impl( bSearch ? *m_xSearchLB : *m_xReplaceLB );
1564     }
1565     bSet = true;
1566     pImpl->bSaveToModule = false;
1567     FlagHdl_Impl(*m_xLayoutBtn);
1568     pImpl->bSaveToModule = true;
1569 }
1570 
1571 void SvxSearchDialog::Remember_Impl( const OUString &rStr, bool _bSearch )
1572 {
1573     if ( rStr.isEmpty() )
1574         return;
1575 
1576     std::vector<OUString>* pArr = _bSearch ? &aSearchStrings : &aReplaceStrings;
1577     weld::ComboBox* pListBox = _bSearch ? m_xSearchLB.get() : m_xReplaceLB.get();
1578 
1579     // ignore identical strings
1580     if (std::find(pArr->begin(), pArr->end(), rStr) != pArr->end())
1581         return;
1582 
1583     // delete oldest entry at maximum occupancy (ListBox and Array)
1584     if(nRememberSize < pArr->size())
1585     {
1586         pListBox->remove(static_cast<sal_uInt16>(nRememberSize - 1));
1587         (*pArr)[nRememberSize - 1] = rStr;
1588         pArr->erase(pArr->begin() + nRememberSize - 1);
1589     }
1590 
1591     pArr->insert(pArr->begin(), rStr);
1592     pListBox->insert_text(0, rStr);
1593 }
1594 
1595 void SvxSearchDialog::TemplatesChanged_Impl( SfxStyleSheetBasePool& rPool )
1596 {
1597     OUString aOldSrch( m_xSearchTmplLB->get_active_text() );
1598     OUString aOldRepl( m_xReplaceTmplLB->get_active_text() );
1599     m_xSearchTmplLB->clear();
1600     m_xReplaceTmplLB->clear();
1601     rPool.SetSearchMask( pSearchItem->GetFamily() );
1602     m_xSearchTmplLB->freeze();
1603     m_xReplaceTmplLB->freeze();
1604     SfxStyleSheetBase* pBase = rPool.First();
1605 
1606     while ( pBase )
1607     {
1608         if ( pBase->IsUsed() )
1609             m_xSearchTmplLB->append_text( pBase->GetName() );
1610         m_xReplaceTmplLB->append_text( pBase->GetName() );
1611         pBase = rPool.Next();
1612     }
1613     m_xSearchTmplLB->thaw();
1614     m_xReplaceTmplLB->thaw();
1615     m_xSearchTmplLB->set_active(0);
1616 
1617     if ( !aOldSrch.isEmpty() )
1618         m_xSearchTmplLB->set_active_text( aOldSrch );
1619     m_xReplaceTmplLB->set_active(0);
1620 
1621     if ( !aOldRepl.isEmpty() )
1622         m_xReplaceTmplLB->set_active_text( aOldRepl );
1623 
1624     if ( m_xSearchTmplLB->get_count() )
1625     {
1626         EnableControl_Impl(*m_xSearchBtn);
1627         EnableControl_Impl(*m_xBackSearchBtn);
1628         EnableControl_Impl(*m_xSearchAllBtn);
1629         EnableControl_Impl(*m_xReplaceBtn);
1630         EnableControl_Impl(*m_xReplaceAllBtn);
1631     }
1632 }
1633 
1634 
1635 void SvxSearchDialog::EnableControls_Impl( const SearchOptionFlags nFlags )
1636 {
1637     if ( nFlags == nOptions )
1638         return;
1639     else
1640         nOptions = nFlags;
1641 
1642     bool bNoSearch = true;
1643 
1644     bool bEnableSearch = bool( SearchOptionFlags::SEARCH & nOptions );
1645     m_xSearchBtn->set_sensitive(bEnableSearch);
1646     m_xBackSearchBtn->set_sensitive(bEnableSearch);
1647 
1648     if( bEnableSearch )
1649         bNoSearch = false;
1650 
1651 
1652     if ( SearchOptionFlags::SEARCHALL & nOptions )
1653     {
1654         m_xSearchAllBtn->set_sensitive(true);
1655         bNoSearch = false;
1656     }
1657     else
1658         m_xSearchAllBtn->set_sensitive(false);
1659     if ( SearchOptionFlags::REPLACE & nOptions )
1660     {
1661         m_xReplaceBtn->set_sensitive(true);
1662         m_xReplaceFrame->set_sensitive(true);
1663         m_xReplaceLB->set_sensitive(true);
1664         m_xReplaceTmplLB->set_sensitive(true);
1665         bNoSearch = false;
1666     }
1667     else
1668     {
1669         m_xReplaceBtn->set_sensitive(false);
1670         m_xReplaceFrame->set_sensitive(false);
1671         m_xReplaceLB->set_sensitive(false);
1672         m_xReplaceTmplLB->set_sensitive(false);
1673     }
1674     if ( SearchOptionFlags::REPLACE_ALL & nOptions )
1675     {
1676         m_xReplaceAllBtn->set_sensitive(true);
1677         bNoSearch = false;
1678     }
1679     else
1680         m_xReplaceAllBtn->set_sensitive(false);
1681     m_xComponentFrame->set_sensitive(!bNoSearch);
1682     m_xSearchBtn->set_sensitive( !bNoSearch );
1683     m_xBackSearchBtn->set_sensitive( !bNoSearch );
1684     m_xSearchFrame->set_sensitive( !bNoSearch );
1685     m_xSearchLB->set_sensitive( !bNoSearch );
1686     m_xNotesBtn->set_sensitive(true);
1687 
1688     if ( SearchOptionFlags::WHOLE_WORDS & nOptions )
1689         m_xWordBtn->set_sensitive(true);
1690     else
1691         m_xWordBtn->set_sensitive(false);
1692     if ( SearchOptionFlags::BACKWARDS & nOptions )
1693     {
1694         m_xBackSearchBtn->set_sensitive(true);
1695         m_xReplaceBackwardsCB->set_sensitive(true);
1696     }
1697     else
1698     {
1699         m_xBackSearchBtn->set_sensitive(false);
1700         m_xReplaceBackwardsCB->set_sensitive(false);
1701     }
1702     if ( SearchOptionFlags::REG_EXP & nOptions )
1703         m_xRegExpBtn->set_sensitive(true);
1704     else
1705         m_xRegExpBtn->set_sensitive(false);
1706     if ( SearchOptionFlags::WILDCARD & nOptions )
1707         m_xWildcardBtn->set_sensitive(true);
1708     else
1709         m_xWildcardBtn->set_sensitive(false);
1710     if ( SearchOptionFlags::EXACT & nOptions )
1711         m_xMatchCaseCB->set_sensitive(true);
1712     else
1713         m_xMatchCaseCB->set_sensitive(false);
1714     if ( SearchOptionFlags::SELECTION & nOptions )
1715         m_xSelectionBtn->set_sensitive(true);
1716     else
1717         m_xSelectionBtn->set_sensitive(false);
1718     if ( SearchOptionFlags::FAMILIES & nOptions )
1719         m_xLayoutBtn->set_sensitive(true);
1720     else
1721         m_xLayoutBtn->set_sensitive(false);
1722     if ( SearchOptionFlags::FORMAT & nOptions )
1723     {
1724         m_xAttributeBtn->set_sensitive(true);
1725         m_xFormatBtn->set_sensitive(true);
1726         m_xNoFormatBtn->set_sensitive(true);
1727     }
1728     else
1729     {
1730         m_xAttributeBtn->set_sensitive(false);
1731         m_xFormatBtn->set_sensitive(false);
1732         m_xNoFormatBtn->set_sensitive(false);
1733     }
1734 
1735     if ( SearchOptionFlags::SIMILARITY & nOptions )
1736     {
1737         m_xSimilarityBox->set_sensitive(true);
1738         m_xSimilarityBtn->set_sensitive(true);
1739     }
1740     else
1741     {
1742         m_xSimilarityBox->set_sensitive(false);
1743         m_xSimilarityBtn->set_sensitive(false);
1744     }
1745 
1746     if ( pSearchItem )
1747         Init_Impl( pSearchItem->GetPattern() &&
1748                    ( !pSearchList || !pSearchList->Count() ) );
1749 }
1750 
1751 void SvxSearchDialog::EnableControl_Impl(const weld::Widget& rCtrl)
1752 {
1753     if (m_xSearchBtn.get() == &rCtrl && ( SearchOptionFlags::SEARCH & nOptions ) )
1754     {
1755         m_xComponentFrame->set_sensitive(true);
1756         m_xSearchBtn->set_sensitive(true);
1757         return;
1758     }
1759     if ( m_xSearchAllBtn.get() == &rCtrl &&
1760          ( SearchOptionFlags::SEARCHALL & nOptions )  )
1761     {
1762         m_xSearchAllBtn->set_sensitive(true);
1763         return;
1764     }
1765     if ( m_xReplaceBtn.get() == &rCtrl && ( SearchOptionFlags::REPLACE & nOptions )  )
1766     {
1767         m_xReplaceBtn->set_sensitive(true);
1768         return;
1769     }
1770     if ( m_xReplaceAllBtn.get() == &rCtrl &&
1771          ( SearchOptionFlags::REPLACE_ALL & nOptions ) )
1772     {
1773         m_xReplaceAllBtn->set_sensitive(true);
1774         return;
1775     }
1776     if ( m_xWordBtn.get() == &rCtrl && ( SearchOptionFlags::WHOLE_WORDS & nOptions ) )
1777     {
1778         m_xWordBtn->set_sensitive(true);
1779         return;
1780     }
1781     if ( SearchOptionFlags::BACKWARDS & nOptions )
1782     {
1783         if( m_xBackSearchBtn.get() == &rCtrl )
1784         {
1785             m_xBackSearchBtn->set_sensitive(true);
1786             return;
1787         }
1788         else if ( m_xReplaceBackwardsCB.get() == &rCtrl )
1789         {
1790             m_xReplaceBackwardsCB->set_sensitive(true);
1791             return;
1792         }
1793     }
1794     if (m_xNotesBtn.get() == &rCtrl)
1795     {
1796         m_xNotesBtn->set_sensitive(true);
1797         return;
1798     }
1799     if ( m_xRegExpBtn.get() == &rCtrl && ( SearchOptionFlags::REG_EXP & nOptions )
1800         && !m_xSimilarityBox->get_active() && !m_xWildcardBtn->get_active())
1801     {
1802         m_xRegExpBtn->set_sensitive(true);
1803         return;
1804     }
1805     if ( m_xWildcardBtn.get() == &rCtrl && ( SearchOptionFlags::WILDCARD & nOptions )
1806         && !m_xSimilarityBox->get_active() && !m_xRegExpBtn->get_active())
1807     {
1808         m_xWildcardBtn->set_sensitive(true);
1809         return;
1810     }
1811     if ( m_xMatchCaseCB.get() == &rCtrl && ( SearchOptionFlags::EXACT & nOptions ) )
1812     {
1813         if (!m_xJapOptionsCB->get_active())
1814             m_xMatchCaseCB->set_sensitive(true);
1815         return;
1816     }
1817     if ( m_xSelectionBtn.get() == &rCtrl && ( SearchOptionFlags::SELECTION & nOptions ) )
1818     {
1819         m_xSelectionBtn->set_sensitive(true);
1820         return;
1821     }
1822     if ( m_xLayoutBtn.get() == &rCtrl && ( SearchOptionFlags::FAMILIES & nOptions ) )
1823     {
1824         m_xLayoutBtn->set_sensitive(true);
1825         return;
1826     }
1827     if ( m_xAttributeBtn.get() == &rCtrl
1828          && ( SearchOptionFlags::FORMAT & nOptions )
1829          && pSearchList )
1830     {
1831         m_xAttributeBtn->set_sensitive( pImpl->bFocusOnSearch );
1832     }
1833     if ( m_xFormatBtn.get() == &rCtrl && ( SearchOptionFlags::FORMAT & nOptions ) )
1834     {
1835         m_xFormatBtn->set_sensitive(true);
1836         return;
1837     }
1838     if ( m_xNoFormatBtn.get() == &rCtrl && ( SearchOptionFlags::FORMAT & nOptions ) )
1839     {
1840         m_xNoFormatBtn->set_sensitive(true);
1841         return;
1842     }
1843     if ( m_xSimilarityBox.get() == &rCtrl && ( SearchOptionFlags::SIMILARITY & nOptions )
1844         && !m_xRegExpBtn->get_active() && !m_xWildcardBtn->get_active())
1845     {
1846         m_xSimilarityBox->set_sensitive(true);
1847 
1848         if ( m_xSimilarityBox->get_active() )
1849             m_xSimilarityBtn->set_sensitive(true);
1850     }
1851 }
1852 
1853 void SvxSearchDialog::SetItem_Impl( const SvxSearchItem* pItem )
1854 {
1855     //TODO: save pItem and process later if m_executingSubDialog?
1856     if ( pItem && !m_executingSubDialog )
1857     {
1858         pSearchItem.reset(static_cast<SvxSearchItem*>(pItem->Clone()));
1859         Init_Impl( pSearchItem->GetPattern() &&
1860                    ( !pSearchList || !pSearchList->Count() ) );
1861     }
1862 }
1863 
1864 IMPL_LINK(SvxSearchDialog, FocusHdl_Impl, weld::Widget&, rControl, void)
1865 {
1866     sal_Int32 nTxtLen = m_xSearchAttrText->get_label().getLength();
1867     weld::Widget* pCtrl = &rControl;
1868     if (pCtrl == m_xSearchLB.get())
1869     {
1870         if (pCtrl->has_focus())
1871             pImpl->bFocusOnSearch = true;
1872         pCtrl = m_xSearchLB.get();
1873         bSearch = true;
1874 
1875         if( nTxtLen )
1876             EnableControl_Impl(*m_xNoFormatBtn);
1877         else
1878             m_xNoFormatBtn->set_sensitive(false);
1879         EnableControl_Impl(*m_xAttributeBtn);
1880     }
1881     else
1882     {
1883         pImpl->bFocusOnSearch = false;
1884         pCtrl = m_xReplaceLB.get();
1885         bSearch = false;
1886 
1887         if (!m_xReplaceAttrText->get_label().isEmpty())
1888             EnableControl_Impl(*m_xNoFormatBtn);
1889         else
1890             m_xNoFormatBtn->set_sensitive(false);
1891         m_xAttributeBtn->set_sensitive(false);
1892     }
1893     bSet = true;
1894 
1895     weld::ComboBox &rComboBox = dynamic_cast<weld::ComboBox&>(*pCtrl);
1896     rComboBox.select_entry_region(0, -1);
1897     ModifyHdl_Impl(rComboBox);
1898 
1899     if (bFormat && nTxtLen)
1900         m_xLayoutBtn->set_label(aLayoutStr);
1901     else
1902     {
1903         SvtModuleOptions::EFactory eFactory = getModule(rBindings);
1904         bool bWriterApp =
1905             eFactory == SvtModuleOptions::EFactory::WRITER ||
1906             eFactory == SvtModuleOptions::EFactory::WRITERWEB ||
1907             eFactory == SvtModuleOptions::EFactory::WRITERGLOBAL;
1908         bool bCalcApp = eFactory == SvtModuleOptions::EFactory::CALC;
1909 
1910         if (bWriterApp)
1911             m_xLayoutBtn->set_label(aLayoutWriterStr);
1912         else
1913         {
1914             if (bCalcApp)
1915                 m_xLayoutBtn->set_label(aLayoutCalcStr);
1916             else
1917                 m_xLayoutBtn->set_label(aStylesStr);
1918         }
1919     }
1920 }
1921 
1922 IMPL_LINK_NOARG(SvxSearchDialog, LoseFocusHdl_Impl, weld::Widget&, void)
1923 {
1924     SaveToModule_Impl();
1925 }
1926 
1927 IMPL_LINK_NOARG(SvxSearchDialog, FormatHdl_Impl, weld::Button&, void)
1928 {
1929     SfxObjectShell* pSh = SfxObjectShell::Current();
1930 
1931     DBG_ASSERT( pSh, "no DocShell" );
1932 
1933     if ( !pSh || !pImpl->pRanges )
1934         return;
1935 
1936     SfxItemPool& rPool = pSh->GetPool();
1937     SfxItemSet aSet(rPool, pImpl->pRanges.get());
1938 
1939     aSet.MergeRange(SID_ATTR_PARA_MODEL, SID_ATTR_PARA_MODEL);
1940 
1941     sal_uInt16 nBrushWhich = pSh->GetPool().GetWhich(SID_ATTR_BRUSH);
1942     aSet.MergeRange(nBrushWhich, nBrushWhich);
1943 
1944     aSet.MergeRange(XATTR_FILL_FIRST, XATTR_FILL_LAST);
1945 
1946     OUString aTxt;
1947 
1948     aSet.InvalidateAllItems();
1949     aSet.Put(SvxBrushItem(nBrushWhich));
1950 
1951     if ( bSearch )
1952     {
1953         aTxt = SvxResId( RID_SVXSTR_SEARCH );
1954         pSearchList->Get( aSet );
1955     }
1956     else
1957     {
1958         aTxt = SvxResId( RID_SVXSTR_REPLACE );
1959         pReplaceList->Get( aSet );
1960     }
1961     aSet.DisableItem(SID_ATTR_PARA_MODEL);
1962     aSet.DisableItem(rPool.GetWhich(SID_ATTR_PARA_PAGEBREAK));
1963     aSet.DisableItem(rPool.GetWhich(SID_ATTR_PARA_KEEP));
1964 
1965 
1966     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1967     ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateTabItemDialog(m_xDialog.get(), aSet));
1968     pDlg->SetText( aTxt );
1969 
1970     if ( executeSubDialog(pDlg.get()) == RET_OK )
1971     {
1972         DBG_ASSERT( pDlg->GetOutputItemSet(), "invalid Output-Set" );
1973         SfxItemSet aOutSet( *pDlg->GetOutputItemSet() );
1974 
1975         SearchAttrItemList* pList = bSearch ? pSearchList.get() : pReplaceList.get();
1976 
1977         const SfxPoolItem* pItem;
1978         for( sal_uInt16 n = 0; n < pList->Count(); ++n )
1979         {
1980             SearchAttrItem* pAItem;
1981             if( !IsInvalidItem( (pAItem = &pList->GetObject(n))->pItem ) &&
1982                 SfxItemState::SET == aOutSet.GetItemState(
1983                     pAItem->pItem->Which(), false, &pItem ) )
1984             {
1985                 delete pAItem->pItem;
1986                 pAItem->pItem = pItem->Clone();
1987                 aOutSet.ClearItem( pAItem->pItem->Which() );
1988             }
1989         }
1990 
1991         if( aOutSet.Count() )
1992             pList->Put( aOutSet );
1993 
1994         PaintAttrText_Impl(); // Set AttributText in GroupBox
1995     }
1996 }
1997 
1998 IMPL_LINK_NOARG(SvxSearchDialog, NoFormatHdl_Impl, weld::Button&, void)
1999 {
2000     SvtModuleOptions::EFactory eFactory = getModule(rBindings);
2001     bool bWriterApp =
2002         eFactory == SvtModuleOptions::EFactory::WRITER ||
2003         eFactory == SvtModuleOptions::EFactory::WRITERWEB ||
2004         eFactory == SvtModuleOptions::EFactory::WRITERGLOBAL;
2005     bool bCalcApp = eFactory == SvtModuleOptions::EFactory::CALC;
2006 
2007     if (bCalcApp)
2008         m_xLayoutBtn->set_label( aLayoutCalcStr );
2009     else
2010     {
2011         if (bWriterApp)
2012             m_xLayoutBtn->set_label( aLayoutWriterStr);
2013         else
2014             m_xLayoutBtn->set_label( aStylesStr );
2015     }
2016 
2017     bFormat = false;
2018     m_xLayoutBtn->set_active( false );
2019 
2020     bool bSetOptimalLayoutSize = false;
2021 
2022     if ( bSearch )
2023     {
2024         pSearchList->Clear();
2025         m_xSearchAttrText->set_label( "" );
2026         if (m_xSearchAttrText->get_visible())
2027         {
2028             m_xSearchAttrText->hide();
2029             bSetOptimalLayoutSize = true;
2030         }
2031     }
2032     else
2033     {
2034         pReplaceList->Clear();
2035         m_xReplaceAttrText->set_label( "" );
2036         if (m_xReplaceAttrText->get_visible())
2037         {
2038             m_xReplaceAttrText->hide();
2039             bSetOptimalLayoutSize = true;
2040         }
2041     }
2042 
2043     if (bSetOptimalLayoutSize)
2044         m_xDialog->resize_to_request();
2045 
2046     pImpl->bSaveToModule = false;
2047     TemplateHdl_Impl(*m_xLayoutBtn);
2048     pImpl->bSaveToModule = true;
2049     m_xNoFormatBtn->set_sensitive(false);
2050 }
2051 
2052 IMPL_LINK_NOARG(SvxSearchDialog, AttributeHdl_Impl, weld::Button&, void)
2053 {
2054     if ( !pSearchList || !pImpl->pRanges )
2055         return;
2056 
2057     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
2058     ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSvxSearchAttributeDialog(m_xDialog.get(), *pSearchList, pImpl->pRanges.get()));
2059     executeSubDialog(pDlg.get());
2060     PaintAttrText_Impl();
2061 }
2062 
2063 IMPL_LINK( SvxSearchDialog, TimeoutHdl_Impl, Timer *, pTimer, void )
2064 {
2065     SfxViewShell* pViewShell = SfxViewShell::Current();
2066 
2067     if ( pViewShell )
2068     {
2069         if ( pViewShell->HasSelection( m_xSearchLB->get_visible() ) )
2070             EnableControl_Impl(*m_xSelectionBtn);
2071         else
2072         {
2073             m_xSelectionBtn->set_active( false );
2074             m_xSelectionBtn->set_sensitive(false);
2075         }
2076     }
2077 
2078     pTimer->Start();
2079 }
2080 
2081 OUString& SvxSearchDialog::BuildAttrText_Impl( OUString& rStr,
2082                                              bool bSrchFlag ) const
2083 {
2084     rStr.clear();
2085 
2086     SfxObjectShell* pSh = SfxObjectShell::Current();
2087     DBG_ASSERT( pSh, "no DocShell" );
2088 
2089     if ( !pSh )
2090         return rStr;
2091 
2092     SfxItemPool& rPool = pSh->GetPool();
2093     SearchAttrItemList* pList = bSrchFlag ? pSearchList.get() : pReplaceList.get();
2094 
2095     if ( !pList )
2096         return rStr;
2097 
2098     // Metric query
2099     MapUnit eMapUnit = MapUnit::MapCM;
2100     FieldUnit eFieldUnit = pSh->GetModule()->GetFieldUnit();
2101     switch ( eFieldUnit )
2102     {
2103         case FieldUnit::MM:          eMapUnit = MapUnit::MapMM; break;
2104         case FieldUnit::CM:
2105         case FieldUnit::M:
2106         case FieldUnit::KM:          eMapUnit = MapUnit::MapCM; break;
2107         case FieldUnit::TWIP:        eMapUnit = MapUnit::MapTwip; break;
2108         case FieldUnit::POINT:
2109         case FieldUnit::PICA:        eMapUnit = MapUnit::MapPoint; break;
2110         case FieldUnit::INCH:
2111         case FieldUnit::FOOT:
2112         case FieldUnit::MILE:        eMapUnit = MapUnit::MapInch; break;
2113         case FieldUnit::MM_100TH:    eMapUnit = MapUnit::Map100thMM; break;
2114         default: ;//prevent warning
2115     }
2116 
2117     IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
2118     for ( sal_uInt16 i = 0; i < pList->Count(); ++i )
2119     {
2120         const SearchAttrItem& rItem = pList->GetObject(i);
2121 
2122         if ( !rStr.isEmpty() )
2123             rStr += ", ";
2124 
2125         if ( !IsInvalidItem( rItem.pItem ) )
2126         {
2127             OUString aStr;
2128             rPool.GetPresentation(*rItem.pItem, eMapUnit, aStr, aIntlWrapper);
2129             rStr += aStr;
2130         }
2131         else if ( rItem.nSlot == SID_ATTR_BRUSH_CHAR )
2132         {
2133             // Special treatment for text background
2134             rStr += SvxResId( RID_SVXITEMS_BRUSH_CHAR );
2135         }
2136         else
2137         {
2138             sal_uInt32 nId = SvxAttrNameTable::FindIndex(rItem.nSlot);
2139             if ( RESARRAY_INDEX_NOTFOUND != nId )
2140                 rStr += SvxAttrNameTable::GetString(nId);
2141         }
2142     }
2143     return rStr;
2144 }
2145 
2146 
2147 void SvxSearchDialog::PaintAttrText_Impl()
2148 {
2149     OUString aDesc;
2150     BuildAttrText_Impl( aDesc, bSearch );
2151 
2152     if ( !bFormat && !aDesc.isEmpty() )
2153         bFormat = true;
2154 
2155     bool bSetOptimalLayoutSize = false;
2156 
2157     if ( bSearch )
2158     {
2159         m_xSearchAttrText->set_label( aDesc );
2160         if (!aDesc.isEmpty() && !m_xSearchAttrText->get_visible())
2161         {
2162             m_xSearchAttrText->show();
2163             bSetOptimalLayoutSize = true;
2164         }
2165 
2166         FocusHdl_Impl(*m_xSearchLB);
2167     }
2168     else
2169     {
2170         m_xReplaceAttrText->set_label( aDesc );
2171         if (!aDesc.isEmpty() && !m_xReplaceAttrText->get_visible())
2172         {
2173             m_xReplaceAttrText->show();
2174             bSetOptimalLayoutSize = true;
2175         }
2176 
2177         FocusHdl_Impl(*m_xReplaceLB);
2178     }
2179 
2180     if (bSetOptimalLayoutSize)
2181         m_xDialog->resize_to_request();
2182 }
2183 
2184 void SvxSearchDialog::SetModifyFlag_Impl( const weld::Widget* pCtrl )
2185 {
2186     if (m_xSearchLB.get() == pCtrl)
2187     {
2188         nModifyFlag |= ModifyFlags::Search;
2189         m_xSearchLB->set_entry_message_type(weld::EntryMessageType::Normal);
2190         SvxSearchDialogWrapper::SetSearchLabel("");
2191     }
2192     else if ( m_xReplaceLB.get() == pCtrl )
2193         nModifyFlag |= ModifyFlags::Replace;
2194     else if ( m_xWordBtn.get() == pCtrl )
2195         nModifyFlag |= ModifyFlags::Word;
2196     else if ( m_xMatchCaseCB.get() == pCtrl )
2197         nModifyFlag |= ModifyFlags::Exact;
2198     else if ( m_xReplaceBackwardsCB.get() == pCtrl )
2199         nModifyFlag |= ModifyFlags::Backwards;
2200     else if ( m_xNotesBtn.get() == pCtrl )
2201         nModifyFlag |= ModifyFlags::Notes;
2202     else if ( m_xSelectionBtn.get() == pCtrl )
2203         nModifyFlag |= ModifyFlags::Selection;
2204     else if ( m_xRegExpBtn.get() == pCtrl )
2205         nModifyFlag |= ModifyFlags::Regexp;
2206     else if ( m_xWildcardBtn.get() == pCtrl )
2207         nModifyFlag |= ModifyFlags::Wildcard;
2208     else if ( m_xLayoutBtn.get() == pCtrl )
2209         nModifyFlag |= ModifyFlags::Layout;
2210     else if ( m_xSimilarityBox.get() == pCtrl )
2211         nModifyFlag |= ModifyFlags::Similarity;
2212     else if ( m_xCalcSearchInLB.get() == pCtrl )
2213     {
2214         nModifyFlag |= ModifyFlags::Formulas;
2215         nModifyFlag |= ModifyFlags::Values;
2216         nModifyFlag |= ModifyFlags::CalcNotes;
2217     }
2218     else if ( m_xRowsBtn.get() == pCtrl )
2219         nModifyFlag |= ModifyFlags::Rows;
2220     else if ( m_xColumnsBtn.get() == pCtrl )
2221         nModifyFlag |= ModifyFlags::Columns;
2222     else if ( m_xAllSheetsCB.get() == pCtrl )
2223         nModifyFlag |= ModifyFlags::AllTables;
2224 }
2225 
2226 void SvxSearchDialog::SaveToModule_Impl()
2227 {
2228     if ( !pSearchItem )
2229         return;
2230 
2231     if ( m_xLayoutBtn->get_active() )
2232     {
2233         pSearchItem->SetSearchString ( m_xSearchTmplLB->get_active_text() );
2234         pSearchItem->SetReplaceString( m_xReplaceTmplLB->get_active_text() );
2235     }
2236     else
2237     {
2238         pSearchItem->SetSearchString ( m_xSearchLB->get_active_text() );
2239         pSearchItem->SetReplaceString( m_xReplaceLB->get_active_text() );
2240         Remember_Impl( m_xSearchLB->get_active_text(), true );
2241     }
2242 
2243     pSearchItem->SetRegExp( false );
2244     pSearchItem->SetWildcard( false );
2245     pSearchItem->SetLevenshtein( false );
2246     if (GetCheckBoxValue(*m_xRegExpBtn))
2247         pSearchItem->SetRegExp( true );
2248     else if (GetCheckBoxValue(*m_xWildcardBtn))
2249         pSearchItem->SetWildcard( true );
2250     else if (GetCheckBoxValue(*m_xSimilarityBox))
2251         pSearchItem->SetLevenshtein( true );
2252 
2253     pSearchItem->SetWordOnly(GetCheckBoxValue(*m_xWordBtn));
2254     pSearchItem->SetBackward(GetCheckBoxValue(*m_xReplaceBackwardsCB));
2255     pSearchItem->SetNotes(GetCheckBoxValue(*m_xNotesBtn));
2256     pSearchItem->SetPattern(GetCheckBoxValue(*m_xLayoutBtn));
2257     pSearchItem->SetSelection(GetCheckBoxValue(*m_xSelectionBtn));
2258     pSearchItem->SetUseAsianOptions(GetCheckBoxValue(*m_xJapOptionsCB));
2259 
2260     SvtSearchOptions aOpt;
2261     aOpt.SetIgnoreDiacritics_CTL(GetNegatedCheckBoxValue(*m_xIncludeDiacritics));
2262     aOpt.SetIgnoreKashida_CTL(GetNegatedCheckBoxValue(*m_xIncludeKashida));
2263     aOpt.Commit();
2264 
2265     TransliterationFlags nFlags = GetTransliterationFlags();
2266     if( !pSearchItem->IsUseAsianOptions())
2267         nFlags &= TransliterationFlags::IGNORE_CASE |
2268                    TransliterationFlags::IGNORE_WIDTH;
2269     if (GetNegatedCheckBoxValue(*m_xIncludeDiacritics))
2270         nFlags |= TransliterationFlags::IGNORE_DIACRITICS_CTL;
2271     if (GetNegatedCheckBoxValue(*m_xIncludeKashida))
2272         nFlags |= TransliterationFlags::IGNORE_KASHIDA_CTL;
2273     pSearchItem->SetTransliterationFlags( nFlags );
2274 
2275     if ( !bWriter )
2276     {
2277         if (m_xCalcSearchInLB->get_active() != -1)
2278             pSearchItem->SetCellType( static_cast<SvxSearchCellType>(m_xCalcSearchInLB->get_active()) );
2279 
2280         pSearchItem->SetRowDirection( m_xRowsBtn->get_active() );
2281         pSearchItem->SetAllTables( m_xAllSheetsCB->get_active() );
2282         pSearchItem->SetSearchFormatted( m_xSearchFormattedCB->get_active() );
2283     }
2284 
2285     pSearchItem->SetCommand( SvxSearchCmd::FIND );
2286     nModifyFlag = ModifyFlags::NONE;
2287     const SfxPoolItem* ppArgs[] = { pSearchItem.get(), nullptr };
2288     rBindings.GetDispatcher()->Execute( SID_SEARCH_ITEM, SfxCallMode::SLOT, ppArgs );
2289 }
2290 
2291 void SvxSearchDialog::SetDocWin(vcl::Window* pDocWin)
2292 {
2293     m_xDialog->clear_extra_accessible_relations();
2294 
2295     if (!pDocWin)
2296         return;
2297 
2298     Reference<css::accessibility::XAccessible> xDocAcc = pDocWin->GetAccessible();
2299     if (!xDocAcc.is())
2300     {
2301         return;
2302     }
2303     Reference<css::accessibility::XAccessibleGetAccFlowTo> xGetAccFlowTo(xDocAcc, UNO_QUERY);
2304     if (!xGetAccFlowTo.is())
2305     {
2306         return;
2307     }
2308 
2309     const sal_Int32 FORFINDREPLACEFLOWTO = 2;
2310     uno::Sequence<uno::Any> aAnySeq = xGetAccFlowTo->getAccFlowTo(Any(GetSrchFlag()),  FORFINDREPLACEFLOWTO);
2311 
2312     sal_Int32 nLen = aAnySeq.getLength();
2313     if (nLen)
2314     {
2315         uno::Sequence<uno::Reference<uno::XInterface>> aSequence(nLen);
2316         std::transform(aAnySeq.begin(), aAnySeq.end(), aSequence.begin(),
2317             [](const uno::Any& rAny) -> uno::Reference < css::accessibility::XAccessible > {
2318                 uno::Reference < css::accessibility::XAccessible > xAcc;
2319                 rAny >>= xAcc;
2320                 return xAcc;
2321             });
2322         m_xDialog->add_extra_accessible_relation(css::accessibility::AccessibleRelation(css::accessibility::AccessibleRelationType::CONTENT_FLOWS_TO, aSequence));
2323     }
2324 }
2325 
2326 short SvxSearchDialog::executeSubDialog(VclAbstractDialog * dialog) {
2327     assert(!m_executingSubDialog);
2328     comphelper::ScopeGuard g([this] { m_executingSubDialog = false; });
2329     m_executingSubDialog = true;
2330     return dialog->Execute();
2331 }
2332 
2333 SFX_IMPL_CHILDWINDOW_WITHID(SvxSearchDialogWrapper, SID_SEARCH_DLG);
2334 
2335 
2336 SvxSearchDialogWrapper::SvxSearchDialogWrapper( vcl::Window* _pParent, sal_uInt16 nId,
2337                                                 SfxBindings* pBindings,
2338                                                 SfxChildWinInfo const * pInfo )
2339     : SfxChildWindow( _pParent, nId )
2340     , dialog(new SvxSearchDialog(_pParent->GetFrameWeld(), this, *pBindings))
2341 {
2342     SetController(dialog);
2343     dialog->Initialize( pInfo );
2344 
2345     pBindings->Update( SID_SEARCH_ITEM );
2346     pBindings->Update( SID_SEARCH_OPTIONS );
2347     pBindings->Update( SID_SEARCH_SEARCHSET );
2348     pBindings->Update( SID_SEARCH_REPLACESET );
2349     dialog->bConstruct = false;
2350 }
2351 
2352 SvxSearchDialogWrapper::~SvxSearchDialogWrapper ()
2353 {
2354 }
2355 
2356 
2357 SfxChildWinInfo SvxSearchDialogWrapper::GetInfo() const
2358 {
2359     SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
2360     aInfo.bVisible = false;
2361     return aInfo;
2362 }
2363 
2364 static void lcl_SetSearchLabelWindow(const OUString& rStr)
2365 {
2366     SfxViewFrame* pViewFrame = SfxViewFrame::Current();
2367     if (!pViewFrame)
2368         return;
2369 
2370     bool bNotFound = rStr == SvxResId(RID_SVXSTR_SEARCH_NOT_FOUND);
2371 
2372     css::uno::Reference< css::beans::XPropertySet > xPropSet(
2373             pViewFrame->GetFrame().GetFrameInterface(), css::uno::UNO_QUERY_THROW);
2374     css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
2375     xPropSet->getPropertyValue("LayoutManager") >>= xLayoutManager;
2376     css::uno::Reference< css::ui::XUIElement > xUIElement =
2377         xLayoutManager->getElement("private:resource/toolbar/findbar");
2378     if (!xUIElement.is())
2379         return;
2380     css::uno::Reference< css::awt::XWindow > xWindow(
2381             xUIElement->getRealInterface(), css::uno::UNO_QUERY_THROW);
2382     VclPtr< ToolBox > pToolBox = static_cast<ToolBox*>( VCLUnoHelper::GetWindow(xWindow).get() );
2383     for (ToolBox::ImplToolItems::size_type i = 0; pToolBox && i < pToolBox->GetItemCount(); ++i)
2384     {
2385         sal_uInt16 id = pToolBox->GetItemId(i);
2386         if (pToolBox->GetItemCommand(id) == ".uno:SearchLabel")
2387         {
2388             vcl::Window* pSearchLabel = pToolBox->GetItemWindow(id);
2389             assert(pSearchLabel);
2390             pSearchLabel->SetText(rStr);
2391             if (rStr.isEmpty())
2392                 pSearchLabel->SetSizePixel(Size(16, pSearchLabel->get_preferred_size().Height()));
2393             else
2394                 pSearchLabel->SetSizePixel(pSearchLabel->get_preferred_size());
2395         }
2396 
2397         if (pToolBox->GetItemCommand(id) == ".uno:FindText")
2398         {
2399             ComboBox* pFindText = dynamic_cast<ComboBox*>(pToolBox->GetItemWindow(id));
2400             assert(pFindText);
2401             Edit* pEdit = pFindText->GetSubEdit();
2402             if (bNotFound)
2403                 pEdit->SetControlForeground(COL_LIGHTRED);
2404             else
2405                 pEdit->SetControlForeground();
2406         }
2407     }
2408     xLayoutManager->doLayout();
2409     pToolBox->Resize();
2410 }
2411 
2412 OUString SvxSearchDialogWrapper::GetSearchLabel()
2413 {
2414     SfxViewFrame* pViewFrame = SfxViewFrame::Current();
2415     if (!pViewFrame)
2416         return OUString();
2417 
2418     css::uno::Reference< css::beans::XPropertySet > xPropSet(
2419             pViewFrame->GetFrame().GetFrameInterface(), css::uno::UNO_QUERY_THROW);
2420     css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
2421     xPropSet->getPropertyValue("LayoutManager") >>= xLayoutManager;
2422     css::uno::Reference< css::ui::XUIElement > xUIElement =
2423         xLayoutManager->getElement("private:resource/toolbar/findbar");
2424     if (!xUIElement.is())
2425         return OUString();
2426     css::uno::Reference< css::awt::XWindow > xWindow(
2427             xUIElement->getRealInterface(), css::uno::UNO_QUERY_THROW);
2428     VclPtr< ToolBox > pToolBox = static_cast<ToolBox*>( VCLUnoHelper::GetWindow(xWindow).get() );
2429     for (ToolBox::ImplToolItems::size_type i = 0; pToolBox && i < pToolBox->GetItemCount(); ++i)
2430     {
2431         sal_uInt16 id = pToolBox->GetItemId(i);
2432         if (pToolBox->GetItemCommand(id) == ".uno:SearchLabel")
2433         {
2434             vcl::Window* pSearchLabel = pToolBox->GetItemWindow(id);
2435             return pSearchLabel ? pSearchLabel->GetText() : OUString();
2436         }
2437     }
2438     return OUString();
2439 }
2440 
2441 void SvxSearchDialogWrapper::SetSearchLabel(const SearchLabel& rSL)
2442 {
2443     OUString sStr;
2444     if (rSL == SearchLabel::End)
2445         sStr = SvxResId(RID_SVXSTR_SEARCH_END);
2446     else if (rSL == SearchLabel::Start)
2447         sStr = SvxResId(RID_SVXSTR_SEARCH_START);
2448     else if (rSL == SearchLabel::EndWrapped)
2449         sStr = SvxResId(RID_SVXSTR_SEARCH_END_WRAPPED);
2450     else if (rSL == SearchLabel::StartWrapped)
2451         sStr = SvxResId(RID_SVXSTR_SEARCH_START_WRAPPED);
2452     else if (rSL == SearchLabel::EndSheet)
2453         sStr = SvxResId(RID_SVXSTR_SEARCH_END_SHEET);
2454     else if (rSL == SearchLabel::NotFound)
2455         sStr = SvxResId(RID_SVXSTR_SEARCH_NOT_FOUND);
2456     else if (rSL == SearchLabel::NavElementNotFound)
2457         sStr = SvxResId(RID_SVXSTR_SEARCH_NAV_ELEMENT_NOT_FOUND);
2458 
2459     lcl_SetSearchLabelWindow(sStr);
2460     if (SvxSearchDialogWrapper *pWrp = static_cast<SvxSearchDialogWrapper*>( SfxViewFrame::Current()->
2461             GetChildWindow( SvxSearchDialogWrapper::GetChildWindowId() )))
2462         pWrp->getDialog()->SetSearchLabel(sStr);
2463 }
2464 
2465 void SvxSearchDialogWrapper::SetSearchLabel(const OUString& sStr)
2466 {
2467 
2468     lcl_SetSearchLabelWindow(sStr);
2469     if (SvxSearchDialogWrapper *pWrp = static_cast<SvxSearchDialogWrapper*>( SfxViewFrame::Current()->
2470             GetChildWindow( SvxSearchDialogWrapper::GetChildWindowId() )))
2471         pWrp->getDialog()->SetSearchLabel(sStr);
2472 }
2473 
2474 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2475