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