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