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