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/beans/PropertyValues.hpp>
21 #include <AnnotationWin.hxx>
22 #include <comphelper/lok.hxx>
23 #include <hintids.hxx>
24 #include <IDocumentFieldsAccess.hxx>
25 #include <sfx2/bindings.hxx>
26 #include <sfx2/lnkbase.hxx>
28 #include <svl/itempool.hxx>
29 #include <svl/numformat.hxx>
30 #include <editeng/editobj.hxx>
31 #include <tools/lineend.hxx>
32 #include <svl/whiter.hxx>
33 #include <svl/eitem.hxx>
34 #include <svl/macitem.hxx>
35 #include <sfx2/viewfrm.hxx>
36 #include <sfx2/request.hxx>
37 #include <svx/postattr.hxx>
38 #include <svx/hlnkitem.hxx>
39 #include <svx/svxdlg.hxx>
40 #include <osl/diagnose.h>
41 #include <charatr.hxx>
42 #include <fmtfsize.hxx>
43 #include <fmthdft.hxx>
44 #include <fmtinfmt.hxx>
45 #include <fldwrap.hxx>
47 #include <hfspacingitem.hxx>
48 #include <redline.hxx>
51 #include <viewopt.hxx>
54 #include <docufld.hxx>
59 #include <strings.hrc>
60 #include <sfx2/event.hxx>
61 #include <swabstdlg.hxx>
63 #include <PostItMgr.hxx>
64 #include <swmodule.hxx>
65 #include <svtools/strings.hrc>
66 #include <svtools/svtresid.hxx>
68 #include <xmloff/odffields.hxx>
69 #include <IDocumentContentOperations.hxx>
70 #include <IDocumentLayoutAccess.hxx>
71 #include <IDocumentRedlineAccess.hxx>
72 #include <IDocumentUndoRedo.hxx>
73 #include <svl/zforlist.hxx>
74 #include <svl/zformat.hxx>
75 #include <svx/xfillit0.hxx>
76 #include <svx/pageitem.hxx>
77 #include <comphelper/sequenceashashmap.hxx>
79 #include <officecfg/Office/Common.hxx>
80 #include <officecfg/Office/Compatibility.hxx>
82 #include <translatehelper.hxx>
83 #include <sfx2/dispatch.hxx>
86 using namespace nsSwDocInfoSubType
;
88 static OUString
lcl_BuildTitleWithRedline( const SwRangeRedline
*pRedline
)
90 const OUString
sTitle(SwResId(STR_REDLINE_COMMENT
));
93 switch( pRedline
->GetType() )
95 case RedlineType::Insert
:
96 pResId
= STR_REDLINE_INSERTED
;
98 case RedlineType::Delete
:
99 pResId
= STR_REDLINE_DELETED
;
101 case RedlineType::Format
:
102 case RedlineType::ParagraphFormat
:
103 pResId
= STR_REDLINE_FORMATTED
;
105 case RedlineType::Table
:
106 pResId
= STR_REDLINE_TABLECHG
;
108 case RedlineType::FmtColl
:
109 pResId
= STR_REDLINE_FMTCOLLSET
;
115 return sTitle
+ SwResId(pResId
);
118 static bool lcl_canUserModifyAnnotation(const SwView
& rView
, std::u16string_view sAuthor
)
120 return !comphelper::LibreOfficeKit::isActive() || !rView
.IsLokReadOnlyView()
121 || sAuthor
== rView
.GetRedlineAuthor();
124 static bool lcl_canUserModifyAnnotation(const SwView
& rView
,
125 const sw::annotation::SwAnnotationWin
* pAnnotationWin
)
127 return pAnnotationWin
&& lcl_canUserModifyAnnotation(rView
, pAnnotationWin
->GetAuthor());
130 static bool lcl_canUserModifyAnnotation(const SwView
& rView
, sal_uInt32 nPostItId
)
132 return lcl_canUserModifyAnnotation(rView
, rView
.GetPostItMgr()->GetAnnotationWin(nPostItId
));
135 void SwTextShell::ExecField(SfxRequest
&rReq
)
137 SwWrtShell
& rSh
= GetShell();
138 const SfxPoolItem
* pItem
= nullptr;
140 sal_uInt16 nSlot
= rReq
.GetSlot();
141 const SfxItemSet
* pArgs
= rReq
.GetArgs();
143 pArgs
->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot
), false, &pItem
);
147 SwFieldTypesEnum nInsertType
= SwFieldTypesEnum::Date
;
148 sal_uInt16 nInsertSubType
= 0;
149 sal_uInt32 nInsertFormat
= 0;
155 SwField
* pField
= rSh
.GetCurField(true);
158 switch ( pField
->GetTypeId() )
160 case SwFieldTypesEnum::DDE
:
162 ::sfx2::SvBaseLink
& rLink
= static_cast<SwDDEFieldType
*>(pField
->GetTyp())->
164 if(rLink
.IsVisible())
166 if (officecfg::Office::Common::Security::Scripting::DisableActiveContent::get())
168 std::unique_ptr
<weld::MessageDialog
> xError(
169 Application::CreateMessageDialog(
170 nullptr, VclMessageType::Warning
, VclButtonsType::Ok
,
171 SvtResId(STR_WARNING_EXTERNAL_LINK_EDIT_DISABLED
)));
176 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
177 VclPtr
<SfxAbstractLinksDialog
> pDlg(pFact
->CreateLinksDialog(GetView().GetFrameWeld(), &rSh
.GetLinkManager(), false, &rLink
));
178 pDlg
->StartExecuteAsync(
179 [pDlg
] (sal_Int32
/*nResult*/)->void
189 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
190 VclPtr
<SfxAbstractDialog
> pDlg(pFact
->CreateSwFieldEditDlg( GetView() ));
191 // without TabPage no dialog
193 pDlg
->StartExecuteAsync(
194 [pDlg
] (sal_Int32
/*nResult*/)->void
204 case FN_UPDATE_SEL_FIELD
:
206 SwField
*pField
= rSh
.GetCurField();
210 rSh
.UpdateOneField(*pField
);
214 case FN_EXECUTE_MACROFIELD
:
216 SwField
* pField
= rSh
.GetCurField();
217 if(pField
&& pField
->GetTyp()->Which() == SwFieldIds::Macro
)
220 const OUString
& rMacro
= static_cast<SwMacroField
*>(pField
)->GetMacro();
221 sal_Int32 nPos
= rMacro
.indexOf('.');
224 SvxMacro
aMacro( rMacro
.copy(nPos
+ 1), rMacro
.copy(0,nPos
), STARBASIC
);
225 rSh
.ExecMacro(aMacro
);
231 case FN_GOTO_NEXT_INPUTFLD
:
232 case FN_GOTO_PREV_INPUTFLD
:
235 SwFieldType
* pField
= rSh
.GetFieldType( 0, SwFieldIds::Input
);
236 const bool bAddSetExpressionFields
= !( rSh
.GetViewOptions()->IsReadonly() );
237 if ( pField
!= nullptr
238 && rSh
.MoveFieldType(
240 FN_GOTO_NEXT_INPUTFLD
== nSlot
,
242 bAddSetExpressionFields
) )
245 if (!rSh
.IsMultiSelection()
246 && (nullptr != dynamic_cast<const SwTextInputField
*>(
247 SwCursorShell::GetTextFieldAtCursor(rSh
.GetCursor(), ::sw::GetTextAttrMode::Default
))))
251 SwCursorShell::StartOfInputFieldAtPos( *(rSh
.GetCursor()->Start()) ) + 1,
252 SwCursorShell::EndOfInputFieldAtPos( *(rSh
.GetCursor()->Start()) ) - 1 );
254 else if (SwField
* pCurrentField
= rSh
.GetCurField(true))
256 rSh
.StartInputFieldDlg(pCurrentField
, false, false, GetView().GetFrameWeld());
261 rReq
.SetReturnValue( SfxBoolItem( nSlot
, bRet
));
267 const SfxStringItem
* pName
= rReq
.GetArg
<SfxStringItem
>(FN_GOTO_MARK
);
270 rSh
.GotoMark(pName
->GetValue());
280 // Here come the slots with FieldMgr.
281 SwFieldMgr
aFieldMgr(GetShellPtr());
284 case FN_INSERT_DBFIELD
:
289 sal_uInt32 nFormat
= 0;
290 SwFieldTypesEnum nType
= SwFieldTypesEnum::Date
;
291 OUString aPar1
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
293 sal_Int32 nCommand
= 0;
295 if( const SfxUInt16Item
* pFieldItem
= pArgs
->GetItemIfSet( FN_PARAM_FIELD_TYPE
,
297 nType
= static_cast<SwFieldTypesEnum
>(pFieldItem
->GetValue());
298 aPar1
+= OUStringChar(DB_DELIM
);
299 if( SfxItemState::SET
== pArgs
->GetItemState(
300 FN_PARAM_1
, false, &pItem
))
302 aPar1
+= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
304 if( SfxItemState::SET
== pArgs
->GetItemState(
305 FN_PARAM_3
, false, &pItem
))
306 nCommand
= static_cast<const SfxInt32Item
*>(pItem
)->GetValue();
307 aPar1
+= OUStringChar(DB_DELIM
)
308 + OUString::number(nCommand
)
309 + OUStringChar(DB_DELIM
);
310 if( SfxItemState::SET
== pArgs
->GetItemState(
311 FN_PARAM_2
, false, &pItem
))
313 aPar1
+= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
315 if( const SfxStringItem
* pContentItem
= pArgs
->GetItemIfSet(
316 FN_PARAM_FIELD_CONTENT
, false ))
317 aPar2
= pContentItem
->GetValue();
318 if( const SfxUInt32Item
* pFormatItem
= pArgs
->GetItemIfSet(
319 FN_PARAM_FIELD_FORMAT
, false ))
320 nFormat
= pFormatItem
->GetValue();
321 OSL_FAIL("Command is not yet used");
322 SwInsertField_Data
aData(nType
, 0, aPar1
, aPar2
, nFormat
, GetShellPtr(), ' '/*separator*/ );
323 bRes
= aFieldMgr
.InsertField(aData
);
325 rReq
.SetReturnValue(SfxBoolItem( nSlot
, bRes
));
328 case FN_INSERT_FIELD_CTRL
:
329 case FN_INSERT_FIELD
:
332 if( pItem
&& nSlot
!= FN_INSERT_FIELD_CTRL
)
334 sal_uInt32 nFormat
= 0;
335 SwFieldTypesEnum nType
= SwFieldTypesEnum::Date
;
336 sal_uInt16 nSubType
= 0;
337 OUString aPar1
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
339 sal_Unicode cSeparator
= ' ';
341 if( const SfxUInt16Item
* pTypeItem
= pArgs
->GetItemIfSet( FN_PARAM_FIELD_TYPE
,
343 nType
= static_cast<SwFieldTypesEnum
>(pTypeItem
->GetValue());
344 else if (pArgs
->GetItemState(FN_PARAM_4
, false, &pItem
) == SfxItemState::SET
)
346 const OUString
& rTypeName
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
347 nType
= SwFieldTypeFromString(rTypeName
);
349 if( const SfxUInt16Item
* pSubtypeItem
= pArgs
->GetItemIfSet( FN_PARAM_FIELD_SUBTYPE
,
351 nSubType
= pSubtypeItem
->GetValue();
352 if( const SfxStringItem
* pContentItem
= pArgs
->GetItemIfSet(
353 FN_PARAM_FIELD_CONTENT
, false ))
354 aPar2
= pContentItem
->GetValue();
355 if( const SfxUInt32Item
* pFormatItem
= pArgs
->GetItemIfSet(
356 FN_PARAM_FIELD_FORMAT
, false ))
357 nFormat
= pFormatItem
->GetValue();
358 if( SfxItemState::SET
== pArgs
->GetItemState(
359 FN_PARAM_3
, false, &pItem
))
361 OUString sTmp
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
363 cSeparator
= sTmp
[0];
365 if (pArgs
->GetItemState(FN_PARAM_5
, false, &pItem
) == SfxItemState::SET
)
367 // Wrap the field in the requested container instead of inserting it
368 // directly at the cursor position.
369 const OUString
& rWrapper
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
370 if (rWrapper
== "Footnote")
372 GetShellPtr()->InsertFootnote(OUString());
374 else if (rWrapper
== "Endnote")
376 GetShellPtr()->InsertFootnote(OUString(), /*bEndNote=*/true);
379 SwInsertField_Data
aData(nType
, nSubType
, aPar1
, aPar2
, nFormat
, GetShellPtr(), cSeparator
);
380 bRes
= aFieldMgr
.InsertField( aData
);
384 //#i5788# prevent closing of the field dialog while a modal dialog ( Input field dialog ) is active
385 if(!GetView().GetViewFrame().IsInModalMode())
387 SfxViewFrame
& rVFrame
= GetView().GetViewFrame();
388 rVFrame
.ToggleChildWindow(FN_INSERT_FIELD
);
389 bRes
= rVFrame
.GetChildWindow( nSlot
) != nullptr;
390 Invalidate(rReq
.GetSlot());
391 Invalidate(FN_INSERT_FIELD_CTRL
);
395 rReq
.SetReturnValue(SfxBoolItem( nSlot
, bRes
));
399 case FN_INSERT_REF_FIELD
:
401 SfxViewFrame
& rVFrame
= GetView().GetViewFrame();
402 if (!rVFrame
.HasChildWindow(FN_INSERT_FIELD
))
403 rVFrame
.ToggleChildWindow(FN_INSERT_FIELD
); // Show dialog
405 // Switch Fielddlg at a new TabPage
406 sal_uInt16 nId
= SwFieldDlgWrapper::GetChildWindowId();
407 SwFieldDlgWrapper
*pWrp
= static_cast<SwFieldDlgWrapper
*>(rVFrame
.GetChildWindow(nId
));
409 pWrp
->ShowReferencePage();
413 case FN_DELETE_COMMENT
:
415 const SvxPostItIdItem
* pIdItem
= rReq
.GetArg
<SvxPostItIdItem
>(SID_ATTR_POSTIT_ID
);
416 if (pIdItem
&& !pIdItem
->GetValue().isEmpty() && GetView().GetPostItMgr())
418 sal_uInt32 nPostItId
= pIdItem
->GetValue().toUInt32();
419 if (lcl_canUserModifyAnnotation(GetView(), nPostItId
))
420 GetView().GetPostItMgr()->Delete(nPostItId
);
422 else if ( GetView().GetPostItMgr() &&
423 GetView().GetPostItMgr()->HasActiveSidebarWin() )
425 sw::annotation::SwAnnotationWin
* pAnnotationWin
426 = GetView().GetPostItMgr()->GetActiveSidebarWin();
427 if (lcl_canUserModifyAnnotation(GetView(), pAnnotationWin
))
428 GetView().GetPostItMgr()->DeleteActiveSidebarWin();
432 case FN_DELETE_COMMENT_THREAD
:
434 const SvxPostItIdItem
* pIdItem
= rReq
.GetArg
<SvxPostItIdItem
>(SID_ATTR_POSTIT_ID
);
435 if (pIdItem
&& !pIdItem
->GetValue().isEmpty() && GetView().GetPostItMgr())
437 sal_uInt32 nPostItId
= pIdItem
->GetValue().toUInt32();
438 if (lcl_canUserModifyAnnotation(GetView(), nPostItId
))
439 GetView().GetPostItMgr()->DeleteCommentThread(nPostItId
);
441 else if (GetView().GetPostItMgr() && GetView().GetPostItMgr()->HasActiveSidebarWin())
443 sw::annotation::SwAnnotationWin
* pAnnotationWin
444 = GetView().GetPostItMgr()->GetActiveSidebarWin();
445 if (lcl_canUserModifyAnnotation(GetView(), pAnnotationWin
))
446 GetView().GetPostItMgr()->DeleteActiveSidebarWin();
450 case FN_RESOLVE_NOTE
:
452 const SvxPostItIdItem
* pIdItem
= rReq
.GetArg
<SvxPostItIdItem
>(SID_ATTR_POSTIT_ID
);
453 if (pIdItem
&& !pIdItem
->GetValue().isEmpty() && GetView().GetPostItMgr())
455 GetView().GetPostItMgr()->ToggleResolved(pIdItem
->GetValue().toUInt32());
459 case FN_RESOLVE_NOTE_THREAD
:
461 const SvxPostItIdItem
* pIdItem
= rReq
.GetArg
<SvxPostItIdItem
>(SID_ATTR_POSTIT_ID
);
462 if (pIdItem
&& !pIdItem
->GetValue().isEmpty() && GetView().GetPostItMgr())
464 GetView().GetPostItMgr()->ToggleResolvedForThread(pIdItem
->GetValue().toUInt32());
468 case FN_DELETE_ALL_NOTES
:
469 if ( GetView().GetPostItMgr() )
470 GetView().GetPostItMgr()->Delete();
472 case FN_FORMAT_ALL_NOTES
:
474 SwPostItMgr
* pPostItMgr
= GetView().GetPostItMgr();
476 pPostItMgr
->ExecuteFormatAllDialog(GetView());
479 case FN_DELETE_NOTE_AUTHOR
:
481 const SfxStringItem
* pNoteItem
= rReq
.GetArg
<SfxStringItem
>(nSlot
);
482 if (pNoteItem
&& GetView().GetPostItMgr()
483 && lcl_canUserModifyAnnotation(GetView(), pNoteItem
->GetValue()))
484 GetView().GetPostItMgr()->Delete(pNoteItem
->GetValue());
488 if ( GetView().GetPostItMgr() &&
489 GetView().GetPostItMgr()->HasActiveSidebarWin() )
491 GetView().GetPostItMgr()->HideActiveSidebarWin();
494 case FN_HIDE_ALL_NOTES
:
495 if ( GetView().GetPostItMgr() )
496 GetView().GetPostItMgr()->Hide();
498 case FN_HIDE_NOTE_AUTHOR
:
500 const SfxStringItem
* pNoteItem
= rReq
.GetArg
<SfxStringItem
>(nSlot
);
501 if ( pNoteItem
&& GetView().GetPostItMgr() )
502 GetView().GetPostItMgr()->Hide( pNoteItem
->GetValue() );
507 const SvxPostItIdItem
* pIdItem
= rReq
.GetArg
<SvxPostItIdItem
>(SID_ATTR_POSTIT_ID
);
508 if (pIdItem
&& !pIdItem
->GetValue().isEmpty())
510 SwFieldType
* pType
= rSh
.GetDoc()->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::Postit
, OUString(), false);
511 if(pType
->FindFormatForPostItId(pIdItem
->GetValue().toUInt32()))
513 auto pMgr
= GetView().GetPostItMgr();
514 auto pWin
= pMgr
->GetAnnotationWin(pIdItem
->GetValue().toUInt32());
517 if (const SvxPostItTextItem
* pHtmlItem
= rReq
.GetArg
<SvxPostItTextItem
>(SID_ATTR_POSTIT_HTML
))
519 SwDocShell
* pDocSh
= GetView().GetDocShell();
520 Outliner
aOutliner(&pDocSh
->GetPool(), OutlinerMode::TextObject
);
521 SwPostItHelper::ImportHTML(aOutliner
, pHtmlItem
->GetValue());
522 if (std::optional
<OutlinerParaObject
> oPara
= aOutliner
.CreateParaObject())
523 pMgr
->RegisterAnswer(oPara
.value());
527 if(const auto pTextItem
= rReq
.GetArg
<SvxPostItTextItem
>(SID_ATTR_POSTIT_TEXT
))
528 sText
= pTextItem
->GetValue();
529 pMgr
->RegisterAnswerText(sText
);
530 pWin
->ExecuteCommand(nSlot
);
538 rSh
.InsertPostIt(aFieldMgr
, rReq
);
541 case SID_EDIT_POSTIT
:
543 const SvxPostItIdItem
* pIdItem
= rReq
.GetArg
<SvxPostItIdItem
>(SID_ATTR_POSTIT_ID
);
544 if (pIdItem
&& !pIdItem
->GetValue().isEmpty())
546 sw::annotation::SwAnnotationWin
* pAnnotationWin
= GetView().GetPostItMgr()->GetAnnotationWin(pIdItem
->GetValue().toUInt32());
547 if (pAnnotationWin
&& lcl_canUserModifyAnnotation(GetView(), pAnnotationWin
))
549 if (const SvxPostItTextItem
* pHtmlItem
= rReq
.GetArg
<SvxPostItTextItem
>(SID_ATTR_POSTIT_HTML
))
550 pAnnotationWin
->UpdateHTML(pHtmlItem
->GetValue());
553 const SvxPostItTextItem
* pTextItem
= rReq
.GetArg
<SvxPostItTextItem
>(SID_ATTR_POSTIT_TEXT
);
556 sText
= pTextItem
->GetValue();
557 pAnnotationWin
->UpdateText(sText
);
560 // explicit state update to get the Undo state right
561 GetView().AttrChangedNotify(nullptr);
566 case FN_PROMOTE_COMMENT
:
568 const SvxPostItIdItem
* pIdItem
= rReq
.GetArg
<SvxPostItIdItem
>(SID_ATTR_POSTIT_ID
);
569 if (pIdItem
&& !pIdItem
->GetValue().isEmpty() && GetView().GetPostItMgr())
571 GetView().GetPostItMgr()->PromoteToRoot(pIdItem
->GetValue().toUInt32());
575 case FN_REDLINE_COMMENT
:
577 const SwRangeRedline
*pRedline
= rSh
.GetCurrRedline();
578 SwDoc
*pDoc
= rSh
.GetDoc();
579 // If index is specified, goto and select the appropriate redline
580 if (pArgs
&& pArgs
->GetItemState(nSlot
, false, &pItem
) == SfxItemState::SET
)
582 const sal_uInt32 nChangeId
= static_cast<const SfxUInt32Item
*>(pItem
)->GetValue();
583 const SwRedlineTable
& rRedlineTable
= pDoc
->getIDocumentRedlineAccess().GetRedlineTable();
584 for (SwRedlineTable::size_type nRedline
= 0; nRedline
< rRedlineTable
.size(); ++nRedline
)
586 if (nChangeId
== rRedlineTable
[nRedline
]->GetId())
587 pRedline
= rSh
.GotoRedline(nRedline
, true);
591 OUString sCommentText
;
592 const SfxStringItem
* pTextItem
= rReq
.GetArg
<SvxPostItTextItem
>(SID_ATTR_POSTIT_TEXT
);
594 sCommentText
= pTextItem
->GetValue();
598 // In case of LOK and comment text is already provided, skip
599 // dialog creation and just change the redline comment directly
600 if (comphelper::LibreOfficeKit::isActive() && !sCommentText
.isEmpty())
602 rSh
.SetRedlineComment(sCommentText
);
603 GetView().AttrChangedNotify(nullptr);
604 MaybeNotifyRedlineModification(const_cast<SwRangeRedline
&>(*pRedline
), pRedline
->GetDoc());
608 OUString sComment
= convertLineEnd(pRedline
->GetComment(), GetSystemLineEnd());
610 bool bTravel
= false;
612 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
613 ::DialogGetRanges fnGetRange
= pFact
->GetDialogGetRangesFunc();
614 SfxItemSet
aSet(GetPool(), fnGetRange());
615 aSet
.Put(SvxPostItTextItem(sComment
, SID_ATTR_POSTIT_TEXT
));
616 aSet
.Put(SvxPostItAuthorItem(pRedline
->GetAuthorString(), SID_ATTR_POSTIT_AUTHOR
));
618 aSet
.Put( SvxPostItDateItem( GetAppLangDateTimeString(
619 pRedline
->GetRedlineData().GetTimeStamp() ),
620 SID_ATTR_POSTIT_DATE
));
622 // Traveling only if more than one field.
626 const SwRangeRedline
*pActRed
= rSh
.SelPrevRedline();
628 if (pActRed
== pRedline
)
629 { // New cursor is at the beginning of the current redlines.
630 rSh
.Pop(); // Throw old cursor away
632 pActRed
= rSh
.SelPrevRedline();
635 bool bPrev
= pActRed
!= nullptr;
636 rSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
);
640 // Select current redline.
641 pActRed
= rSh
.SelNextRedline();
642 if (pActRed
!= pRedline
)
643 rSh
.SelPrevRedline();
647 pActRed
= rSh
.SelNextRedline();
648 bool bNext
= pActRed
!= nullptr;
649 rSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
); // Restore cursor position
651 if( rSh
.IsCursorPtAtEnd() )
656 bTravel
|= bNext
|| bPrev
;
658 SvxAbstractDialogFactory
* pFact2
= SvxAbstractDialogFactory::Create();
659 ScopedVclPtr
<AbstractSvxPostItDialog
> pDlg(pFact2
->CreateSvxPostItDialog(GetView().GetFrameWeld(), aSet
, bTravel
));
662 pDlg
->SetText(lcl_BuildTitleWithRedline(pRedline
));
666 pDlg
->EnableTravel(bNext
, bPrev
);
667 pDlg
->SetPrevHdl(LINK(this, SwTextShell
, RedlinePrevHdl
));
668 pDlg
->SetNextHdl(LINK(this, SwTextShell
, RedlineNextHdl
));
671 SwViewShell::SetCareDialog(pDlg
->GetDialog());
672 g_bNoInterrupt
= true;
674 if ( pDlg
->Execute() == RET_OK
)
676 const SfxItemSet
* pOutSet
= pDlg
->GetOutputItemSet();
677 OUString
sMsg(pOutSet
->Get(SID_ATTR_POSTIT_TEXT
).GetValue());
679 // Insert or change a comment
680 rSh
.SetRedlineComment(sMsg
);
683 SwViewShell::SetCareDialog(nullptr);
684 pDlg
.disposeAndClear();
685 g_bNoInterrupt
= false;
687 GetView().AttrChangedNotify(nullptr);
694 OUString aType
, aText
;
697 bool bUpdate
= false;
701 aText
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
702 const SfxStringItem
* pType
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_2
);
703 const SfxBoolItem
* pIsUrl
= rReq
.GetArg
<SfxBoolItem
>(FN_PARAM_1
);
705 aType
= pType
->GetValue();
707 bIsUrl
= pIsUrl
->GetValue();
709 SwScriptField
* pField
= static_cast<SwScriptField
*>(aMgr
.GetCurField());
710 bNew
= !pField
|| (pField
->GetTyp()->Which() != SwFieldIds::Script
);
711 bUpdate
= pField
&& ( bIsUrl
!= static_cast<bool>(pField
->GetFormat()) || pField
->GetPar2() != aType
|| pField
->GetPar1() != aText
);
715 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
716 ScopedVclPtr
<AbstractJavaEditDialog
> pDlg(pFact
->CreateJavaEditDialog(GetView().GetFrameWeld(), &rSh
));
717 if ( pDlg
->Execute() )
719 aType
= pDlg
->GetScriptType();
720 aText
= pDlg
->GetScriptText();
721 bIsUrl
= pDlg
->IsUrl();
722 bNew
= pDlg
->IsNew();
723 bUpdate
= pDlg
->IsUpdate();
724 rReq
.AppendItem( SfxStringItem( FN_JAVAEDIT
, aText
) );
725 rReq
.AppendItem( SfxStringItem( FN_PARAM_2
, aType
) );
726 rReq
.AppendItem( SfxBoolItem( FN_PARAM_1
, bIsUrl
) );
732 SwInsertField_Data
aData(SwFieldTypesEnum::Script
, 0, aType
, aText
, bIsUrl
? 1 : 0);
733 aMgr
.InsertField(aData
);
738 aMgr
.UpdateCurField( bIsUrl
? 1 : 0, aType
, aText
);
739 rSh
.SetUndoNoResetModified();
747 case FN_INSERT_FLD_DATE
:
748 case FN_INSERT_FLD_DATE_VAR
:
750 nInsertType
= SwFieldTypesEnum::Date
;
751 nInsertSubType
= nSlot
== FN_INSERT_FLD_DATE
? 0 : 1;
753 // use long date format for Hungarian
754 SwPaM
* pCursorPos
= rSh
.GetCursor();
757 LanguageType nLang
= pCursorPos
->GetPoint()->GetNode().GetTextNode()->GetLang(pCursorPos
->GetPoint()->GetContentIndex());
758 if (nLang
== LANGUAGE_HUNGARIAN
)
759 nInsertFormat
= rSh
.GetNumberFormatter()->GetFormatIndex(NF_DATE_SYSTEM_LONG
, nLang
);
763 case FN_INSERT_FLD_TIME
:
764 case FN_INSERT_FLD_TIME_VAR
:
765 nInsertType
= SwFieldTypesEnum::Time
;
766 nInsertSubType
= nSlot
== FN_INSERT_FLD_TIME
? 0 : 1;
769 case FN_INSERT_FLD_PGNUMBER
:
770 nInsertType
= SwFieldTypesEnum::PageNumber
;
771 nInsertFormat
= SVX_NUM_PAGEDESC
; // Like page template
774 case FN_INSERT_FLD_PGCOUNT
:
775 nInsertType
= SwFieldTypesEnum::DocumentStatistics
;
778 nInsertFormat
= SVX_NUM_PAGEDESC
;
780 case FN_INSERT_FLD_TOPIC
:
781 nInsertType
= SwFieldTypesEnum::DocumentInfo
;
782 nInsertSubType
= DI_SUBJECT
;
784 case FN_INSERT_FLD_TITLE
:
785 nInsertType
= SwFieldTypesEnum::DocumentInfo
;
786 nInsertSubType
= DI_TITLE
;
788 case FN_INSERT_FLD_AUTHOR
:
789 nInsertType
= SwFieldTypesEnum::DocumentInfo
;
790 nInsertSubType
= DI_CREATE
|DI_SUB_AUTHOR
;
794 //format conversion should only be done for number formatter formats
796 nInsertFormat
= aFieldMgr
.GetDefaultFormat(nInsertType
, bIsText
, rSh
.GetNumberFormatter());
797 SwInsertField_Data
aData(nInsertType
, nInsertSubType
,
798 OUString(), OUString(), nInsertFormat
);
799 aFieldMgr
.InsertField(aData
);
804 case FN_INSERT_TEXT_FORMFIELD
:
806 OUString
aFieldType(ODF_FORMTEXT
);
807 const SfxStringItem
* pFieldType
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
810 // Allow overwriting the default type.
811 aFieldType
= pFieldType
->GetValue();
815 const SfxStringItem
* pFieldCode
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_2
);
818 // Allow specifying a field code/command.
819 aFieldCode
= pFieldCode
->GetValue();
822 if (rSh
.HasReadonlySel())
824 // Inform the user that the request has been ignored.
825 auto xInfo
= std::make_shared
<weld::GenericDialogController
>(
826 GetView().GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui",
827 "InfoReadonlyDialog");
828 weld::DialogController::runAsync(xInfo
, [](sal_Int32
/*nResult*/) {});
832 rSh
.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD
, nullptr);
834 SwPaM
* pCursorPos
= rSh
.GetCursor();
837 // Insert five En Space into the text field so the field has extent
838 OUString
aFieldResult(vEnSpaces
);
839 const SfxStringItem
* pFieldResult
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_3
);
842 // Allow specifying a field result / expanded value.
843 aFieldResult
= pFieldResult
->GetValue();
846 const SfxStringItem
* pWrapper
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_4
);
849 // Wrap the fieldmark in the requested container instead of inserting it
850 // directly at the cursor position.
851 OUString aWrapper
= pWrapper
->GetValue();
852 if (aWrapper
== "Footnote")
854 rSh
.InsertFootnote(OUString());
856 else if (aWrapper
== "Endnote")
858 // It's important that there is no Start/EndAction() around this, so the
859 // inner EndAction() triggers a layout update and the cursor can jump to the
860 // created SwFootnoteFrame.
861 rSh
.InsertFootnote(OUString(), /*bEndNote=*/true);
865 // Don't update the layout after inserting content and before deleting temporary
869 // Split node to remember where the start position is.
870 bool bSuccess
= rSh
.GetDoc()->getIDocumentContentOperations().SplitNode(
871 *pCursorPos
->GetPoint(), false);
874 SwPaM
aFieldPam(*pCursorPos
->GetPoint());
875 aFieldPam
.Move(fnMoveBackward
, GoInContent
);
878 // Paste HTML content.
879 SwTranslateHelper::PasteHTMLToPaM(rSh
, pCursorPos
, aFieldResult
.toUtf8());
880 if (pCursorPos
->GetPoint()->GetContentIndex() == 0)
882 // The paste created a last empty text node, remove it.
883 SwPaM
aPam(*pCursorPos
->GetPoint());
885 aPam
.Move(fnMoveBackward
, GoInContent
);
886 rSh
.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPam
);
891 // Insert default placeholder.
892 rSh
.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos
,
895 // Undo the above SplitNode().
897 aFieldPam
.Move(fnMoveForward
, GoInContent
);
898 rSh
.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aFieldPam
);
899 *aFieldPam
.GetMark() = *pCursorPos
->GetPoint();
901 IDocumentMarkAccess
* pMarksAccess
= rSh
.GetDoc()->getIDocumentMarkAccess();
902 sw::mark::Fieldmark
* pFieldmark
= pMarksAccess
->makeFieldBookmark(
903 aFieldPam
, OUString(), aFieldType
, aFieldPam
.Start());
904 if (pFieldmark
&& !aFieldCode
.isEmpty())
906 pFieldmark
->GetParameters()->insert(
907 std::pair
<OUString
, uno::Any
>(ODF_CODE_PARAM
, uno::Any(aFieldCode
)));
913 rSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD
, nullptr);
914 rSh
.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO
);
917 case FN_INSERT_CHECKBOX_FORMFIELD
:
919 rSh
.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD
, nullptr);
921 SwPaM
* pCursorPos
= rSh
.GetCursor();
924 IDocumentMarkAccess
* pMarksAccess
= rSh
.GetDoc()->getIDocumentMarkAccess();
925 pMarksAccess
->makeNoTextFieldBookmark(*pCursorPos
, OUString(), ODF_FORMCHECKBOX
);
928 rSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD
, nullptr);
929 rSh
.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO
);
932 case FN_INSERT_DROPDOWN_FORMFIELD
:
934 rSh
.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD
, nullptr);
936 SwPaM
* pCursorPos
= rSh
.GetCursor();
939 IDocumentMarkAccess
* pMarksAccess
= rSh
.GetDoc()->getIDocumentMarkAccess();
940 pMarksAccess
->makeNoTextFieldBookmark(*pCursorPos
, OUString(), ODF_FORMDROPDOWN
);
943 rSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD
, nullptr);
944 rSh
.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO
);
947 case FN_INSERT_DATE_FORMFIELD
:
949 rSh
.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD
, nullptr);
951 SwPaM
* pCursorPos
= rSh
.GetCursor();
954 // Insert five enspaces into the text field so the field has extent
955 bool bSuccess
= rSh
.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos
, vEnSpaces
);
958 IDocumentMarkAccess
* pMarksAccess
= rSh
.GetDoc()->getIDocumentMarkAccess();
959 SwPaM
aFieldPam(pCursorPos
->GetPoint()->GetNode(), pCursorPos
->GetPoint()->GetContentIndex() - ODF_FORMFIELD_DEFAULT_LENGTH
,
960 pCursorPos
->GetPoint()->GetNode(), pCursorPos
->GetPoint()->GetContentIndex());
961 sw::mark::Fieldmark
* pFieldBM
= pMarksAccess
->makeFieldBookmark(aFieldPam
, OUString(), ODF_FORMDATE
,
964 // Use a default date format and language
965 sw::mark::Fieldmark::parameter_map_t
* pParameters
= pFieldBM
->GetParameters();
966 SvNumberFormatter
* pFormatter
= rSh
.GetDoc()->GetNumberFormatter();
967 sal_uInt32 nStandardFormat
= pFormatter
->GetStandardFormat(SvNumFormatType::DATE
);
968 const SvNumberformat
* pFormat
= pFormatter
->GetEntry(nStandardFormat
);
970 (*pParameters
)[ODF_FORMDATE_DATEFORMAT
] <<= pFormat
->GetFormatstring();
971 (*pParameters
)[ODF_FORMDATE_DATEFORMAT_LANGUAGE
] <<= LanguageTag(pFormat
->GetLanguage()).getBcp47();
975 rSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD
, nullptr);
976 rSh
.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO
);
979 case FN_UPDATE_TEXT_FORMFIELDS
:
981 // This updates multiple fieldmarks in a document, based on their field name & field command
984 const SfxStringItem
* pFieldType
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
987 aFieldType
= pFieldType
->GetValue();
989 OUString aFieldCommandPrefix
;
990 const SfxStringItem
* pFieldCommandPrefix
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_2
);
991 if (pFieldCommandPrefix
)
993 aFieldCommandPrefix
= pFieldCommandPrefix
->GetValue();
995 uno::Sequence
<beans::PropertyValues
> aFields
;
996 const SfxUnoAnyItem
* pFields
= rReq
.GetArg
<SfxUnoAnyItem
>(FN_PARAM_3
);
999 pFields
->GetValue() >>= aFields
;
1002 rSh
.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_FORM_FIELDS
, nullptr);
1005 IDocumentMarkAccess
* pMarkAccess
= rSh
.GetDoc()->getIDocumentMarkAccess();
1006 sal_Int32 nFieldIndex
= 0;
1007 for (auto it
= pMarkAccess
->getFieldmarksBegin(); it
!= pMarkAccess
->getFieldmarksEnd(); ++it
)
1009 sw::mark::Fieldmark
* pFieldmark
= *it
;
1011 if (pFieldmark
->GetFieldname() != aFieldType
)
1016 auto itParam
= pFieldmark
->GetParameters()->find(ODF_CODE_PARAM
);
1017 if (itParam
== pFieldmark
->GetParameters()->end())
1023 itParam
->second
>>= aCommand
;
1024 if (!aCommand
.startsWith(aFieldCommandPrefix
))
1029 if (aFields
.getLength() <= nFieldIndex
)
1034 comphelper::SequenceAsHashMap
aMap(aFields
[nFieldIndex
++]);
1035 itParam
->second
= aMap
[u
"FieldCommand"_ustr
];
1036 SwPaM
aPaM(pFieldmark
->GetMarkPos(), pFieldmark
->GetOtherMarkPos());
1038 // Skip field start & separator.
1039 aPaM
.GetPoint()->AdjustContent(2);
1041 aPaM
.GetMark()->AdjustContent(-1);
1042 rSh
.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPaM
);
1043 OUString aFieldResult
;
1044 aMap
[u
"FieldResult"_ustr
] >>= aFieldResult
;
1045 SwTranslateHelper::PasteHTMLToPaM(rSh
, &aPaM
, aFieldResult
.toUtf8());
1049 rSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_FORM_FIELDS
, nullptr);
1052 case FN_DELETE_TEXT_FORMFIELDS
:
1054 // This deletes all fieldmarks that match the provided field type & field command prefix.
1055 OUString aFieldType
;
1056 const SfxStringItem
* pFieldType
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
1059 aFieldType
= pFieldType
->GetValue();
1061 OUString aFieldCommandPrefix
;
1062 const SfxStringItem
* pFieldCommandPrefix
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_2
);
1063 if (pFieldCommandPrefix
)
1065 aFieldCommandPrefix
= pFieldCommandPrefix
->GetValue();
1067 rSh
.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_FORM_FIELDS
, nullptr);
1070 IDocumentMarkAccess
* pMarkAccess
= rSh
.GetDoc()->getIDocumentMarkAccess();
1071 std::vector
<sw::mark::MarkBase
*> aRemovals
;
1072 for (auto it
= pMarkAccess
->getFieldmarksBegin(); it
!= pMarkAccess
->getFieldmarksEnd(); ++it
)
1074 sw::mark::Fieldmark
* pFieldmark
= *it
;
1076 if (pFieldmark
->GetFieldname() != aFieldType
)
1081 if (!aFieldCommandPrefix
.isEmpty())
1083 auto itParam
= pFieldmark
->GetParameters()->find(ODF_CODE_PARAM
);
1084 if (itParam
== pFieldmark
->GetParameters()->end())
1090 itParam
->second
>>= aCommand
;
1091 if (!aCommand
.startsWith(aFieldCommandPrefix
))
1097 aRemovals
.push_back(pFieldmark
);
1100 for (const auto& pMark
: aRemovals
)
1102 pMarkAccess
->deleteMark(pMark
);
1106 rSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_FORM_FIELDS
, nullptr);
1109 case FN_PGNUMBER_WIZARD
:
1111 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
1112 VclPtr
<AbstractSwPageNumberDlg
> pDlg(
1113 pFact
->CreateSwPageNumberDlg(GetView().GetFrameWeld()));
1114 auto pShell
= GetShellPtr();
1116 const SwPageDesc
& rCurrDesc
= rSh
.GetPageDesc(rSh
.GetCurPageDesc());
1117 pDlg
->SetPageNumberType(rCurrDesc
.GetNumType().GetNumberingType());
1119 pDlg
->StartExecuteAsync([pShell
, &rSh
, pDlg
](int nResult
) {
1120 if ( nResult
== RET_OK
)
1122 auto& rDoc
= *rSh
.GetDoc();
1125 rSh
.StartAllAction();
1126 rSh
.SwCursorShell::Push();
1127 rDoc
.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_PAGE_NUMBER
, nullptr);
1129 const size_t nPageDescIndex
= rSh
.GetCurPageDesc();
1130 const SwPageDesc
& rDesc
= rSh
.GetPageDesc(nPageDescIndex
);
1131 const bool bHeader
= !pDlg
->GetPageNumberPosition();
1132 const bool bHeaderAlreadyOn
= rDesc
.GetMaster().GetHeader().IsActive();
1133 const bool bFooterAlreadyOn
= rDesc
.GetMaster().GetFooter().IsActive();
1134 const bool bIsSinglePage
= rDesc
.GetFollow() != &rDesc
;
1135 const size_t nMirrorPagesNeeded
= rDesc
.IsFirstShared() ? 2 : 3;
1136 const OUString sBookmarkName
= OUString::Concat("PageNumWizard_")
1137 + (bHeader
? "HEADER" : "FOOTER") + "_" + rDesc
.GetName()
1138 + OUString::number(rSh
.GetVirtPageNum());
1139 IDocumentMarkAccess
& rIDMA
= *rSh
.getIDocumentMarkAccess();
1141 // Allow wizard to be re-run: delete previously wizard-inserted page number.
1142 // Try before creating non-shared header: avoid copying ODD bookmark onto EVEN page.
1143 auto ppMark
= rIDMA
.findMark(sBookmarkName
);
1144 if (ppMark
!= rIDMA
.getAllMarksEnd() && *ppMark
)
1146 SwPaM
aDeleteOldPageNum((*ppMark
)->GetMarkStart(), (*ppMark
)->GetMarkEnd());
1147 rDoc
.getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum
);
1150 SwPageDesc
aNewDesc(rDesc
);
1151 bool bChangePageDesc
= false;
1152 if (pDlg
->GetPageNumberType() != aNewDesc
.GetNumType().GetNumberingType())
1154 bChangePageDesc
= true;
1155 SvxNumberType
aNewType(rDesc
.GetNumType());
1156 aNewType
.SetNumberingType(pDlg
->GetPageNumberType());
1157 aNewDesc
.SetNumType(aNewType
);
1160 // Insert header/footer
1161 if ((bHeader
&& !bHeaderAlreadyOn
) || (!bHeader
&& !bFooterAlreadyOn
))
1163 bChangePageDesc
= true;
1164 SwFrameFormat
&rMaster
= aNewDesc
.GetMaster();
1166 rMaster
.SetFormatAttr(SwFormatHeader(/*On=*/true));
1168 rMaster
.SetFormatAttr(SwFormatFooter(/*On=*/true));
1170 // Init copied from ChangeHeaderOrFooter: keep in sync
1171 constexpr tools::Long constTwips_5mm
= o3tl::toTwips(5, o3tl::Length::mm
);
1172 const SvxULSpaceItem
aUL(bHeader
? 0 : constTwips_5mm
,
1173 bHeader
? constTwips_5mm
: 0,
1175 const XFillStyleItem
aFill(drawing::FillStyle_NONE
);
1176 SwFrameFormat
& rFormat
1178 ? const_cast<SwFrameFormat
&>(*rMaster
.GetHeader().GetHeaderFormat())
1179 : const_cast<SwFrameFormat
&>(*rMaster
.GetFooter().GetFooterFormat());
1180 rFormat
.SetFormatAttr(aUL
);
1181 rFormat
.SetFormatAttr(aFill
);
1183 if (pDlg
->GetFitIntoExistingMargins())
1185 SvxULSpaceItem
aPageUL(aNewDesc
.GetMaster().GetULSpace());
1186 tools::Long nPageMargin
= bHeader
? aPageUL
.GetUpper() : aPageUL
.GetLower();
1188 // most printers can't print to paper edge - use arbitrary ~14pt as minimum
1189 if (nPageMargin
> constTwips_5mm
)
1191 // reduce existing margin by the "Spacing"
1192 nPageMargin
-= constTwips_5mm
;
1194 // also reduce by the "Height" (as calculated from the font)
1195 tools::Long nFontHeight
= constTwips_5mm
; // appropriate for 12pt font
1196 const OutputDevice
* pOutDev
= Application::GetDefaultDevice();
1197 const SwViewShell
* pViewSh
1198 = rDoc
.getIDocumentLayoutAccess().GetCurrentViewShell();
1199 OUString
sParaStyle(bHeader
? "Header" : "Footer");
1200 SwTextFormatColl
* pStyle
= rDoc
.FindTextFormatCollByName(sParaStyle
);
1201 if (pStyle
&& pOutDev
)
1204 &pStyle
->GetAttrSet(), /*IDocumentSettingAccess=*/nullptr);
1206 // sledgehammer approach: since the in-use-font (Latin/CTL/CKJ)
1207 // is not known, use the tallest of the three just to ensure fit.
1208 sal_uInt16 nHeight
= aFont
.GetHeight(pViewSh
, *pOutDev
); // Latin
1210 aFont
.SetActual(SwFontScript::CTL
);
1211 nHeight
= std::max(nHeight
, aFont
.GetHeight(pViewSh
, *pOutDev
));
1213 aFont
.SetActual(SwFontScript::CJK
);
1214 nFontHeight
= std::max(nHeight
, aFont
.GetHeight(pViewSh
, *pOutDev
));
1216 // Spacing: above and below paragraph
1217 const SvxULSpaceItem
& rParaStyleUL
= pStyle
->GetULSpace();
1218 nFontHeight
+= rParaStyleUL
.GetUpper() + rParaStyleUL
.GetLower();
1220 // Border padding: top and bottom
1221 const SvxBoxItem rBorders
= pStyle
->GetBox();
1222 nFontHeight
+= rBorders
.CalcLineSpace(SvxBoxItemLine::TOP
, true);
1223 nFontHeight
+= rBorders
.CalcLineSpace(SvxBoxItemLine::BOTTOM
, true);
1225 nPageMargin
-= nFontHeight
;
1227 nPageMargin
= std::max(nPageMargin
, constTwips_5mm
);
1229 aPageUL
.SetUpper(nPageMargin
);
1231 aPageUL
.SetLower(nPageMargin
);
1232 aNewDesc
.GetMaster().SetFormatAttr(aPageUL
);
1234 // force aggressively calculated font height as minimum to ensure
1235 // effective margin stays the same (instead of getting smaller)
1236 SwFormatFrameSize
aSize(rFormat
.GetFrameSize());
1237 aSize
.SetHeightSizeType(SwFrameSize::Minimum
);
1238 // frame size property includes both Spacing + Height
1239 aSize
.SetHeight(constTwips_5mm
+ nFontHeight
);
1240 rFormat
.SetFormatAttr(aSize
);
1242 // in case the calculated font height isn't actually large enough,
1243 // eat into spacing first before pushing into the content area.
1244 rFormat
.SetFormatAttr(SwHeaderAndFooterEatSpacingItem(
1245 RES_HEADER_FOOTER_EAT_SPACING
, true));
1249 // Might as well turn on margin mirroring too - if appropriate
1250 if (pDlg
->GetMirrorOnEvenPages() && !bHeaderAlreadyOn
&& !bFooterAlreadyOn
1252 && (aNewDesc
.ReadUseOn() & UseOnPage::Mirror
) == UseOnPage::All
)
1254 aNewDesc
.WriteUseOn(rDesc
.ReadUseOn() | UseOnPage::Mirror
);
1258 const bool bCreateMirror
= !bIsSinglePage
&& pDlg
->GetMirrorOnEvenPages()
1259 && nMirrorPagesNeeded
<= rSh
.GetPageCnt();
1262 // Use different left/right header/footer
1263 if ((bHeader
&& rDesc
.IsHeaderShared()) || (!bHeader
&& rDesc
.IsFooterShared()))
1265 bChangePageDesc
= true;
1267 aNewDesc
.ChgHeaderShare(/*Share=*/false);
1269 aNewDesc
.ChgFooterShare(/*Share=*/false);
1273 if (bChangePageDesc
)
1274 rSh
.ChgPageDesc(nPageDescIndex
, aNewDesc
);
1276 // Go to the header or footer insert position
1278 bool bSkipMirror
= true;
1279 size_t nEvenPage
= 0;
1280 if (bCreateMirror
|| !rSh
.GetCurrFrame())
1282 // Come here if Currframe can't be found, otherwise Goto*Text will crash.
1283 // Get*PageNum will also be invalid (0), so we have no idea where we are.
1284 // (Since not asking for mirror, the likelihood is that the bHeader is shared,
1285 // in which case it doesn't matter anyway, and we just hope for the best.)
1286 // Read the code in this block assuming that bCreateMirror is true.
1288 // There are enough pages that there probably is a valid odd page.
1289 // However, that is not guaranteed: perhaps the page style switched,
1290 // or a blank page was forced, or some other complexity.
1291 bInHF
= rSh
.SetCursorInHdFt(nPageDescIndex
, bHeader
, /*Even=*/true);
1294 // Remember valid EVEN page. Mirror it if also a valid ODD or FIRST page
1295 nEvenPage
= rSh
.GetVirtPageNum();
1296 assert (nEvenPage
&& "couldn't find page number. Use a bool instead");
1299 bInHF
= rSh
.SetCursorInHdFt(nPageDescIndex
, bHeader
, /*Even=*/false);
1300 if (bInHF
&& nEvenPage
)
1302 // Even though the cursor may be on a FIRST page,
1303 // the user requested mirrored pages, and we have both ODD and EVEN,
1304 // so set page numbers on these two pages, and leave FIRST alone.
1305 bSkipMirror
= false;
1309 // no ODD page, look for FIRST page
1310 bInHF
= rSh
.SetCursorInHdFt(nPageDescIndex
, bHeader
, false, /*First=*/true);
1311 if (bInHF
&& nEvenPage
)
1313 // Unlikely but valid situation: EVEN and FIRST pages, but no ODD page.
1314 // In this case, the first header gets the specified page number
1315 // and the even header is mirrored, with an empty odd header,
1316 // as the user (somewhat) requested.
1317 bSkipMirror
= false;
1320 assert((bInHF
|| nEvenPage
) && "Impossible - why couldn't the move happen?");
1321 assert((bInHF
|| nEvenPage
== rSh
.GetVirtPageNum()) && "Unexpected move");
1326 bInHF
= rSh
.GotoHeaderText();
1328 bInHF
= rSh
.GotoFooterText();
1329 assert(bInHF
&& "shouldn't have a problem going to text when no mirroring");
1332 // Allow wizard to be re-run: delete previously wizard-inserted page number.
1333 // Now that the cursor may have moved to a different page, try delete again.
1334 ppMark
= rIDMA
.findMark(sBookmarkName
);
1335 if (ppMark
!= rIDMA
.getAllMarksEnd() && *ppMark
)
1337 SwPaM
aDeleteOldPageNum((*ppMark
)->GetMarkStart(), (*ppMark
)->GetMarkEnd());
1338 rDoc
.getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum
);
1341 SwTextNode
* pTextNode
= rSh
.GetCursor()->GetPoint()->GetNode().GetTextNode();
1343 // Insert new line if there is already text in header/footer
1344 if (pTextNode
&& !pTextNode
->GetText().isEmpty())
1346 rDoc
.getIDocumentContentOperations().SplitNode(*rSh
.GetCursor()->GetPoint(), false);
1348 // Go back to start of header/footer
1350 rSh
.GotoHeaderText();
1352 rSh
.GotoFooterText();
1355 // Set alignment for the new line
1356 switch (pDlg
->GetPageNumberAlignment())
1360 SvxAdjustItem
aAdjustItem(SvxAdjust::Left
, RES_PARATR_ADJUST
);
1361 rSh
.SetAttrItem(aAdjustItem
);
1366 SvxAdjustItem
aAdjustItem(SvxAdjust::Center
, RES_PARATR_ADJUST
);
1367 rSh
.SetAttrItem(aAdjustItem
);
1372 SvxAdjustItem
aAdjustItem(SvxAdjust::Right
, RES_PARATR_ADJUST
);
1373 rSh
.SetAttrItem(aAdjustItem
);
1378 sal_Int32 nStartContentIndex
= rSh
.GetCursor()->Start()->GetContentIndex();
1379 assert(!nStartContentIndex
&& "earlier split node if not empty, but not zero?");
1381 // Insert page number
1382 SwFieldMgr
aMgr(pShell
);
1383 SwInsertField_Data
aData(SwFieldTypesEnum::PageNumber
, 0,
1384 OUString(), OUString(), SVX_NUM_PAGEDESC
);
1385 aMgr
.InsertField(aData
);
1386 if (pDlg
->GetIncludePageTotal())
1388 rDoc
.getIDocumentContentOperations().InsertString(*rSh
.GetCursor(), u
" / "_ustr
);
1389 SwInsertField_Data
aPageTotalData(SwFieldTypesEnum::DocumentStatistics
, DS_PAGE
,
1390 OUString(), OUString(), SVX_NUM_PAGEDESC
);
1391 aMgr
.InsertField(aPageTotalData
);
1394 // Mark inserted fields with a bookmark - so it can be found/removed if re-run
1395 SwPaM
aNewBookmarkPaM(*rSh
.GetCursor()->Start());
1396 aNewBookmarkPaM
.SetMark();
1397 assert(aNewBookmarkPaM
.GetPointContentNode() && "only SetContent on content node");
1398 aNewBookmarkPaM
.Start()->SetContent(nStartContentIndex
);
1399 sw::mark::MarkBase
* pNewMark
= rIDMA
.makeMark(aNewBookmarkPaM
,
1401 IDocumentMarkAccess::MarkType::BOOKMARK
,
1402 sw::mark::InsertMode::New
);
1404 // Mirror on the even pages
1405 if (!bSkipMirror
&& bCreateMirror
1406 && rSh
.SetCursorInHdFt(nPageDescIndex
, bHeader
, /*Even=*/true))
1408 assert(nEvenPage
&& "what? no even page and yet we got here?");
1411 SwPaM
aDeleteOldPageNum(pNewMark
->GetMarkStart(), pNewMark
->GetMarkEnd());
1412 rDoc
.getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum
);
1415 pTextNode
= rSh
.GetCursor()->GetPoint()->GetNode().GetTextNode();
1417 // Insert new line if there is already text in header/footer
1418 if (pTextNode
&& !pTextNode
->GetText().isEmpty())
1420 rDoc
.getIDocumentContentOperations().SplitNode(
1421 *rSh
.GetCursor()->GetPoint(), false);
1422 // Go back to start of header/footer
1423 rSh
.SetCursorInHdFt(nPageDescIndex
, bHeader
, /*Even=*/true);
1426 // mirror the adjustment
1427 assert(pDlg
->GetPageNumberAlignment() != 1 && "cannot have Center and bMirror");
1428 SvxAdjust eAdjust
= SvxAdjust::Left
;
1429 if (!pDlg
->GetPageNumberAlignment())
1430 eAdjust
= SvxAdjust::Right
;
1431 SvxAdjustItem
aMirrorAdjustItem(eAdjust
, RES_PARATR_ADJUST
);
1432 rSh
.SetAttrItem(aMirrorAdjustItem
);
1434 nStartContentIndex
= rSh
.GetCursor()->Start()->GetContentIndex();
1436 // Insert page number
1437 SwFieldMgr
aEvenMgr(pShell
);
1438 aEvenMgr
.InsertField(aData
);
1439 if (pDlg
->GetIncludePageTotal())
1441 rDoc
.getIDocumentContentOperations().InsertString(*rSh
.GetCursor(), u
" / "_ustr
);
1442 SwInsertField_Data
aPageTotalData(SwFieldTypesEnum::DocumentStatistics
,
1443 DS_PAGE
, OUString(), OUString(),
1445 aMgr
.InsertField(aPageTotalData
);
1448 // Mark inserted fields with a bookmark - so it can be found/removed if re-run
1449 SwPaM
aNewEvenBookmarkPaM(*rSh
.GetCursor()->Start());
1450 aNewEvenBookmarkPaM
.SetMark();
1451 aNewEvenBookmarkPaM
.Start()->SetContent(nStartContentIndex
);
1452 rIDMA
.makeMark(aNewEvenBookmarkPaM
,
1454 IDocumentMarkAccess::MarkType::BOOKMARK
,
1455 sw::mark::InsertMode::New
);
1458 rSh
.SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent
);
1460 rSh
.LockView(false);
1461 rDoc
.GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_PAGE_NUMBER
, nullptr);
1463 pDlg
->disposeOnce();
1468 case FN_UPDATE_TEXT_FORMFIELD
:
1470 // This updates a single fieldmark under the current cursor.
1471 OUString aFieldType
;
1472 const SfxStringItem
* pFieldType
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
1475 aFieldType
= pFieldType
->GetValue();
1477 OUString aFieldCommandPrefix
;
1478 const SfxStringItem
* pFieldCommandPrefix
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_2
);
1479 if (pFieldCommandPrefix
)
1481 aFieldCommandPrefix
= pFieldCommandPrefix
->GetValue();
1483 uno::Sequence
<beans::PropertyValue
> aField
;
1484 const SfxUnoAnyItem
* pFields
= rReq
.GetArg
<SfxUnoAnyItem
>(FN_PARAM_3
);
1487 pFields
->GetValue() >>= aField
;
1490 IDocumentMarkAccess
& rIDMA
= *rSh
.getIDocumentMarkAccess();
1491 SwPosition
& rCursor
= *rSh
.GetCursor()->GetPoint();
1492 sw::mark::Fieldmark
* pFieldmark
= rIDMA
.getInnerFieldmarkFor(rCursor
);
1498 if (pFieldmark
->GetFieldname() != aFieldType
)
1503 auto itParam
= pFieldmark
->GetParameters()->find(ODF_CODE_PARAM
);
1504 if (itParam
== pFieldmark
->GetParameters()->end())
1510 itParam
->second
>>= aCommand
;
1511 if (!aCommand
.startsWith(aFieldCommandPrefix
))
1516 rSh
.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_FORM_FIELD
, nullptr);
1518 comphelper::SequenceAsHashMap
aMap(aField
);
1519 itParam
->second
= aMap
[u
"FieldCommand"_ustr
];
1520 SwPaM
aPaM(pFieldmark
->GetMarkPos(), pFieldmark
->GetOtherMarkPos());
1522 // Skip field start & separator.
1523 aPaM
.GetPoint()->AdjustContent(2);
1525 aPaM
.GetMark()->AdjustContent(-1);
1526 rSh
.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPaM
);
1527 OUString aFieldResult
;
1528 aMap
[u
"FieldResult"_ustr
] >>= aFieldResult
;
1529 SwTranslateHelper::PasteHTMLToPaM(rSh
, &aPaM
, aFieldResult
.toUtf8());
1532 rSh
.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_FORM_FIELD
, nullptr);
1536 OSL_FAIL("wrong dispatcher");
1541 void SwTextShell::StateField( SfxItemSet
&rSet
)
1543 SwWrtShell
& rSh
= GetShell();
1544 SfxWhichIter
aIter( rSet
);
1545 const SwField
* pField
= nullptr;
1546 bool bGetField
= false;
1547 sal_uInt16 nWhich
= aIter
.FirstWhich();
1553 case FN_DELETE_COMMENT
:
1554 case FN_DELETE_NOTE_AUTHOR
:
1555 case FN_DELETE_ALL_NOTES
:
1556 case FN_FORMAT_ALL_NOTES
:
1558 case FN_HIDE_NOTE_AUTHOR
:
1559 case FN_HIDE_ALL_NOTES
:
1561 SwPostItMgr
* pPostItMgr
= GetView().GetPostItMgr();
1563 rSet
.InvalidateItem( nWhich
);
1564 else if ( !pPostItMgr
->HasActiveSidebarWin() )
1566 rSet
.InvalidateItem( FN_DELETE_COMMENT
);
1567 rSet
.InvalidateItem( FN_HIDE_NOTE
);
1569 // tdf#137568 do not offer comment formatting, if no comments are present
1570 if (!pPostItMgr
|| !pPostItMgr
->HasNotes())
1571 rSet
.DisableItem( FN_FORMAT_ALL_NOTES
);
1579 pField
= rSh
.GetCurField(true);
1583 SwFieldIds nTempWhich
= pField
? pField
->GetTyp()->Which() : SwFieldIds::Unknown
;
1584 if( SwFieldIds::Unknown
== nTempWhich
||
1585 SwFieldIds::Postit
== nTempWhich
||
1586 SwFieldIds::Script
== nTempWhich
||
1587 SwFieldIds::TableOfAuthorities
== nTempWhich
)
1588 rSet
.DisableItem( nWhich
);
1589 else if( SwFieldIds::Dde
== nTempWhich
&&
1590 !static_cast<SwDDEFieldType
*>(pField
->GetTyp())->GetBaseLink().IsVisible())
1592 // nested links cannot be edited
1593 rSet
.DisableItem( nWhich
);
1598 case FN_UPDATE_SEL_FIELD
:
1600 pField
= rSh
.GetCurField();
1603 rSet
.DisableItem( nWhich
);
1608 case FN_EXECUTE_MACROFIELD
:
1612 pField
= rSh
.GetCurField();
1615 if(!pField
|| pField
->GetTyp()->Which() != SwFieldIds::Macro
)
1616 rSet
.DisableItem(nWhich
);
1620 case FN_INSERT_FIELD
:
1622 if ( rSh
.CursorInsideInputField() )
1624 rSet
.DisableItem(nWhich
);
1628 SfxViewFrame
& rVFrame
= GetView().GetViewFrame();
1629 //#i5788# prevent closing of the field dialog while a modal dialog ( Input field dialog ) is active
1630 if(!rVFrame
.IsInModalMode() &&
1631 rVFrame
.KnowsChildWindow(FN_INSERT_FIELD
) && !rVFrame
.HasChildWindow(FN_INSERT_FIELD_DATA_ONLY
) )
1632 rSet
.Put(SfxBoolItem( FN_INSERT_FIELD
, rVFrame
.HasChildWindow(nWhich
)));
1634 rSet
.DisableItem(FN_INSERT_FIELD
);
1639 case FN_INSERT_REF_FIELD
:
1641 SfxViewFrame
& rVFrame
= GetView().GetViewFrame();
1642 if ( !rVFrame
.KnowsChildWindow(FN_INSERT_FIELD
)
1643 || rSh
.CursorInsideInputField() )
1645 rSet
.DisableItem(FN_INSERT_REF_FIELD
);
1650 case FN_INSERT_FIELD_CTRL
:
1651 if ( rSh
.CursorInsideInputField() )
1653 rSet
.DisableItem(nWhich
);
1657 rSet
.Put(SfxBoolItem( nWhich
, GetView().GetViewFrame().HasChildWindow(FN_INSERT_FIELD
)));
1661 case FN_REDLINE_COMMENT
:
1662 if (!comphelper::LibreOfficeKit::isActive() && !rSh
.GetCurrRedline())
1663 rSet
.DisableItem(nWhich
);
1667 if (!comphelper::LibreOfficeKit::isActive())
1668 rSet
.DisableItem(nWhich
);
1674 bool bCurField
= false;
1675 pField
= rSh
.GetCurField();
1676 if(nWhich
== FN_POSTIT
)
1677 bCurField
= pField
&& pField
->GetTyp()->Which() == SwFieldIds::Postit
;
1679 bCurField
= pField
&& pField
->GetTyp()->Which() == SwFieldIds::Script
;
1681 if( !bCurField
&& rSh
.IsReadOnlyAvailable() && rSh
.HasReadonlySel() )
1683 rSet
.DisableItem(nWhich
);
1685 else if ( rSh
.CursorInsideInputField() )
1687 rSet
.DisableItem(nWhich
);
1689 // tdf#86188, tdf#135794: Allow disabling comment insertion
1690 // on footnote/endnote/header/frames for better OOXML interoperability
1691 else if (!officecfg::Office::Compatibility::View::AllowCommentsInFootnotes::get() &&
1692 (rSh
.IsCursorInFootnote() || rSh
.IsInHeaderFooter() ||
1693 rSh
.GetCurrFlyFrame(/*bCalcFrame=*/false)))
1695 rSet
.DisableItem(nWhich
);
1701 case FN_INSERT_FLD_AUTHOR
:
1702 case FN_INSERT_FLD_DATE
:
1703 case FN_INSERT_FLD_PGCOUNT
:
1704 case FN_INSERT_FLD_PGNUMBER
:
1705 case FN_INSERT_FLD_TIME
:
1706 case FN_INSERT_FLD_TITLE
:
1707 case FN_INSERT_FLD_TOPIC
:
1708 case FN_INSERT_DBFIELD
:
1709 if ( rSh
.CursorInsideInputField() )
1711 rSet
.DisableItem(nWhich
);
1715 case FN_INSERT_TEXT_FORMFIELD
:
1716 case FN_INSERT_CHECKBOX_FORMFIELD
:
1717 case FN_INSERT_DROPDOWN_FORMFIELD
:
1718 case FN_INSERT_DATE_FORMFIELD
:
1719 if ( rSh
.CursorInsideInputField() )
1721 rSet
.DisableItem(nWhich
);
1725 // Check whether we are in a text form field
1726 SwPosition
aCursorPos(*rSh
.GetCursor()->GetPoint());
1727 sw::mark::Fieldmark
* pFieldBM
= GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aCursorPos
);
1728 if ((!pFieldBM
|| pFieldBM
->GetFieldname() != ODF_FORMTEXT
)
1729 && aCursorPos
.GetContentIndex() > 0)
1731 SwPosition
aPos(*aCursorPos
.GetContentNode(), aCursorPos
.GetContentIndex() - 1);
1732 pFieldBM
= GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos
);
1734 if (pFieldBM
&& pFieldBM
->GetFieldname() == ODF_FORMTEXT
&&
1735 (aCursorPos
> pFieldBM
->GetMarkStart() && aCursorPos
< pFieldBM
->GetMarkEnd() ))
1737 rSet
.DisableItem(nWhich
);
1743 nWhich
= aIter
.NextWhich();
1747 void SwTextShell::InsertHyperlink(const SvxHyperlinkItem
& rHlnkItem
)
1749 const OUString
& rName
= rHlnkItem
.GetName();
1750 const OUString
& rURL
= rHlnkItem
.GetURL();
1751 const OUString
& rTarget
= rHlnkItem
.GetTargetFrame();
1752 const OUString
& rReplacementText
= rHlnkItem
.GetReplacementText();
1753 sal_uInt16 nType
= o3tl::narrowing
<sal_uInt16
>(rHlnkItem
.GetInsertMode());
1754 nType
&= ~HLINK_HTMLMODE
;
1755 const SvxMacroTableDtor
* pMacroTable
= rHlnkItem
.GetMacroTable();
1757 SwWrtShell
& rSh
= GetShell();
1759 if( !(rSh
.GetSelectionType() & SelectionType::Text
) )
1763 SfxItemSetFixed
<RES_TXTATR_INETFMT
, RES_TXTATR_INETFMT
> aSet(GetPool());
1764 rSh
.GetCurAttr( aSet
);
1766 if(SfxItemState::SET
== aSet
.GetItemState(RES_TXTATR_INETFMT
, false))
1769 rSh
.SwCursorShell::SelectTextAttr(RES_TXTATR_INETFMT
, false);
1776 SwFormatINetFormat
aINetFormat( rURL
, rTarget
);
1777 aINetFormat
.SetName(rHlnkItem
.GetIntName());
1780 const SvxMacro
*pMacro
= pMacroTable
->Get( SvMacroItemId::OnMouseOver
);
1782 aINetFormat
.SetMacro(SvMacroItemId::OnMouseOver
, *pMacro
);
1783 pMacro
= pMacroTable
->Get( SvMacroItemId::OnClick
);
1785 aINetFormat
.SetMacro(SvMacroItemId::OnClick
, *pMacro
);
1786 pMacro
= pMacroTable
->Get( SvMacroItemId::OnMouseOut
);
1788 aINetFormat
.SetMacro(SvMacroItemId::OnMouseOut
, *pMacro
);
1791 // inserting mention
1792 if (comphelper::LibreOfficeKit::isActive() && !rReplacementText
.isEmpty())
1794 SwPaM
* pCursorPos
= rSh
.GetCursor();
1795 // move cursor backwards to select @mention
1796 for(int i
=0; i
< rReplacementText
.getLength(); i
++)
1797 pCursorPos
->Move(fnMoveBackward
);
1798 rSh
.InsertURL( aINetFormat
, rName
, false );
1802 rSh
.InsertURL( aINetFormat
, rName
, true );
1809 bool bSel
= rSh
.HasSelection();
1812 InsertURLButton( rURL
, rTarget
, rName
);
1819 IMPL_LINK( SwTextShell
, RedlineNextHdl
, AbstractSvxPostItDialog
&, rDlg
, void )
1821 SwWrtShell
* pSh
= GetShellPtr();
1823 // Insert or change a comment.
1824 pSh
->SetRedlineComment(rDlg
.GetNote());
1826 const SwRangeRedline
*pRedline
= pSh
->GetCurrRedline();
1831 // Traveling only if more than one field.
1832 if( !pSh
->IsCursorPtAtEnd() )
1833 pSh
->SwapPam(); // Move the cursor behind the Redline.
1836 const SwRangeRedline
*pActRed
= pSh
->SelNextRedline();
1837 pSh
->Pop((pActRed
!= nullptr) ? SwCursorShell::PopMode::DeleteStack
: SwCursorShell::PopMode::DeleteCurrent
);
1839 bool bEnable
= false;
1845 bEnable
= pSh
->SelNextRedline() != nullptr;
1846 pSh
->Pop(SwCursorShell::PopMode::DeleteCurrent
);
1850 rDlg
.EnableTravel(bEnable
, true);
1852 if( pSh
->IsCursorPtAtEnd() )
1855 pRedline
= pSh
->GetCurrRedline();
1856 OUString sComment
= convertLineEnd(pRedline
->GetComment(), GetSystemLineEnd());
1858 rDlg
.SetNote(sComment
);
1859 rDlg
.ShowLastAuthor( pRedline
->GetAuthorString(),
1860 GetAppLangDateTimeString(
1861 pRedline
->GetRedlineData().GetTimeStamp() ));
1863 rDlg
.SetText(lcl_BuildTitleWithRedline(pRedline
));
1867 IMPL_LINK( SwTextShell
, RedlinePrevHdl
, AbstractSvxPostItDialog
&, rDlg
, void )
1869 SwWrtShell
* pSh
= GetShellPtr();
1871 // Insert or change a comment.
1872 pSh
->SetRedlineComment(rDlg
.GetNote());
1874 const SwRangeRedline
*pRedline
= pSh
->GetCurrRedline();
1879 // Traveling only if more than one field.
1881 const SwRangeRedline
*pActRed
= pSh
->SelPrevRedline();
1882 pSh
->Pop((pActRed
!= nullptr) ? SwCursorShell::PopMode::DeleteStack
: SwCursorShell::PopMode::DeleteCurrent
);
1884 bool bEnable
= false;
1890 bEnable
= pSh
->SelPrevRedline() != nullptr;
1891 pSh
->Pop(SwCursorShell::PopMode::DeleteCurrent
);
1895 rDlg
.EnableTravel(true, bEnable
);
1897 pRedline
= pSh
->GetCurrRedline();
1898 OUString sComment
= convertLineEnd(pRedline
->GetComment(), GetSystemLineEnd());
1900 rDlg
.SetNote(sComment
);
1901 rDlg
.ShowLastAuthor(pRedline
->GetAuthorString(),
1902 GetAppLangDateTimeString(
1903 pRedline
->GetRedlineData().GetTimeStamp() ));
1905 rDlg
.SetText(lcl_BuildTitleWithRedline(pRedline
));
1909 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */