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 <com/sun/star/i18n/WordType.hpp>
21 #include <com/sun/star/linguistic2/XThesaurus.hpp>
22 
23 #include <hintids.hxx>
24 #include <cmdid.h>
25 #include <comphelper/lok.hxx>
26 
27 #include <i18nutil/unicode.hxx>
28 #include <i18nlangtag/languagetag.hxx>
29 #include <svtools/langtab.hxx>
30 #include <svl/slstitm.hxx>
31 #include <svl/stritem.hxx>
32 #include <sfx2/htmlmode.hxx>
33 #include <svl/whiter.hxx>
34 #include <sfx2/bindings.hxx>
35 #include <sfx2/viewfrm.hxx>
36 #include <vcl/unohelp2.hxx>
37 #include <vcl/weld.hxx>
38 #include <sfx2/request.hxx>
39 #include <svl/eitem.hxx>
40 #include <editeng/lrspitem.hxx>
41 #include <editeng/colritem.hxx>
42 #include <editeng/tstpitem.hxx>
43 #include <editeng/brushitem.hxx>
44 #include <editeng/svxacorr.hxx>
45 #include <svl/cjkoptions.hxx>
46 #include <svl/ctloptions.hxx>
47 #include <IDocumentDrawModelAccess.hxx>
48 #include <IDocumentSettingAccess.hxx>
49 #include <charfmt.hxx>
50 #include <svx/SmartTagItem.hxx>
51 #include <svx/xflgrit.hxx>
52 #include <svx/xflhtit.hxx>
53 #include <fmtinfmt.hxx>
54 #include <wrtsh.hxx>
55 #include <wview.hxx>
56 #include <swmodule.hxx>
57 #include <viewopt.hxx>
58 #include <uitool.hxx>
59 #include <textsh.hxx>
60 #include <IMark.hxx>
61 #include <swdtflvr.hxx>
62 #include <swundo.hxx>
63 #include <reffld.hxx>
64 #include <docsh.hxx>
65 #include <inputwin.hxx>
66 #include <chrdlgmodes.hxx>
67 #include <fmtcol.hxx>
68 #include <cellatr.hxx>
69 #include <edtwin.hxx>
70 #include <fldmgr.hxx>
71 #include <strings.hrc>
72 #include <paratr.hxx>
73 #include <vcl/svapp.hxx>
74 #include <sfx2/app.hxx>
75 #include <breakit.hxx>
76 #include <SwSmartTagMgr.hxx>
77 #include <editeng/acorrcfg.hxx>
78 #include <swabstdlg.hxx>
79 #include <sfx2/sfxdlg.hxx>
80 #include <com/sun/star/container/XNameContainer.hpp>
81 #include <com/sun/star/beans/XPropertySet.hpp>
82 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
83 #include <com/sun/star/uno/Any.hxx>
84 #include <com/sun/star/linguistic2/ProofreadingResult.hpp>
85 #include <com/sun/star/linguistic2/XDictionary.hpp>
86 #include <com/sun/star/linguistic2/XSpellAlternatives.hpp>
87 #include <editeng/unolingu.hxx>
88 #include <doc.hxx>
89 #include <drawdoc.hxx>
90 #include <view.hxx>
91 #include <pam.hxx>
92 #include <sfx2/objface.hxx>
93 #include <langhelper.hxx>
94 #include <uiitems.hxx>
95 #include <svx/nbdtmgfact.hxx>
96 #include <svx/nbdtmg.hxx>
97 #include <SwRewriter.hxx>
98 #include <svx/drawitem.hxx>
99 #include <numrule.hxx>
100 #include <memory>
101 #include <xmloff/odffields.hxx>
102 #include <bookmrk.hxx>
103 #include <linguistic/misc.hxx>
104 #include <authfld.hxx>
105 
106 using namespace ::com::sun::star;
107 using namespace com::sun::star::beans;
108 using namespace ::com::sun::star::container;
109 using namespace com::sun::star::style;
110 using namespace svx::sidebar;
111 
112 static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell &rWrtSh, std::shared_ptr<SfxItemSet> const & pCoreSet, bool bSel, bool bSelectionPut, SfxRequest *pReq);
113 
sw_CharDialog(SwWrtShell & rWrtSh,bool bUseDialog,sal_uInt16 nSlot,const SfxItemSet * pArgs,SfxRequest * pReq)114 static void sw_CharDialog(SwWrtShell &rWrtSh, bool bUseDialog, sal_uInt16 nSlot, const SfxItemSet *pArgs, SfxRequest *pReq )
115 {
116     FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( &rWrtSh.GetView()) != nullptr );
117     SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
118     auto pCoreSet = std::make_shared<SfxItemSet>(
119         rWrtSh.GetView().GetPool(),
120         svl::Items<
121             RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
122             RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
123             RES_BACKGROUND, RES_SHADOW,
124             XATTR_FILLSTYLE, XATTR_FILLCOLOR,
125             SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
126             SID_HTML_MODE, SID_HTML_MODE,
127             SID_ATTR_CHAR_WIDTH_FIT_TO_LINE, SID_ATTR_CHAR_WIDTH_FIT_TO_LINE,
128             FN_PARAM_SELECTION, FN_PARAM_SELECTION>{});
129     rWrtSh.GetCurAttr(*pCoreSet);
130 
131     bool bSel = rWrtSh.HasSelection();
132     bool bSelectionPut = false;
133     if(bSel || rWrtSh.IsInWord())
134     {
135         if(!bSel)
136         {
137             rWrtSh.StartAction();
138             rWrtSh.Push();
139             if(!rWrtSh.SelectTextAttr( RES_TXTATR_INETFMT ))
140                 rWrtSh.SelWrd();
141         }
142         pCoreSet->Put(SfxStringItem(FN_PARAM_SELECTION, rWrtSh.GetSelText()));
143         bSelectionPut = true;
144         if(!bSel)
145         {
146             rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
147             rWrtSh.EndAction();
148         }
149     }
150     pCoreSet->Put(SfxUInt16Item(SID_ATTR_CHAR_WIDTH_FIT_TO_LINE, rWrtSh.GetScalingOfSelectedText()));
151 
152     ::ConvertAttrCharToGen(*pCoreSet);
153 
154     // Setting the BoxInfo
155     ::PrepareBoxInfo(*pCoreSet, rWrtSh);
156 
157     pCoreSet->Put(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(rWrtSh.GetView().GetDocShell())));
158     VclPtr<SfxAbstractTabDialog> pDlg;
159     if ( bUseDialog && GetActiveView() )
160     {
161         SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
162         pDlg.reset(pFact->CreateSwCharDlg(rWrtSh.GetView().GetFrameWeld(), rWrtSh.GetView(), *pCoreSet, SwCharDlgMode::Std));
163 
164         if (nSlot == FN_INSERT_HYPERLINK)
165             pDlg->SetCurPageId("hyperlink");
166         else if (nSlot == SID_CHAR_DLG_EFFECT)
167             pDlg->SetCurPageId("fonteffects");
168         else if (nSlot == SID_CHAR_DLG_FOR_PARAGRAPH)
169             pDlg->SetCurPageId("font");
170         else if (pReq)
171         {
172             const SfxStringItem* pItem = (*pReq).GetArg<SfxStringItem>(FN_PARAM_1);
173             if (pItem)
174                 pDlg->SetCurPageId(OUStringToOString(pItem->GetValue(), RTL_TEXTENCODING_UTF8));
175         }
176     }
177 
178     if (bUseDialog)
179     {
180         std::shared_ptr<SfxRequest> pRequest;
181         if (pReq)
182         {
183             pRequest = std::make_shared<SfxRequest>(*pReq);
184             pReq->Ignore(); // the 'old' request is not relevant any more
185         }
186         pDlg->StartExecuteAsync([pDlg, &rWrtSh, pCoreSet, bSel, bSelectionPut, pRequest](sal_Int32 nResult){
187             if (nResult == RET_OK)
188             {
189                 sw_CharDialogResult(pDlg->GetOutputItemSet(), rWrtSh, pCoreSet, bSel, bSelectionPut, pRequest.get());
190             }
191             pDlg->disposeOnce();
192         });
193     }
194     else if (pArgs)
195     {
196         sw_CharDialogResult(pArgs, rWrtSh, pCoreSet, bSel, bSelectionPut, pReq);
197     }
198 }
199 
sw_CharDialogResult(const SfxItemSet * pSet,SwWrtShell & rWrtSh,std::shared_ptr<SfxItemSet> const & pCoreSet,bool bSel,bool bSelectionPut,SfxRequest * pReq)200 static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell &rWrtSh, std::shared_ptr<SfxItemSet> const & pCoreSet, bool bSel, bool bSelectionPut, SfxRequest *pReq)
201 {
202     SfxItemSet aTmpSet( *pSet );
203     ::ConvertAttrGenToChar(aTmpSet, *pCoreSet);
204 
205     const SfxPoolItem* pSelectionItem;
206     bool bInsert = false;
207     sal_Int32 nInsert = 0;
208 
209     // The old item is for unknown reasons back in the set again.
210     if( !bSelectionPut && SfxItemState::SET == aTmpSet.GetItemState(FN_PARAM_SELECTION, false, &pSelectionItem) )
211     {
212         OUString sInsert = static_cast<const SfxStringItem*>(pSelectionItem)->GetValue();
213         bInsert = !sInsert.isEmpty();
214         if(bInsert)
215         {
216             nInsert = sInsert.getLength();
217             rWrtSh.StartAction();
218             rWrtSh.Insert( sInsert );
219             rWrtSh.SetMark();
220             rWrtSh.ExtendSelection(false, sInsert.getLength());
221             SfxRequest aReq( rWrtSh.GetView().GetViewFrame(), FN_INSERT_STRING );
222             aReq.AppendItem( SfxStringItem( FN_INSERT_STRING, sInsert ) );
223             aReq.Done();
224             SfxRequest aReq1( rWrtSh.GetView().GetViewFrame(), FN_CHAR_LEFT );
225             aReq1.AppendItem( SfxInt32Item(FN_PARAM_MOVE_COUNT, nInsert) );
226             aReq1.AppendItem( SfxBoolItem(FN_PARAM_MOVE_SELECTION, true) );
227             aReq1.Done();
228         }
229     }
230     aTmpSet.ClearItem(FN_PARAM_SELECTION);
231 
232     SwTextFormatColl* pColl = rWrtSh.GetCurTextFormatColl();
233     if(bSel && rWrtSh.IsSelFullPara() && pColl && pColl->IsAutoUpdateFormat())
234     {
235         rWrtSh.AutoUpdatePara(pColl, aTmpSet);
236     }
237     else
238         rWrtSh.SetAttrSet( aTmpSet );
239     if (pReq)
240         pReq->Done(aTmpSet);
241     if(bInsert)
242     {
243         SfxRequest aReq1( rWrtSh.GetView().GetViewFrame(), FN_CHAR_RIGHT );
244         aReq1.AppendItem( SfxInt32Item(FN_PARAM_MOVE_COUNT, nInsert) );
245         aReq1.AppendItem( SfxBoolItem(FN_PARAM_MOVE_SELECTION, false) );
246         aReq1.Done();
247         rWrtSh.SwapPam();
248         rWrtSh.ClearMark();
249         rWrtSh.DontExpandFormat();
250         rWrtSh.EndAction();
251     }
252 
253 }
254 
lcl_AskRedlineFlags(weld::Window * pWin)255 static short lcl_AskRedlineFlags(weld::Window *pWin)
256 {
257     std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pWin, "modules/swriter/ui/queryredlinedialog.ui"));
258     std::unique_ptr<weld::MessageDialog> xQBox(xBuilder->weld_message_dialog("QueryRedlineDialog"));
259     return xQBox->run();
260 }
261 
sw_ParagraphDialogResult(SfxItemSet * pSet,SwWrtShell & rWrtSh,SfxRequest & rReq,SwPaM * pPaM)262 static void sw_ParagraphDialogResult(SfxItemSet* pSet, SwWrtShell &rWrtSh, SfxRequest& rReq, SwPaM* pPaM)
263 {
264     if (!pSet)
265         return;
266 
267     rReq.Done( *pSet );
268     ::SfxToSwPageDescAttr( rWrtSh, *pSet );
269     // #i56253#
270     // enclose all undos.
271     // Thus, check conditions, if actions will be performed.
272     const bool bUndoNeeded( pSet->Count() ||
273             SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART) ||
274             SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART_AT) );
275     if ( bUndoNeeded )
276     {
277         rWrtSh.StartUndo( SwUndoId::INSATTR );
278     }
279     if( pSet->Count() )
280     {
281         rWrtSh.StartAction();
282         const SfxPoolItem* pItem = nullptr;
283         if ( SfxItemState::SET == pSet->GetItemState(FN_DROP_TEXT, false, &pItem) )
284         {
285             if ( !static_cast<const SfxStringItem*>(pItem)->GetValue().isEmpty() )
286                 rWrtSh.ReplaceDropText(static_cast<const SfxStringItem*>(pItem)->GetValue(), pPaM);
287         }
288         rWrtSh.SetAttrSet(*pSet, SetAttrMode::DEFAULT, pPaM);
289         rWrtSh.EndAction();
290         SwTextFormatColl* pColl = rWrtSh.GetPaMTextFormatColl(pPaM);
291         if(pColl && pColl->IsAutoUpdateFormat())
292         {
293             rWrtSh.AutoUpdatePara(pColl, *pSet, pPaM);
294         }
295     }
296 
297     if( SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART) )
298     {
299         //SetNumRuleStart(true) restarts the numbering at the value
300         //that is defined at the starting point of the numbering level
301         //otherwise the SetNodeNumStart() value determines the start
302         //if it's set to something different than USHRT_MAX
303 
304         bool bStart = static_cast<const SfxBoolItem&>(pSet->Get(FN_NUMBER_NEWSTART)).GetValue();
305 
306         // Default value for restart value has to be USHRT_MAX
307         // in order to indicate that the restart value of the list
308         // style has to be used on restart.
309         sal_uInt16 nNumStart = USHRT_MAX;
310         if( SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART_AT) )
311         {
312             nNumStart = static_cast<const SfxUInt16Item&>(pSet->Get(FN_NUMBER_NEWSTART_AT)).GetValue();
313         }
314         rWrtSh.SetNumRuleStart(bStart, pPaM);
315         rWrtSh.SetNodeNumStart(nNumStart);
316     }
317     else if( SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART_AT) )
318     {
319         rWrtSh.SetNodeNumStart(static_cast<const SfxUInt16Item&>(pSet->Get(FN_NUMBER_NEWSTART_AT)).GetValue());
320         rWrtSh.SetNumRuleStart(false, pPaM);
321     }
322     // #i56253#
323     if ( bUndoNeeded )
324     {
325         rWrtSh.EndUndo( SwUndoId::INSATTR );
326     }
327 }
328 
329 namespace {
330 
InsertBreak(SwWrtShell & rWrtSh,sal_uInt16 nKind,::std::optional<sal_uInt16> oPageNumber,const OUString & rTemplateName)331 void InsertBreak(SwWrtShell& rWrtSh,
332                  sal_uInt16 nKind,
333                  ::std::optional<sal_uInt16> oPageNumber,
334                  const OUString& rTemplateName)
335 {
336     switch ( nKind )
337     {
338         case 1 :
339             rWrtSh.InsertLineBreak(); break;
340         case 2 :
341             rWrtSh.InsertColumnBreak(); break;
342         case 3 :
343         {
344             rWrtSh.StartAllAction();
345             if( !rTemplateName.isEmpty() )
346                 rWrtSh.InsertPageBreak( &rTemplateName, oPageNumber );
347             else
348                 rWrtSh.InsertPageBreak();
349             rWrtSh.EndAllAction();
350         }
351     }
352 }
353 
354 }
355 
Execute(SfxRequest & rReq)356 void SwTextShell::Execute(SfxRequest &rReq)
357 {
358     bool bUseDialog = true;
359     const SfxItemSet *pArgs = rReq.GetArgs();
360     SwWrtShell& rWrtSh = GetShell();
361     const SfxPoolItem* pItem = nullptr;
362     const sal_uInt16 nSlot = rReq.GetSlot();
363     if(pArgs)
364         pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem);
365     switch( nSlot )
366     {
367         case SID_UNICODE_NOTATION_TOGGLE:
368         {
369             tools::Long nMaxUnits = 256;
370             sal_Int32 nSelLength = rWrtSh.GetSelText().getLength();
371             if( rWrtSh.IsSelection() && !rWrtSh.IsMultiSelection() && (nSelLength < nMaxUnits) )
372                 nMaxUnits = nSelLength;
373 
374             tools::Long index = 0;
375             ToggleUnicodeCodepoint aToggle;
376             while( nMaxUnits-- && aToggle.AllowMoreInput(rWrtSh.GetChar(true, index-1)) )
377                 --index;
378 
379             OUString sReplacement = aToggle.ReplacementString();
380             if( !sReplacement.isEmpty() )
381             {
382                 if (rWrtSh.HasReadonlySel() && !rWrtSh.CursorInsideInputField())
383                 {
384                     // Only break if there's something to do; don't nag with the dialog otherwise
385                     auto xInfo(std::make_unique<weld::GenericDialogController>(
386                         rWrtSh.GetView().GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui",
387                         "InfoReadonlyDialog"));
388                     xInfo->run();
389                     break;
390                 }
391                 SwRewriter aRewriter;
392                 aRewriter.AddRule( UndoArg1, aToggle.StringToReplace() );
393                 aRewriter.AddRule( UndoArg2, SwResId(STR_YIELDS) );
394                 aRewriter.AddRule( UndoArg3, sReplacement );
395                 rWrtSh.StartUndo(SwUndoId::REPLACE, &aRewriter);
396                 rWrtSh.GetCursor()->Normalize(false);
397 
398                 rWrtSh.ClearMark();
399                 if( rWrtSh.IsInSelect() )  // cancel any in-progress keyboard selection as well
400                     rWrtSh.EndSelect();
401 
402                 for( sal_uInt32 i=aToggle.CharsToDelete(); i > 0; --i )
403                     rWrtSh.DelLeft();
404                 rWrtSh.Insert2( sReplacement );
405                 rWrtSh.EndUndo(SwUndoId::REPLACE, &aRewriter);
406             }
407         }
408         break;
409 
410         case SID_LANGUAGE_STATUS:
411         {
412             // get the language
413             OUString aNewLangText;
414             const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(SID_LANGUAGE_STATUS);
415             if (pItem2)
416                 aNewLangText = pItem2->GetValue();
417 
418             //!! Remember the view frame right now...
419             //!! (call to GetView().GetViewFrame() will break if the
420             //!! SwTextShell got destroyed meanwhile.)
421             SfxViewFrame *pViewFrame = GetView().GetViewFrame();
422 
423             if (aNewLangText == "*")
424             {
425                 // open the dialog "Tools/Options/Language Settings - Language"
426                 // to set the documents default language
427                 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
428                 ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclDialog(GetView().GetFrameWeld(), SID_LANGUAGE_OPTIONS));
429                 pDlg->Execute();
430             }
431             else
432             {
433                 //!! We have to use StartAction / EndAction bracketing in
434                 //!! order to prevent possible destruction of the SwTextShell
435                 //!! due to the selection changes coming below.
436                 rWrtSh.StartAction();
437                 // prevent view from jumping because of (temporary) selection changes
438                 rWrtSh.LockView( true );
439 
440                 // setting the new language...
441                 if (!aNewLangText.isEmpty())
442                 {
443                     static const OUStringLiteral aSelectionLangPrefix(u"Current_");
444                     static const OUStringLiteral aParagraphLangPrefix(u"Paragraph_");
445                     static const OUStringLiteral aDocumentLangPrefix(u"Default_");
446 
447                     SfxItemSet aCoreSet( GetPool(),
448                             svl::Items<RES_CHRATR_LANGUAGE,        RES_CHRATR_LANGUAGE,
449                             RES_CHRATR_CJK_LANGUAGE,    RES_CHRATR_CJK_LANGUAGE,
450                             RES_CHRATR_CTL_LANGUAGE,    RES_CHRATR_CTL_LANGUAGE>{} );
451 
452                     sal_Int32 nPos = 0;
453                     bool bForSelection = true;
454                     bool bForParagraph = false;
455                     if (-1 != (nPos = aNewLangText.indexOf( aSelectionLangPrefix )))
456                     {
457                         // ... for the current selection
458                         aNewLangText = aNewLangText.replaceAt(nPos, aSelectionLangPrefix.getLength(), "");
459                         bForSelection = true;
460                     }
461                     else if (-1 != (nPos = aNewLangText.indexOf(aParagraphLangPrefix)))
462                     {
463                         // ... for the current paragraph language
464                         aNewLangText = aNewLangText.replaceAt(nPos, aParagraphLangPrefix.getLength(), "");
465                         bForSelection = true;
466                         bForParagraph = true;
467                     }
468                     else if (-1 != (nPos = aNewLangText.indexOf(aDocumentLangPrefix)))
469                     {
470                         // ... as default document language
471                         aNewLangText = aNewLangText.replaceAt(nPos, aDocumentLangPrefix.getLength(), "");
472                         bForSelection = false;
473                     }
474 
475                     if (bForParagraph || !bForSelection)
476                     {
477                         rWrtSh.Push(); // save selection for later restoration
478                         rWrtSh.ClearMark(); // fdo#67796: invalidate table crsr
479                     }
480 
481                     if (bForParagraph)
482                         SwLangHelper::SelectCurrentPara( rWrtSh );
483 
484                     if (!bForSelection) // document language to be changed...
485                     {
486                         rWrtSh.SelAll();
487                         rWrtSh.ExtendedSelectAll();
488                     }
489 
490                     rWrtSh.StartUndo( ( !bForParagraph && !bForSelection ) ? SwUndoId::SETDEFTATTR : SwUndoId::EMPTY );
491                     if (aNewLangText == "LANGUAGE_NONE")
492                         SwLangHelper::SetLanguage_None( rWrtSh, bForSelection, aCoreSet );
493                     else if (aNewLangText == "RESET_LANGUAGES")
494                         SwLangHelper::ResetLanguages( rWrtSh );
495                     else
496                         SwLangHelper::SetLanguage( rWrtSh, aNewLangText, bForSelection, aCoreSet );
497                     rWrtSh.EndUndo();
498 
499                     if (bForParagraph || !bForSelection)
500                     {
501                         rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent); // restore selection...
502                     }
503                 }
504 
505                 rWrtSh.LockView( false );
506                 rWrtSh.EndAction();
507             }
508 
509             // invalidate slot to get the new language displayed
510             pViewFrame->GetBindings().Invalidate( nSlot );
511 
512             rReq.Done();
513             break;
514         }
515 
516         case SID_THES:
517         {
518             // replace word/selection with text from selected sub menu entry
519             OUString aReplaceText;
520             const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(SID_THES);
521             if (pItem2)
522                 aReplaceText = pItem2->GetValue();
523             if (!aReplaceText.isEmpty())
524             {
525                 SwView &rView2 = rWrtSh.GetView();
526                 const bool bSelection = rWrtSh.HasSelection();
527                 const OUString aLookUpText = rView2.GetThesaurusLookUpText( bSelection );
528                 rView2.InsertThesaurusSynonym( aReplaceText, aLookUpText, bSelection );
529             }
530         }
531         break;
532 
533         case SID_CHARMAP:
534         {
535             InsertSymbol( rReq );
536         }
537         break;
538         case FN_INSERT_FOOTNOTE:
539         case FN_INSERT_ENDNOTE:
540         {
541             OUString aStr;
542             const SfxStringItem* pFont = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
543             const SfxStringItem* pNameItem = rReq.GetArg<SfxStringItem>(nSlot);
544             if ( pNameItem )
545                 aStr = pNameItem->GetValue();
546             bool bFont = pFont && !pFont->GetValue().isEmpty();
547             rWrtSh.StartUndo( SwUndoId::UI_INSERT_FOOTNOTE );
548             rWrtSh.InsertFootnote( aStr, nSlot == FN_INSERT_ENDNOTE, !bFont );
549             if ( bFont )
550             {
551                 rWrtSh.Left( CRSR_SKIP_CHARS, true, 1, false );
552                 SfxItemSet aSet( rWrtSh.GetAttrPool(), svl::Items<RES_CHRATR_FONT, RES_CHRATR_FONT>{} );
553                 rWrtSh.GetCurAttr( aSet );
554                 rWrtSh.SetAttrSet( aSet, SetAttrMode::DONTEXPAND );
555                 rWrtSh.ResetSelect(nullptr, false);
556                 rWrtSh.EndSelect();
557                 rWrtSh.GotoFootnoteText();
558             }
559             rWrtSh.EndUndo( SwUndoId::UI_INSERT_FOOTNOTE );
560             rReq.Done();
561         }
562         break;
563         case FN_INSERT_FOOTNOTE_DLG:
564         {
565             SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
566             ScopedVclPtr<AbstractInsFootNoteDlg> pDlg(pFact->CreateInsFootNoteDlg(
567                 GetView().GetFrameWeld(), rWrtSh));
568             pDlg->SetHelpId(GetStaticInterface()->GetSlot(nSlot)->GetCommand());
569             if ( pDlg->Execute() == RET_OK )
570             {
571                 const sal_uInt16 nId = pDlg->IsEndNote() ? FN_INSERT_ENDNOTE : FN_INSERT_FOOTNOTE;
572                 SfxRequest aReq( GetView().GetViewFrame(), nId );
573                 if ( !pDlg->GetStr().isEmpty() )
574                     aReq.AppendItem( SfxStringItem( nId, pDlg->GetStr() ) );
575                 if ( !pDlg->GetFontName().isEmpty() )
576                     aReq.AppendItem( SfxStringItem( FN_PARAM_1, pDlg->GetFontName() ) );
577                 ExecuteSlot( aReq );
578             }
579 
580             rReq.Ignore();
581         }
582         break;
583         case FN_FORMAT_FOOTNOTE_DLG:
584         case FN_FORMAT_CURRENT_FOOTNOTE_DLG:
585         {
586             GetView().ExecFormatFootnote();
587             break;
588         }
589         case SID_INSERTDOC:
590         {
591             GetView().ExecuteInsertDoc( rReq, pItem );
592             break;
593         }
594         case FN_FORMAT_RESET:
595         {
596             // #i78856, reset all attributes but not the language attributes
597             // (for this build an array of all relevant attributes and
598             // remove the languages from that)
599             o3tl::sorted_vector<sal_uInt16> aAttribs;
600 
601             constexpr std::pair<sal_uInt16, sal_uInt16> aResetableSetRange[] = {
602                 // tdf#40496: we don't want to change writing direction, so exclude RES_FRAMEDIR:
603                 { RES_FRMATR_BEGIN, RES_FRAMEDIR - 1 },
604                 { RES_FRAMEDIR + 1, RES_FRMATR_END - 1 },
605                 { RES_CHRATR_BEGIN, RES_CHRATR_LANGUAGE - 1 },
606                 { RES_CHRATR_LANGUAGE + 1, RES_CHRATR_CJK_LANGUAGE - 1 },
607                 { RES_CHRATR_CJK_LANGUAGE + 1, RES_CHRATR_CTL_LANGUAGE - 1 },
608                 { RES_CHRATR_CTL_LANGUAGE + 1, RES_CHRATR_END - 1 },
609                 { RES_PARATR_BEGIN, RES_PARATR_END - 1 },
610                 { RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER },
611                 { RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END - 1 },
612             };
613             for (const auto& [nBegin, nEnd] : aResetableSetRange)
614             {
615                 for (sal_uInt16 i = nBegin; i <= nEnd; ++i)
616                     aAttribs.insert( i );
617             }
618             rWrtSh.ResetAttr( aAttribs );
619 
620             // also clear the direct formatting flag inside SwTableBox(es)
621             GetView().GetDocShell()->GetFEShell()->UpdateTableStyleFormatting(nullptr, true);
622 
623             rReq.Done();
624             break;
625         }
626         case FN_INSERT_BREAK_DLG:
627         {
628             if ( pItem )
629             {
630                 ::std::optional<sal_uInt16> oPageNumber;
631                 OUString aTemplateName;
632                 sal_uInt16 nKind = static_cast<const SfxInt16Item*>(pItem)->GetValue();
633                 const SfxStringItem* pTemplate = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
634                 const SfxUInt16Item* pNumber = rReq.GetArg<SfxUInt16Item>(FN_PARAM_2);
635                 const SfxBoolItem* pIsNumberFilled = rReq.GetArg<SfxBoolItem>(FN_PARAM_3);
636                 if ( pTemplate )
637                     aTemplateName = pTemplate->GetValue();
638                 if ( pNumber && pIsNumberFilled && pIsNumberFilled->GetValue() )
639                     oPageNumber = pNumber->GetValue();
640 
641                 InsertBreak(rWrtSh, nKind, oPageNumber, aTemplateName);
642             }
643             else
644             {
645                 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
646 
647                 std::shared_ptr<AbstractSwBreakDlg> pAbstractDialog(pFact->CreateSwBreakDlg(GetView().GetFrameWeld(), rWrtSh));
648                 std::shared_ptr<weld::DialogController> pDialogController(pAbstractDialog->getDialogController());
649 
650                 weld::DialogController::runAsync(pDialogController,
651                     [pAbstractDialog, &rWrtSh] (sal_Int32 nResult) {
652                         if( RET_OK == nResult )
653                         {
654                             sal_uInt16 nKind = pAbstractDialog->GetKind();
655                             OUString aTemplateName = pAbstractDialog->GetTemplateName();
656                             ::std::optional<sal_uInt16> oPageNumber = pAbstractDialog->GetPageNumber();
657 
658                             InsertBreak(rWrtSh, nKind, oPageNumber, aTemplateName);
659                         }
660                     });
661             }
662 
663             break;
664         }
665         case FN_INSERT_BOOKMARK:
666         {
667             if ( pItem )
668             {
669                 OUString sName = static_cast<const SfxStringItem*>(pItem)->GetValue();
670                 rWrtSh.SetBookmark( vcl::KeyCode(), sName );
671             }
672             else
673             {
674                 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
675                 ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwInsertBookmarkDlg(GetView().GetFrameWeld(), rWrtSh));
676                 VclAbstractDialog::AsyncContext aContext;
677                 aContext.maEndDialogFn = [](sal_Int32){};
678                 pDlg->StartExecuteAsync(aContext);
679             }
680 
681             break;
682         }
683         case FN_DELETE_BOOKMARK:
684         {
685             if (pItem && !rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS))
686             {
687                 IDocumentMarkAccess* const pMarkAccess = rWrtSh.getIDocumentMarkAccess();
688                 pMarkAccess->deleteMark( pMarkAccess->findMark(static_cast<const SfxStringItem*>(pItem)->GetValue()) );
689             }
690             break;
691         }
692         case FN_SET_REMINDER:
693         {
694             // collect and sort navigator reminder names
695             IDocumentMarkAccess* const pMarkAccess = rWrtSh.getIDocumentMarkAccess();
696             std::vector< OUString > vNavMarkNames;
697             for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAllMarksBegin();
698                 ppMark != pMarkAccess->getAllMarksEnd();
699                 ++ppMark)
700             {
701                 if( IDocumentMarkAccess::GetType(**ppMark) == IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER )
702                     vNavMarkNames.push_back((*ppMark)->GetName());
703             }
704             std::sort(vNavMarkNames.begin(), vNavMarkNames.end());
705 
706             // we are maxed out so delete the first one
707             // this assumes that IDocumentMarkAccess generates Names in ascending order
708             if(vNavMarkNames.size() == MAX_MARKS)
709                 pMarkAccess->deleteMark(pMarkAccess->findMark(vNavMarkNames[0]));
710 
711             rWrtSh.SetBookmark(vcl::KeyCode(), OUString(), IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER);
712             SwView::SetActMark(vNavMarkNames.size() < MAX_MARKS ? vNavMarkNames.size() : MAX_MARKS-1);
713 
714             break;
715         }
716         case FN_AUTOFORMAT_REDLINE_APPLY:
717         {
718             SvxSwAutoFormatFlags aFlags(SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags());
719             // This must always be false for the postprocessing.
720             aFlags.bAFormatByInput = false;
721             aFlags.bWithRedlining = true;
722             rWrtSh.AutoFormat( &aFlags );
723             aFlags.bWithRedlining = false;
724 
725             SfxViewFrame* pVFrame = GetView().GetViewFrame();
726             if (pVFrame->HasChildWindow(FN_REDLINE_ACCEPT))
727                 pVFrame->ToggleChildWindow(FN_REDLINE_ACCEPT);
728 
729             SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
730             ScopedVclPtr<AbstractSwModalRedlineAcceptDlg> xDlg(pFact->CreateSwModalRedlineAcceptDlg(GetView().GetEditWin().GetFrameWeld()));
731 
732             switch (lcl_AskRedlineFlags(GetView().GetFrameWeld()))
733             {
734                 case RET_OK:
735                 {
736                     xDlg->AcceptAll(true);
737                     SfxRequest aReq( pVFrame, FN_AUTOFORMAT_APPLY );
738                     aReq.Done();
739                     rReq.Ignore();
740                     break;
741                 }
742 
743                 case RET_CANCEL:
744                     xDlg->AcceptAll(false);
745                     rReq.Ignore();
746                     break;
747 
748                 case 102:
749                     xDlg->Execute();
750                     rReq.Done();
751                     break;
752             }
753         }
754         break;
755 
756         case FN_AUTOFORMAT_APPLY:
757         {
758             SvxSwAutoFormatFlags aFlags(SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags());
759             // This must always be false for the postprocessing.
760             aFlags.bAFormatByInput = false;
761             rWrtSh.AutoFormat( &aFlags );
762             rReq.Done();
763         }
764         break;
765         case FN_AUTOFORMAT_AUTO:
766         {
767             SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get();
768             bool bSet = pItem ? static_cast<const SfxBoolItem*>(pItem)->GetValue() : !rACfg.IsAutoFormatByInput();
769             if( bSet != rACfg.IsAutoFormatByInput() )
770             {
771                 rACfg.SetAutoFormatByInput( bSet );
772                 rACfg.Commit();
773                 GetView().GetViewFrame()->GetBindings().Invalidate( nSlot );
774                 if ( !pItem )
775                     rReq.AppendItem( SfxBoolItem( GetPool().GetWhich(nSlot), bSet ) );
776                 rReq.Done();
777             }
778         }
779         break;
780         case FN_AUTO_CORRECT:
781         {
782             // At first set to blank as default.
783             rWrtSh.AutoCorrect( *SvxAutoCorrCfg::Get().GetAutoCorrect(), ' ' );
784             rReq.Done();
785         }
786         break;
787         case FN_TABLE_SORT_DIALOG:
788         case FN_SORTING_DLG:
789         {
790             SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
791             ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwSortingDialog(GetView().GetFrameWeld(), rWrtSh));
792             pDlg->Execute();
793             rReq.Done();
794         }
795         break;
796         case FN_NUMBERING_OUTLINE_DLG:
797         {
798             GetView().ExecNumberingOutline(GetPool());
799             rReq.Done();
800         }
801             break;
802         case FN_CALCULATE:
803             {
804                 rtl::Reference<SwTransferable> pTransfer = new SwTransferable( rWrtSh );
805                 pTransfer->CalculateAndCopy();
806                 rReq.Done();
807             }
808             break;
809         case FN_GOTO_REFERENCE:
810         {
811             SwField *pField = rWrtSh.GetCurField();
812             if(pField && pField->GetTypeId() == SwFieldTypesEnum::GetRef)
813             {
814                 rWrtSh.StartAllAction();
815                 rWrtSh.SwCursorShell::GotoRefMark( static_cast<SwGetRefField*>(pField)->GetSetRefName(),
816                                     static_cast<SwGetRefField*>(pField)->GetSubType(),
817                                     static_cast<SwGetRefField*>(pField)->GetSeqNo() );
818                 rWrtSh.EndAllAction();
819                 rReq.Done();
820             }
821         }
822             break;
823         case FN_EDIT_FORMULA:
824         {
825             const sal_uInt16 nId = SwInputChild::GetChildWindowId();
826             SfxViewFrame* pVFrame = GetView().GetViewFrame();
827             if(pItem)
828             {
829                 //if the ChildWindow is active it has to be removed
830                 if( pVFrame->HasChildWindow( nId ) )
831                 {
832                     pVFrame->ToggleChildWindow( nId );
833                     pVFrame->GetBindings().InvalidateAll( true );
834                 }
835 
836                 OUString sFormula(static_cast<const SfxStringItem*>(pItem)->GetValue());
837                 SwFieldMgr aFieldMgr;
838                 rWrtSh.StartAllAction();
839                 bool bDelSel = rWrtSh.HasSelection();
840                 if( bDelSel )
841                 {
842                     rWrtSh.StartUndo( SwUndoId::START );
843                     rWrtSh.DelRight();
844                 }
845                 else
846                 {
847                     rWrtSh.EnterStdMode();
848                 }
849 
850                 if( !bDelSel && aFieldMgr.GetCurField() && SwFieldTypesEnum::Formel == aFieldMgr.GetCurTypeId() )
851                     aFieldMgr.UpdateCurField( aFieldMgr.GetCurField()->GetFormat(), OUString(), sFormula );
852                 else if( !sFormula.isEmpty() )
853                 {
854                     if( rWrtSh.IsCursorInTable() )
855                     {
856                         SfxItemSet aSet( rWrtSh.GetAttrPool(), svl::Items<RES_BOXATR_FORMULA, RES_BOXATR_FORMULA>{} );
857                         aSet.Put( SwTableBoxFormula( sFormula ));
858                         rWrtSh.SetTableBoxFormulaAttrs( aSet );
859                         rWrtSh.UpdateTable();
860                     }
861                     else
862                     {
863                         SvNumberFormatter* pFormatter = rWrtSh.GetNumberFormatter();
864                         const sal_uInt32 nSysNumFormat = pFormatter->GetFormatIndex( NF_NUMBER_STANDARD, LANGUAGE_SYSTEM);
865                         SwInsertField_Data aData(SwFieldTypesEnum::Formel, nsSwGetSetExpType::GSE_FORMULA, OUString(), sFormula, nSysNumFormat);
866                         aFieldMgr.InsertField(aData);
867                     }
868                 }
869 
870                 if( bDelSel )
871                     rWrtSh.EndUndo( SwUndoId::END );
872                 rWrtSh.EndAllAction();
873                 rReq.Done();
874             }
875             else
876             {
877                 rWrtSh.EndAllTableBoxEdit();
878                 pVFrame->ToggleChildWindow( nId );
879                 if( !pVFrame->HasChildWindow( nId ) )
880                     pVFrame->GetBindings().InvalidateAll( true );
881                 rReq.Ignore();
882             }
883         }
884 
885         break;
886         case FN_TABLE_UNSET_READ_ONLY:
887         {
888             rWrtSh.UnProtectTables();
889         }
890         break;
891         case SID_EDIT_HYPERLINK:
892             GetView().GetViewFrame()->SetChildWindow(SID_HYPERLINK_DIALOG, true);
893         break;
894         case SID_REMOVE_HYPERLINK:
895         {
896             bool bSel = rWrtSh.HasSelection();
897             if(!bSel)
898             {
899                 rWrtSh.StartAction();
900                 rWrtSh.Push();
901                 if(!rWrtSh.SelectTextAttr( RES_TXTATR_INETFMT ))
902                     rWrtSh.SelWrd();
903             }
904             //now remove the attribute
905             rWrtSh.ResetAttr({ RES_TXTATR_INETFMT });
906             if(!bSel)
907             {
908                 rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
909                 rWrtSh.EndAction();
910             }
911         }
912         break;
913         case SID_ATTR_BRUSH_CHAR :
914         case SID_ATTR_CHAR_SCALEWIDTH :
915         case SID_ATTR_CHAR_ROTATED :
916         case FN_TXTATR_INET :
917         case FN_INSERT_HYPERLINK:
918         {
919             const sal_uInt16 nWhich = GetPool().GetWhich( nSlot );
920             if ( pArgs && pArgs->GetItemState( nWhich ) == SfxItemState::SET )
921                 bUseDialog = false;
922             [[fallthrough]];
923         }
924         case SID_CHAR_DLG:
925         case SID_CHAR_DLG_EFFECT:
926         {
927             sw_CharDialog( rWrtSh, bUseDialog, nSlot, pArgs, &rReq );
928         }
929         break;
930         case SID_CHAR_DLG_FOR_PARAGRAPH:
931         {
932             rWrtSh.Push();          //save current cursor
933             SwLangHelper::SelectCurrentPara( rWrtSh );
934             sw_CharDialog( rWrtSh, bUseDialog, nSlot, pArgs, &rReq );
935             rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent); // restore old cursor
936         }
937         break;
938         case SID_ATTR_LRSPACE :
939         case SID_ATTR_ULSPACE :
940         case SID_ATTR_BRUSH :
941         case SID_PARA_VERTALIGN :
942         case SID_ATTR_PARA_NUMRULE :
943         case SID_ATTR_PARA_REGISTER :
944         case SID_ATTR_PARA_PAGENUM :
945         case FN_FORMAT_LINENUMBER :
946         case FN_NUMBER_NEWSTART :
947         case FN_NUMBER_NEWSTART_AT :
948         case FN_FORMAT_DROPCAPS :
949         case FN_DROP_TEXT:
950         case SID_ATTR_PARA_LRSPACE:
951         {
952             const sal_uInt16 nWhich = GetPool().GetWhich( nSlot );
953             if ( pArgs && pArgs->GetItemState( nWhich ) == SfxItemState::SET )
954                 bUseDialog = false;
955             [[fallthrough]];
956         }
957         case SID_PARA_DLG:
958         {
959             SwPaM* pPaM = nullptr;
960 
961             if ( pArgs )
962             {
963                 const SfxPoolItem* pPaMItem = nullptr;
964                 pArgs->GetItemState( GetPool().GetWhich( FN_PARAM_PAM ), false, &pPaMItem );
965                 if ( pPaMItem )
966                     pPaM = static_cast< const SwPaMItem* >( pPaMItem )->GetValue( );
967             }
968 
969             if ( !pPaM )
970                 pPaM = rWrtSh.GetCursor();
971 
972             FieldUnit eMetric = ::GetDfltMetric( dynamic_cast<SwWebView*>( &GetView()) != nullptr );
973             SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
974 
975             bool bApplyCharUnit = ::HasCharUnit( dynamic_cast<SwWebView*>( &GetView()) != nullptr  );
976             SW_MOD()->PutItem(SfxBoolItem(SID_ATTR_APPLYCHARUNIT, bApplyCharUnit));
977 
978             SfxItemSet aCoreSet(
979                 GetPool(),
980                 svl::Items<
981                     RES_PARATR_BEGIN, RES_FRMATR_END - 1,
982                     // FillAttribute support:
983                     XATTR_FILL_FIRST, XATTR_FILL_LAST,
984                     // Includes SID_ATTR_TABSTOP_POS:
985                     SID_ATTR_TABSTOP_DEFAULTS, SID_ATTR_TABSTOP_OFFSET,
986                     SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
987                     SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP,
988                     // Items to hand over XPropertyList things like XColorList,
989                     // XHatchList, XGradientList, and XBitmapList to the Area
990                     // TabPage:
991                     SID_COLOR_TABLE, SID_PATTERN_LIST,
992                     SID_HTML_MODE, SID_HTML_MODE,
993                     SID_ATTR_PARA_PAGENUM, SID_ATTR_PARA_PAGENUM,
994                     FN_PARAM_1, FN_PARAM_1,
995                     FN_NUMBER_NEWSTART, FN_NUMBER_NEWSTART_AT,
996                     FN_DROP_TEXT, FN_DROP_CHAR_STYLE_NAME>{});
997 
998             // get also the list level indent values merged as LR-SPACE item, if needed.
999             rWrtSh.GetPaMAttr( pPaM, aCoreSet, true );
1000 
1001             // create needed items for XPropertyList entries from the DrawModel so that
1002             // the Area TabPage can access them
1003             // Do this after GetCurAttr, this resets the ItemSet content again
1004             SwDrawModel* pDrawModel = GetView().GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
1005 
1006             aCoreSet.Put(SvxColorListItem(pDrawModel->GetColorList(), SID_COLOR_TABLE));
1007             aCoreSet.Put(SvxGradientListItem(pDrawModel->GetGradientList(), SID_GRADIENT_LIST));
1008             aCoreSet.Put(SvxHatchListItem(pDrawModel->GetHatchList(), SID_HATCH_LIST));
1009             aCoreSet.Put(SvxBitmapListItem(pDrawModel->GetBitmapList(), SID_BITMAP_LIST));
1010             aCoreSet.Put(SvxPatternListItem(pDrawModel->GetPatternList(), SID_PATTERN_LIST));
1011             aCoreSet.Put(SfxUInt16Item(SID_HTML_MODE,
1012                             ::GetHtmlMode(GetView().GetDocShell())));
1013 
1014             // Tabulators: Put DefaultTabs into ItemSet
1015             const SvxTabStopItem& rDefTabs =
1016                             GetPool().GetDefaultItem(RES_PARATR_TABSTOP);
1017 
1018             const sal_uInt16 nDefDist = o3tl::narrowing<sal_uInt16>(::GetTabDist( rDefTabs ));
1019             SfxUInt16Item aDefDistItem( SID_ATTR_TABSTOP_DEFAULTS, nDefDist );
1020             aCoreSet.Put( aDefDistItem );
1021 
1022             // Current tabulator
1023             SfxUInt16Item aTabPos( SID_ATTR_TABSTOP_POS, 0 );
1024             aCoreSet.Put( aTabPos );
1025 
1026             // Left border as offset
1027             //#i24363# tab stops relative to indent
1028             const tools::Long nOff = rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::TABS_RELATIVE_TO_INDENT) ?
1029                 aCoreSet.Get( RES_LR_SPACE ).GetTextLeft() : 0;
1030             SfxInt32Item aOff( SID_ATTR_TABSTOP_OFFSET, nOff );
1031             aCoreSet.Put( aOff );
1032 
1033             // Setting the BoxInfo
1034             ::PrepareBoxInfo( aCoreSet, rWrtSh );
1035 
1036             // Current page format
1037             ::SwToSfxPageDescAttr( aCoreSet );
1038 
1039             // Properties of numbering
1040             if (rWrtSh.GetNumRuleAtCurrCursorPos())
1041             {
1042                 SfxBoolItem aStart( FN_NUMBER_NEWSTART, rWrtSh.IsNumRuleStart( pPaM ) );
1043                 aCoreSet.Put(aStart);
1044                 SfxUInt16Item aStartAt( FN_NUMBER_NEWSTART_AT,
1045                                         rWrtSh.GetNodeNumStart( pPaM ) );
1046                 aCoreSet.Put(aStartAt);
1047             }
1048             VclPtr<SfxAbstractTabDialog> pDlg;
1049 
1050             if ( bUseDialog && GetActiveView() )
1051             {
1052                 OString sDefPage;
1053                 if (pItem)
1054                     sDefPage = OUStringToOString(static_cast<const SfxStringItem*>(pItem)->GetValue(), RTL_TEXTENCODING_UTF8);
1055 
1056                 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
1057                 pDlg.reset(pFact->CreateSwParaDlg(GetView().GetFrameWeld(), GetView(), aCoreSet, false, sDefPage));
1058             }
1059 
1060             if ( !bUseDialog )
1061             {
1062                 if ( nSlot == SID_ATTR_PARA_LRSPACE)
1063                 {
1064                     SvxLRSpaceItem aParaMargin(static_cast<const SvxLRSpaceItem&>(pArgs->Get(nSlot)));
1065                     aParaMargin.SetWhich( RES_LR_SPACE);
1066                     aCoreSet.Put(aParaMargin);
1067 
1068                     sw_ParagraphDialogResult(&aCoreSet, rWrtSh, rReq, pPaM);
1069                 }
1070                 else
1071                     sw_ParagraphDialogResult(const_cast<SfxItemSet*>(pArgs), rWrtSh, rReq, pPaM);
1072             }
1073             else if (pDlg)
1074             {
1075                 auto pRequest = std::make_shared<SfxRequest>(rReq);
1076                 rReq.Ignore(); // the 'old' request is not relevant any more
1077 
1078                 auto vCursors = CopyPaMRing(*pPaM); // tdf#134439 make a copy to use at later apply
1079                 pDlg->StartExecuteAsync([pDlg, &rWrtSh, pDrawModel, pRequest, nDefDist, vCursors](sal_Int32 nResult){
1080                     if (nResult == RET_OK)
1081                     {
1082                         // Apply defaults if necessary.
1083                         SfxItemSet* pSet = const_cast<SfxItemSet*>(pDlg->GetOutputItemSet());
1084                         sal_uInt16 nNewDist;
1085                         const SfxPoolItem* pItem2 = nullptr;
1086                         if (SfxItemState::SET == pSet->GetItemState(SID_ATTR_TABSTOP_DEFAULTS, false, &pItem2) &&
1087                             nDefDist != (nNewDist = static_cast<const SfxUInt16Item*>(pItem2)->GetValue()) )
1088                         {
1089                             SvxTabStopItem aDefTabs( 0, 0, SvxTabAdjust::Default, RES_PARATR_TABSTOP );
1090                             MakeDefTabs( nNewDist, aDefTabs );
1091                             rWrtSh.SetDefault( aDefTabs );
1092                             pSet->ClearItem( SID_ATTR_TABSTOP_DEFAULTS );
1093                         }
1094 
1095                         if (SfxItemState::SET == pSet->GetItemState(FN_PARAM_1, false, &pItem2))
1096                         {
1097                             pSet->Put(SfxStringItem(FN_DROP_TEXT, static_cast<const SfxStringItem*>(pItem2)->GetValue()));
1098                             pSet->ClearItem(FN_PARAM_1);
1099                         }
1100 
1101                         if (SfxItemState::SET == pSet->GetItemState(RES_PARATR_DROP, false, &pItem2))
1102                         {
1103                             OUString sCharStyleName;
1104                             if (static_cast<const SwFormatDrop*>(pItem2)->GetCharFormat())
1105                                 sCharStyleName = static_cast<const SwFormatDrop*>(pItem2)->GetCharFormat()->GetName();
1106                             pSet->Put(SfxStringItem(FN_DROP_CHAR_STYLE_NAME, sCharStyleName));
1107                         }
1108 
1109                         const XFillGradientItem* pTempGradItem = pSet->GetItem<XFillGradientItem>(XATTR_FILLGRADIENT);
1110                         if (pTempGradItem && pTempGradItem->GetName().isEmpty())
1111                         {
1112                             // MigrateItemSet guarantees unique gradient names
1113                             SfxItemSet aMigrateSet(rWrtSh.GetView().GetPool(), svl::Items<XATTR_FILLGRADIENT, XATTR_FILLGRADIENT>{});
1114                             aMigrateSet.Put(XFillGradientItem("gradient", pTempGradItem->GetGradientValue()));
1115                             SdrModel::MigrateItemSet(&aMigrateSet, pSet, pDrawModel);
1116                         }
1117 
1118                         const XFillHatchItem* pTempHatchItem = pSet->GetItem<XFillHatchItem>(XATTR_FILLHATCH);
1119                         if (pTempHatchItem && pTempHatchItem->GetName().isEmpty())
1120                         {
1121                             SfxItemSet aMigrateSet(rWrtSh.GetView().GetPool(), svl::Items<XATTR_FILLHATCH, XATTR_FILLHATCH>{});
1122                             aMigrateSet.Put(XFillHatchItem("hatch", pTempHatchItem->GetHatchValue()));
1123                             SdrModel::MigrateItemSet(&aMigrateSet, pSet, pDrawModel);
1124                         }
1125 
1126                         sw_ParagraphDialogResult(pSet, rWrtSh, *pRequest, vCursors->front().get());
1127                     }
1128                     pDlg->disposeOnce();
1129                 });
1130             }
1131         }
1132         break;
1133         case FN_NUM_CONTINUE:
1134         {
1135             OUString sContinuedListId;
1136             const SwNumRule* pRule =
1137                 rWrtSh.SearchNumRule( true, sContinuedListId );
1138             // #i86492#
1139             // Search also for bullet list
1140             if ( !pRule )
1141             {
1142                 pRule = rWrtSh.SearchNumRule( false, sContinuedListId );
1143             }
1144             if ( pRule )
1145             {
1146                 rWrtSh.SetCurNumRule( *pRule, false, sContinuedListId );
1147             }
1148         }
1149         break;
1150 
1151         case FN_SELECT_PARA:
1152         {
1153             if ( !rWrtSh.IsSttOfPara() )
1154                 rWrtSh.SttPara();
1155             else
1156                 rWrtSh.EnterStdMode();
1157             rWrtSh.EndPara( true );
1158         }
1159         break;
1160 
1161         case SID_DEC_INDENT:
1162         case SID_INC_INDENT:
1163         //According to the requirement, modified the behavior when user
1164         //using the indent button on the toolbar. Now if we increase/decrease indent for a
1165         //paragraph which has bullet style it will increase/decrease the bullet level.
1166         {
1167             //If the current paragraph has bullet call the function to
1168             //increase or decrease the bullet level.
1169             //Why could I know whether a paragraph has bullet or not by checking the below conditions?
1170             //Please refer to the "case KEY_TAB:" section in SwEditWin::KeyInput(..) :
1171             //      if( rSh.GetCurNumRule() && rSh.IsSttOfPara() &&
1172             //                  !rSh.HasReadonlySel() )
1173             //              eKeyState = KS_NumDown;
1174             //Above code demonstrates that when the cursor is at the start of a paragraph which has bullet,
1175             //press TAB will increase the bullet level.
1176             //So I copied from that ^^
1177             if ( rWrtSh.GetNumRuleAtCurrCursorPos() && !rWrtSh.HasReadonlySel() )
1178             {
1179                 rWrtSh.NumUpDown( SID_INC_INDENT == nSlot );
1180             }
1181             else                //execute the original processing functions
1182             {
1183                 //below is copied of the old codes
1184                 rWrtSh.MoveLeftMargin( SID_INC_INDENT == nSlot, rReq.GetModifier() != KEY_MOD1 );
1185             }
1186         }
1187         rReq.Done();
1188         break;
1189 
1190         case FN_DEC_INDENT_OFFSET:
1191         case FN_INC_INDENT_OFFSET:
1192             rWrtSh.MoveLeftMargin( FN_INC_INDENT_OFFSET == nSlot, rReq.GetModifier() == KEY_MOD1 );
1193             rReq.Done();
1194             break;
1195 
1196         case SID_ATTR_CHAR_COLOR2:
1197         {
1198             Color aSet;
1199             const SfxPoolItem* pColorStringItem = nullptr;
1200             bool bHasItem = false;
1201 
1202             if(pItem)
1203             {
1204                 aSet = static_cast<const SvxColorItem*>(pItem)->GetValue();
1205                 bHasItem = true;
1206             }
1207             else if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_COLOR_STR, false, &pColorStringItem))
1208             {
1209                 OUString sColor = static_cast<const SfxStringItem*>(pColorStringItem)->GetValue();
1210                 aSet = Color(ColorTransparency, sColor.toInt32(16));
1211                 bHasItem = true;
1212             }
1213 
1214             if (bHasItem)
1215             {
1216                 SwEditWin& rEditWin = GetView().GetEditWin();
1217                 rEditWin.SetWaterCanTextColor(aSet);
1218                 SwApplyTemplate* pApply = rEditWin.GetApplyTemplate();
1219 
1220                 // If there is a selection, then set the color on it
1221                 // otherwise, it'll be the color for the next text to be typed
1222                 if(!pApply || pApply->nColor != SID_ATTR_CHAR_COLOR_EXT)
1223                 {
1224                     rWrtSh.SetAttrItem(SvxColorItem (aSet, RES_CHRATR_COLOR));
1225                 }
1226 
1227                 rReq.Done();
1228             }
1229         }
1230         break;
1231         case SID_ATTR_CHAR_COLOR_BACKGROUND:
1232         case SID_ATTR_CHAR_COLOR_BACKGROUND_EXT:
1233         case SID_ATTR_CHAR_COLOR_EXT:
1234         {
1235             Color aSet;
1236             const SfxPoolItem* pColorStringItem = nullptr;
1237 
1238             if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_COLOR_STR, false, &pColorStringItem))
1239             {
1240                 OUString sColor = static_cast<const SfxStringItem*>(pColorStringItem)->GetValue();
1241                 if (sColor == "transparent")
1242                     aSet = COL_TRANSPARENT;
1243                 else
1244                     aSet = Color(ColorTransparency, sColor.toInt32(16));
1245             }
1246             else if (pItem)
1247                 aSet = static_cast<const SvxColorItem*>(pItem)->GetValue();
1248             else
1249                 aSet = COL_TRANSPARENT;
1250 
1251             SwEditWin& rEdtWin = GetView().GetEditWin();
1252             if (nSlot != SID_ATTR_CHAR_COLOR_EXT)
1253                 rEdtWin.SetWaterCanTextBackColor(aSet);
1254             else if (pItem)
1255                 rEdtWin.SetWaterCanTextColor(aSet);
1256 
1257             SwApplyTemplate* pApply = rEdtWin.GetApplyTemplate();
1258             SwApplyTemplate aTempl;
1259             if (!pApply && (rWrtSh.HasSelection() || rReq.IsAPI()))
1260             {
1261                 if (nSlot != SID_ATTR_CHAR_COLOR_EXT)
1262                 {
1263                     SfxItemSet aCoreSet( rWrtSh.GetView().GetPool(), svl::Items<
1264                                          RES_CHRATR_BACKGROUND, RES_CHRATR_BACKGROUND>{} );
1265 
1266                     rWrtSh.GetCurAttr( aCoreSet );
1267 
1268                     // Remove highlight if already set of the same color
1269                     const SvxBrushItem& rBrushItem = aCoreSet.Get(RES_CHRATR_BACKGROUND);
1270                     if ( aSet == rBrushItem.GetColor() )
1271                         aSet = COL_TRANSPARENT;
1272 
1273                     ApplyCharBackground(aSet, rWrtSh);
1274                 }
1275                 else
1276                     rWrtSh.SetAttrItem(
1277                         SvxColorItem(aSet, RES_CHRATR_COLOR) );
1278             }
1279             else if (nSlot == SID_ATTR_CHAR_COLOR_BACKGROUND)
1280             {
1281                 if (!pApply || pApply->nColor != SID_ATTR_CHAR_COLOR_BACKGROUND_EXT)
1282                 {
1283                     aTempl.nColor = SID_ATTR_CHAR_COLOR_BACKGROUND_EXT;
1284                     rEdtWin.SetApplyTemplate(aTempl);
1285                 }
1286             }
1287             else
1288             {
1289                 if(!pApply || pApply->nColor != nSlot)
1290                     aTempl.nColor = nSlot;
1291                 rEdtWin.SetApplyTemplate(aTempl);
1292             }
1293 
1294             rReq.Done();
1295         }
1296         break;
1297 
1298         case FN_NUM_BULLET_MOVEDOWN:
1299             if (!rWrtSh.IsAddMode())
1300                 rWrtSh.MoveParagraph();
1301             rReq.Done();
1302             break;
1303 
1304         case FN_NUM_BULLET_MOVEUP:
1305             if (!rWrtSh.IsAddMode())
1306                 rWrtSh.MoveParagraph(-1);
1307             rReq.Done();
1308             break;
1309         case SID_RUBY_DIALOG:
1310         case SID_HYPERLINK_DIALOG:
1311         {
1312             SfxRequest aReq(nSlot, SfxCallMode::SLOT, SfxGetpApp()->GetPool());
1313             GetView().GetViewFrame()->ExecuteSlot( aReq);
1314             rReq.Ignore();
1315         }
1316         break;
1317     case FN_INSERT_PAGEHEADER:
1318     case FN_INSERT_PAGEFOOTER:
1319     if(pArgs && pArgs->Count())
1320     {
1321         OUString sStyleName;
1322         if(pItem)
1323             sStyleName = static_cast<const SfxStringItem*>(pItem)->GetValue();
1324         bool bOn = true;
1325         if( SfxItemState::SET == pArgs->GetItemState(FN_PARAM_1, false, &pItem))
1326             bOn = static_cast<const SfxBoolItem*>(pItem)->GetValue();
1327         rWrtSh.ChangeHeaderOrFooter(sStyleName, FN_INSERT_PAGEHEADER == nSlot, bOn, !rReq.IsAPI());
1328         rReq.Done();
1329     }
1330     break;
1331     case FN_READONLY_SELECTION_MODE :
1332         if(GetView().GetDocShell()->IsReadOnly())
1333         {
1334             rWrtSh.SetReadonlySelectionOption(
1335                 !rWrtSh.GetViewOptions()->IsSelectionInReadonly());
1336             rWrtSh.ShowCursor();
1337         }
1338     break;
1339     case FN_SELECTION_MODE_DEFAULT:
1340     case FN_SELECTION_MODE_BLOCK :
1341     {
1342         bool bSetBlockMode = !rWrtSh.IsBlockMode();
1343         if( pArgs && SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem))
1344             bSetBlockMode = static_cast<const SfxBoolItem*>(pItem)->GetValue();
1345         if( ( nSlot == FN_SELECTION_MODE_DEFAULT ) != bSetBlockMode )
1346             rWrtSh.EnterBlockMode();
1347         else
1348             rWrtSh.EnterStdMode();
1349         SfxBindings &rBnd = GetView().GetViewFrame()->GetBindings();
1350         rBnd.Invalidate(FN_STAT_SELMODE);
1351         rBnd.Update(FN_STAT_SELMODE);
1352     }
1353     break;
1354     case SID_OPEN_HYPERLINK:
1355     case SID_COPY_HYPERLINK_LOCATION:
1356     {
1357         SfxItemSet aSet(GetPool(),
1358                         svl::Items<RES_TXTATR_INETFMT,
1359                         RES_TXTATR_INETFMT>{});
1360         rWrtSh.GetCurAttr(aSet);
1361         if(SfxItemState::SET <= aSet.GetItemState( RES_TXTATR_INETFMT ))
1362         {
1363             const SwFormatINetFormat& rINetFormat = dynamic_cast<const SwFormatINetFormat&>( aSet.Get(RES_TXTATR_INETFMT) );
1364             if( nSlot == SID_COPY_HYPERLINK_LOCATION )
1365             {
1366                 OUString hyperlinkLocation = rINetFormat.GetValue();
1367                 ::uno::Reference< datatransfer::clipboard::XClipboard > xClipboard = GetView().GetEditWin().GetClipboard();
1368 
1369                 vcl::unohelper::TextDataObject::CopyStringTo(hyperlinkLocation, xClipboard, SfxViewShell::Current());
1370             }
1371             else
1372                 rWrtSh.ClickToINetAttr(rINetFormat);
1373         }
1374         else
1375         {
1376             SwField* pField = rWrtSh.GetCurField();
1377             if (pField && pField->GetTyp()->Which() == SwFieldIds::TableOfAuthorities)
1378             {
1379                 const auto& rAuthorityField = *static_cast<const SwAuthorityField*>(pField);
1380                 if (rAuthorityField.HasURL())
1381                 {
1382                     // Bibliography entry with URL also provides a hyperlink.
1383                     const OUString& rURL
1384                         = rAuthorityField.GetAuthEntry()->GetAuthorField(AUTH_FIELD_URL);
1385                     ::LoadURL(rWrtSh, rURL, LoadUrlFlags::NewView, /*rTargetFrameName=*/OUString());
1386                 }
1387             }
1388         }
1389     }
1390     break;
1391     case SID_OPEN_XML_FILTERSETTINGS:
1392     {
1393         HandleOpenXmlFilterSettings(rReq);
1394     }
1395     break;
1396     case FN_FORMAT_APPLY_HEAD1:
1397     {
1398     }
1399     break;
1400     case FN_FORMAT_APPLY_HEAD2:
1401     {
1402     }
1403     break;
1404     case FN_FORMAT_APPLY_HEAD3:
1405     {
1406     }
1407     break;
1408     case FN_FORMAT_APPLY_DEFAULT:
1409     {
1410     }
1411     break;
1412     case FN_FORMAT_APPLY_TEXTBODY:
1413     {
1414     }
1415     break;
1416     case FN_WORDCOUNT_DIALOG:
1417     {
1418         GetView().UpdateWordCount(this, nSlot);
1419     }
1420     break;
1421     case FN_PROTECT_FIELDS:
1422     case FN_PROTECT_BOOKMARKS:
1423     {
1424         IDocumentSettingAccess& rIDSA = rWrtSh.getIDocumentSettingAccess();
1425         DocumentSettingId aSettingId = nSlot == FN_PROTECT_FIELDS
1426                                            ? DocumentSettingId::PROTECT_FIELDS
1427                                            : DocumentSettingId::PROTECT_BOOKMARKS;
1428         rIDSA.set(aSettingId, !rIDSA.get(aSettingId));
1429         // Invalidate so that toggle state gets updated
1430         SfxViewFrame* pViewFrame = GetView().GetViewFrame();
1431         pViewFrame->GetBindings().Invalidate(nSlot);
1432         pViewFrame->GetBindings().Update(nSlot);
1433     }
1434     break;
1435     case SID_FM_CTL_PROPERTIES:
1436     {
1437         SwPosition aPos(*GetShell().GetCursor()->GetPoint());
1438         sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aPos);
1439         if ( !pFieldBM )
1440         {
1441             --aPos.nContent;
1442             pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aPos);
1443         }
1444 
1445         if ( pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDROPDOWN )
1446         {
1447             SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
1448             ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateDropDownFormFieldDialog(rWrtSh.GetView().GetFrameWeld(), pFieldBM));
1449             if (pDlg->Execute() == RET_OK)
1450             {
1451                 pFieldBM->Invalidate();
1452                 rWrtSh.InvalidateWindows( SwRect(rWrtSh.GetView().GetVisArea()) );
1453                 rWrtSh.UpdateCursor(); // cursor position might be invalid
1454             }
1455         }
1456         else if ( pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDATE )
1457         {
1458             SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
1459             sw::mark::DateFieldmark& rDateField = dynamic_cast<sw::mark::DateFieldmark&>(*pFieldBM);
1460             ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateDateFormFieldDialog(rWrtSh.GetView().GetFrameWeld(), &rDateField, *GetView().GetDocShell()->GetDoc()));
1461             if (pDlg->Execute() == RET_OK)
1462             {
1463                 rDateField.Invalidate();
1464                 rWrtSh.InvalidateWindows( SwRect(rWrtSh.GetView().GetVisArea()) );
1465                 rWrtSh.UpdateCursor(); // cursor position might be invalid
1466             }
1467         }
1468         else
1469         {
1470             SfxRequest aReq( GetView().GetViewFrame(), SID_FM_CTL_PROPERTIES );
1471             aReq.AppendItem( SfxBoolItem( SID_FM_CTL_PROPERTIES, true ) );
1472             rWrtSh.GetView().GetFormShell()->Execute( aReq );
1473         }
1474     }
1475     break;
1476     case SID_SPELLCHECK_IGNORE:
1477     {
1478         SwPaM *pPaM = rWrtSh.GetCursor();
1479         if (pPaM)
1480             SwEditShell::IgnoreGrammarErrorAt( *pPaM );
1481     }
1482     break;
1483     case SID_SPELLCHECK_IGNORE_ALL:
1484     {
1485         OUString sApplyText;
1486         const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
1487         if (pItem2)
1488             sApplyText = pItem2->GetValue();
1489 
1490         if(sApplyText == "Grammar")
1491         {
1492             linguistic2::ProofreadingResult aGrammarCheckRes;
1493             sal_Int32 nErrorInResult = -1;
1494             uno::Sequence< OUString > aSuggestions;
1495             sal_Int32 nErrorPosInText = -1;
1496             SwRect aToFill;
1497             bool bCorrectionRes = rWrtSh.GetGrammarCorrection( aGrammarCheckRes, nErrorPosInText, nErrorInResult, aSuggestions, nullptr, aToFill );
1498             if(bCorrectionRes)
1499             {
1500                 try {
1501                     uno::Reference< linguistic2::XDictionary > xDictionary = LinguMgr::GetIgnoreAllList();
1502                     aGrammarCheckRes.xProofreader->ignoreRule(
1503                         aGrammarCheckRes.aErrors[ nErrorInResult ].aRuleIdentifier,
1504                             aGrammarCheckRes.aLocale );
1505                     // refresh the layout of the actual paragraph (faster)
1506                     SwPaM *pPaM = rWrtSh.GetCursor();
1507                     if (pPaM)
1508                         SwEditShell::IgnoreGrammarErrorAt( *pPaM );
1509                     // refresh the layout of all paragraphs (workaround to launch a dictionary event)
1510                     xDictionary->setActive(false);
1511                     xDictionary->setActive(true);
1512                 }
1513                 catch( const uno::Exception& )
1514                 {
1515                 }
1516             }
1517         }
1518         else if (sApplyText == "Spelling")
1519         {
1520             SwRect aToFill;
1521             uno::Reference<linguistic2::XSpellAlternatives>  xSpellAlt(rWrtSh.GetCorrection(nullptr, aToFill));
1522             if (!xSpellAlt.is())
1523                 return;
1524             uno::Reference< linguistic2::XDictionary > xDictionary = LinguMgr::GetIgnoreAllList();
1525             OUString sWord(xSpellAlt->getWord());
1526             linguistic::DictionaryError nAddRes = linguistic::AddEntryToDic( xDictionary,
1527                     sWord, false, OUString() );
1528             if (linguistic::DictionaryError::NONE != nAddRes && xDictionary.is() && !xDictionary->getEntry(sWord).is())
1529             {
1530                 SvxDicError(rWrtSh.GetView().GetFrameWeld(), nAddRes);
1531             }
1532         }
1533     }
1534     break;
1535     case SID_SPELLCHECK_APPLY_SUGGESTION:
1536     {
1537         OUString sApplyText;
1538         const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
1539         if (pItem2)
1540             sApplyText = pItem2->GetValue();
1541 
1542         static const OUStringLiteral sSpellingRule(u"Spelling_");
1543         static const OUStringLiteral sGrammarRule(u"Grammar_");
1544 
1545         bool bGrammar = false;
1546         sal_Int32 nPos = 0;
1547         uno::Reference< linguistic2::XSpellAlternatives >  xSpellAlt;
1548         if(-1 != (nPos = sApplyText.indexOf( sGrammarRule )))
1549         {
1550             sApplyText = sApplyText.replaceAt(nPos, sGrammarRule.getLength(), "");
1551             bGrammar = true;
1552         }
1553         else if (-1 != (nPos = sApplyText.indexOf( sSpellingRule )))
1554         {
1555             sApplyText = sApplyText.replaceAt(nPos, sSpellingRule.getLength(), "");
1556             SwRect aToFill;
1557             xSpellAlt.set(rWrtSh.GetCorrection(nullptr, aToFill));
1558             bGrammar = false;
1559         }
1560 
1561         if (!bGrammar && !xSpellAlt.is())
1562             return;
1563 
1564         bool bOldIns = rWrtSh.IsInsMode();
1565         rWrtSh.SetInsMode();
1566 
1567         OUString aTmp( sApplyText );
1568         OUString aOrig( bGrammar ? OUString() : xSpellAlt->getWord() );
1569 
1570         // if original word has a trailing . (likely the end of a sentence)
1571         // and the replacement text hasn't, then add it to the replacement
1572         if (!aTmp.isEmpty() && !aOrig.isEmpty() &&
1573             aOrig.endsWith(".") && /* !IsAlphaNumeric ??*/
1574             !aTmp.endsWith("."))
1575         {
1576             aTmp += ".";
1577         }
1578 
1579         SwRewriter aRewriter;
1580 
1581         aRewriter.AddRule(UndoArg1, rWrtSh.GetCursorDescr());
1582         aRewriter.AddRule(UndoArg2, SwResId(STR_YIELDS));
1583 
1584         OUString aTmpStr = SwResId(STR_START_QUOTE) +
1585             aTmp + SwResId(STR_END_QUOTE);
1586         aRewriter.AddRule(UndoArg3, aTmpStr);
1587 
1588         rWrtSh.StartUndo(SwUndoId::UI_REPLACE, &aRewriter);
1589         rWrtSh.StartAction();
1590 
1591         rWrtSh.Replace(aTmp, false);
1592 
1593         rWrtSh.EndAction();
1594         rWrtSh.EndUndo();
1595 
1596         rWrtSh.SetInsMode( bOldIns );
1597     }
1598     break;
1599     default:
1600         OSL_ENSURE(false, "wrong dispatcher");
1601         return;
1602     }
1603 }
1604 
GetState(SfxItemSet & rSet)1605 void SwTextShell::GetState( SfxItemSet &rSet )
1606 {
1607     SwWrtShell &rSh = GetShell();
1608     SfxWhichIter aIter( rSet );
1609     sal_uInt16 nWhich = aIter.FirstWhich();
1610     while ( nWhich )
1611     {
1612         switch ( nWhich )
1613         {
1614         case FN_FORMAT_CURRENT_FOOTNOTE_DLG:
1615             if( !rSh.IsCursorInFootnote() )
1616                 rSet.DisableItem( nWhich );
1617         break;
1618 
1619         case SID_LANGUAGE_STATUS:
1620             {
1621                 // the value of used script types
1622                 OUString aScriptTypesInUse( OUString::number( static_cast<int>(rSh.GetScriptType()) ) );
1623 
1624                 // get keyboard language
1625                 OUString aKeyboardLang;
1626                 SwEditWin& rEditWin = GetView().GetEditWin();
1627                 LanguageType nLang = rEditWin.GetInputLanguage();
1628                 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
1629                     aKeyboardLang = SvtLanguageTable::GetLanguageString( nLang );
1630 
1631                 // get the language that is in use
1632                 OUString aCurrentLang = "*";
1633                 nLang = SwLangHelper::GetCurrentLanguage( rSh );
1634                 if (nLang != LANGUAGE_DONTKNOW)
1635                 {
1636                     aCurrentLang = SvtLanguageTable::GetLanguageString( nLang );
1637                     if (comphelper::LibreOfficeKit::isActive())
1638                     {
1639                         if (nLang == LANGUAGE_NONE)
1640                         {
1641                             aCurrentLang += ";-";
1642                         }
1643                         else
1644                         {
1645                             aCurrentLang += ";" + LanguageTag(nLang).getBcp47(false);
1646                         }
1647                     }
1648                 }
1649 
1650                 // build sequence for status value
1651                 uno::Sequence< OUString > aSeq( 4 );
1652                 aSeq[0] = aCurrentLang;
1653                 aSeq[1] = aScriptTypesInUse;
1654                 aSeq[2] = aKeyboardLang;
1655                 aSeq[3] = SwLangHelper::GetTextForLanguageGuessing( rSh );
1656 
1657                 // set sequence as status value
1658                 SfxStringListItem aItem( SID_LANGUAGE_STATUS );
1659                 aItem.SetStringList( aSeq );
1660                 rSet.Put( aItem );
1661             }
1662         break;
1663 
1664         case SID_THES:
1665         {
1666             // is there a valid selection to get text from?
1667             OUString aText;
1668             bool bValid = !rSh.HasSelection() ||
1669                     (rSh.IsSelOnePara() && !rSh.IsMultiSelection());
1670             // prevent context menu from showing when cursor is not in or at the end of a word
1671             // (GetCurWord will return the next word if there is none at the current position...)
1672             const sal_Int16 nWordType = ::i18n::WordType::DICTIONARY_WORD;
1673             bool bWord = rSh.IsInWord( nWordType ) || rSh.IsStartWord( nWordType ) || rSh.IsEndWord( nWordType );
1674             if (bValid && bWord)
1675                aText = rSh.HasSelection()? rSh.GetSelText() : rSh.GetCurWord();
1676 
1677             LanguageType nLang = rSh.GetCurLang();
1678             LanguageTag aLanguageTag( nLang);
1679             const lang::Locale& aLocale( aLanguageTag.getLocale());
1680 
1681             // disable "Thesaurus" context menu entry if there is nothing to look up
1682             uno::Reference< linguistic2::XThesaurus >  xThes( ::GetThesaurus() );
1683             if (aText.isEmpty() ||
1684                 !xThes.is() || nLang == LANGUAGE_NONE || !xThes->hasLocale( aLocale ))
1685                 rSet.DisableItem( SID_THES );
1686             else
1687             {
1688                 // set word and locale to look up as status value
1689                 OUString aStatusVal = aText + "#" + aLanguageTag.getBcp47();
1690                 rSet.Put( SfxStringItem( SID_THES, aStatusVal ) );
1691             }
1692         }
1693         break;
1694 
1695         case FN_NUMBER_NEWSTART :
1696             if(!rSh.GetNumRuleAtCurrCursorPos())
1697                     rSet.DisableItem(nWhich);
1698             else
1699                 rSet.Put(SfxBoolItem(FN_NUMBER_NEWSTART,
1700                     rSh.IsNumRuleStart()));
1701         break;
1702 
1703         case FN_EDIT_FORMULA:
1704         case SID_CHARMAP:
1705         case SID_EMOJI_CONTROL:
1706         case SID_CHARMAP_CONTROL:
1707             {
1708                 const SelectionType nType = rSh.GetSelectionType();
1709                 if (!(nType & SelectionType::Text) &&
1710                     !(nType & SelectionType::Table) &&
1711                     !(nType & SelectionType::NumberList))
1712                 {
1713                     rSet.DisableItem(nWhich);
1714                 }
1715                 else if ( nWhich == FN_EDIT_FORMULA
1716                           && rSh.CursorInsideInputField() )
1717                 {
1718                     rSet.DisableItem( nWhich );
1719                 }
1720             }
1721             break;
1722 
1723         case FN_INSERT_ENDNOTE:
1724         case FN_INSERT_FOOTNOTE:
1725         case FN_INSERT_FOOTNOTE_DLG:
1726             {
1727                 const FrameTypeFlags nNoType =
1728                     FrameTypeFlags::FLY_ANY | FrameTypeFlags::HEADER | FrameTypeFlags::FOOTER | FrameTypeFlags::FOOTNOTE;
1729                 if ( rSh.GetFrameType(nullptr,true) & nNoType )
1730                     rSet.DisableItem(nWhich);
1731 
1732                 if ( rSh.CursorInsideInputField() )
1733                 {
1734                     rSet.DisableItem( nWhich );
1735                 }
1736             }
1737             break;
1738 
1739         case FN_INSERT_HYPERLINK:
1740         case SID_INSERTDOC:
1741         case FN_INSERT_GLOSSARY:
1742         case FN_EXPAND_GLOSSARY:
1743             if ( rSh.CursorInsideInputField() )
1744             {
1745                 rSet.DisableItem( nWhich );
1746             }
1747             break;
1748 
1749         case FN_INSERT_TABLE:
1750             if ( rSh.CursorInsideInputField()
1751                  || rSh.GetTableFormat()
1752                  || (rSh.GetFrameType(nullptr,true) & FrameTypeFlags::FOOTNOTE) )
1753             {
1754                 rSet.DisableItem( nWhich );
1755             }
1756             break;
1757 
1758         case FN_CALCULATE:
1759             if ( !rSh.IsSelection() )
1760                 rSet.DisableItem(nWhich);
1761             break;
1762         case FN_GOTO_REFERENCE:
1763             {
1764                 SwField *pField = rSh.GetCurField();
1765                 if ( !pField || (pField->GetTypeId() != SwFieldTypesEnum::GetRef) )
1766                     rSet.DisableItem(nWhich);
1767             }
1768             break;
1769         case FN_AUTOFORMAT_AUTO:
1770             {
1771                 rSet.Put( SfxBoolItem( nWhich, SvxAutoCorrCfg::Get().IsAutoFormatByInput() ));
1772             }
1773             break;
1774 
1775         case SID_DEC_INDENT:
1776         case SID_INC_INDENT:
1777         {
1778             //if the paragraph has bullet we'll do the following things:
1779             //1: if the bullet level is the first level, disable the decrease-indent button
1780             //2: if the bullet level is the last level, disable the increase-indent button
1781             if ( rSh.GetNumRuleAtCurrCursorPos() && !rSh.HasReadonlySel() )
1782             {
1783                 const sal_uInt8 nLevel = rSh.GetNumLevel();
1784                 if ( ( nLevel == ( MAXLEVEL - 1 ) && nWhich == SID_INC_INDENT )
1785                      || ( nLevel == 0 && nWhich == SID_DEC_INDENT ) )
1786                 {
1787                     rSet.DisableItem( nWhich );
1788                 }
1789             }
1790             else
1791             {
1792                 sal_uInt16 nHtmlMode = ::GetHtmlMode( GetView().GetDocShell() );
1793                 nHtmlMode &= HTMLMODE_ON | HTMLMODE_SOME_STYLES;
1794                 if ( ( nHtmlMode == HTMLMODE_ON )
1795                      || !rSh.IsMoveLeftMargin( SID_INC_INDENT == nWhich ) )
1796                 {
1797                     rSet.DisableItem( nWhich );
1798                 }
1799             }
1800         }
1801         break;
1802 
1803         case FN_DEC_INDENT_OFFSET:
1804         case FN_INC_INDENT_OFFSET:
1805             {
1806                 sal_uInt16 nHtmlMode = ::GetHtmlMode(GetView().GetDocShell());
1807                 nHtmlMode &= HTMLMODE_ON|HTMLMODE_SOME_STYLES;
1808                 if( (nHtmlMode == HTMLMODE_ON) ||
1809                     !rSh.IsMoveLeftMargin( FN_INC_INDENT_OFFSET == nWhich,
1810                                             false ))
1811                     rSet.DisableItem( nWhich );
1812             }
1813             break;
1814 
1815         case SID_ATTR_CHAR_COLOR2:
1816             {
1817                 SfxItemSet aSet( GetPool() );
1818                 rSh.GetCurAttr( aSet );
1819                 const SvxColorItem& aColorItem = aSet.Get(RES_CHRATR_COLOR);
1820                 rSet.Put( aColorItem.CloneSetWhich(SID_ATTR_CHAR_COLOR2) );
1821             }
1822             break;
1823         case SID_ATTR_CHAR_COLOR_BACKGROUND:
1824             {
1825                 // Always use the visible background
1826                 SfxItemSet aSet( GetPool() );
1827                 rSh.GetCurAttr( aSet );
1828                 const SvxBrushItem& aBrushItem = aSet.Get(RES_CHRATR_HIGHLIGHT);
1829                 if( aBrushItem.GetColor() != COL_TRANSPARENT )
1830                 {
1831                     rSet.Put( SvxColorItem(aBrushItem.GetColor(), nWhich) );
1832                 }
1833                 else
1834                 {
1835                     const SvxBrushItem& aBrushItem2 = aSet.Get(RES_CHRATR_BACKGROUND);
1836                     rSet.Put( SvxColorItem(aBrushItem2.GetColor(), nWhich) );
1837                 }
1838             }
1839             break;
1840         case SID_ATTR_CHAR_COLOR_BACKGROUND_EXT:
1841         case SID_ATTR_CHAR_COLOR_EXT:
1842             {
1843                 SwEditWin& rEdtWin = GetView().GetEditWin();
1844                 SwApplyTemplate* pApply = rEdtWin.GetApplyTemplate();
1845                 rSet.Put(SfxBoolItem(nWhich, pApply && pApply->nColor == nWhich));
1846             }
1847             break;
1848         case FN_SET_REMINDER:
1849         case FN_INSERT_BOOKMARK:
1850             if( rSh.IsTableMode()
1851                 || rSh.CursorInsideInputField() )
1852             {
1853                 rSet.DisableItem( nWhich );
1854             }
1855             break;
1856 
1857         case FN_INSERT_BREAK:
1858             if ( rSh.HasReadonlySel()
1859                  && !rSh.CursorInsideInputField() )
1860             {
1861                 rSet.DisableItem( nWhich );
1862             }
1863             break;
1864 
1865         case FN_INSERT_BREAK_DLG:
1866         case FN_INSERT_COLUMN_BREAK:
1867         case FN_INSERT_PAGEBREAK:
1868             if( rSh.CursorInsideInputField() )
1869             {
1870                 rSet.DisableItem( nWhich );
1871             }
1872             break;
1873 
1874         case FN_INSERT_PAGEHEADER:
1875         case FN_INSERT_PAGEFOOTER:
1876             if (comphelper::LibreOfficeKit::isActive())
1877             {
1878                 bool bState = false;
1879                 bool bAllState = true;
1880                 bool bIsPhysical = false;
1881 
1882                 OUString aStyleName;
1883                 std::vector<OUString> aList;
1884                 static const OUStringLiteral sPhysical(u"IsPhysical");
1885                 static const OUStringLiteral sDisplay(u"DisplayName");
1886                 const OUString sHeaderOn(nWhich == FN_INSERT_PAGEHEADER ? OUString("HeaderIsOn") : OUString("FooterIsOn"));
1887 
1888                 uno::Reference< XStyleFamiliesSupplier > xSupplier(GetView().GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
1889                 if (xSupplier.is())
1890                 {
1891                     uno::Reference< XNameContainer > xContainer;
1892                     uno::Reference< XNameAccess > xFamilies = xSupplier->getStyleFamilies();
1893                     if (xFamilies->getByName("PageStyles") >>= xContainer)
1894                     {
1895                         const uno::Sequence< OUString > aSeqNames = xContainer->getElementNames();
1896                         for (const auto& rName : aSeqNames)
1897                         {
1898                             aStyleName = rName;
1899                             uno::Reference<XPropertySet> xPropSet(xContainer->getByName(aStyleName), uno::UNO_QUERY);
1900                             if (xPropSet.is() && (xPropSet->getPropertyValue(sPhysical) >>= bIsPhysical) && bIsPhysical)
1901                             {
1902                                 xPropSet->getPropertyValue(sDisplay) >>= aStyleName;
1903                                 if ((xPropSet->getPropertyValue(sHeaderOn)>>= bState) && bState)
1904                                     aList.push_back(aStyleName);
1905                                 else
1906                                     bState = false;
1907 
1908                                 // Check if all entries have the same state
1909                                 bAllState &= bState;
1910                             }
1911                             else
1912                                 bIsPhysical = false;
1913                        }
1914                     }
1915                 }
1916 
1917                 if (bAllState && aList.size() > 1)
1918                     aList.push_back("_ALL_");
1919 
1920                 rSet.Put(SfxStringListItem(nWhich, &aList));
1921             }
1922             else
1923             {
1924                 rSet.Put( SfxObjectShellItem( nWhich, GetView().GetDocShell() ));
1925             }
1926             break;
1927             case FN_TABLE_SORT_DIALOG:
1928             case FN_SORTING_DLG:
1929                 if(!rSh.HasSelection() ||
1930                         (FN_TABLE_SORT_DIALOG == nWhich && !rSh.GetTableFormat()))
1931                     rSet.DisableItem( nWhich );
1932             break;
1933 
1934             case SID_RUBY_DIALOG:
1935                 {
1936                     SvtCJKOptions aCJKOptions;
1937                     if( !aCJKOptions.IsRubyEnabled()
1938                         || rSh.CursorInsideInputField() )
1939                     {
1940                         GetView().GetViewFrame()->GetBindings().SetVisibleState( nWhich, false );
1941                         rSet.DisableItem(nWhich);
1942                     }
1943                     else
1944                         GetView().GetViewFrame()->GetBindings().SetVisibleState( nWhich, true );
1945                 }
1946                 break;
1947 
1948             case SID_HYPERLINK_DIALOG:
1949                 if( GetView().GetDocShell()->IsReadOnly()
1950                     || ( !GetView().GetViewFrame()->HasChildWindow(nWhich)
1951                          && rSh.HasReadonlySel() )
1952                     || rSh.CursorInsideInputField() )
1953                 {
1954                     rSet.DisableItem(nWhich);
1955                 }
1956                 else
1957                 {
1958                     rSet.Put(SfxBoolItem( nWhich, nullptr != GetView().GetViewFrame()->GetChildWindow( nWhich ) ));
1959                 }
1960                 break;
1961 
1962             case SID_EDIT_HYPERLINK:
1963             case SID_COPY_HYPERLINK_LOCATION:
1964                 {
1965                     SfxItemSet aSet(GetPool(),
1966                         svl::Items<RES_TXTATR_INETFMT,
1967                         RES_TXTATR_INETFMT>{});
1968                     rSh.GetCurAttr(aSet);
1969                     if(SfxItemState::SET > aSet.GetItemState( RES_TXTATR_INETFMT ) || rSh.HasReadonlySel())
1970                     {
1971                         rSet.DisableItem(nWhich);
1972                     }
1973                 }
1974             break;
1975             case SID_REMOVE_HYPERLINK:
1976             {
1977                 SfxItemSet aSet(GetPool(),
1978                                 svl::Items<RES_TXTATR_INETFMT,
1979                                 RES_TXTATR_INETFMT>{});
1980                 rSh.GetCurAttr(aSet);
1981 
1982                 // If a hyperlink is selected, either alone or along with other text...
1983                 if ((aSet.GetItemState(RES_TXTATR_INETFMT) < SfxItemState::SET &&
1984                     aSet.GetItemState(RES_TXTATR_INETFMT) != SfxItemState::DONTCARE) ||
1985                     rSh.HasReadonlySel())
1986                 {
1987                     rSet.DisableItem(nWhich);
1988                 }
1989             }
1990             break;
1991             case SID_TRANSLITERATE_HALFWIDTH:
1992             case SID_TRANSLITERATE_FULLWIDTH:
1993             case SID_TRANSLITERATE_HIRAGANA:
1994             case SID_TRANSLITERATE_KATAKANA:
1995             {
1996                 SvtCJKOptions aCJKOptions;
1997                 if(!aCJKOptions.IsChangeCaseMapEnabled())
1998                 {
1999                     GetView().GetViewFrame()->GetBindings().SetVisibleState( nWhich, false );
2000                     rSet.DisableItem(nWhich);
2001                 }
2002                 else
2003                     GetView().GetViewFrame()->GetBindings().SetVisibleState( nWhich, true );
2004             }
2005             break;
2006             case FN_READONLY_SELECTION_MODE :
2007                 if(!GetView().GetDocShell()->IsReadOnly())
2008                     rSet.DisableItem( nWhich );
2009                 else
2010                 {
2011                     rSet.Put(SfxBoolItem(nWhich, rSh.GetViewOptions()->IsSelectionInReadonly()));
2012                 }
2013             break;
2014             case FN_SELECTION_MODE_DEFAULT:
2015             case FN_SELECTION_MODE_BLOCK :
2016                     rSet.Put(SfxBoolItem(nWhich, (nWhich == FN_SELECTION_MODE_DEFAULT) != rSh.IsBlockMode()));
2017             break;
2018             case  SID_OPEN_HYPERLINK:
2019             {
2020                 SfxItemSet aSet(GetPool(),
2021                                 svl::Items<RES_TXTATR_INETFMT,
2022                                 RES_TXTATR_INETFMT>{});
2023                 rSh.GetCurAttr(aSet);
2024 
2025                 bool bAuthorityFieldURL = false;
2026                 SwField* pField = rSh.GetCurField();
2027                 if (pField && pField->GetTyp()->Which() == SwFieldIds::TableOfAuthorities)
2028                 {
2029                     // Bibliography entry with URL also provides a hyperlink.
2030                     const auto& rAuthorityField = *static_cast<const SwAuthorityField*>(pField);
2031                     bAuthorityFieldURL = rAuthorityField.HasURL();
2032                 }
2033                 if (SfxItemState::SET > aSet.GetItemState(RES_TXTATR_INETFMT, false)
2034                     && !bAuthorityFieldURL)
2035                     rSet.DisableItem(nWhich);
2036             }
2037             break;
2038             case  SID_OPEN_SMARTTAGMENU:
2039             {
2040                  std::vector< OUString > aSmartTagTypes;
2041                  uno::Sequence< uno::Reference< container::XStringKeyMap > > aStringKeyMaps;
2042                  uno::Reference<text::XTextRange> xRange;
2043 
2044                  rSh.GetSmartTagTerm( aSmartTagTypes, aStringKeyMaps, xRange );
2045 
2046                  if ( xRange.is() && !aSmartTagTypes.empty() )
2047                  {
2048                      uno::Sequence < uno::Sequence< uno::Reference< smarttags::XSmartTagAction > > > aActionComponentsSequence;
2049                      uno::Sequence < uno::Sequence< sal_Int32 > > aActionIndicesSequence;
2050 
2051                      const SmartTagMgr& rSmartTagMgr = SwSmartTagMgr::Get();
2052                      rSmartTagMgr.GetActionSequences( aSmartTagTypes,
2053                                                       aActionComponentsSequence,
2054                                                       aActionIndicesSequence );
2055 
2056                      uno::Reference <frame::XController> xController = GetView().GetController();
2057                      const lang::Locale aLocale( SW_BREAKITER()->GetLocale( GetAppLanguageTag() ) );
2058                      const OUString& aApplicationName( rSmartTagMgr.GetApplicationName() );
2059                      const OUString aRangeText = xRange->getString();
2060 
2061                      const SvxSmartTagItem aItem( nWhich,
2062                                                   aActionComponentsSequence,
2063                                                   aActionIndicesSequence,
2064                                                   aStringKeyMaps,
2065                                                   xRange,
2066                                                   xController,
2067                                                   aLocale,
2068                                                   aApplicationName,
2069                                                   aRangeText );
2070 
2071                      rSet.Put( aItem );
2072                  }
2073                  else
2074                      rSet.DisableItem(nWhich);
2075             }
2076             break;
2077 
2078             case FN_NUM_NUMBERING_ON:
2079                 rSet.Put(SfxBoolItem(FN_NUM_NUMBERING_ON,rSh.SelectionHasNumber()));
2080             break;
2081 
2082             case FN_NUM_BULLET_ON:
2083                 rSet.Put(SfxBoolItem(FN_NUM_BULLET_ON,rSh.SelectionHasBullet()));
2084             break;
2085 
2086             case FN_NUM_BULLET_OFF:
2087                 rSet.Put(SfxBoolItem(FN_NUM_BULLET_OFF,(!rSh.SelectionHasBullet() &&
2088                     !rSh.SelectionHasNumber())));
2089             break;
2090 
2091             case FN_BUL_NUM_RULE_INDEX:
2092             case FN_NUM_NUM_RULE_INDEX:
2093             case FN_OUTLINE_RULE_INDEX:
2094         {
2095             SwNumRule* pCurRule = const_cast<SwNumRule*>(GetShell().GetNumRuleAtCurrCursorPos());
2096             if( pCurRule )
2097             {
2098                 sal_uInt16 nActNumLvl = GetShell().GetNumLevel();
2099                 if( nActNumLvl < MAXLEVEL )
2100                 {
2101                     nActNumLvl = 1<<nActNumLvl;
2102                 }
2103                 SvxNumRule aSvxRule = pCurRule->MakeSvxNumRule();
2104                 if ( GetShell().HasBullet())
2105                 {
2106                     rSet.Put(SfxUInt16Item(FN_BUL_NUM_RULE_INDEX, USHRT_MAX));
2107                     rSet.Put(SfxUInt16Item(FN_NUM_NUM_RULE_INDEX, USHRT_MAX));
2108                     NBOTypeMgrBase* pBullets = NBOutlineTypeMgrFact::CreateInstance(NBOType::Bullets);
2109                     if ( pBullets )
2110                     {
2111                         const sal_uInt16 nBulIndex = pBullets->GetNBOIndexForNumRule(aSvxRule,nActNumLvl);
2112                         rSet.Put(SfxUInt16Item(FN_BUL_NUM_RULE_INDEX,nBulIndex));
2113                     }
2114                 }else if ( GetShell().HasNumber() )
2115                 {
2116                     rSet.Put(SfxUInt16Item(FN_BUL_NUM_RULE_INDEX, USHRT_MAX));
2117                     rSet.Put(SfxUInt16Item(FN_NUM_NUM_RULE_INDEX, USHRT_MAX));
2118                     NBOTypeMgrBase* pNumbering = NBOutlineTypeMgrFact::CreateInstance(NBOType::Numbering);
2119                     if ( pNumbering )
2120                     {
2121                         const sal_uInt16 nBulIndex = pNumbering->GetNBOIndexForNumRule(aSvxRule,nActNumLvl);
2122                         rSet.Put(SfxUInt16Item(FN_NUM_NUM_RULE_INDEX,nBulIndex));
2123                     }
2124                 }
2125 
2126                 if ( nWhich == FN_OUTLINE_RULE_INDEX )
2127                 {
2128                     rSet.Put(SfxUInt16Item(FN_OUTLINE_RULE_INDEX, USHRT_MAX));
2129                     NBOTypeMgrBase* pOutline = NBOutlineTypeMgrFact::CreateInstance(NBOType::Outline);
2130                     if ( pOutline )
2131                     {
2132                         const sal_uInt16 nIndex = pOutline->GetNBOIndexForNumRule(aSvxRule,nActNumLvl);
2133                         rSet.Put(SfxUInt16Item(FN_OUTLINE_RULE_INDEX,nIndex));
2134                     }
2135                 }
2136             }
2137         }
2138             break;
2139             case FN_NUM_CONTINUE:
2140             {
2141                 // #i86492#
2142                 // Search also for bullet list
2143                 OUString aDummy;
2144                 const SwNumRule* pRule =
2145                         rSh.SearchNumRule( true, aDummy );
2146                 if ( !pRule )
2147                 {
2148                     pRule = rSh.SearchNumRule( false, aDummy );
2149                 }
2150                 if ( !pRule )
2151                     rSet.DisableItem(nWhich);
2152             }
2153             break;
2154             case SID_INSERT_RLM :
2155             case SID_INSERT_LRM :
2156             {
2157                 SvtCTLOptions aCTLOptions;
2158                 bool bEnabled = aCTLOptions.IsCTLFontEnabled();
2159                 GetView().GetViewFrame()->GetBindings().SetVisibleState( nWhich, bEnabled );
2160                 if(!bEnabled)
2161                     rSet.DisableItem(nWhich);
2162             }
2163             break;
2164             case SID_FM_CTL_PROPERTIES:
2165             {
2166                 bool bDisable = false;
2167 
2168                 // First get the state from the form shell
2169                 SfxItemSet aSet(GetShell().GetAttrPool(), svl::Items<SID_FM_CTL_PROPERTIES, SID_FM_CTL_PROPERTIES>{});
2170                 aSet.Put(SfxBoolItem( SID_FM_CTL_PROPERTIES, true ));
2171                 GetShell().GetView().GetFormShell()->GetState( aSet );
2172 
2173                 if(SfxItemState::DISABLED == aSet.GetItemState(SID_FM_CTL_PROPERTIES))
2174                 {
2175                     bDisable = true;
2176                 }
2177 
2178                 // Enable it if we have a valid object other than what form shell knows
2179                 SwPosition aPos(*GetShell().GetCursor()->GetPoint());
2180                 sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aPos);
2181                 if ( !pFieldBM && aPos.nContent.GetIndex() > 0)
2182                 {
2183                     --aPos.nContent;
2184                     pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aPos);
2185                 }
2186                 if ( pFieldBM && (pFieldBM->GetFieldname() == ODF_FORMDROPDOWN || pFieldBM->GetFieldname() == ODF_FORMDATE) )
2187                 {
2188                     bDisable = false;
2189                 }
2190 
2191                 if(bDisable)
2192                     rSet.DisableItem(nWhich);
2193             }
2194             break;
2195             case SID_COPY:
2196             case SID_CUT:
2197             {
2198                 if (GetObjectShell()->isContentExtractionLocked())
2199                     rSet.DisableItem(nWhich);
2200                 break;
2201             }
2202             case FN_PROTECT_FIELDS:
2203             case FN_PROTECT_BOOKMARKS:
2204             {
2205                 DocumentSettingId aSettingId = nWhich == FN_PROTECT_FIELDS
2206                                                    ? DocumentSettingId::PROTECT_FIELDS
2207                                                    : DocumentSettingId::PROTECT_BOOKMARKS;
2208                 bool bProtected = rSh.getIDocumentSettingAccess().get(aSettingId);
2209                 rSet.Put(SfxBoolItem(nWhich, bProtected));
2210             }
2211             break;
2212         }
2213         nWhich = aIter.NextWhich();
2214     }
2215 }
2216 
2217 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2218