1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/i18n/WordType.hpp>
21 #include <com/sun/star/linguistic2/XThesaurus.hpp>
23 #include <hintids.hxx>
25 #include <comphelper/lok.hxx>
27 #include <i18nutil/unicode.hxx>
28 #include <i18nlangtag/languagetag.hxx>
29 #include <svtools/langtab.hxx>
30 #include <svl/numformat.hxx>
31 #include <svl/slstitm.hxx>
32 #include <svl/stritem.hxx>
33 #include <sfx2/htmlmode.hxx>
34 #include <svl/whiter.hxx>
35 #include <sfx2/bindings.hxx>
36 #include <sfx2/viewfrm.hxx>
37 #include <vcl/unohelp2.hxx>
38 #include <vcl/weld.hxx>
39 #include <sfx2/request.hxx>
40 #include <svl/eitem.hxx>
41 #include <editeng/lrspitem.hxx>
42 #include <editeng/colritem.hxx>
43 #include <editeng/tstpitem.hxx>
44 #include <editeng/brushitem.hxx>
45 #include <editeng/svxacorr.hxx>
46 #include <svl/cjkoptions.hxx>
47 #include <svl/ctloptions.hxx>
48 #include <IDocumentDrawModelAccess.hxx>
49 #include <IDocumentSettingAccess.hxx>
50 #include <charfmt.hxx>
51 #include <svx/SmartTagItem.hxx>
52 #include <svx/xflgrit.hxx>
53 #include <svx/xflhtit.hxx>
54 #include <svx/xfillit0.hxx>
55 #include <fmtinfmt.hxx>
58 #include <swmodule.hxx>
59 #include <viewopt.hxx>
63 #include <swdtflvr.hxx>
67 #include <inputwin.hxx>
68 #include <chrdlgmodes.hxx>
70 #include <cellatr.hxx>
73 #include <strings.hrc>
75 #include <vcl/svapp.hxx>
76 #include <sfx2/app.hxx>
77 #include <breakit.hxx>
78 #include <SwSmartTagMgr.hxx>
79 #include <editeng/acorrcfg.hxx>
80 #include <swabstdlg.hxx>
81 #include <sfx2/sfxdlg.hxx>
82 #include <com/sun/star/container/XNameContainer.hpp>
83 #include <com/sun/star/beans/XPropertySet.hpp>
84 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
85 #include <com/sun/star/uno/Any.hxx>
86 #include <com/sun/star/linguistic2/ProofreadingResult.hpp>
87 #include <com/sun/star/linguistic2/XDictionary.hpp>
88 #include <com/sun/star/linguistic2/XSpellAlternatives.hpp>
89 #include <editeng/unolingu.hxx>
91 #include <drawdoc.hxx>
94 #include <sfx2/objface.hxx>
95 #include <langhelper.hxx>
96 #include <uiitems.hxx>
97 #include <svx/nbdtmgfact.hxx>
98 #include <svx/nbdtmg.hxx>
99 #include <SwRewriter.hxx>
100 #include <svx/drawitem.hxx>
101 #include <numrule.hxx>
103 #include <xmloff/odffields.hxx>
104 #include <bookmark.hxx>
105 #include <linguistic/misc.hxx>
106 #include <comphelper/sequenceashashmap.hxx>
107 #include <comphelper/scopeguard.hxx>
108 #include <authfld.hxx>
109 #include <config_wasm_strip.h>
110 #if !ENABLE_WASM_STRIP_EXTRA
111 #include <officecfg/Office/Common.hxx>
112 #include <officecfg/Office/Linguistic.hxx>
113 #include <svl/visitem.hxx>
114 #include <translatelangselect.hxx>
115 #endif // ENABLE_WASM_STRIP_EXTRA
116 #include <translatehelper.hxx>
117 #include <IDocumentContentOperations.hxx>
118 #include <IDocumentUndoRedo.hxx>
119 #include <fmtcntnt.hxx>
120 #include <fmtrfmrk.hxx>
122 using namespace ::com::sun::star
;
123 using namespace com::sun::star::beans
;
124 using namespace ::com::sun::star::container
;
125 using namespace com::sun::star::style
;
126 using namespace svx::sidebar
;
128 static void sw_CharDialogResult(const SfxItemSet
* pSet
, SwWrtShell
&rWrtSh
, std::shared_ptr
<SfxItemSet
> const & pCoreSet
, bool bSel
,
129 bool bSelectionPut
, bool bApplyToParagraph
, SfxRequest
*pReq
);
131 static void sw_CharDialog(SwWrtShell
& rWrtSh
, bool bUseDialog
, bool bApplyToParagraph
,
132 sal_uInt16 nSlot
, const SfxItemSet
* pArgs
, SfxRequest
* pReq
)
134 FieldUnit eMetric
= ::GetDfltMetric(dynamic_cast<SwWebView
*>( &rWrtSh
.GetView()) != nullptr );
135 SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC
, static_cast< sal_uInt16
>(eMetric
)));
136 auto pCoreSet
= std::make_shared
<SfxItemSetFixed
<
137 RES_CHRATR_BEGIN
, RES_CHRATR_END
- 1,
138 RES_TXTATR_INETFMT
, RES_TXTATR_INETFMT
,
139 RES_BACKGROUND
, RES_SHADOW
,
140 XATTR_FILLSTYLE
, XATTR_FILLCOLOR
,
141 SID_ATTR_BORDER_INNER
, SID_ATTR_BORDER_INNER
,
142 SID_HTML_MODE
, SID_HTML_MODE
,
143 SID_ATTR_CHAR_WIDTH_FIT_TO_LINE
, SID_ATTR_CHAR_WIDTH_FIT_TO_LINE
,
144 FN_PARAM_SELECTION
, FN_PARAM_SELECTION
>> ( rWrtSh
.GetView().GetPool() );
145 rWrtSh
.GetCurAttr(*pCoreSet
);
147 bool bSel
= rWrtSh
.HasSelection();
148 bool bSelectionPut
= false;
149 if(bSel
|| rWrtSh
.IsInWord())
153 rWrtSh
.StartAction();
155 if(!rWrtSh
.SelectTextAttr( RES_TXTATR_INETFMT
))
158 pCoreSet
->Put(SfxStringItem(FN_PARAM_SELECTION
, rWrtSh
.GetSelText()));
159 bSelectionPut
= true;
162 rWrtSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
);
166 pCoreSet
->Put(SfxUInt16Item(SID_ATTR_CHAR_WIDTH_FIT_TO_LINE
, rWrtSh
.GetScalingOfSelectedText()));
168 ::ConvertAttrCharToGen(*pCoreSet
);
170 // Setting the BoxInfo
171 ::PrepareBoxInfo(*pCoreSet
, rWrtSh
);
173 pCoreSet
->Put(SfxUInt16Item(SID_HTML_MODE
, ::GetHtmlMode(rWrtSh
.GetView().GetDocShell())));
174 VclPtr
<SfxAbstractTabDialog
> pDlg
;
175 if ( bUseDialog
&& GetActiveView() )
177 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
178 pDlg
.reset(pFact
->CreateSwCharDlg(rWrtSh
.GetView().GetFrameWeld(), rWrtSh
.GetView(), *pCoreSet
, SwCharDlgMode::Std
));
180 if (nSlot
== FN_INSERT_HYPERLINK
)
181 pDlg
->SetCurPageId("hyperlink");
182 else if (nSlot
== SID_CHAR_DLG_EFFECT
)
183 pDlg
->SetCurPageId("fonteffects");
184 else if (nSlot
== SID_CHAR_DLG_POSITION
)
185 pDlg
->SetCurPageId("position");
186 else if (nSlot
== SID_CHAR_DLG_FOR_PARAGRAPH
)
187 pDlg
->SetCurPageId("font");
190 const SfxStringItem
* pItem
= (*pReq
).GetArg
<SfxStringItem
>(FN_PARAM_1
);
192 pDlg
->SetCurPageId(pItem
->GetValue());
198 std::shared_ptr
<SfxRequest
> pRequest
;
201 pRequest
= std::make_shared
<SfxRequest
>(*pReq
);
202 pReq
->Ignore(); // the 'old' request is not relevant any more
204 pDlg
->StartExecuteAsync([pDlg
, &rWrtSh
, pCoreSet
, bSel
, bSelectionPut
, bApplyToParagraph
, pRequest
](sal_Int32 nResult
){
205 if (nResult
== RET_OK
)
207 sw_CharDialogResult(pDlg
->GetOutputItemSet(), rWrtSh
, pCoreSet
, bSel
, bSelectionPut
,
208 bApplyToParagraph
, pRequest
.get());
215 sw_CharDialogResult(pArgs
, rWrtSh
, pCoreSet
, bSel
, bSelectionPut
, bApplyToParagraph
, pReq
);
219 static void sw_CharDialogResult(const SfxItemSet
* pSet
, SwWrtShell
& rWrtSh
, std::shared_ptr
<SfxItemSet
> const & pCoreSet
, bool bSel
,
220 bool bSelectionPut
, bool bApplyToParagraph
, SfxRequest
* pReq
)
222 SfxItemSet
aTmpSet( *pSet
);
223 ::ConvertAttrGenToChar(aTmpSet
, *pCoreSet
);
225 const bool bWasLocked
= rWrtSh
.IsViewLocked();
226 if (bApplyToParagraph
)
228 rWrtSh
.StartAction();
229 rWrtSh
.LockView(true);
231 SwLangHelper::SelectCurrentPara(rWrtSh
);
234 const SfxStringItem
* pSelectionItem
;
235 bool bInsert
= false;
236 sal_Int32 nInsert
= 0;
238 // The old item is for unknown reasons back in the set again.
239 if( !bSelectionPut
&& (pSelectionItem
= aTmpSet
.GetItemIfSet(FN_PARAM_SELECTION
, false)) )
241 OUString sInsert
= pSelectionItem
->GetValue();
242 bInsert
= !sInsert
.isEmpty();
245 nInsert
= sInsert
.getLength();
246 rWrtSh
.StartAction();
247 rWrtSh
.Insert( sInsert
);
249 rWrtSh
.ExtendSelection(false, sInsert
.getLength());
250 SfxRequest
aReq(rWrtSh
.GetView().GetViewFrame(), FN_INSERT_STRING
);
251 aReq
.AppendItem( SfxStringItem( FN_INSERT_STRING
, sInsert
) );
253 SfxRequest
aReq1(rWrtSh
.GetView().GetViewFrame(), FN_CHAR_LEFT
);
254 aReq1
.AppendItem( SfxInt32Item(FN_PARAM_MOVE_COUNT
, nInsert
) );
255 aReq1
.AppendItem( SfxBoolItem(FN_PARAM_MOVE_SELECTION
, true) );
259 aTmpSet
.ClearItem(FN_PARAM_SELECTION
);
261 SwTextFormatColl
* pColl
= rWrtSh
.GetCurTextFormatColl();
262 if(bSel
&& rWrtSh
.IsSelFullPara() && pColl
&& pColl
->IsAutoUpdateOnDirectFormat())
264 rWrtSh
.AutoUpdatePara(pColl
, aTmpSet
);
267 rWrtSh
.SetAttrSet( aTmpSet
);
272 SfxRequest
aReq1(rWrtSh
.GetView().GetViewFrame(), FN_CHAR_RIGHT
);
273 aReq1
.AppendItem( SfxInt32Item(FN_PARAM_MOVE_COUNT
, nInsert
) );
274 aReq1
.AppendItem( SfxBoolItem(FN_PARAM_MOVE_SELECTION
, false) );
278 rWrtSh
.DontExpandFormat();
282 if (bApplyToParagraph
)
284 rWrtSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
);
285 rWrtSh
.LockView(bWasLocked
);
291 static void sw_ParagraphDialogResult(SfxItemSet
* pSet
, SwWrtShell
&rWrtSh
, SfxRequest
& rReq
, SwPaM
* pPaM
)
297 ::SfxToSwPageDescAttr( rWrtSh
, *pSet
);
299 // enclose all undos.
300 // Thus, check conditions, if actions will be performed.
301 const bool bUndoNeeded( pSet
->Count() ||
302 SfxItemState::SET
== pSet
->GetItemState(FN_NUMBER_NEWSTART
) ||
303 SfxItemState::SET
== pSet
->GetItemState(FN_NUMBER_NEWSTART_AT
) );
306 rWrtSh
.StartUndo( SwUndoId::INSATTR
);
310 rWrtSh
.StartAction();
311 if ( const SfxStringItem
* pDropTextItem
= pSet
->GetItemIfSet(FN_DROP_TEXT
, false) )
313 if ( !pDropTextItem
->GetValue().isEmpty() )
314 rWrtSh
.ReplaceDropText(pDropTextItem
->GetValue(), pPaM
);
316 rWrtSh
.SetAttrSet(*pSet
, SetAttrMode::DEFAULT
, pPaM
);
318 SwTextFormatColl
* pColl
= rWrtSh
.GetPaMTextFormatColl(pPaM
);
319 if(pColl
&& pColl
->IsAutoUpdateOnDirectFormat())
321 rWrtSh
.AutoUpdatePara(pColl
, *pSet
, pPaM
);
325 if( SfxItemState::SET
== pSet
->GetItemState(FN_NUMBER_NEWSTART
) )
327 //SetNumRuleStart(true) restarts the numbering at the value
328 //that is defined at the starting point of the numbering level
329 //otherwise the SetNodeNumStart() value determines the start
330 //if it's set to something different than USHRT_MAX
332 bool bStart
= static_cast<const SfxBoolItem
&>(pSet
->Get(FN_NUMBER_NEWSTART
)).GetValue();
334 // Default value for restart value has to be USHRT_MAX
335 // in order to indicate that the restart value of the list
336 // style has to be used on restart.
337 sal_uInt16 nNumStart
= USHRT_MAX
;
338 if( SfxItemState::SET
== pSet
->GetItemState(FN_NUMBER_NEWSTART_AT
) )
340 nNumStart
= pSet
->Get(FN_NUMBER_NEWSTART_AT
).GetValue();
342 rWrtSh
.SetNumRuleStart(bStart
, pPaM
);
343 rWrtSh
.SetNodeNumStart(nNumStart
);
345 else if( SfxItemState::SET
== pSet
->GetItemState(FN_NUMBER_NEWSTART_AT
) )
347 rWrtSh
.SetNodeNumStart(pSet
->Get(FN_NUMBER_NEWSTART_AT
).GetValue());
348 rWrtSh
.SetNumRuleStart(false, pPaM
);
353 rWrtSh
.EndUndo( SwUndoId::INSATTR
);
359 void InsertBreak(SwWrtShell
& rWrtSh
,
361 ::std::optional
<sal_uInt16
> oPageNumber
,
362 const OUString
& rTemplateName
, std::optional
<SwLineBreakClear
> oClear
)
367 rWrtSh
.InsertLineBreak(oClear
);
370 rWrtSh
.InsertColumnBreak(); break;
373 rWrtSh
.StartAllAction();
374 if( !rTemplateName
.isEmpty() )
375 rWrtSh
.InsertPageBreak( &rTemplateName
, oPageNumber
);
377 rWrtSh
.InsertPageBreak();
378 rWrtSh
.EndAllAction();
383 OUString
GetLocalURL(const SwWrtShell
& rSh
)
385 SwField
* pField
= rSh
.GetCurField();
391 if (pField
->GetTyp()->Which() != SwFieldIds::TableOfAuthorities
)
396 const auto& rAuthorityField
= *static_cast<const SwAuthorityField
*>(pField
);
397 SwAuthEntry
* pAuthEntry
= rAuthorityField
.GetAuthEntry();
403 const OUString
& rLocalURL
= pAuthEntry
->GetAuthorField(AUTH_FIELD_LOCAL_URL
);
407 void UpdateSections(SfxRequest
& rReq
, SwWrtShell
& rWrtSh
)
409 OUString aSectionNamePrefix
;
410 const SfxStringItem
* pSectionNamePrefix
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
411 if (pSectionNamePrefix
)
413 aSectionNamePrefix
= pSectionNamePrefix
->GetValue();
416 uno::Sequence
<beans::PropertyValues
> aSections
;
417 const SfxUnoAnyItem
* pSections
= rReq
.GetArg
<SfxUnoAnyItem
>(FN_PARAM_2
);
420 pSections
->GetValue() >>= aSections
;
423 rWrtSh
.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_SECTIONS
, nullptr);
424 rWrtSh
.StartAction();
426 SwDoc
* pDoc
= rWrtSh
.GetDoc();
427 sal_Int32 nSectionIndex
= 0;
428 const SwSectionFormats
& rFormats
= pDoc
->GetSections();
429 IDocumentContentOperations
& rIDCO
= pDoc
->getIDocumentContentOperations();
430 for (size_t i
= 0; i
< rFormats
.size(); ++i
)
432 const SwSectionFormat
* pFormat
= rFormats
[i
];
433 if (!pFormat
->GetName().startsWith(aSectionNamePrefix
))
438 if (nSectionIndex
>= aSections
.getLength())
443 comphelper::SequenceAsHashMap
aMap(aSections
[nSectionIndex
++]);
444 OUString aSectionName
= aMap
["RegionName"].get
<OUString
>();
445 if (aSectionName
!= pFormat
->GetName())
447 const_cast<SwSectionFormat
*>(pFormat
)->SetFormatName(aSectionName
, /*bBroadcast=*/true);
448 SwSectionData
aSectionData(*pFormat
->GetSection());
449 aSectionData
.SetSectionName(aSectionName
);
450 pDoc
->UpdateSection(i
, aSectionData
);
453 const SwFormatContent
& rContent
= pFormat
->GetContent();
454 const SwNodeIndex
* pContentNodeIndex
= rContent
.GetContentIdx();
455 if (pContentNodeIndex
)
457 SwPaM
aSectionStart(SwPosition
{*pContentNodeIndex
});
458 aSectionStart
.Move(fnMoveForward
, GoInContent
);
459 SwPaM
* pCursorPos
= rWrtSh
.GetCursor();
460 *pCursorPos
= aSectionStart
;
461 rWrtSh
.EndOfSection(/*bSelect=*/true);
462 rIDCO
.DeleteAndJoin(*pCursorPos
);
465 OUString aSectionText
= aMap
["Content"].get
<OUString
>();
466 SwTranslateHelper::PasteHTMLToPaM(rWrtSh
, pCursorPos
, aSectionText
.toUtf8(), true);
471 rWrtSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_SECTIONS
, nullptr);
474 void DeleteSections(SfxRequest
& rReq
, SwWrtShell
& rWrtSh
)
476 OUString aSectionNamePrefix
;
477 const SfxStringItem
* pSectionNamePrefix
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
478 if (pSectionNamePrefix
)
480 aSectionNamePrefix
= pSectionNamePrefix
->GetValue();
483 rWrtSh
.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_SECTIONS
, nullptr);
484 rWrtSh
.StartAction();
485 comphelper::ScopeGuard
g(
489 rWrtSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_SECTIONS
, nullptr);
492 SwDoc
* pDoc
= rWrtSh
.GetDoc();
493 SwSectionFormats
& rFormats
= pDoc
->GetSections();
494 std::vector
<SwSectionFormat
*> aRemovals
;
495 for (size_t i
= 0; i
< rFormats
.size(); ++i
)
497 SwSectionFormat
* pFormat
= rFormats
[i
];
499 if (!aSectionNamePrefix
.isEmpty())
501 if (!pFormat
->GetName().startsWith(aSectionNamePrefix
))
507 aRemovals
.push_back(pFormat
);
510 for (const auto& pFormat
: aRemovals
)
512 // Just delete the format, not the content of the section.
513 pDoc
->DelSectionFormat(pFormat
);
517 void UpdateBookmarks(SfxRequest
& rReq
, SwWrtShell
& rWrtSh
)
519 if (rWrtSh
.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS
))
524 OUString aBookmarkNamePrefix
;
525 const SfxStringItem
* pBookmarkNamePrefix
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
526 if (pBookmarkNamePrefix
)
528 aBookmarkNamePrefix
= pBookmarkNamePrefix
->GetValue();
531 uno::Sequence
<beans::PropertyValues
> aBookmarks
;
532 const SfxUnoAnyItem
* pBookmarks
= rReq
.GetArg
<SfxUnoAnyItem
>(FN_PARAM_2
);
535 pBookmarks
->GetValue() >>= aBookmarks
;
538 rWrtSh
.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_BOOKMARKS
, nullptr);
539 rWrtSh
.StartAction();
541 IDocumentMarkAccess
& rIDMA
= *rWrtSh
.GetDoc()->getIDocumentMarkAccess();
542 sal_Int32 nBookmarkIndex
= 0;
543 bool bSortMarks
= false;
544 for (auto it
= rIDMA
.getBookmarksBegin(); it
!= rIDMA
.getBookmarksEnd(); ++it
)
546 auto pMark
= dynamic_cast<sw::mark::Bookmark
*>(*it
);
548 if (!pMark
->GetName().startsWith(aBookmarkNamePrefix
))
553 if (aBookmarks
.getLength() <= nBookmarkIndex
)
558 comphelper::SequenceAsHashMap
aMap(aBookmarks
[nBookmarkIndex
++]);
559 if (aMap
["Bookmark"].get
<OUString
>() != pMark
->GetName())
561 rIDMA
.renameMark(pMark
, aMap
["Bookmark"].get
<OUString
>());
564 OUString aBookmarkText
= aMap
["BookmarkText"].get
<OUString
>();
566 // Insert markers to remember where the paste positions are.
567 SwPaM
aMarkers(pMark
->GetMarkEnd());
568 IDocumentContentOperations
& rIDCO
= rWrtSh
.GetDoc()->getIDocumentContentOperations();
569 bool bSuccess
= rIDCO
.InsertString(aMarkers
, "XY");
572 SwPaM
aPasteEnd(pMark
->GetMarkEnd());
573 aPasteEnd
.Move(fnMoveForward
, GoInContent
);
575 // Paste HTML content.
576 SwPaM
* pCursorPos
= rWrtSh
.GetCursor();
577 *pCursorPos
= aPasteEnd
;
578 SwTranslateHelper::PasteHTMLToPaM(rWrtSh
, pCursorPos
, aBookmarkText
.toUtf8(), true);
580 // Update the bookmark to point to the new content.
581 SwPaM
aPasteStart(pMark
->GetMarkEnd());
582 aPasteStart
.Move(fnMoveForward
, GoInContent
);
583 SwPaM
aStartMarker(pMark
->GetMarkStart(), *aPasteStart
.GetPoint());
584 SwPaM
aEndMarker(*aPasteEnd
.GetPoint(), *aPasteEnd
.GetPoint());
585 aEndMarker
.GetMark()->AdjustContent(1);
586 pMark
->SetMarkPos(*aPasteStart
.GetPoint());
587 pMark
->SetOtherMarkPos(*aPasteEnd
.GetPoint());
590 // Remove markers. the start marker includes the old content as well.
591 rIDCO
.DeleteAndJoin(aStartMarker
);
592 rIDCO
.DeleteAndJoin(aEndMarker
);
597 rIDMA
.assureSortedMarkContainers();
601 rWrtSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_BOOKMARKS
, nullptr);
604 void UpdateBookmark(SfxRequest
& rReq
, SwWrtShell
& rWrtSh
)
606 if (rWrtSh
.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS
))
611 OUString aBookmarkNamePrefix
;
612 const SfxStringItem
* pBookmarkNamePrefix
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
613 if (pBookmarkNamePrefix
)
615 aBookmarkNamePrefix
= pBookmarkNamePrefix
->GetValue();
618 uno::Sequence
<beans::PropertyValue
> aBookmark
;
619 const SfxUnoAnyItem
* pBookmarks
= rReq
.GetArg
<SfxUnoAnyItem
>(FN_PARAM_2
);
622 pBookmarks
->GetValue() >>= aBookmark
;
625 IDocumentMarkAccess
& rIDMA
= *rWrtSh
.GetDoc()->getIDocumentMarkAccess();
626 SwPosition
& rCursor
= *rWrtSh
.GetCursor()->GetPoint();
627 auto pBookmark
= dynamic_cast<sw::mark::Bookmark
*>(rIDMA
.getOneInnermostBookmarkFor(rCursor
));
628 if (!pBookmark
|| !pBookmark
->GetName().startsWith(aBookmarkNamePrefix
))
633 SwRewriter aRewriter
;
634 aRewriter
.AddRule(UndoArg1
, pBookmark
->GetName());
635 rWrtSh
.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_BOOKMARK
, &aRewriter
);
636 rWrtSh
.StartAction();
637 comphelper::ScopeGuard
g(
638 [&rWrtSh
, &aRewriter
]
641 rWrtSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_BOOKMARK
, &aRewriter
);
645 comphelper::SequenceAsHashMap
aMap(aBookmark
);
646 if (aMap
["Bookmark"].get
<OUString
>() != pBookmark
->GetName())
648 rIDMA
.renameMark(pBookmark
, aMap
["Bookmark"].get
<OUString
>());
651 // Insert markers to remember where the paste positions are.
652 SwPaM
aMarkers(pBookmark
->GetMarkEnd());
653 IDocumentContentOperations
& rIDCO
= rWrtSh
.GetDoc()->getIDocumentContentOperations();
654 if (!rIDCO
.InsertString(aMarkers
, "XY"))
659 SwPaM
aPasteEnd(pBookmark
->GetMarkEnd());
660 aPasteEnd
.Move(fnMoveForward
, GoInContent
);
662 OUString aBookmarkText
= aMap
["BookmarkText"].get
<OUString
>();
664 // Paste HTML content.
665 SwPaM
* pCursorPos
= rWrtSh
.GetCursor();
666 *pCursorPos
= aPasteEnd
;
667 SwTranslateHelper::PasteHTMLToPaM(rWrtSh
, pCursorPos
, aBookmarkText
.toUtf8(), true);
669 // Update the bookmark to point to the new content.
670 SwPaM
aPasteStart(pBookmark
->GetMarkEnd());
671 aPasteStart
.Move(fnMoveForward
, GoInContent
);
672 SwPaM
aStartMarker(pBookmark
->GetMarkStart(), *aPasteStart
.GetPoint());
673 SwPaM
aEndMarker(*aPasteEnd
.GetPoint(), *aPasteEnd
.GetPoint());
674 aEndMarker
.GetMark()->AdjustContent(1);
675 pBookmark
->SetMarkPos(*aPasteStart
.GetPoint());
676 pBookmark
->SetOtherMarkPos(*aPasteEnd
.GetPoint());
678 // Remove markers. the start marker includes the old content as well.
679 rIDCO
.DeleteAndJoin(aStartMarker
);
680 rIDCO
.DeleteAndJoin(aEndMarker
);
681 rIDMA
.assureSortedMarkContainers();
684 void DeleteBookmarks(SfxRequest
& rReq
, SwWrtShell
& rWrtSh
)
686 if (rWrtSh
.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS
))
691 OUString aBookmarkNamePrefix
;
692 const SfxStringItem
* pBookmarkNamePrefix
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
693 if (pBookmarkNamePrefix
)
695 aBookmarkNamePrefix
= pBookmarkNamePrefix
->GetValue();
698 rWrtSh
.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_BOOKMARKS
, nullptr);
699 rWrtSh
.StartAction();
700 comphelper::ScopeGuard
g(
704 rWrtSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_BOOKMARKS
, nullptr);
707 IDocumentMarkAccess
* pMarkAccess
= rWrtSh
.GetDoc()->getIDocumentMarkAccess();
708 std::vector
<sw::mark::IMark
*> aRemovals
;
709 for (auto it
= pMarkAccess
->getBookmarksBegin(); it
!= pMarkAccess
->getBookmarksEnd(); ++it
)
711 auto pBookmark
= dynamic_cast<sw::mark::Bookmark
*>(*it
);
714 if (!aBookmarkNamePrefix
.isEmpty())
716 if (!pBookmark
->GetName().startsWith(aBookmarkNamePrefix
))
722 aRemovals
.push_back(pBookmark
);
725 for (const auto& pMark
: aRemovals
)
727 pMarkAccess
->deleteMark(pMark
);
731 void DeleteFields(SfxRequest
& rReq
, SwWrtShell
& rWrtSh
)
733 const SfxStringItem
* pTypeName
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
734 if (!pTypeName
|| pTypeName
->GetValue() != "SetRef")
736 // This is implemented so far only for reference marks.
740 OUString aNamePrefix
;
741 const SfxStringItem
* pNamePrefix
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_2
);
744 aNamePrefix
= pNamePrefix
->GetValue();
747 SwDoc
* pDoc
= rWrtSh
.GetDoc();
748 pDoc
->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_FIELDS
, nullptr);
749 rWrtSh
.StartAction();
750 comphelper::ScopeGuard
g(
754 rWrtSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_FIELDS
, nullptr);
757 std::vector
<const SwFormatRefMark
*> aRemovals
;
758 for (sal_uInt16 i
= 0; i
< pDoc
->GetRefMarks(); ++i
)
760 const SwFormatRefMark
* pRefMark
= pDoc
->GetRefMark(i
);
761 if (!aNamePrefix
.isEmpty())
763 if (!pRefMark
->GetRefName().startsWith(aNamePrefix
))
769 aRemovals
.push_back(pRefMark
);
772 for (const auto& pMark
: aRemovals
)
774 pDoc
->DeleteFormatRefMark(pMark
);
779 void SwTextShell::Execute(SfxRequest
&rReq
)
781 bool bUseDialog
= true;
782 const SfxItemSet
*pArgs
= rReq
.GetArgs();
783 SwWrtShell
& rWrtSh
= GetShell();
784 const SfxPoolItem
* pItem
= nullptr;
785 const sal_uInt16 nSlot
= rReq
.GetSlot();
787 pArgs
->GetItemState(GetPool().GetWhich(nSlot
), false, &pItem
);
790 case SID_UNICODE_NOTATION_TOGGLE
:
792 tools::Long nMaxUnits
= 256;
793 sal_Int32 nSelLength
= rWrtSh
.GetSelText().getLength();
794 if( rWrtSh
.IsSelection() && !rWrtSh
.IsMultiSelection() && (nSelLength
< nMaxUnits
) )
795 nMaxUnits
= nSelLength
;
797 tools::Long index
= 0;
798 ToggleUnicodeCodepoint aToggle
;
799 while( nMaxUnits
-- && aToggle
.AllowMoreInput(rWrtSh
.GetChar(true, index
-1)) )
802 OUString sReplacement
= aToggle
.ReplacementString();
803 if( !sReplacement
.isEmpty() )
805 if (rWrtSh
.HasReadonlySel() && !rWrtSh
.CursorInsideInputField())
807 // Only break if there's something to do; don't nag with the dialog otherwise
808 rWrtSh
.InfoReadOnlyDialog(false);
811 SwRewriter aRewriter
;
812 aRewriter
.AddRule( UndoArg1
, aToggle
.StringToReplace() );
813 aRewriter
.AddRule( UndoArg2
, SwResId(STR_YIELDS
) );
814 aRewriter
.AddRule( UndoArg3
, sReplacement
);
815 rWrtSh
.StartUndo(SwUndoId::REPLACE
, &aRewriter
);
816 rWrtSh
.GetCursor()->Normalize(false);
819 if( rWrtSh
.IsInSelect() ) // cancel any in-progress keyboard selection as well
822 for( sal_uInt32 i
=aToggle
.CharsToDelete(); i
> 0; --i
)
824 rWrtSh
.Insert2( sReplacement
);
825 rWrtSh
.EndUndo(SwUndoId::REPLACE
, &aRewriter
);
830 case SID_LANGUAGE_STATUS
:
833 OUString aNewLangText
;
834 const SfxStringItem
* pItem2
= rReq
.GetArg
<SfxStringItem
>(SID_LANGUAGE_STATUS
);
836 aNewLangText
= pItem2
->GetValue();
838 //!! Remember the view frame right now...
839 //!! (call to GetView().GetViewFrame() will break if the
840 //!! SwTextShell got destroyed meanwhile.)
841 SfxViewFrame
& rViewFrame
= GetView().GetViewFrame();
843 if (aNewLangText
== "*")
845 // open the dialog "Tools/Options/Language Settings - Language"
846 // to set the documents default language
847 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
848 ScopedVclPtr
<VclAbstractDialog
> pDlg(pFact
->CreateVclDialog(GetView().GetFrameWeld(), SID_LANGUAGE_OPTIONS
));
853 //!! We have to use StartAction / EndAction bracketing in
854 //!! order to prevent possible destruction of the SwTextShell
855 //!! due to the selection changes coming below.
856 rWrtSh
.StartAction();
857 // prevent view from jumping because of (temporary) selection changes
858 rWrtSh
.LockView( true );
860 // setting the new language...
861 if (!aNewLangText
.isEmpty())
863 static const OUStringLiteral
aSelectionLangPrefix(u
"Current_");
864 static const OUStringLiteral
aParagraphLangPrefix(u
"Paragraph_");
865 static const OUStringLiteral
aDocumentLangPrefix(u
"Default_");
868 <RES_CHRATR_LANGUAGE
, RES_CHRATR_LANGUAGE
,
869 RES_CHRATR_CJK_LANGUAGE
, RES_CHRATR_CJK_LANGUAGE
,
870 RES_CHRATR_CTL_LANGUAGE
, RES_CHRATR_CTL_LANGUAGE
> aCoreSet( GetPool() );
873 bool bForSelection
= true;
874 bool bForParagraph
= false;
875 if (-1 != (nPos
= aNewLangText
.indexOf( aSelectionLangPrefix
)))
877 // ... for the current selection
878 aNewLangText
= aNewLangText
.replaceAt(nPos
, aSelectionLangPrefix
.getLength(), u
"");
879 bForSelection
= true;
881 else if (-1 != (nPos
= aNewLangText
.indexOf(aParagraphLangPrefix
)))
883 // ... for the current paragraph language
884 aNewLangText
= aNewLangText
.replaceAt(nPos
, aParagraphLangPrefix
.getLength(), u
"");
885 bForSelection
= true;
886 bForParagraph
= true;
888 else if (-1 != (nPos
= aNewLangText
.indexOf(aDocumentLangPrefix
)))
890 // ... as default document language
891 aNewLangText
= aNewLangText
.replaceAt(nPos
, aDocumentLangPrefix
.getLength(), u
"");
892 bForSelection
= false;
895 if (bForParagraph
|| !bForSelection
)
897 rWrtSh
.Push(); // save selection for later restoration
898 rWrtSh
.ClearMark(); // fdo#67796: invalidate table crsr
902 SwLangHelper::SelectCurrentPara( rWrtSh
);
904 if (!bForSelection
) // document language to be changed...
907 rWrtSh
.ExtendedSelectAll();
910 rWrtSh
.StartUndo( ( !bForParagraph
&& !bForSelection
) ? SwUndoId::SETDEFTATTR
: SwUndoId::EMPTY
);
911 if (aNewLangText
== "LANGUAGE_NONE")
912 SwLangHelper::SetLanguage_None( rWrtSh
, bForSelection
, aCoreSet
);
913 else if (aNewLangText
== "RESET_LANGUAGES")
914 SwLangHelper::ResetLanguages( rWrtSh
);
916 SwLangHelper::SetLanguage( rWrtSh
, aNewLangText
, bForSelection
, aCoreSet
);
919 if (bForParagraph
|| !bForSelection
)
921 rWrtSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
); // restore selection...
925 rWrtSh
.LockView( false );
929 // invalidate slot to get the new language displayed
930 rViewFrame
.GetBindings().Invalidate( nSlot
);
938 // replace word/selection with text from selected sub menu entry
939 OUString aReplaceText
;
940 const SfxStringItem
* pItem2
= rReq
.GetArg(FN_PARAM_THES_WORD_REPLACE
);
942 aReplaceText
= pItem2
->GetValue();
943 if (!aReplaceText
.isEmpty())
945 SwView
&rView2
= rWrtSh
.GetView();
946 const bool bSelection
= rWrtSh
.HasSelection();
947 const OUString aLookUpText
= rView2
.GetThesaurusLookUpText( bSelection
);
948 rView2
.InsertThesaurusSynonym( aReplaceText
, aLookUpText
, bSelection
);
955 InsertSymbol( rReq
);
958 case FN_INSERT_FOOTNOTE
:
959 case FN_INSERT_ENDNOTE
:
962 const SfxStringItem
* pFont
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
963 const SfxStringItem
* pNameItem
= rReq
.GetArg
<SfxStringItem
>(nSlot
);
965 aStr
= pNameItem
->GetValue();
966 bool bFont
= pFont
&& !pFont
->GetValue().isEmpty();
967 rWrtSh
.StartUndo( SwUndoId::UI_INSERT_FOOTNOTE
);
968 rWrtSh
.InsertFootnote( aStr
, nSlot
== FN_INSERT_ENDNOTE
, !bFont
);
971 rWrtSh
.Left( SwCursorSkipMode::Chars
, true, 1, false );
972 SfxItemSetFixed
<RES_CHRATR_FONT
, RES_CHRATR_FONT
> aSet( rWrtSh
.GetAttrPool() );
973 rWrtSh
.GetCurAttr( aSet
);
974 rWrtSh
.SetAttrSet( aSet
, SetAttrMode::DONTEXPAND
);
975 rWrtSh
.ResetSelect(nullptr, false);
977 rWrtSh
.GotoFootnoteText();
979 rWrtSh
.EndUndo( SwUndoId::UI_INSERT_FOOTNOTE
);
983 case FN_INSERT_FOOTNOTE_DLG
:
985 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
986 ScopedVclPtr
<AbstractInsFootNoteDlg
> pDlg(pFact
->CreateInsFootNoteDlg(
987 GetView().GetFrameWeld(), rWrtSh
));
988 pDlg
->SetHelpId(GetStaticInterface()->GetSlot(nSlot
)->GetCommand());
989 if ( pDlg
->Execute() == RET_OK
)
991 const sal_uInt16 nId
= pDlg
->IsEndNote() ? FN_INSERT_ENDNOTE
: FN_INSERT_FOOTNOTE
;
992 SfxRequest
aReq(GetView().GetViewFrame(), nId
);
993 if ( !pDlg
->GetStr().isEmpty() )
994 aReq
.AppendItem( SfxStringItem( nId
, pDlg
->GetStr() ) );
995 if ( !pDlg
->GetFontName().isEmpty() )
996 aReq
.AppendItem( SfxStringItem( FN_PARAM_1
, pDlg
->GetFontName() ) );
1003 case FN_FORMAT_FOOTNOTE_DLG
:
1004 case FN_FORMAT_CURRENT_FOOTNOTE_DLG
:
1006 GetView().ExecFormatFootnote();
1011 GetView().ExecuteInsertDoc( rReq
, pItem
);
1014 case FN_FORMAT_RESET
:
1016 // #i78856, reset all attributes but not the language attributes
1017 // (for this build an array of all relevant attributes and
1018 // remove the languages from that)
1019 o3tl::sorted_vector
<sal_uInt16
> aAttribs
;
1021 constexpr std::pair
<sal_uInt16
, sal_uInt16
> aResetableSetRange
[] = {
1022 // tdf#40496: we don't want to change writing direction, so exclude RES_FRAMEDIR:
1023 { RES_FRMATR_BEGIN
, RES_FRAMEDIR
- 1 },
1024 { RES_FRAMEDIR
+ 1, RES_FRMATR_END
- 1 },
1025 { RES_CHRATR_BEGIN
, RES_CHRATR_LANGUAGE
- 1 },
1026 { RES_CHRATR_LANGUAGE
+ 1, RES_CHRATR_CJK_LANGUAGE
- 1 },
1027 { RES_CHRATR_CJK_LANGUAGE
+ 1, RES_CHRATR_CTL_LANGUAGE
- 1 },
1028 { RES_CHRATR_CTL_LANGUAGE
+ 1, RES_CHRATR_END
- 1 },
1029 { RES_PARATR_BEGIN
, RES_PARATR_END
- 1 },
1030 { RES_PARATR_LIST_AUTOFMT
, RES_PARATR_LIST_AUTOFMT
},
1031 { RES_TXTATR_UNKNOWN_CONTAINER
, RES_TXTATR_UNKNOWN_CONTAINER
},
1032 { RES_UNKNOWNATR_BEGIN
, RES_UNKNOWNATR_END
- 1 },
1034 for (const auto& [nBegin
, nEnd
] : aResetableSetRange
)
1036 for (sal_uInt16 i
= nBegin
; i
<= nEnd
; ++i
)
1037 aAttribs
.insert( i
);
1039 rWrtSh
.ResetAttr( aAttribs
);
1041 // also clear the direct formatting flag inside SwTableBox(es)
1042 if (SwFEShell
* pFEShell
= GetView().GetDocShell()->GetFEShell())
1043 pFEShell
->UpdateTableStyleFormatting(nullptr, true);
1048 case FN_INSERT_BREAK_DLG
:
1052 ::std::optional
<sal_uInt16
> oPageNumber
;
1053 std::optional
<SwLineBreakClear
> oClear
;
1054 OUString aTemplateName
;
1055 sal_uInt16 nKind
= static_cast<const SfxInt16Item
*>(pItem
)->GetValue();
1056 const SfxStringItem
* pTemplate
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
1057 const SfxUInt16Item
* pNumber
= rReq
.GetArg
<SfxUInt16Item
>(FN_PARAM_2
);
1058 const SfxBoolItem
* pIsNumberFilled
= rReq
.GetArg
<SfxBoolItem
>(FN_PARAM_3
);
1060 aTemplateName
= pTemplate
->GetValue();
1061 if ( pNumber
&& pIsNumberFilled
&& pIsNumberFilled
->GetValue() )
1062 oPageNumber
= pNumber
->GetValue();
1064 InsertBreak(rWrtSh
, nKind
, oPageNumber
, aTemplateName
, oClear
);
1068 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
1070 std::shared_ptr
<AbstractSwBreakDlg
> pAbstractDialog(pFact
->CreateSwBreakDlg(GetView().GetFrameWeld(), rWrtSh
));
1071 std::shared_ptr
<weld::DialogController
> pDialogController(pAbstractDialog
->getDialogController());
1073 weld::DialogController::runAsync(pDialogController
,
1074 [pAbstractDialog
, &rWrtSh
] (sal_Int32 nResult
) {
1075 if( RET_OK
== nResult
)
1077 sal_uInt16 nKind
= pAbstractDialog
->GetKind();
1078 OUString aTemplateName
= pAbstractDialog
->GetTemplateName();
1079 ::std::optional
<sal_uInt16
> oPageNumber
= pAbstractDialog
->GetPageNumber();
1080 std::optional
<SwLineBreakClear
> oClear
= pAbstractDialog
->GetClear();
1082 InsertBreak(rWrtSh
, nKind
, oPageNumber
, aTemplateName
, oClear
);
1089 case FN_INSERT_BOOKMARK
:
1091 const SfxStringItem
* pBookmarkText
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
1092 SwPaM
* pCursorPos
= rWrtSh
.GetCursor();
1095 rWrtSh
.StartAction();
1096 OUString sName
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
1100 OUString aBookmarkText
= pBookmarkText
->GetValue();
1101 // Split node to remember where the start position is.
1102 bool bSuccess
= rWrtSh
.GetDoc()->getIDocumentContentOperations().SplitNode(
1103 *pCursorPos
->GetPoint(), /*bChkTableStart=*/false);
1106 SwPaM
aBookmarkPam(*pCursorPos
->GetPoint());
1107 aBookmarkPam
.Move(fnMoveBackward
, GoInContent
);
1109 // Paste HTML content.
1110 SwTranslateHelper::PasteHTMLToPaM(
1111 rWrtSh
, pCursorPos
, aBookmarkText
.toUtf8(), /*bSetSelection=*/true);
1112 if (pCursorPos
->GetPoint()->GetContentIndex() == 0)
1114 // The paste created a last empty text node, remove it.
1115 SwPaM
aPam(*pCursorPos
->GetPoint());
1117 aPam
.Move(fnMoveBackward
, GoInContent
);
1118 rWrtSh
.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPam
);
1121 // Undo the above SplitNode().
1122 aBookmarkPam
.SetMark();
1123 aBookmarkPam
.Move(fnMoveForward
, GoInContent
);
1124 rWrtSh
.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(
1126 *aBookmarkPam
.GetMark() = *pCursorPos
->GetPoint();
1127 *pCursorPos
= aBookmarkPam
;
1131 rWrtSh
.SetBookmark( vcl::KeyCode(), sName
);
1134 pCursorPos
->DeleteMark();
1141 case FN_EDIT_BOOKMARK
:
1143 ::std::optional
<OUString
> oName
;
1146 oName
.emplace(static_cast<const SfxStringItem
*>(pItem
)->GetValue());
1149 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
1150 ScopedVclPtr
<VclAbstractDialog
> pDlg(pFact
->CreateSwInsertBookmarkDlg(GetView().GetFrameWeld(), rWrtSh
, oName
? &*oName
: nullptr));
1151 VclAbstractDialog::AsyncContext aContext
;
1152 aContext
.maEndDialogFn
= [](sal_Int32
){};
1153 pDlg
->StartExecuteAsync(aContext
);
1158 case FN_UPDATE_BOOKMARKS
:
1160 // This updates all bookmarks in the document that match the conditions specified in
1162 UpdateBookmarks(rReq
, rWrtSh
);
1165 case FN_UPDATE_BOOKMARK
:
1167 // This updates the bookmark under the cursor.
1168 UpdateBookmark(rReq
, rWrtSh
);
1171 case FN_DELETE_BOOKMARK
:
1173 // This deletes a bookmark with the specified name.
1174 if (pItem
&& !rWrtSh
.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS
))
1176 IDocumentMarkAccess
* const pMarkAccess
= rWrtSh
.getIDocumentMarkAccess();
1177 pMarkAccess
->deleteMark(pMarkAccess
->findMark(static_cast<const SfxStringItem
*>(pItem
)->GetValue()), false);
1181 case FN_DELETE_BOOKMARKS
:
1183 // This deletes all bookmarks in the document matching a specified prefix.
1184 DeleteBookmarks(rReq
, rWrtSh
);
1187 case FN_DELETE_FIELDS
:
1189 // This deletes all fields in the document matching a specified type & prefix.
1190 DeleteFields(rReq
, rWrtSh
);
1193 case FN_UPDATE_SECTIONS
:
1195 UpdateSections(rReq
, rWrtSh
);
1198 case FN_DELETE_SECTIONS
:
1200 // This deletes all sections in the document matching a specified prefix. Note that the
1201 // section is deleted, but not its contents.
1202 DeleteSections(rReq
, rWrtSh
);
1205 case FN_SET_REMINDER
:
1207 // collect and sort navigator reminder names
1208 IDocumentMarkAccess
* const pMarkAccess
= rWrtSh
.getIDocumentMarkAccess();
1209 std::vector
< OUString
> vNavMarkNames
;
1210 for(IDocumentMarkAccess::const_iterator_t ppMark
= pMarkAccess
->getAllMarksBegin();
1211 ppMark
!= pMarkAccess
->getAllMarksEnd();
1214 if( IDocumentMarkAccess::GetType(**ppMark
) == IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER
)
1215 vNavMarkNames
.push_back((*ppMark
)->GetName());
1217 std::sort(vNavMarkNames
.begin(), vNavMarkNames
.end());
1219 // we are maxed out so delete the first one
1220 // this assumes that IDocumentMarkAccess generates Names in ascending order
1221 if(vNavMarkNames
.size() == MAX_MARKS
)
1222 pMarkAccess
->deleteMark(pMarkAccess
->findMark(vNavMarkNames
[0]), false);
1224 rWrtSh
.SetBookmark(vcl::KeyCode(), OUString(), IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER
);
1225 SwView::SetActMark(vNavMarkNames
.size() < MAX_MARKS
? vNavMarkNames
.size() : MAX_MARKS
-1);
1229 case FN_AUTOFORMAT_REDLINE_APPLY
:
1231 SvxSwAutoFormatFlags
aFlags(SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags());
1232 // This must always be false for the postprocessing.
1233 aFlags
.bAFormatByInput
= false;
1234 aFlags
.bWithRedlining
= true;
1235 rWrtSh
.AutoFormat( &aFlags
);
1236 aFlags
.bWithRedlining
= false;
1238 SfxViewFrame
& rVFrame
= GetView().GetViewFrame();
1239 if (rVFrame
.HasChildWindow(FN_REDLINE_ACCEPT
))
1240 rVFrame
.ToggleChildWindow(FN_REDLINE_ACCEPT
);
1242 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
1243 ScopedVclPtr
<AbstractSwModalRedlineAcceptDlg
> xDlg(pFact
->CreateSwModalRedlineAcceptDlg(GetView().GetEditWin().GetFrameWeld()));
1250 case FN_AUTOFORMAT_APPLY
:
1252 SvxSwAutoFormatFlags
aFlags(SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags());
1253 // This must always be false for the postprocessing.
1254 aFlags
.bAFormatByInput
= false;
1255 rWrtSh
.AutoFormat( &aFlags
);
1259 case FN_AUTOFORMAT_AUTO
:
1261 SvxAutoCorrCfg
& rACfg
= SvxAutoCorrCfg::Get();
1262 bool bSet
= pItem
? static_cast<const SfxBoolItem
*>(pItem
)->GetValue() : !rACfg
.IsAutoFormatByInput();
1263 if( bSet
!= rACfg
.IsAutoFormatByInput() )
1265 rACfg
.SetAutoFormatByInput( bSet
);
1267 GetView().GetViewFrame().GetBindings().Invalidate( nSlot
);
1269 rReq
.AppendItem( SfxBoolItem( GetPool().GetWhich(nSlot
), bSet
) );
1274 case FN_AUTO_CORRECT
:
1276 // At first set to blank as default.
1277 rWrtSh
.AutoCorrect( *SvxAutoCorrCfg::Get().GetAutoCorrect(), ' ' );
1281 case FN_TABLE_SORT_DIALOG
:
1282 case FN_SORTING_DLG
:
1284 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
1285 ScopedVclPtr
<VclAbstractDialog
> pDlg(pFact
->CreateSwSortingDialog(GetView().GetFrameWeld(), rWrtSh
));
1290 case FN_NUMBERING_OUTLINE_DLG
:
1292 GetView().ExecNumberingOutline(GetPool());
1298 rtl::Reference
<SwTransferable
> pTransfer
= new SwTransferable( rWrtSh
);
1299 pTransfer
->CalculateAndCopy();
1303 case FN_GOTO_REFERENCE
:
1305 SwField
*pField
= rWrtSh
.GetCurField();
1306 if(pField
&& pField
->GetTypeId() == SwFieldTypesEnum::GetRef
)
1308 rWrtSh
.StartAllAction();
1309 rWrtSh
.SwCursorShell::GotoRefMark( static_cast<SwGetRefField
*>(pField
)->GetSetRefName(),
1310 static_cast<SwGetRefField
*>(pField
)->GetSubType(),
1311 static_cast<SwGetRefField
*>(pField
)->GetSeqNo() );
1312 rWrtSh
.EndAllAction();
1317 case FN_EDIT_FORMULA
:
1319 const sal_uInt16 nId
= SwInputChild::GetChildWindowId();
1320 SfxViewFrame
& rVFrame
= GetView().GetViewFrame();
1323 //if the ChildWindow is active it has to be removed
1324 if( rVFrame
.HasChildWindow( nId
) )
1326 rVFrame
.ToggleChildWindow( nId
);
1327 rVFrame
.GetBindings().InvalidateAll( true );
1330 OUString
sFormula(static_cast<const SfxStringItem
*>(pItem
)->GetValue());
1331 SwFieldMgr aFieldMgr
;
1332 rWrtSh
.StartAllAction();
1333 bool bDelSel
= rWrtSh
.HasSelection();
1336 rWrtSh
.StartUndo( SwUndoId::START
);
1341 rWrtSh
.EnterStdMode();
1344 if( !bDelSel
&& aFieldMgr
.GetCurField() && SwFieldTypesEnum::Formel
== aFieldMgr
.GetCurTypeId() )
1345 aFieldMgr
.UpdateCurField( aFieldMgr
.GetCurField()->GetFormat(), OUString(), sFormula
);
1346 else if( !sFormula
.isEmpty() )
1348 if( rWrtSh
.IsCursorInTable() )
1350 SfxItemSetFixed
<RES_BOXATR_FORMULA
, RES_BOXATR_FORMULA
> aSet( rWrtSh
.GetAttrPool() );
1351 aSet
.Put( SwTableBoxFormula( sFormula
));
1352 rWrtSh
.SetTableBoxFormulaAttrs( aSet
);
1353 rWrtSh
.UpdateTable();
1357 SvNumberFormatter
* pFormatter
= rWrtSh
.GetNumberFormatter();
1358 const sal_uInt32 nSysNumFormat
= pFormatter
->GetFormatIndex( NF_NUMBER_STANDARD
, LANGUAGE_SYSTEM
);
1359 SwInsertField_Data
aData(SwFieldTypesEnum::Formel
, nsSwGetSetExpType::GSE_FORMULA
, OUString(), sFormula
, nSysNumFormat
);
1360 aFieldMgr
.InsertField(aData
);
1365 rWrtSh
.EndUndo( SwUndoId::END
);
1366 rWrtSh
.EndAllAction();
1371 rWrtSh
.EndAllTableBoxEdit();
1372 rVFrame
.ToggleChildWindow( nId
);
1373 if( !rVFrame
.HasChildWindow( nId
) )
1374 rVFrame
.GetBindings().InvalidateAll( true );
1380 case FN_TABLE_UNSET_READ_ONLY
:
1382 rWrtSh
.UnProtectTables();
1385 case SID_EDIT_HYPERLINK
:
1386 GetView().GetViewFrame().SetChildWindow(SID_HYPERLINK_DIALOG
, true);
1388 case SID_REMOVE_HYPERLINK
:
1390 bool bSel
= rWrtSh
.HasSelection();
1393 rWrtSh
.StartAction();
1395 if(!rWrtSh
.SelectTextAttr( RES_TXTATR_INETFMT
))
1398 //now remove the attribute
1399 rWrtSh
.ResetAttr({ RES_TXTATR_INETFMT
});
1402 rWrtSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
);
1407 case SID_ATTR_BRUSH_CHAR
:
1408 case SID_ATTR_CHAR_SCALEWIDTH
:
1409 case SID_ATTR_CHAR_ROTATED
:
1410 case FN_TXTATR_INET
:
1411 case FN_INSERT_HYPERLINK
:
1413 const sal_uInt16 nWhich
= GetPool().GetWhich( nSlot
);
1414 if ( pArgs
&& pArgs
->GetItemState( nWhich
) == SfxItemState::SET
)
1419 case SID_CHAR_DLG_EFFECT
:
1420 case SID_CHAR_DLG_POSITION
:
1422 sw_CharDialog(rWrtSh
, bUseDialog
, /*ApplyToParagraph*/false, nSlot
, pArgs
, &rReq
);
1425 case SID_CHAR_DLG_FOR_PARAGRAPH
:
1427 sw_CharDialog(rWrtSh
, /*UseDialog*/true, /*ApplyToParagraph*/true, nSlot
, pArgs
, &rReq
);
1430 case SID_ATTR_LRSPACE
:
1431 case SID_ATTR_ULSPACE
:
1432 case SID_ATTR_BRUSH
:
1433 case SID_PARA_VERTALIGN
:
1434 case SID_ATTR_PARA_NUMRULE
:
1435 case SID_ATTR_PARA_REGISTER
:
1436 case SID_ATTR_PARA_PAGENUM
:
1437 case FN_FORMAT_LINENUMBER
:
1438 case FN_NUMBER_NEWSTART
:
1439 case FN_NUMBER_NEWSTART_AT
:
1440 case FN_FORMAT_DROPCAPS
:
1442 case SID_ATTR_PARA_LRSPACE
:
1444 const sal_uInt16 nWhich
= GetPool().GetWhich( nSlot
);
1445 if ( pArgs
&& pArgs
->GetItemState( nWhich
) == SfxItemState::SET
)
1451 SwPaM
* pPaM
= nullptr;
1455 const SwPaMItem
* pPaMItem
= pArgs
->GetItemIfSet( GetPool().GetWhich( FN_PARAM_PAM
), false );
1457 pPaM
= pPaMItem
->GetValue( );
1461 pPaM
= rWrtSh
.GetCursor();
1463 FieldUnit eMetric
= ::GetDfltMetric( dynamic_cast<SwWebView
*>( &GetView()) != nullptr );
1464 SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC
, static_cast< sal_uInt16
>(eMetric
)));
1466 bool bApplyCharUnit
= ::HasCharUnit( dynamic_cast<SwWebView
*>( &GetView()) != nullptr );
1467 SW_MOD()->PutItem(SfxBoolItem(SID_ATTR_APPLYCHARUNIT
, bApplyCharUnit
));
1470 RES_PARATR_BEGIN
, RES_FRMATR_END
- 1,
1471 // FillAttribute support:
1472 XATTR_FILL_FIRST
, XATTR_FILL_LAST
,
1473 // Includes SID_ATTR_TABSTOP_POS:
1474 SID_ATTR_TABSTOP_DEFAULTS
, SID_ATTR_TABSTOP_OFFSET
,
1475 SID_ATTR_BORDER_INNER
, SID_ATTR_BORDER_INNER
,
1476 SID_ATTR_PARA_MODEL
, SID_ATTR_PARA_KEEP
,
1477 // Items to hand over XPropertyList things like XColorList,
1478 // XHatchList, XGradientList, and XBitmapList to the Area
1480 SID_COLOR_TABLE
, SID_PATTERN_LIST
,
1481 SID_HTML_MODE
, SID_HTML_MODE
,
1482 SID_ATTR_PARA_PAGENUM
, SID_ATTR_PARA_PAGENUM
,
1483 FN_PARAM_1
, FN_PARAM_1
,
1484 FN_NUMBER_NEWSTART
, FN_NUMBER_NEWSTART_AT
,
1485 FN_DROP_TEXT
, FN_DROP_CHAR_STYLE_NAME
> aCoreSet( GetPool() );
1487 // get also the list level indent values merged as LR-SPACE item, if needed.
1488 rWrtSh
.GetPaMAttr( pPaM
, aCoreSet
, true );
1490 // create needed items for XPropertyList entries from the DrawModel so that
1491 // the Area TabPage can access them
1492 // Do this after GetCurAttr, this resets the ItemSet content again
1493 SwDrawModel
* pDrawModel
= GetView().GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
1495 aCoreSet
.Put(SvxColorListItem(pDrawModel
->GetColorList(), SID_COLOR_TABLE
));
1496 aCoreSet
.Put(SvxGradientListItem(pDrawModel
->GetGradientList(), SID_GRADIENT_LIST
));
1497 aCoreSet
.Put(SvxHatchListItem(pDrawModel
->GetHatchList(), SID_HATCH_LIST
));
1498 aCoreSet
.Put(SvxBitmapListItem(pDrawModel
->GetBitmapList(), SID_BITMAP_LIST
));
1499 aCoreSet
.Put(SvxPatternListItem(pDrawModel
->GetPatternList(), SID_PATTERN_LIST
));
1500 aCoreSet
.Put(SfxUInt16Item(SID_HTML_MODE
,
1501 ::GetHtmlMode(GetView().GetDocShell())));
1503 // Tabulators: Put DefaultTabs into ItemSet
1504 const SvxTabStopItem
& rDefTabs
=
1505 GetPool().GetDefaultItem(RES_PARATR_TABSTOP
);
1507 const sal_uInt16 nDefDist
= o3tl::narrowing
<sal_uInt16
>(::GetTabDist( rDefTabs
));
1508 SfxUInt16Item
aDefDistItem( SID_ATTR_TABSTOP_DEFAULTS
, nDefDist
);
1509 aCoreSet
.Put( aDefDistItem
);
1511 // Current tabulator
1512 SfxUInt16Item
aTabPos( SID_ATTR_TABSTOP_POS
, 0 );
1513 aCoreSet
.Put( aTabPos
);
1515 // Left border as offset
1516 //#i24363# tab stops relative to indent
1517 const tools::Long nOff
= rWrtSh
.getIDocumentSettingAccess().get(DocumentSettingId::TABS_RELATIVE_TO_INDENT
)
1518 ? aCoreSet
.Get(RES_MARGIN_TEXTLEFT
).GetTextLeft() : 0;
1519 SfxInt32Item
aOff( SID_ATTR_TABSTOP_OFFSET
, nOff
);
1520 aCoreSet
.Put( aOff
);
1522 // Setting the BoxInfo
1523 ::PrepareBoxInfo( aCoreSet
, rWrtSh
);
1525 // Current page format
1526 ::SwToSfxPageDescAttr( aCoreSet
);
1528 // Properties of numbering
1529 if (rWrtSh
.GetNumRuleAtCurrCursorPos())
1531 SfxBoolItem
aStart( FN_NUMBER_NEWSTART
, rWrtSh
.IsNumRuleStart( pPaM
) );
1532 aCoreSet
.Put(aStart
);
1533 SfxUInt16Item
aStartAt( FN_NUMBER_NEWSTART_AT
,
1534 rWrtSh
.GetNodeNumStart( pPaM
) );
1535 aCoreSet
.Put(aStartAt
);
1537 VclPtr
<SfxAbstractTabDialog
> pDlg
;
1539 if ( bUseDialog
&& GetActiveView() )
1543 sDefPage
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
1545 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
1546 pDlg
.reset(pFact
->CreateSwParaDlg(GetView().GetFrameWeld(), GetView(), aCoreSet
, false, sDefPage
));
1551 if ( nSlot
== SID_ATTR_PARA_LRSPACE
)
1553 SvxLRSpaceItem
aParaMargin(static_cast<const SvxLRSpaceItem
&>(pArgs
->Get(nSlot
)));
1554 SvxFirstLineIndentItem
firstLine(RES_MARGIN_FIRSTLINE
);
1555 SvxTextLeftMarginItem
leftMargin(RES_MARGIN_TEXTLEFT
);
1556 SvxRightMarginItem
rightMargin(RES_MARGIN_RIGHT
);
1557 firstLine
.SetTextFirstLineOffset(aParaMargin
.GetTextFirstLineOffset(), aParaMargin
.GetPropTextFirstLineOffset());
1558 firstLine
.SetAutoFirst(aParaMargin
.IsAutoFirst());
1559 leftMargin
.SetTextLeft(aParaMargin
.GetTextLeft(), aParaMargin
.GetPropLeft());
1560 rightMargin
.SetRight(aParaMargin
.GetRight(), aParaMargin
.GetPropRight());
1561 aCoreSet
.Put(firstLine
);
1562 aCoreSet
.Put(leftMargin
);
1563 aCoreSet
.Put(rightMargin
);
1565 sw_ParagraphDialogResult(&aCoreSet
, rWrtSh
, rReq
, pPaM
);
1568 sw_ParagraphDialogResult(const_cast<SfxItemSet
*>(pArgs
), rWrtSh
, rReq
, pPaM
);
1572 auto pRequest
= std::make_shared
<SfxRequest
>(rReq
);
1573 rReq
.Ignore(); // the 'old' request is not relevant any more
1575 auto vCursors
= CopyPaMRing(*pPaM
); // tdf#134439 make a copy to use at later apply
1576 pDlg
->StartExecuteAsync([pDlg
, &rWrtSh
, pDrawModel
, pRequest
, nDefDist
, vCursors
](sal_Int32 nResult
){
1577 if (nResult
== RET_OK
)
1579 // Apply defaults if necessary.
1580 SfxItemSet
* pSet
= const_cast<SfxItemSet
*>(pDlg
->GetOutputItemSet());
1581 sal_uInt16 nNewDist
;
1582 const SfxUInt16Item
* pDefaultsItem
= pSet
->GetItemIfSet(SID_ATTR_TABSTOP_DEFAULTS
, false);
1583 if (pDefaultsItem
&& nDefDist
!= (nNewDist
= pDefaultsItem
->GetValue()) )
1585 SvxTabStopItem
aDefTabs( 0, 0, SvxTabAdjust::Default
, RES_PARATR_TABSTOP
);
1586 MakeDefTabs( nNewDist
, aDefTabs
);
1587 rWrtSh
.SetDefault( aDefTabs
);
1588 pSet
->ClearItem( SID_ATTR_TABSTOP_DEFAULTS
);
1591 const SfxPoolItem
* pItem2
= nullptr;
1592 if (SfxItemState::SET
== pSet
->GetItemState(FN_PARAM_1
, false, &pItem2
))
1594 pSet
->Put(SfxStringItem(FN_DROP_TEXT
, static_cast<const SfxStringItem
*>(pItem2
)->GetValue()));
1595 pSet
->ClearItem(FN_PARAM_1
);
1598 if (const SwFormatDrop
* pDropItem
= pSet
->GetItemIfSet(RES_PARATR_DROP
, false))
1600 OUString sCharStyleName
;
1601 if (pDropItem
->GetCharFormat())
1602 sCharStyleName
= pDropItem
->GetCharFormat()->GetName();
1603 pSet
->Put(SfxStringItem(FN_DROP_CHAR_STYLE_NAME
, sCharStyleName
));
1606 const XFillStyleItem
* pFS
= pSet
->GetItem
<XFillStyleItem
>(XATTR_FILLSTYLE
);
1607 bool bSet
= pFS
&& pFS
->GetValue() == drawing::FillStyle_GRADIENT
;
1608 const XFillGradientItem
* pTempGradItem
1609 = bSet
? pSet
->GetItem
<XFillGradientItem
>(XATTR_FILLGRADIENT
) : nullptr;
1610 if (pTempGradItem
&& pTempGradItem
->GetName().isEmpty())
1612 // MigrateItemSet guarantees unique gradient names
1613 SfxItemSetFixed
<XATTR_FILLGRADIENT
, XATTR_FILLGRADIENT
> aMigrateSet(rWrtSh
.GetView().GetPool());
1614 aMigrateSet
.Put(XFillGradientItem("gradient", pTempGradItem
->GetGradientValue()));
1615 SdrModel::MigrateItemSet(&aMigrateSet
, pSet
, pDrawModel
);
1618 bSet
= pFS
&& pFS
->GetValue() == drawing::FillStyle_HATCH
;
1619 const XFillHatchItem
* pTempHatchItem
1620 = bSet
? pSet
->GetItem
<XFillHatchItem
>(XATTR_FILLHATCH
) : nullptr;
1621 if (pTempHatchItem
&& pTempHatchItem
->GetName().isEmpty())
1623 SfxItemSetFixed
<XATTR_FILLHATCH
, XATTR_FILLHATCH
> aMigrateSet(rWrtSh
.GetView().GetPool());
1624 aMigrateSet
.Put(XFillHatchItem("hatch", pTempHatchItem
->GetHatchValue()));
1625 SdrModel::MigrateItemSet(&aMigrateSet
, pSet
, pDrawModel
);
1628 sw_ParagraphDialogResult(pSet
, rWrtSh
, *pRequest
, vCursors
->front().get());
1630 pDlg
->disposeOnce();
1635 case FN_NUM_CONTINUE
:
1637 OUString sContinuedListId
;
1638 const SwNumRule
* pRule
=
1639 rWrtSh
.SearchNumRule( true, sContinuedListId
);
1641 // Search also for bullet list
1644 pRule
= rWrtSh
.SearchNumRule( false, sContinuedListId
);
1648 rWrtSh
.SetCurNumRule( *pRule
, false, sContinuedListId
);
1653 case FN_SELECT_PARA
:
1655 if ( !rWrtSh
.IsSttOfPara() )
1658 rWrtSh
.EnterStdMode();
1659 rWrtSh
.EndPara( true );
1663 case SID_DEC_INDENT
:
1664 case SID_INC_INDENT
:
1665 //According to the requirement, modified the behavior when user
1666 //using the indent button on the toolbar. Now if we increase/decrease indent for a
1667 //paragraph which has bullet style it will increase/decrease the bullet level.
1669 //If the current paragraph has bullet call the function to
1670 //increase or decrease the bullet level.
1671 //Why could I know whether a paragraph has bullet or not by checking the below conditions?
1672 //Please refer to the "case KEY_TAB:" section in SwEditWin::KeyInput(..) :
1673 // if( rSh.GetCurNumRule() && rSh.IsSttOfPara() &&
1674 // !rSh.HasReadonlySel() )
1675 // eKeyState = KS_NumDown;
1676 //Above code demonstrates that when the cursor is at the start of a paragraph which has bullet,
1677 //press TAB will increase the bullet level.
1678 //So I copied from that ^^
1679 if ( rWrtSh
.GetNumRuleAtCurrCursorPos() && !rWrtSh
.HasReadonlySel() )
1681 rWrtSh
.NumUpDown( SID_INC_INDENT
== nSlot
);
1683 else //execute the original processing functions
1685 //below is copied of the old codes
1686 rWrtSh
.MoveLeftMargin( SID_INC_INDENT
== nSlot
, rReq
.GetModifier() != KEY_MOD1
);
1692 case FN_DEC_INDENT_OFFSET
:
1693 case FN_INC_INDENT_OFFSET
:
1694 rWrtSh
.MoveLeftMargin( FN_INC_INDENT_OFFSET
== nSlot
, rReq
.GetModifier() == KEY_MOD1
);
1698 case SID_ATTR_CHAR_COLOR2
:
1702 auto* pColorItem
= static_cast<const SvxColorItem
*>(pItem
);
1703 SwEditWin
& rEditWin
= GetView().GetEditWin();
1704 rEditWin
.SetWaterCanTextColor(pColorItem
->GetValue());
1705 SwApplyTemplate
* pApply
= rEditWin
.GetApplyTemplate();
1707 // If there is a selection, then set the color on it
1708 // otherwise, it'll be the color for the next text to be typed
1709 if (!pApply
|| pApply
->nColor
!= SID_ATTR_CHAR_COLOR_EXT
)
1711 rWrtSh
.SetAttrItem(SvxColorItem(pColorItem
->GetValue(), pColorItem
->getComplexColor(), RES_CHRATR_COLOR
));
1718 case SID_ATTR_CHAR_BACK_COLOR
:
1719 case SID_ATTR_CHAR_COLOR_BACKGROUND
: // deprecated
1720 case SID_ATTR_CHAR_COLOR_EXT
:
1723 model::ComplexColor aComplexColor
;
1727 auto* pColorItem
= static_cast<const SvxColorItem
*>(pItem
);
1728 aColor
= pColorItem
->GetValue();
1729 aComplexColor
= pColorItem
->getComplexColor();
1732 aColor
= COL_TRANSPARENT
;
1734 SwEditWin
& rEdtWin
= GetView().GetEditWin();
1735 if (nSlot
!= SID_ATTR_CHAR_COLOR_EXT
)
1736 rEdtWin
.SetWaterCanTextBackColor(aColor
);
1738 rEdtWin
.SetWaterCanTextColor(aColor
);
1740 SwApplyTemplate
* pApply
= rEdtWin
.GetApplyTemplate();
1741 SwApplyTemplate aTempl
;
1742 if (!pApply
&& (rWrtSh
.HasSelection() || rReq
.IsAPI()))
1744 if (nSlot
!= SID_ATTR_CHAR_COLOR_EXT
)
1746 SfxItemSetFixed
<RES_CHRATR_BACKGROUND
, RES_CHRATR_BACKGROUND
> aCoreSet( rWrtSh
.GetView().GetPool() );
1748 rWrtSh
.GetCurAttr(aCoreSet
);
1750 // Remove highlight if already set of the same color
1751 const SvxBrushItem
& rBrushItem
= aCoreSet
.Get(RES_CHRATR_BACKGROUND
);
1752 if (aColor
== rBrushItem
.GetColor())
1754 aComplexColor
= model::ComplexColor();
1755 aColor
= COL_TRANSPARENT
;
1757 ApplyCharBackground(aColor
, aComplexColor
, rWrtSh
);
1760 rWrtSh
.SetAttrItem(SvxColorItem(aColor
, aComplexColor
, RES_CHRATR_COLOR
));
1764 if(!pApply
|| pApply
->nColor
!= nSlot
)
1765 aTempl
.nColor
= nSlot
;
1766 rEdtWin
.SetApplyTemplate(aTempl
);
1773 case FN_NUM_BULLET_MOVEDOWN
:
1774 if (!rWrtSh
.IsAddMode())
1775 rWrtSh
.MoveParagraph();
1779 case FN_NUM_BULLET_MOVEUP
:
1780 if (!rWrtSh
.IsAddMode())
1781 rWrtSh
.MoveParagraph(SwNodeOffset(-1));
1784 case SID_RUBY_DIALOG
:
1785 case SID_HYPERLINK_DIALOG
:
1787 SfxRequest
aReq(nSlot
, SfxCallMode::SLOT
, SfxGetpApp()->GetPool());
1788 GetView().GetViewFrame().ExecuteSlot( aReq
);
1792 case FN_INSERT_PAGEHEADER
:
1793 case FN_INSERT_PAGEFOOTER
:
1794 if(pArgs
&& pArgs
->Count())
1796 OUString sStyleName
;
1798 sStyleName
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
1800 if( SfxItemState::SET
== pArgs
->GetItemState(FN_PARAM_1
, false, &pItem
))
1801 bOn
= static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
1802 rWrtSh
.ChangeHeaderOrFooter(sStyleName
, FN_INSERT_PAGEHEADER
== nSlot
, bOn
, !rReq
.IsAPI());
1806 case FN_READONLY_SELECTION_MODE
:
1807 if(GetView().GetDocShell()->IsReadOnly())
1809 rWrtSh
.SetReadonlySelectionOption(
1810 !rWrtSh
.GetViewOptions()->IsSelectionInReadonly());
1811 rWrtSh
.ShowCursor();
1814 case FN_SELECTION_MODE_DEFAULT
:
1815 case FN_SELECTION_MODE_BLOCK
:
1817 bool bSetBlockMode
= !rWrtSh
.IsBlockMode();
1818 if( pArgs
&& SfxItemState::SET
== pArgs
->GetItemState(nSlot
, false, &pItem
))
1819 bSetBlockMode
= static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
1820 if( ( nSlot
== FN_SELECTION_MODE_DEFAULT
) != bSetBlockMode
)
1821 rWrtSh
.EnterBlockMode();
1823 rWrtSh
.EnterStdMode();
1824 SfxBindings
&rBnd
= GetView().GetViewFrame().GetBindings();
1825 rBnd
.Invalidate(FN_STAT_SELMODE
);
1826 rBnd
.Update(FN_STAT_SELMODE
);
1829 case SID_OPEN_HYPERLINK
:
1830 case SID_COPY_HYPERLINK_LOCATION
:
1832 SfxItemSetFixed
<RES_TXTATR_INETFMT
, RES_TXTATR_INETFMT
> aSet(GetPool());
1833 rWrtSh
.GetCurAttr(aSet
);
1834 if(SfxItemState::SET
<= aSet
.GetItemState( RES_TXTATR_INETFMT
))
1836 const SwFormatINetFormat
& rINetFormat
= aSet
.Get(RES_TXTATR_INETFMT
);
1838 if (nSlot
== SID_OPEN_HYPERLINK
)
1840 rWrtSh
.ClickToINetAttr(rINetFormat
);
1842 else if (nSlot
== SID_COPY_HYPERLINK_LOCATION
)
1844 OUString hyperlinkLocation
= rINetFormat
.GetValue();
1845 ::uno::Reference
< datatransfer::clipboard::XClipboard
> xClipboard
= GetView().GetEditWin().GetClipboard();
1846 vcl::unohelper::TextDataObject::CopyStringTo(hyperlinkLocation
, xClipboard
, SfxViewShell::Current());
1851 SwField
* pField
= rWrtSh
.GetCurField();
1852 if (pField
&& pField
->GetTyp()->Which() == SwFieldIds::TableOfAuthorities
)
1854 const auto& rAuthorityField
= *static_cast<const SwAuthorityField
*>(pField
);
1855 OUString targetURL
= "";
1857 if (auto targetType
= rAuthorityField
.GetTargetType();
1858 targetType
== SwAuthorityField::TargetType::UseDisplayURL
1859 || targetType
== SwAuthorityField::TargetType::UseTargetURL
)
1861 // Bibliography entry with URL also provides a hyperlink.
1862 targetURL
= rAuthorityField
.GetAbsoluteURL();
1865 if (targetURL
.getLength() > 0)
1867 if (nSlot
== SID_OPEN_HYPERLINK
)
1869 ::LoadURL(rWrtSh
, targetURL
, LoadUrlFlags::NewView
, /*rTargetFrameName=*/OUString());
1871 else if (nSlot
== SID_COPY_HYPERLINK_LOCATION
)
1873 ::uno::Reference
< datatransfer::clipboard::XClipboard
> xClipboard
= GetView().GetEditWin().GetClipboard();
1874 vcl::unohelper::TextDataObject::CopyStringTo(targetURL
, xClipboard
, SfxViewShell::Current());
1881 case FN_OPEN_LOCAL_URL
:
1883 OUString aLocalURL
= GetLocalURL(rWrtSh
);
1884 if (!aLocalURL
.isEmpty())
1886 ::LoadURL(rWrtSh
, aLocalURL
, LoadUrlFlags::NewView
, /*rTargetFrameName=*/OUString());
1890 case SID_OPEN_XML_FILTERSETTINGS
:
1892 HandleOpenXmlFilterSettings(rReq
);
1895 case FN_FORMAT_APPLY_HEAD1
:
1899 case FN_FORMAT_APPLY_HEAD2
:
1903 case FN_FORMAT_APPLY_HEAD3
:
1907 case FN_FORMAT_APPLY_DEFAULT
:
1911 case FN_FORMAT_APPLY_TEXTBODY
:
1915 case FN_WORDCOUNT_DIALOG
:
1917 GetView().UpdateWordCount(this, nSlot
);
1920 case FN_PROTECT_FIELDS
:
1921 case FN_PROTECT_BOOKMARKS
:
1923 IDocumentSettingAccess
& rIDSA
= rWrtSh
.getIDocumentSettingAccess();
1924 DocumentSettingId aSettingId
= nSlot
== FN_PROTECT_FIELDS
1925 ? DocumentSettingId::PROTECT_FIELDS
1926 : DocumentSettingId::PROTECT_BOOKMARKS
;
1927 rIDSA
.set(aSettingId
, !rIDSA
.get(aSettingId
));
1928 // Invalidate so that toggle state gets updated
1929 SfxViewFrame
& rViewFrame
= GetView().GetViewFrame();
1930 rViewFrame
.GetBindings().Invalidate(nSlot
);
1931 rViewFrame
.GetBindings().Update(nSlot
);
1934 case SID_FM_CTL_PROPERTIES
:
1936 SwPosition
aPos(*GetShell().GetCursor()->GetPoint());
1937 sw::mark::IFieldmark
* pFieldBM
= GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos
);
1940 aPos
.AdjustContent(-1);
1941 pFieldBM
= GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos
);
1944 if ( pFieldBM
&& pFieldBM
->GetFieldname() == ODF_FORMDROPDOWN
1945 && !(rWrtSh
.GetCurrSection() && rWrtSh
.GetCurrSection()->IsProtect()) )
1947 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
1948 ScopedVclPtr
<VclAbstractDialog
> pDlg(pFact
->CreateDropDownFormFieldDialog(rWrtSh
.GetView().GetFrameWeld(), pFieldBM
));
1949 if (pDlg
->Execute() == RET_OK
)
1951 pFieldBM
->Invalidate();
1952 rWrtSh
.InvalidateWindows( SwRect(rWrtSh
.GetView().GetVisArea()) );
1953 rWrtSh
.UpdateCursor(); // cursor position might be invalid
1956 else if ( pFieldBM
&& pFieldBM
->GetFieldname() == ODF_FORMDATE
)
1958 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
1959 sw::mark::DateFieldmark
& rDateField
= dynamic_cast<sw::mark::DateFieldmark
&>(*pFieldBM
);
1960 ScopedVclPtr
<VclAbstractDialog
> pDlg(pFact
->CreateDateFormFieldDialog(rWrtSh
.GetView().GetFrameWeld(), &rDateField
, *GetView().GetDocShell()->GetDoc()));
1961 if (pDlg
->Execute() == RET_OK
)
1963 rDateField
.Invalidate();
1964 rWrtSh
.InvalidateWindows( SwRect(rWrtSh
.GetView().GetVisArea()) );
1965 rWrtSh
.UpdateCursor(); // cursor position might be invalid
1970 SfxRequest
aReq(GetView().GetViewFrame(), SID_FM_CTL_PROPERTIES
);
1971 aReq
.AppendItem( SfxBoolItem( SID_FM_CTL_PROPERTIES
, true ) );
1972 rWrtSh
.GetView().GetFormShell()->Execute( aReq
);
1976 case SID_FM_TRANSLATE
:
1978 #if !ENABLE_WASM_STRIP_EXTRA
1979 const SfxPoolItem
* pTargetLangStringItem
= nullptr;
1980 if (pArgs
&& SfxItemState::SET
== pArgs
->GetItemState(SID_ATTR_TARGETLANG_STR
, false, &pTargetLangStringItem
))
1982 std::optional
<OUString
> oDeeplAPIUrl
= officecfg::Office::Linguistic::Translation::Deepl::ApiURL::get();
1983 std::optional
<OUString
> oDeeplKey
= officecfg::Office::Linguistic::Translation::Deepl::AuthKey::get();
1984 if (!oDeeplAPIUrl
|| oDeeplAPIUrl
->isEmpty() || !oDeeplKey
|| oDeeplKey
->isEmpty())
1986 SAL_WARN("sw.ui", "SID_FM_TRANSLATE: API options are not set");
1989 const OString aAPIUrl
= OUStringToOString(rtl::Concat2View(*oDeeplAPIUrl
+ "?tag_handling=html"), RTL_TEXTENCODING_UTF8
).trim();
1990 const OString aAuthKey
= OUStringToOString(*oDeeplKey
, RTL_TEXTENCODING_UTF8
).trim();
1991 OString aTargetLang
= OUStringToOString(static_cast<const SfxStringItem
*>(pTargetLangStringItem
)->GetValue(), RTL_TEXTENCODING_UTF8
);
1992 SwTranslateHelper::TranslateAPIConfig
aConfig({aAPIUrl
, aAuthKey
, aTargetLang
});
1993 SwTranslateHelper::TranslateDocument(rWrtSh
, aConfig
);
1997 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
1998 std::shared_ptr
<AbstractSwTranslateLangSelectDlg
> pAbstractDialog(pFact
->CreateSwTranslateLangSelectDlg(GetView().GetFrameWeld(), rWrtSh
));
1999 std::shared_ptr
<weld::DialogController
> pDialogController(pAbstractDialog
->getDialogController());
2000 weld::DialogController::runAsync(pDialogController
, [] (sal_Int32
/*nResult*/) { });
2002 #endif // ENABLE_WASM_STRIP_EXTRA
2005 case SID_SPELLCHECK_IGNORE
:
2007 SwPaM
*pPaM
= rWrtSh
.GetCursor();
2009 SwEditShell::IgnoreGrammarErrorAt( *pPaM
);
2012 case SID_SPELLCHECK_IGNORE_ALL
:
2014 OUString sApplyText
;
2015 const SfxStringItem
* pItem2
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
2017 sApplyText
= pItem2
->GetValue();
2019 if(sApplyText
== "Grammar")
2021 linguistic2::ProofreadingResult aGrammarCheckRes
;
2022 sal_Int32 nErrorInResult
= -1;
2023 uno::Sequence
< OUString
> aSuggestions
;
2024 sal_Int32 nErrorPosInText
= -1;
2026 bool bCorrectionRes
= rWrtSh
.GetGrammarCorrection( aGrammarCheckRes
, nErrorPosInText
, nErrorInResult
, aSuggestions
, nullptr, aToFill
);
2030 uno::Reference
< linguistic2::XDictionary
> xDictionary
= LinguMgr::GetIgnoreAllList();
2031 aGrammarCheckRes
.xProofreader
->ignoreRule(
2032 aGrammarCheckRes
.aErrors
[ nErrorInResult
].aRuleIdentifier
,
2033 aGrammarCheckRes
.aLocale
);
2034 // refresh the layout of the actual paragraph (faster)
2035 SwPaM
*pPaM
= rWrtSh
.GetCursor();
2037 SwEditShell::IgnoreGrammarErrorAt( *pPaM
);
2038 if (xDictionary
.is())
2040 // refresh the layout of all paragraphs (workaround to launch a dictionary event)
2041 xDictionary
->setActive(false);
2042 xDictionary
->setActive(true);
2045 catch( const uno::Exception
& )
2050 else if (sApplyText
== "Spelling")
2053 uno::Reference
<linguistic2::XSpellAlternatives
> xSpellAlt(rWrtSh
.GetCorrection(nullptr, aToFill
));
2054 if (!xSpellAlt
.is())
2056 uno::Reference
< linguistic2::XDictionary
> xDictionary
= LinguMgr::GetIgnoreAllList();
2057 OUString
sWord(xSpellAlt
->getWord());
2058 linguistic::DictionaryError nAddRes
= linguistic::AddEntryToDic( xDictionary
,
2059 sWord
, false, OUString() );
2060 if (linguistic::DictionaryError::NONE
!= nAddRes
&& xDictionary
.is() && !xDictionary
->getEntry(sWord
).is())
2062 SvxDicError(rWrtSh
.GetView().GetFrameWeld(), nAddRes
);
2067 case SID_SPELLCHECK_APPLY_SUGGESTION
:
2069 OUString sApplyText
;
2070 const SfxStringItem
* pItem2
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
2072 sApplyText
= pItem2
->GetValue();
2074 static const OUStringLiteral
sSpellingRule(u
"Spelling_");
2075 static const OUStringLiteral
sGrammarRule(u
"Grammar_");
2077 bool bGrammar
= false;
2079 uno::Reference
< linguistic2::XSpellAlternatives
> xSpellAlt
;
2080 if(-1 != (nPos
= sApplyText
.indexOf( sGrammarRule
)))
2082 sApplyText
= sApplyText
.replaceAt(nPos
, sGrammarRule
.getLength(), u
"");
2085 else if (-1 != (nPos
= sApplyText
.indexOf( sSpellingRule
)))
2087 sApplyText
= sApplyText
.replaceAt(nPos
, sSpellingRule
.getLength(), u
"");
2089 xSpellAlt
.set(rWrtSh
.GetCorrection(nullptr, aToFill
));
2093 if (!bGrammar
&& !xSpellAlt
.is())
2096 bool bOldIns
= rWrtSh
.IsInsMode();
2097 rWrtSh
.SetInsMode();
2099 OUString
aTmp( sApplyText
);
2100 OUString
aOrig( bGrammar
? OUString() : xSpellAlt
->getWord() );
2102 // if original word has a trailing . (likely the end of a sentence)
2103 // and the replacement text hasn't, then add it to the replacement
2104 if (!aTmp
.isEmpty() && !aOrig
.isEmpty() &&
2105 aOrig
.endsWith(".") && /* !IsAlphaNumeric ??*/
2106 !aTmp
.endsWith("."))
2111 SwRewriter aRewriter
;
2113 aRewriter
.AddRule(UndoArg1
, rWrtSh
.GetCursorDescr()
2114 // don't show the hidden control character of the comment
2115 .replaceAll(OUStringChar(CH_TXTATR_INWORD
), "") );
2116 aRewriter
.AddRule(UndoArg2
, SwResId(STR_YIELDS
));
2118 OUString aTmpStr
= SwResId(STR_START_QUOTE
) +
2119 aTmp
+ SwResId(STR_END_QUOTE
);
2120 aRewriter
.AddRule(UndoArg3
, aTmpStr
);
2122 rWrtSh
.StartUndo(SwUndoId::UI_REPLACE
, &aRewriter
);
2123 rWrtSh
.StartAction();
2125 // if there is a comment inside the original word, don't delete it:
2126 // but keep it at the end of the replacement
2127 // TODO: keep all the comments with a recursive function
2129 if (SwPaM
*pPaM
= rWrtSh
.GetCursor())
2131 sal_Int32
nCommentPos(pPaM
->GetText().indexOf(OUStringChar(CH_TXTATR_INWORD
)));
2132 if ( nCommentPos
> -1 )
2135 // delete the original word after the comment
2136 pPaM
->GetPoint()->AdjustContent(nCommentPos
+ 1);
2137 rWrtSh
.Replace(OUString(), false);
2138 // and select only the remaining part before the comment
2139 pPaM
->GetPoint()->AdjustContent(-(nCommentPos
+ 1));
2140 pPaM
->GetMark()->AdjustContent(-1);
2144 rWrtSh
.Replace(aTmp
, false);
2149 rWrtSh
.SetInsMode( bOldIns
);
2153 OSL_ENSURE(false, "wrong dispatcher");
2158 void SwTextShell::GetState( SfxItemSet
&rSet
)
2160 SwWrtShell
&rSh
= GetShell();
2161 SfxWhichIter
aIter( rSet
);
2162 sal_uInt16 nWhich
= aIter
.FirstWhich();
2167 case FN_FORMAT_CURRENT_FOOTNOTE_DLG
:
2168 if( !rSh
.IsCursorInFootnote() )
2169 rSet
.DisableItem( nWhich
);
2172 case SID_LANGUAGE_STATUS
:
2174 // the value of used script types
2175 OUString
aScriptTypesInUse( OUString::number( static_cast<int>(rSh
.GetScriptType()) ) );
2177 // get keyboard language
2178 OUString aKeyboardLang
;
2179 SwEditWin
& rEditWin
= GetView().GetEditWin();
2180 LanguageType nLang
= rEditWin
.GetInputLanguage();
2181 if (nLang
!= LANGUAGE_DONTKNOW
&& nLang
!= LANGUAGE_SYSTEM
)
2182 aKeyboardLang
= SvtLanguageTable::GetLanguageString( nLang
);
2184 // get the language that is in use
2185 OUString aCurrentLang
= "*";
2186 nLang
= SwLangHelper::GetCurrentLanguage( rSh
);
2187 if (nLang
!= LANGUAGE_DONTKNOW
)
2189 aCurrentLang
= SvtLanguageTable::GetLanguageString( nLang
);
2190 if (comphelper::LibreOfficeKit::isActive())
2192 if (nLang
== LANGUAGE_NONE
)
2194 aCurrentLang
+= ";-";
2198 aCurrentLang
+= ";" + LanguageTag(nLang
).getBcp47(false);
2203 // build sequence for status value
2204 uno::Sequence
< OUString
> aSeq
{ aCurrentLang
,
2207 SwLangHelper::GetTextForLanguageGuessing( rSh
) };
2209 // set sequence as status value
2210 SfxStringListItem
aItem( SID_LANGUAGE_STATUS
);
2211 aItem
.SetStringList( aSeq
);
2218 // is there a valid selection to get text from?
2220 bool bValid
= !rSh
.HasSelection() ||
2221 (rSh
.IsSelOnePara() && !rSh
.IsMultiSelection());
2222 // prevent context menu from showing when cursor is not in or at the end of a word
2223 // (GetCurWord will return the next word if there is none at the current position...)
2224 const sal_Int16 nWordType
= ::i18n::WordType::DICTIONARY_WORD
;
2225 bool bWord
= rSh
.IsInWord( nWordType
) || rSh
.IsStartWord( nWordType
) || rSh
.IsEndWord( nWordType
);
2226 if (bValid
&& bWord
)
2227 aText
= rSh
.HasSelection()? rSh
.GetSelText() : rSh
.GetCurWord();
2229 LanguageType nLang
= rSh
.GetCurLang();
2230 LanguageTag
aLanguageTag( nLang
);
2231 const lang::Locale
& aLocale( aLanguageTag
.getLocale());
2233 // disable "Thesaurus" context menu entry if there is nothing to look up
2234 uno::Reference
< linguistic2::XThesaurus
> xThes( ::GetThesaurus() );
2235 if (aText
.isEmpty() ||
2236 !xThes
.is() || nLang
== LANGUAGE_NONE
|| !xThes
->hasLocale( aLocale
))
2237 rSet
.DisableItem( SID_THES
);
2240 // set word and locale to look up as status value
2241 OUString aStatusVal
= aText
+ "#" + aLanguageTag
.getBcp47();
2242 rSet
.Put( SfxStringItem( SID_THES
, aStatusVal
) );
2247 case FN_NUMBER_NEWSTART
:
2248 if(!rSh
.GetNumRuleAtCurrCursorPos())
2249 rSet
.DisableItem(nWhich
);
2251 rSet
.Put(SfxBoolItem(FN_NUMBER_NEWSTART
,
2252 rSh
.IsNumRuleStart()));
2255 case FN_EDIT_FORMULA
:
2257 case SID_CHARMAP_CONTROL
:
2259 const SelectionType nType
= rSh
.GetSelectionType();
2260 if (!(nType
& SelectionType::Text
) &&
2261 !(nType
& SelectionType::Table
) &&
2262 !(nType
& SelectionType::NumberList
))
2264 rSet
.DisableItem(nWhich
);
2266 else if ( nWhich
== FN_EDIT_FORMULA
2267 && rSh
.CursorInsideInputField() )
2269 rSet
.DisableItem( nWhich
);
2274 case FN_INSERT_ENDNOTE
:
2275 case FN_INSERT_FOOTNOTE
:
2276 case FN_INSERT_FOOTNOTE_DLG
:
2278 const FrameTypeFlags nNoType
=
2279 FrameTypeFlags::FLY_ANY
| FrameTypeFlags::HEADER
| FrameTypeFlags::FOOTER
| FrameTypeFlags::FOOTNOTE
;
2280 if ( rSh
.GetFrameType(nullptr,true) & nNoType
)
2281 rSet
.DisableItem(nWhich
);
2283 if ( rSh
.CursorInsideInputField() )
2285 rSet
.DisableItem( nWhich
);
2290 case FN_INSERT_HYPERLINK
:
2292 case FN_INSERT_GLOSSARY
:
2293 case FN_EXPAND_GLOSSARY
:
2294 if ( rSh
.CursorInsideInputField() )
2296 rSet
.DisableItem( nWhich
);
2300 case FN_INSERT_TABLE
:
2301 if ( rSh
.CursorInsideInputField()
2302 || rSh
.GetTableFormat()
2303 || (rSh
.GetFrameType(nullptr,true) & FrameTypeFlags::FOOTNOTE
) )
2305 rSet
.DisableItem( nWhich
);
2310 if ( !rSh
.IsSelection() )
2311 rSet
.DisableItem(nWhich
);
2313 case FN_GOTO_REFERENCE
:
2315 SwField
*pField
= rSh
.GetCurField();
2316 if ( !pField
|| (pField
->GetTypeId() != SwFieldTypesEnum::GetRef
) )
2317 rSet
.DisableItem(nWhich
);
2320 case FN_AUTOFORMAT_AUTO
:
2322 rSet
.Put( SfxBoolItem( nWhich
, SvxAutoCorrCfg::Get().IsAutoFormatByInput() ));
2326 case SID_DEC_INDENT
:
2327 case SID_INC_INDENT
:
2329 //if the paragraph has bullet we'll do the following things:
2330 //1: if the bullet level is the first level, disable the decrease-indent button
2331 //2: if the bullet level is the last level, disable the increase-indent button
2332 if ( rSh
.GetNumRuleAtCurrCursorPos() && !rSh
.HasReadonlySel() )
2334 const sal_uInt8 nLevel
= rSh
.GetNumLevel();
2335 if ( ( nLevel
== ( MAXLEVEL
- 1 ) && nWhich
== SID_INC_INDENT
)
2336 || ( nLevel
== 0 && nWhich
== SID_DEC_INDENT
) )
2338 rSet
.DisableItem( nWhich
);
2343 sal_uInt16 nHtmlMode
= ::GetHtmlMode( GetView().GetDocShell() );
2344 nHtmlMode
&= HTMLMODE_ON
| HTMLMODE_SOME_STYLES
;
2345 if ( ( nHtmlMode
== HTMLMODE_ON
)
2346 || !rSh
.IsMoveLeftMargin( SID_INC_INDENT
== nWhich
) )
2348 rSet
.DisableItem( nWhich
);
2354 case FN_DEC_INDENT_OFFSET
:
2355 case FN_INC_INDENT_OFFSET
:
2357 sal_uInt16 nHtmlMode
= ::GetHtmlMode(GetView().GetDocShell());
2358 nHtmlMode
&= HTMLMODE_ON
|HTMLMODE_SOME_STYLES
;
2359 if( (nHtmlMode
== HTMLMODE_ON
) ||
2360 !rSh
.IsMoveLeftMargin( FN_INC_INDENT_OFFSET
== nWhich
,
2362 rSet
.DisableItem( nWhich
);
2366 case SID_ATTR_CHAR_COLOR2
:
2368 SfxItemSet
aSet( GetPool() );
2369 rSh
.GetCurAttr( aSet
);
2370 const SvxColorItem
& aColorItem
= aSet
.Get(RES_CHRATR_COLOR
);
2371 rSet
.Put( aColorItem
.CloneSetWhich(SID_ATTR_CHAR_COLOR2
) );
2374 case SID_ATTR_CHAR_BACK_COLOR
:
2375 case SID_ATTR_CHAR_COLOR_BACKGROUND
:
2377 // Always use the visible background
2378 SfxItemSet
aSet( GetPool() );
2379 rSh
.GetCurAttr( aSet
);
2380 const SvxBrushItem
& aBrushItem
= aSet
.Get(RES_CHRATR_HIGHLIGHT
);
2381 if( aBrushItem
.GetColor() != COL_TRANSPARENT
)
2383 rSet
.Put(SvxColorItem(aBrushItem
.GetColor(), aBrushItem
.getComplexColor(), nWhich
));
2387 const SvxBrushItem
& aBrushItem2
= aSet
.Get(RES_CHRATR_BACKGROUND
);
2388 rSet
.Put(SvxColorItem(aBrushItem2
.GetColor(), aBrushItem2
.getComplexColor(), nWhich
));
2392 case SID_ATTR_CHAR_COLOR_BACKGROUND_EXT
:
2394 SwEditWin
& rEdtWin
= GetView().GetEditWin();
2395 SwApplyTemplate
* pApply
= rEdtWin
.GetApplyTemplate();
2396 const sal_uInt32 nColWhich
= pApply
? pApply
->nColor
: 0;
2397 const bool bUseTemplate
= nColWhich
== SID_ATTR_CHAR_BACK_COLOR
2398 || nColWhich
== SID_ATTR_CHAR_COLOR_BACKGROUND
;
2399 rSet
.Put(SfxBoolItem(nWhich
, bUseTemplate
));
2402 case SID_ATTR_CHAR_COLOR_EXT
:
2404 SwEditWin
& rEdtWin
= GetView().GetEditWin();
2405 SwApplyTemplate
* pApply
= rEdtWin
.GetApplyTemplate();
2406 rSet
.Put(SfxBoolItem(nWhich
, pApply
&& pApply
->nColor
== nWhich
));
2409 case FN_SET_REMINDER
:
2410 case FN_INSERT_BOOKMARK
:
2411 if( rSh
.IsTableMode()
2412 || rSh
.CursorInsideInputField() )
2414 rSet
.DisableItem( nWhich
);
2418 case FN_INSERT_BREAK
:
2419 if ( rSh
.HasReadonlySel()
2420 && !rSh
.CursorInsideInputField() )
2422 rSet
.DisableItem( nWhich
);
2426 case FN_INSERT_BREAK_DLG
:
2427 case FN_INSERT_COLUMN_BREAK
:
2428 case FN_INSERT_PAGEBREAK
:
2429 if( rSh
.CursorInsideInputField() || rSh
.CursorInsideContentControl() )
2431 rSet
.DisableItem( nWhich
);
2435 case FN_INSERT_PAGEHEADER
:
2436 case FN_INSERT_PAGEFOOTER
:
2437 if (comphelper::LibreOfficeKit::isActive())
2439 bool bState
= false;
2440 bool bAllState
= true;
2441 bool bIsPhysical
= false;
2443 OUString aStyleName
;
2444 std::vector
<OUString
> aList
;
2445 static const OUStringLiteral
sPhysical(u
"IsPhysical");
2446 static const OUStringLiteral
sDisplay(u
"DisplayName");
2447 const OUString
sHeaderOn(nWhich
== FN_INSERT_PAGEHEADER
? OUString("HeaderIsOn") : OUString("FooterIsOn"));
2449 uno::Reference
< XStyleFamiliesSupplier
> xSupplier(GetView().GetDocShell()->GetBaseModel(), uno::UNO_QUERY
);
2452 uno::Reference
< XNameContainer
> xContainer
;
2453 uno::Reference
< XNameAccess
> xFamilies
= xSupplier
->getStyleFamilies();
2454 if (xFamilies
->getByName("PageStyles") >>= xContainer
)
2456 const uno::Sequence
< OUString
> aSeqNames
= xContainer
->getElementNames();
2457 for (const auto& rName
: aSeqNames
)
2460 uno::Reference
<XPropertySet
> xPropSet(xContainer
->getByName(aStyleName
), uno::UNO_QUERY
);
2461 if (xPropSet
.is() && (xPropSet
->getPropertyValue(sPhysical
) >>= bIsPhysical
) && bIsPhysical
)
2463 xPropSet
->getPropertyValue(sDisplay
) >>= aStyleName
;
2464 if ((xPropSet
->getPropertyValue(sHeaderOn
)>>= bState
) && bState
)
2465 aList
.push_back(aStyleName
);
2469 // Check if all entries have the same state
2470 bAllState
&= bState
;
2473 bIsPhysical
= false;
2478 if (bAllState
&& aList
.size() > 1)
2479 aList
.push_back("_ALL_");
2481 rSet
.Put(SfxStringListItem(nWhich
, &aList
));
2485 rSet
.Put( SfxObjectShellItem( nWhich
, GetView().GetDocShell() ));
2488 case FN_TABLE_SORT_DIALOG
:
2489 case FN_SORTING_DLG
:
2490 if(!rSh
.HasSelection() ||
2491 (FN_TABLE_SORT_DIALOG
== nWhich
&& !rSh
.GetTableFormat()))
2492 rSet
.DisableItem( nWhich
);
2495 case SID_RUBY_DIALOG
:
2497 if( !SvtCJKOptions::IsRubyEnabled()
2498 || rSh
.CursorInsideInputField() )
2500 GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich
, false );
2501 rSet
.DisableItem(nWhich
);
2504 GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich
, true );
2508 case SID_FM_TRANSLATE
:
2510 #if !ENABLE_WASM_STRIP_EXTRA
2511 if (!officecfg::Office::Common::Misc::ExperimentalMode::get()
2512 && !comphelper::LibreOfficeKit::isActive())
2514 rSet
.Put(SfxVisibilityItem(nWhich
, false));
2517 std::optional
<OUString
> oDeeplAPIUrl
= officecfg::Office::Linguistic::Translation::Deepl::ApiURL::get();
2518 std::optional
<OUString
> oDeeplKey
= officecfg::Office::Linguistic::Translation::Deepl::AuthKey::get();
2519 if (!oDeeplAPIUrl
|| oDeeplAPIUrl
->isEmpty() || !oDeeplKey
|| oDeeplKey
->isEmpty())
2521 rSet
.DisableItem(nWhich
);
2527 case SID_HYPERLINK_DIALOG
:
2528 if( GetView().GetDocShell()->IsReadOnly()
2529 || ( !GetView().GetViewFrame().HasChildWindow(nWhich
)
2530 && rSh
.HasReadonlySel() )
2531 || rSh
.CursorInsideInputField() )
2533 rSet
.DisableItem(nWhich
);
2537 rSet
.Put(SfxBoolItem( nWhich
, nullptr != GetView().GetViewFrame().GetChildWindow( nWhich
) ));
2541 case SID_EDIT_HYPERLINK
:
2543 SfxItemSetFixed
<RES_TXTATR_INETFMT
, RES_TXTATR_INETFMT
> aSet(GetPool());
2544 rSh
.GetCurAttr(aSet
);
2545 if(SfxItemState::SET
> aSet
.GetItemState( RES_TXTATR_INETFMT
) || rSh
.HasReadonlySel())
2547 rSet
.DisableItem(nWhich
);
2551 case SID_REMOVE_HYPERLINK
:
2553 SfxItemSetFixed
<RES_TXTATR_INETFMT
, RES_TXTATR_INETFMT
> aSet(GetPool());
2554 rSh
.GetCurAttr(aSet
);
2556 // If a hyperlink is selected, either alone or along with other text...
2557 if ((aSet
.GetItemState(RES_TXTATR_INETFMT
) < SfxItemState::SET
&&
2558 aSet
.GetItemState(RES_TXTATR_INETFMT
) != SfxItemState::DONTCARE
) ||
2559 rSh
.HasReadonlySel())
2561 rSet
.DisableItem(nWhich
);
2565 case SID_TRANSLITERATE_HALFWIDTH
:
2566 case SID_TRANSLITERATE_FULLWIDTH
:
2567 case SID_TRANSLITERATE_HIRAGANA
:
2568 case SID_TRANSLITERATE_KATAKANA
:
2570 if(!SvtCJKOptions::IsChangeCaseMapEnabled())
2572 GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich
, false );
2573 rSet
.DisableItem(nWhich
);
2576 GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich
, true );
2579 case FN_READONLY_SELECTION_MODE
:
2580 if(!GetView().GetDocShell()->IsReadOnly())
2581 rSet
.DisableItem( nWhich
);
2584 rSet
.Put(SfxBoolItem(nWhich
, rSh
.GetViewOptions()->IsSelectionInReadonly()));
2587 case FN_SELECTION_MODE_DEFAULT
:
2588 case FN_SELECTION_MODE_BLOCK
:
2589 rSet
.Put(SfxBoolItem(nWhich
, (nWhich
== FN_SELECTION_MODE_DEFAULT
) != rSh
.IsBlockMode()));
2591 case SID_COPY_HYPERLINK_LOCATION
:
2592 case SID_OPEN_HYPERLINK
:
2594 SfxItemSetFixed
<RES_TXTATR_INETFMT
, RES_TXTATR_INETFMT
> aSet(GetPool());
2595 rSh
.GetCurAttr(aSet
);
2597 bool bAuthorityFieldURL
= false;
2598 SwField
* pField
= rSh
.GetCurField();
2599 if (pField
&& pField
->GetTyp()->Which() == SwFieldIds::TableOfAuthorities
)
2601 const auto& rAuthorityField
= *static_cast<const SwAuthorityField
*>(pField
);
2602 if (auto targetType
= rAuthorityField
.GetTargetType();
2603 targetType
== SwAuthorityField::TargetType::UseDisplayURL
2604 || targetType
== SwAuthorityField::TargetType::UseTargetURL
)
2606 // Check if the Bibliography entry has a target URL
2607 bAuthorityFieldURL
= rAuthorityField
.GetAbsoluteURL().getLength() > 0;
2610 if (SfxItemState::SET
> aSet
.GetItemState(RES_TXTATR_INETFMT
, false)
2611 && !bAuthorityFieldURL
)
2612 rSet
.DisableItem(nWhich
);
2615 case FN_OPEN_LOCAL_URL
:
2617 if (GetLocalURL(rSh
).isEmpty())
2619 rSet
.DisableItem(nWhich
);
2623 case SID_OPEN_SMARTTAGMENU
:
2625 std::vector
< OUString
> aSmartTagTypes
;
2626 uno::Sequence
< uno::Reference
< container::XStringKeyMap
> > aStringKeyMaps
;
2627 uno::Reference
<text::XTextRange
> xRange
;
2629 rSh
.GetSmartTagTerm( aSmartTagTypes
, aStringKeyMaps
, xRange
);
2631 if ( xRange
.is() && !aSmartTagTypes
.empty() )
2633 uno::Sequence
< uno::Sequence
< uno::Reference
< smarttags::XSmartTagAction
> > > aActionComponentsSequence
;
2634 uno::Sequence
< uno::Sequence
< sal_Int32
> > aActionIndicesSequence
;
2636 const SmartTagMgr
& rSmartTagMgr
= SwSmartTagMgr::Get();
2637 rSmartTagMgr
.GetActionSequences( aSmartTagTypes
,
2638 aActionComponentsSequence
,
2639 aActionIndicesSequence
);
2641 uno::Reference
<frame::XController
> xController
= GetView().GetController();
2642 lang::Locale
aLocale( SW_BREAKITER()->GetLocale( GetAppLanguageTag() ) );
2643 const OUString
& aApplicationName( rSmartTagMgr
.GetApplicationName() );
2644 const OUString aRangeText
= xRange
->getString();
2646 const SvxSmartTagItem
aItem( SID_OPEN_SMARTTAGMENU
,
2647 aActionComponentsSequence
,
2648 aActionIndicesSequence
,
2659 rSet
.DisableItem(nWhich
);
2663 case FN_NUM_NUMBERING_ON
:
2664 rSet
.Put(SfxBoolItem(FN_NUM_NUMBERING_ON
,rSh
.SelectionHasNumber()));
2667 case FN_NUM_BULLET_ON
:
2668 rSet
.Put(SfxBoolItem(FN_NUM_BULLET_ON
,rSh
.SelectionHasBullet()));
2671 case FN_NUM_BULLET_OFF
:
2672 rSet
.Put(SfxBoolItem(FN_NUM_BULLET_OFF
, !rSh
.GetNumRuleAtCurrCursorPos() &&
2673 !rSh
.GetNumRuleAtCurrentSelection()));
2676 case FN_SVX_SET_OUTLINE
:
2678 NBOTypeMgrBase
* pOutline
= NBOutlineTypeMgrFact::CreateInstance(NBOType::Outline
);
2679 auto pCurRule
= const_cast<SwNumRule
*>(rSh
.GetNumRuleAtCurrCursorPos());
2680 if (pOutline
&& pCurRule
)
2682 SvxNumRule aSvxRule
= pCurRule
->MakeSvxNumRule();
2683 const sal_uInt16 nIndex
= pOutline
->GetNBOIndexForNumRule(aSvxRule
, 0);
2684 rSet
.Put(SfxBoolItem(FN_SVX_SET_OUTLINE
, nIndex
< USHRT_MAX
));
2688 case FN_BUL_NUM_RULE_INDEX
:
2689 case FN_NUM_NUM_RULE_INDEX
:
2690 case FN_OUTLINE_RULE_INDEX
:
2692 SwNumRule
* pCurRule
= const_cast<SwNumRule
*>(GetShell().GetNumRuleAtCurrCursorPos());
2695 sal_uInt16 nActNumLvl
= GetShell().GetNumLevel();
2696 if( nActNumLvl
< MAXLEVEL
)
2698 nActNumLvl
= 1<<nActNumLvl
;
2700 SvxNumRule aSvxRule
= pCurRule
->MakeSvxNumRule();
2701 if ( GetShell().HasBullet())
2703 rSet
.Put(SfxUInt16Item(FN_BUL_NUM_RULE_INDEX
, USHRT_MAX
));
2704 rSet
.Put(SfxUInt16Item(FN_NUM_NUM_RULE_INDEX
, USHRT_MAX
));
2705 NBOTypeMgrBase
* pBullets
= NBOutlineTypeMgrFact::CreateInstance(NBOType::Bullets
);
2708 const sal_uInt16 nBulIndex
= pBullets
->GetNBOIndexForNumRule(aSvxRule
,nActNumLvl
);
2709 rSet
.Put(SfxUInt16Item(FN_BUL_NUM_RULE_INDEX
,nBulIndex
));
2711 }else if ( GetShell().HasNumber() )
2713 rSet
.Put(SfxUInt16Item(FN_BUL_NUM_RULE_INDEX
, USHRT_MAX
));
2714 rSet
.Put(SfxUInt16Item(FN_NUM_NUM_RULE_INDEX
, USHRT_MAX
));
2715 NBOTypeMgrBase
* pNumbering
= NBOutlineTypeMgrFact::CreateInstance(NBOType::Numbering
);
2718 const sal_uInt16 nBulIndex
= pNumbering
->GetNBOIndexForNumRule(aSvxRule
,nActNumLvl
);
2719 rSet
.Put(SfxUInt16Item(FN_NUM_NUM_RULE_INDEX
,nBulIndex
));
2723 if ( nWhich
== FN_OUTLINE_RULE_INDEX
)
2725 rSet
.Put(SfxUInt16Item(FN_OUTLINE_RULE_INDEX
, USHRT_MAX
));
2726 NBOTypeMgrBase
* pOutline
= NBOutlineTypeMgrFact::CreateInstance(NBOType::Outline
);
2729 const sal_uInt16 nIndex
= pOutline
->GetNBOIndexForNumRule(aSvxRule
,nActNumLvl
);
2730 rSet
.Put(SfxUInt16Item(FN_OUTLINE_RULE_INDEX
,nIndex
));
2736 case FN_NUM_CONTINUE
:
2739 // Search also for bullet list
2741 const SwNumRule
* pRule
=
2742 rSh
.SearchNumRule( true, aDummy
);
2745 pRule
= rSh
.SearchNumRule( false, aDummy
);
2748 rSet
.DisableItem(nWhich
);
2751 case SID_INSERT_RLM
:
2752 case SID_INSERT_LRM
:
2754 bool bEnabled
= SvtCTLOptions::IsCTLFontEnabled();
2755 GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich
, bEnabled
);
2757 rSet
.DisableItem(nWhich
);
2760 case SID_FM_CTL_PROPERTIES
:
2762 bool bDisable
= false;
2764 // First get the state from the form shell
2765 SfxItemSetFixed
<SID_FM_CTL_PROPERTIES
, SID_FM_CTL_PROPERTIES
> aSet(GetShell().GetAttrPool());
2766 aSet
.Put(SfxBoolItem( SID_FM_CTL_PROPERTIES
, true ));
2767 GetShell().GetView().GetFormShell()->GetState( aSet
);
2769 if(SfxItemState::DISABLED
== aSet
.GetItemState(SID_FM_CTL_PROPERTIES
))
2774 // Enable it if we have a valid object other than what form shell knows
2775 SwPosition
aPos(*GetShell().GetCursor()->GetPoint());
2776 sw::mark::IFieldmark
* pFieldBM
= GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos
);
2777 if ( !pFieldBM
&& aPos
.GetContentIndex() > 0)
2779 aPos
.AdjustContent(-1);
2780 pFieldBM
= GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos
);
2782 if ( pFieldBM
&& (pFieldBM
->GetFieldname() == ODF_FORMDROPDOWN
|| pFieldBM
->GetFieldname() == ODF_FORMDATE
) )
2788 rSet
.DisableItem(nWhich
);
2794 if (GetObjectShell()->isContentExtractionLocked())
2795 rSet
.DisableItem(nWhich
);
2798 case FN_PROTECT_FIELDS
:
2799 case FN_PROTECT_BOOKMARKS
:
2801 DocumentSettingId aSettingId
= nWhich
== FN_PROTECT_FIELDS
2802 ? DocumentSettingId::PROTECT_FIELDS
2803 : DocumentSettingId::PROTECT_BOOKMARKS
;
2804 bool bProtected
= rSh
.getIDocumentSettingAccess().get(aSettingId
);
2805 rSet
.Put(SfxBoolItem(nWhich
, bProtected
));
2808 case FN_CONTENT_CONTROL_PROPERTIES
:
2810 if (!GetShell().CursorInsideContentControl())
2812 rSet
.DisableItem(nWhich
);
2817 nWhich
= aIter
.NextWhich();
2821 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */