summaryrefslogtreecommitdiff
path: root/sw/source/uibase/shells/textfld.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/uibase/shells/textfld.cxx')
-rw-r--r--sw/source/uibase/shells/textfld.cxx836
1 files changed, 765 insertions, 71 deletions
diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx
index 158ba5626915..cec8afc3f76c 100644
--- a/sw/source/uibase/shells/textfld.cxx
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <com/sun/star/beans/PropertyValues.hpp>
#include <AnnotationWin.hxx>
#include <comphelper/lok.hxx>
#include <hintids.hxx>
@@ -25,6 +26,7 @@
#include <sfx2/lnkbase.hxx>
#include <txtfld.hxx>
#include <svl/itempool.hxx>
+#include <svl/numformat.hxx>
#include <tools/lineend.hxx>
#include <svl/whiter.hxx>
#include <svl/eitem.hxx>
@@ -35,6 +37,7 @@
#include <svx/hlnkitem.hxx>
#include <svx/svxdlg.hxx>
#include <osl/diagnose.h>
+#include <fmthdft.hxx>
#include <fmtinfmt.hxx>
#include <fldwrap.hxx>
#include <redline.hxx>
@@ -53,15 +56,25 @@
#include <doc.hxx>
#include <PostItMgr.hxx>
#include <swmodule.hxx>
+#include <svtools/strings.hrc>
+#include <svtools/svtresid.hxx>
+
+#include <editeng/ulspitem.hxx>
#include <xmloff/odffields.hxx>
#include <IDocumentContentOperations.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <IDocumentUndoRedo.hxx>
#include <svl/zforlist.hxx>
#include <svl/zformat.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/pageitem.hxx>
+#include <comphelper/sequenceashashmap.hxx>
#include <IMark.hxx>
+#include <officecfg/Office/Common.hxx>
#include <officecfg/Office/Compatibility.hxx>
#include <ndtxt.hxx>
+#include <translatehelper.hxx>
+#include <sfx2/dispatch.hxx>
using namespace nsSwDocInfoSubType;
@@ -70,7 +83,7 @@ static OUString lcl_BuildTitleWithRedline( const SwRangeRedline *pRedline )
{
const OUString sTitle(SwResId(STR_REDLINE_COMMENT));
- const char* pResId = nullptr;
+ TranslateId pResId;
switch( pRedline->GetType() )
{
case RedlineType::Insert:
@@ -104,7 +117,7 @@ void SwTextShell::ExecField(SfxRequest &rReq)
sal_uInt16 nSlot = rReq.GetSlot();
const SfxItemSet* pArgs = rReq.GetArgs();
if(pArgs)
- pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem);
+ pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem);
bool bMore = false;
bool bIsText = true;
@@ -127,22 +140,54 @@ void SwTextShell::ExecField(SfxRequest &rReq)
GetBaseLink();
if(rLink.IsVisible())
{
+ if (officecfg::Office::Common::Security::Scripting::DisableActiveContent::get())
+ {
+ std::unique_ptr<weld::MessageDialog> xError(
+ Application::CreateMessageDialog(
+ nullptr, VclMessageType::Warning, VclButtonsType::Ok,
+ SvtResId(STR_WARNING_EXTERNAL_LINK_EDIT_DISABLED)));
+ xError->run();
+ break;
+ }
+
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
- ScopedVclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog(GetView().GetFrameWeld(), &rSh.GetLinkManager(), false, &rLink));
- pDlg->Execute();
+ VclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog(GetView().GetFrameWeld(), &rSh.GetLinkManager(), false, &rLink));
+ pDlg->StartExecuteAsync(
+ [pDlg] (sal_Int32 /*nResult*/)->void
+ {
+ pDlg->disposeOnce();
+ }
+ );
}
break;
}
default:
{
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
- ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateSwFieldEditDlg( GetView() ));
- pDlg->Execute();
+ VclPtr<SfxAbstractDialog> pDlg(pFact->CreateSwFieldEditDlg( GetView() ));
+ // without TabPage no dialog
+ if (pDlg)
+ pDlg->StartExecuteAsync(
+ [pDlg] (sal_Int32 /*nResult*/)->void
+ {
+ pDlg->disposeOnce();
+ }
+ );
}
}
}
break;
}
+ case FN_UPDATE_SEL_FIELD:
+ {
+ SwField *pField = rSh.GetCurField();
+
+ if (pField)
+ {
+ rSh.UpdateOneField(*pField);
+ }
+ break;
+ }
case FN_EXECUTE_MACROFIELD:
{
SwField* pField = rSh.GetCurField();
@@ -176,16 +221,16 @@ void SwTextShell::ExecField(SfxRequest &rReq)
rSh.ClearMark();
if (!rSh.IsMultiSelection()
&& (nullptr != dynamic_cast<const SwTextInputField*>(
- SwCursorShell::GetTextFieldAtCursor(rSh.GetCursor(), true))))
+ SwCursorShell::GetTextFieldAtCursor(rSh.GetCursor(), ::sw::GetTextAttrMode::Default))))
{
rSh.SttSelect();
- rSh.SelectText(
+ rSh.SelectTextModel(
SwCursorShell::StartOfInputFieldAtPos( *(rSh.GetCursor()->Start()) ) + 1,
SwCursorShell::EndOfInputFieldAtPos( *(rSh.GetCursor()->Start()) ) - 1 );
}
- else
+ else if (SwField* pCurrentField = rSh.GetCurField(true))
{
- rSh.StartInputFieldDlg(rSh.GetCurField(true), false, false, GetView().GetFrameWeld());
+ rSh.StartInputFieldDlg(pCurrentField, false, false, GetView().GetFrameWeld());
}
bRet = true;
}
@@ -194,6 +239,15 @@ void SwTextShell::ExecField(SfxRequest &rReq)
}
break;
+ case FN_GOTO_MARK:
+ {
+ const SfxStringItem* pName = rReq.GetArg<SfxStringItem>(FN_GOTO_MARK);
+ if (pName)
+ {
+ rSh.GotoMark(pName->GetValue());
+ }
+ }
+ break;
default:
bMore = true;
}
@@ -215,9 +269,9 @@ void SwTextShell::ExecField(SfxRequest &rReq)
OUString aPar2;
sal_Int32 nCommand = 0;
- if( SfxItemState::SET == pArgs->GetItemState( FN_PARAM_FIELD_TYPE,
- false, &pItem ))
- nType = static_cast<SwFieldTypesEnum>(static_cast<const SfxUInt16Item *>(pItem)->GetValue());
+ if( const SfxUInt16Item* pFieldItem = pArgs->GetItemIfSet( FN_PARAM_FIELD_TYPE,
+ false ))
+ nType = static_cast<SwFieldTypesEnum>(pFieldItem->GetValue());
aPar1 += OUStringChar(DB_DELIM);
if( SfxItemState::SET == pArgs->GetItemState(
FN_PARAM_1, false, &pItem ))
@@ -235,12 +289,12 @@ void SwTextShell::ExecField(SfxRequest &rReq)
{
aPar1 += static_cast<const SfxStringItem *>(pItem)->GetValue();
}
- if( SfxItemState::SET == pArgs->GetItemState(
- FN_PARAM_FIELD_CONTENT, false, &pItem ))
- aPar2 = static_cast<const SfxStringItem *>(pItem)->GetValue();
- if( SfxItemState::SET == pArgs->GetItemState(
- FN_PARAM_FIELD_FORMAT, false, &pItem ))
- nFormat = static_cast<const SfxUInt32Item *>(pItem)->GetValue();
+ if( const SfxStringItem* pContentItem = pArgs->GetItemIfSet(
+ FN_PARAM_FIELD_CONTENT, false ))
+ aPar2 = pContentItem->GetValue();
+ if( const SfxUInt32Item* pFormatItem = pArgs->GetItemIfSet(
+ FN_PARAM_FIELD_FORMAT, false ))
+ nFormat = pFormatItem->GetValue();
OSL_FAIL("Command is not yet used");
SwInsertField_Data aData(nType, 0, aPar1, aPar2, nFormat, GetShellPtr(), ' '/*separator*/ );
bRes = aFieldMgr.InsertField(aData);
@@ -261,18 +315,23 @@ void SwTextShell::ExecField(SfxRequest &rReq)
OUString aPar2;
sal_Unicode cSeparator = ' ';
- if( SfxItemState::SET == pArgs->GetItemState( FN_PARAM_FIELD_TYPE,
- false, &pItem ))
- nType = static_cast<SwFieldTypesEnum>(static_cast<const SfxUInt16Item *>(pItem)->GetValue());
- if( SfxItemState::SET == pArgs->GetItemState( FN_PARAM_FIELD_SUBTYPE,
- false, &pItem ))
- nSubType = static_cast<const SfxUInt16Item *>(pItem)->GetValue();
- if( SfxItemState::SET == pArgs->GetItemState(
- FN_PARAM_FIELD_CONTENT, false, &pItem ))
- aPar2 = static_cast<const SfxStringItem *>(pItem)->GetValue();
- if( SfxItemState::SET == pArgs->GetItemState(
- FN_PARAM_FIELD_FORMAT, false, &pItem ))
- nFormat = static_cast<const SfxUInt32Item *>(pItem)->GetValue();
+ if( const SfxUInt16Item* pTypeItem = pArgs->GetItemIfSet( FN_PARAM_FIELD_TYPE,
+ false ))
+ nType = static_cast<SwFieldTypesEnum>(pTypeItem->GetValue());
+ else if (pArgs->GetItemState(FN_PARAM_4, false, &pItem) == SfxItemState::SET)
+ {
+ const OUString& rTypeName = static_cast<const SfxStringItem *>(pItem)->GetValue();
+ nType = SwFieldTypeFromString(rTypeName);
+ }
+ if( const SfxUInt16Item* pSubtypeItem = pArgs->GetItemIfSet( FN_PARAM_FIELD_SUBTYPE,
+ false ))
+ nSubType = pSubtypeItem->GetValue();
+ if( const SfxStringItem* pContentItem = pArgs->GetItemIfSet(
+ FN_PARAM_FIELD_CONTENT, false ))
+ aPar2 = pContentItem->GetValue();
+ if( const SfxUInt32Item* pFormatItem = pArgs->GetItemIfSet(
+ FN_PARAM_FIELD_FORMAT, false ))
+ nFormat = pFormatItem->GetValue();
if( SfxItemState::SET == pArgs->GetItemState(
FN_PARAM_3, false, &pItem ))
{
@@ -280,17 +339,31 @@ void SwTextShell::ExecField(SfxRequest &rReq)
if(!sTmp.isEmpty())
cSeparator = sTmp[0];
}
+ if (pArgs->GetItemState(FN_PARAM_5, false, &pItem) == SfxItemState::SET)
+ {
+ // Wrap the field in the requested container instead of inserting it
+ // directly at the cursor position.
+ const OUString& rWrapper = static_cast<const SfxStringItem *>(pItem)->GetValue();
+ if (rWrapper == "Footnote")
+ {
+ GetShellPtr()->InsertFootnote(OUString());
+ }
+ else if (rWrapper == "Endnote")
+ {
+ GetShellPtr()->InsertFootnote(OUString(), /*bEndNote=*/true);
+ }
+ }
SwInsertField_Data aData(nType, nSubType, aPar1, aPar2, nFormat, GetShellPtr(), cSeparator );
bRes = aFieldMgr.InsertField( aData );
}
else
{
//#i5788# prevent closing of the field dialog while a modal dialog ( Input field dialog ) is active
- if(!GetView().GetViewFrame()->IsInModalMode())
+ if(!GetView().GetViewFrame().IsInModalMode())
{
- SfxViewFrame* pVFrame = GetView().GetViewFrame();
- pVFrame->ToggleChildWindow(FN_INSERT_FIELD);
- bRes = pVFrame->GetChildWindow( nSlot ) != nullptr;
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ rVFrame.ToggleChildWindow(FN_INSERT_FIELD);
+ bRes = rVFrame.GetChildWindow( nSlot ) != nullptr;
Invalidate(rReq.GetSlot());
Invalidate(FN_INSERT_FIELD_CTRL);
rReq.Ignore();
@@ -302,13 +375,13 @@ void SwTextShell::ExecField(SfxRequest &rReq)
case FN_INSERT_REF_FIELD:
{
- SfxViewFrame* pVFrame = GetView().GetViewFrame();
- if (!pVFrame->HasChildWindow(FN_INSERT_FIELD))
- pVFrame->ToggleChildWindow(FN_INSERT_FIELD); // Show dialog
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ if (!rVFrame.HasChildWindow(FN_INSERT_FIELD))
+ rVFrame.ToggleChildWindow(FN_INSERT_FIELD); // Show dialog
// Switch Fielddlg at a new TabPage
sal_uInt16 nId = SwFieldDlgWrapper::GetChildWindowId();
- SwFieldDlgWrapper *pWrp = static_cast<SwFieldDlgWrapper*>(pVFrame->GetChildWindow(nId));
+ SwFieldDlgWrapper *pWrp = static_cast<SwFieldDlgWrapper*>(rVFrame.GetChildWindow(nId));
if (pWrp)
pWrp->ShowReferencePage();
rReq.Ignore();
@@ -413,6 +486,18 @@ void SwTextShell::ExecField(SfxRequest &rReq)
sText = pTextItem->GetValue();
pMgr->RegisterAnswerText(sText);
pWin->ExecuteCommand(nSlot);
+
+ SwPostItField* pLatestPostItField = pMgr->GetLatestPostItField();
+ if (pLatestPostItField)
+ {
+ // Set the parent postit id of the reply.
+ pLatestPostItField->SetParentPostItId(pIdItem->GetValue().toUInt32());
+
+ // If name of the replied comment is empty, we need to set a name in order to connect them in the xml file.
+ pWin->GeneratePostItName(); // Generates a name if the current name is empty.
+
+ pLatestPostItField->SetParentName(pWin->GetPostItField()->GetName());
+ }
}
}
}
@@ -631,21 +716,25 @@ void SwTextShell::ExecField(SfxRequest &rReq)
break;
case FN_INSERT_FLD_DATE :
+ case FN_INSERT_FLD_DATE_VAR:
{
nInsertType = SwFieldTypesEnum::Date;
+ nInsertSubType = nSlot == FN_INSERT_FLD_DATE ? 0 : 1;
bIsText = false;
// use long date format for Hungarian
SwPaM* pCursorPos = rSh.GetCursor();
if( pCursorPos )
{
- LanguageType nLang = pCursorPos->GetPoint()->nNode.GetNode().GetTextNode()->GetLang(pCursorPos->GetPoint()->nContent.GetIndex());
+ LanguageType nLang = pCursorPos->GetPoint()->GetNode().GetTextNode()->GetLang(pCursorPos->GetPoint()->GetContentIndex());
if (nLang == LANGUAGE_HUNGARIAN)
nInsertFormat = rSh.GetNumberFormatter()->GetFormatIndex(NF_DATE_SYSTEM_LONG, nLang);
}
goto FIELD_INSERT;
}
case FN_INSERT_FLD_TIME :
+ case FN_INSERT_FLD_TIME_VAR:
nInsertType = SwFieldTypesEnum::Time;
+ nInsertSubType = nSlot == FN_INSERT_FLD_TIME ? 0 : 1;
bIsText = false;
goto FIELD_INSERT;
case FN_INSERT_FLD_PGNUMBER:
@@ -685,6 +774,32 @@ FIELD_INSERT:
case FN_INSERT_TEXT_FORMFIELD:
{
+ OUString aFieldType(ODF_FORMTEXT);
+ const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pFieldType)
+ {
+ // Allow overwriting the default type.
+ aFieldType = pFieldType->GetValue();
+ }
+
+ OUString aFieldCode;
+ const SfxStringItem* pFieldCode = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ if (pFieldCode)
+ {
+ // Allow specifying a field code/command.
+ aFieldCode = pFieldCode->GetValue();
+ }
+
+ if (rSh.HasReadonlySel())
+ {
+ // Inform the user that the request has been ignored.
+ auto xInfo = std::make_shared<weld::GenericDialogController>(
+ GetView().GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui",
+ "InfoReadonlyDialog");
+ weld::DialogController::runAsync(xInfo, [](sal_Int32 /*nResult*/) {});
+ break;
+ }
+
rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
SwPaM* pCursorPos = rSh.GetCursor();
@@ -692,19 +807,83 @@ FIELD_INSERT:
{
// Insert five En Space into the text field so the field has extent
static constexpr OUStringLiteral vEnSpaces = u"\u2002\u2002\u2002\u2002\u2002";
- bool bSuccess = rSh.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos, vEnSpaces);
+ OUString aFieldResult(vEnSpaces);
+ const SfxStringItem* pFieldResult = rReq.GetArg<SfxStringItem>(FN_PARAM_3);
+ if (pFieldResult)
+ {
+ // Allow specifying a field result / expanded value.
+ aFieldResult = pFieldResult->GetValue();
+ }
+
+ const SfxStringItem* pWrapper = rReq.GetArg<SfxStringItem>(FN_PARAM_4);
+ if (pWrapper)
+ {
+ // Wrap the fieldmark in the requested container instead of inserting it
+ // directly at the cursor position.
+ OUString aWrapper = pWrapper->GetValue();
+ if (aWrapper == "Footnote")
+ {
+ rSh.InsertFootnote(OUString());
+ }
+ else if (aWrapper == "Endnote")
+ {
+ // It's important that there is no Start/EndAction() around this, so the
+ // inner EndAction() triggers a layout update and the cursor can jump to the
+ // created SwFootnoteFrame.
+ rSh.InsertFootnote(OUString(), /*bEndNote=*/true);
+ }
+ }
+
+ // Don't update the layout after inserting content and before deleting temporary
+ // text nodes.
+ rSh.StartAction();
+
+ // Split node to remember where the start position is.
+ bool bSuccess = rSh.GetDoc()->getIDocumentContentOperations().SplitNode(
+ *pCursorPos->GetPoint(), false);
if(bSuccess)
{
+ SwPaM aFieldPam(*pCursorPos->GetPoint());
+ aFieldPam.Move(fnMoveBackward, GoInContent);
+ if (pFieldResult)
+ {
+ // Paste HTML content.
+ SwTranslateHelper::PasteHTMLToPaM(rSh, pCursorPos, aFieldResult.toUtf8());
+ if (pCursorPos->GetPoint()->GetContentIndex() == 0)
+ {
+ // The paste created a last empty text node, remove it.
+ SwPaM aPam(*pCursorPos->GetPoint());
+ aPam.SetMark();
+ aPam.Move(fnMoveBackward, GoInContent);
+ rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPam);
+ }
+ }
+ else
+ {
+ // Insert default placeholder.
+ rSh.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos,
+ aFieldResult);
+ }
+ // Undo the above SplitNode().
+ aFieldPam.SetMark();
+ aFieldPam.Move(fnMoveForward, GoInContent);
+ rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aFieldPam);
+ *aFieldPam.GetMark() = *pCursorPos->GetPoint();
+
IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess();
- SwPaM aFieldPam(pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex() - vEnSpaces.getLength(),
- pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex());
- pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), ODF_FORMTEXT,
- aFieldPam.Start());
+ sw::mark::IFieldmark* pFieldmark = pMarksAccess->makeFieldBookmark(
+ aFieldPam, OUString(), aFieldType, aFieldPam.Start());
+ if (pFieldmark && !aFieldCode.isEmpty())
+ {
+ pFieldmark->GetParameters()->insert(
+ std::pair<OUString, uno::Any>(ODF_CODE_PARAM, uno::Any(aFieldCode)));
+ }
}
+ rSh.EndAction();
}
rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
- rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO );
+ rSh.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO );
}
break;
case FN_INSERT_CHECKBOX_FORMFIELD:
@@ -719,7 +898,7 @@ FIELD_INSERT:
}
rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
- rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO );
+ rSh.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO );
}
break;
case FN_INSERT_DROPDOWN_FORMFIELD:
@@ -734,7 +913,7 @@ FIELD_INSERT:
}
rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
- rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO );
+ rSh.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO );
}
break;
case FN_INSERT_DATE_FORMFIELD:
@@ -750,8 +929,8 @@ FIELD_INSERT:
if(bSuccess)
{
IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess();
- SwPaM aFieldPam(pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex() - ODF_FORMFIELD_DEFAULT_LENGTH,
- pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex());
+ SwPaM aFieldPam(pCursorPos->GetPoint()->GetNode(), pCursorPos->GetPoint()->GetContentIndex() - ODF_FORMFIELD_DEFAULT_LENGTH,
+ pCursorPos->GetPoint()->GetNode(), pCursorPos->GetPoint()->GetContentIndex());
sw::mark::IFieldmark* pFieldBM = pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), ODF_FORMDATE,
aFieldPam.Start());
@@ -767,7 +946,498 @@ FIELD_INSERT:
}
rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
- rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO );
+ rSh.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO );
+ }
+ break;
+ case FN_UPDATE_TEXT_FORMFIELDS:
+ {
+ // This updates multiple fieldmarks in a document, based on their field name & field command
+ // prefix.
+ OUString aFieldType;
+ const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pFieldType)
+ {
+ aFieldType = pFieldType->GetValue();
+ }
+ OUString aFieldCommandPrefix;
+ const SfxStringItem* pFieldCommandPrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ if (pFieldCommandPrefix)
+ {
+ aFieldCommandPrefix = pFieldCommandPrefix->GetValue();
+ }
+ uno::Sequence<beans::PropertyValues> aFields;
+ const SfxUnoAnyItem* pFields = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_3);
+ if (pFields)
+ {
+ pFields->GetValue() >>= aFields;
+ }
+
+ rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_FORM_FIELDS, nullptr);
+ rSh.StartAction();
+
+ IDocumentMarkAccess* pMarkAccess = rSh.GetDoc()->getIDocumentMarkAccess();
+ sal_Int32 nFieldIndex = 0;
+ for (auto it = pMarkAccess->getFieldmarksBegin(); it != pMarkAccess->getFieldmarksEnd(); ++it)
+ {
+ auto pFieldmark = dynamic_cast<sw::mark::IFieldmark*>(*it);
+ assert(pFieldmark);
+ if (pFieldmark->GetFieldname() != aFieldType)
+ {
+ continue;
+ }
+
+ auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM);
+ if (itParam == pFieldmark->GetParameters()->end())
+ {
+ continue;
+ }
+
+ OUString aCommand;
+ itParam->second >>= aCommand;
+ if (!aCommand.startsWith(aFieldCommandPrefix))
+ {
+ continue;
+ }
+
+ if (aFields.getLength() <= nFieldIndex)
+ {
+ continue;
+ }
+
+ comphelper::SequenceAsHashMap aMap(aFields[nFieldIndex++]);
+ itParam->second = aMap["FieldCommand"];
+ SwPaM aPaM(pFieldmark->GetMarkPos(), pFieldmark->GetOtherMarkPos());
+ aPaM.Normalize();
+ // Skip field start & separator.
+ aPaM.GetPoint()->AdjustContent(2);
+ // Skip field end.
+ aPaM.GetMark()->AdjustContent(-1);
+ rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPaM);
+ OUString aFieldResult;
+ aMap["FieldResult"] >>= aFieldResult;
+ SwTranslateHelper::PasteHTMLToPaM(rSh, &aPaM, aFieldResult.toUtf8());
+ }
+
+ rSh.EndAction();
+ rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_FORM_FIELDS, nullptr);
+ }
+ break;
+ case FN_DELETE_TEXT_FORMFIELDS:
+ {
+ // This deletes all fieldmarks that match the provided field type & field command prefix.
+ OUString aFieldType;
+ const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pFieldType)
+ {
+ aFieldType = pFieldType->GetValue();
+ }
+ OUString aFieldCommandPrefix;
+ const SfxStringItem* pFieldCommandPrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ if (pFieldCommandPrefix)
+ {
+ aFieldCommandPrefix = pFieldCommandPrefix->GetValue();
+ }
+ rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_FORM_FIELDS, nullptr);
+ rSh.StartAction();
+
+ IDocumentMarkAccess* pMarkAccess = rSh.GetDoc()->getIDocumentMarkAccess();
+ std::vector<sw::mark::IMark*> aRemovals;
+ for (auto it = pMarkAccess->getFieldmarksBegin(); it != pMarkAccess->getFieldmarksEnd(); ++it)
+ {
+ auto pFieldmark = dynamic_cast<sw::mark::IFieldmark*>(*it);
+ assert(pFieldmark);
+ if (pFieldmark->GetFieldname() != aFieldType)
+ {
+ continue;
+ }
+
+ if (!aFieldCommandPrefix.isEmpty())
+ {
+ auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM);
+ if (itParam == pFieldmark->GetParameters()->end())
+ {
+ continue;
+ }
+
+ OUString aCommand;
+ itParam->second >>= aCommand;
+ if (!aCommand.startsWith(aFieldCommandPrefix))
+ {
+ continue;
+ }
+ }
+
+ aRemovals.push_back(pFieldmark);
+ }
+
+ for (const auto& pMark : aRemovals)
+ {
+ pMarkAccess->deleteMark(pMark);
+ }
+
+ rSh.EndAction();
+ rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_FORM_FIELDS, nullptr);
+ }
+ break;
+ case FN_PGNUMBER_WIZARD:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ VclPtr<AbstractSwPageNumberDlg> pDlg(
+ pFact->CreateSwPageNumberDlg(GetView().GetFrameWeld()));
+ auto pShell = GetShellPtr();
+
+ const SwPageDesc& rCurrDesc = rSh.GetPageDesc(rSh.GetCurPageDesc());
+ pDlg->SetPageNumberType(rCurrDesc.GetNumType().GetNumberingType());
+
+ pDlg->StartExecuteAsync([pShell, &rSh, pDlg](int nResult) {
+ if ( nResult == RET_OK )
+ {
+ auto rDoc = rSh.GetDoc();
+
+ rSh.LockView(true);
+ rSh.StartAllAction();
+ rSh.SwCursorShell::Push();
+ rDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_PAGE_NUMBER, nullptr);
+
+ const size_t nPageDescIndex = rSh.GetCurPageDesc();
+ const SwPageDesc& rDesc = rSh.GetPageDesc(nPageDescIndex);
+ const bool bHeader = !pDlg->GetPageNumberPosition();
+ const bool bHeaderAlreadyOn = rDesc.GetMaster().GetHeader().IsActive();
+ const bool bFooterAlreadyOn = rDesc.GetMaster().GetFooter().IsActive();
+ const bool bIsSinglePage = rDesc.GetFollow() != &rDesc;
+ const size_t nMirrorPagesNeeded = rDesc.IsFirstShared() ? 2 : 3;
+ const OUString sBookmarkName = OUString::Concat("PageNumWizard_")
+ + (bHeader ? "HEADER" : "FOOTER") + "_" + rDesc.GetName();
+ IDocumentMarkAccess& rIDMA = *rSh.getIDocumentMarkAccess();
+
+ // Allow wizard to be re-run: delete previously wizard-inserted page number.
+ // Try before creating non-shared header: avoid copying ODD bookmark onto EVEN page.
+ IDocumentMarkAccess::const_iterator_t ppMark = rIDMA.findMark(
+ sBookmarkName + OUString::number(rSh.GetVirtPageNum()));
+ if (ppMark != rIDMA.getAllMarksEnd() && *ppMark)
+ {
+ SwPaM aDeleteOldPageNum((*ppMark)->GetMarkStart(), (*ppMark)->GetMarkEnd());
+ rDoc->getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum);
+ }
+
+ SwPageDesc aNewDesc(rDesc);
+ bool bChangePageDesc = false;
+ if (pDlg->GetPageNumberType() != aNewDesc.GetNumType().GetNumberingType())
+ {
+ bChangePageDesc = true;
+ SvxNumberType aNewType(rDesc.GetNumType());
+ aNewType.SetNumberingType(pDlg->GetPageNumberType());
+ aNewDesc.SetNumType(aNewType);
+ }
+
+ // Insert header/footer
+ if ((bHeader && !bHeaderAlreadyOn) || (!bHeader && !bFooterAlreadyOn))
+ {
+ bChangePageDesc = true;
+ SwFrameFormat &rMaster = aNewDesc.GetMaster();
+ if (bHeader)
+ rMaster.SetFormatAttr(SwFormatHeader(/*On=*/true));
+ else
+ rMaster.SetFormatAttr(SwFormatFooter(/*On=*/true));
+
+ // Init copied from ChangeHeaderOrFooter: keep in sync
+ constexpr tools::Long constTwips_5mm = o3tl::toTwips(5, o3tl::Length::mm);
+ const SvxULSpaceItem aUL(bHeader ? 0 : constTwips_5mm,
+ bHeader ? constTwips_5mm : 0,
+ RES_UL_SPACE);
+ const XFillStyleItem aFill(drawing::FillStyle_NONE);
+ SwFrameFormat& rFormat
+ = bHeader
+ ? const_cast<SwFrameFormat&>(*rMaster.GetHeader().GetHeaderFormat())
+ : const_cast<SwFrameFormat&>(*rMaster.GetFooter().GetFooterFormat());
+ rFormat.SetFormatAttr(aUL);
+ rFormat.SetFormatAttr(aFill);
+
+ // Might as well turn on margin mirroring too - if appropriate
+ if (pDlg->GetMirrorOnEvenPages() && !bHeaderAlreadyOn && !bFooterAlreadyOn
+ && !bIsSinglePage
+ && (aNewDesc.ReadUseOn() & UseOnPage::Mirror) == UseOnPage::All)
+ {
+ aNewDesc.WriteUseOn(rDesc.ReadUseOn() | UseOnPage::Mirror);
+ }
+ }
+
+ const bool bCreateMirror = !bIsSinglePage && pDlg->GetMirrorOnEvenPages()
+ && nMirrorPagesNeeded <= rSh.GetPageCnt();
+ if (bCreateMirror)
+ {
+ // Use different left/right header/footer
+ if ((bHeader && rDesc.IsHeaderShared()) || (!bHeader && rDesc.IsFooterShared()))
+ {
+ bChangePageDesc = true;
+ if (bHeader)
+ aNewDesc.ChgHeaderShare(/*Share=*/false);
+ else
+ aNewDesc.ChgFooterShare(/*Share=*/false);
+ }
+ }
+
+ if (bChangePageDesc)
+ rSh.ChgPageDesc(nPageDescIndex, aNewDesc);
+
+ // Go to the header or footer insert position
+ bool bInHF = false;
+ bool bSkipMirror = true;
+ size_t nEvenPage = 0;
+ if (bCreateMirror || !rSh.GetCurrFrame())
+ {
+ // Come here if Currframe can't be found, otherwise Goto*Text will crash.
+ // Get*PageNum will also be invalid (0), so we have no idea where we are.
+ // (Since not asking for mirror, the likelihood is that the bHeader is shared,
+ // in which case it doesn't matter anyway, and we just hope for the best.)
+ // Read the code in this block assuming that bCreateMirror is true.
+
+ // There are enough pages that there probably is a valid odd page.
+ // However, that is not guaranteed: perhaps the page style switched,
+ // or a blank page was forced, or some other complexity.
+ bInHF = rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/true);
+ if (bInHF)
+ {
+ // Remember valid EVEN page. Mirror it if also a valid ODD or FIRST page
+ nEvenPage = rSh.GetVirtPageNum();
+ assert (nEvenPage && "couldn't find page number. Use a bool instead");
+ }
+
+ bInHF = rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/false);
+ if (bInHF && nEvenPage)
+ {
+ // Even though the cursor may be on a FIRST page,
+ // the user requested mirrored pages, and we have both ODD and EVEN,
+ // so set page numbers on these two pages, and leave FIRST alone.
+ bSkipMirror = false;
+ }
+ if (!bInHF)
+ {
+ // no ODD page, look for FIRST page
+ bInHF = rSh.SetCursorInHdFt(nPageDescIndex, bHeader, false, /*First=*/true);
+ if (bInHF && nEvenPage)
+ {
+ // Unlikely but valid situation: EVEN and FIRST pages, but no ODD page.
+ // In this case, the first header gets the specified page number
+ // and the even header is mirrored, with an empty odd header,
+ // as the user (somewhat) requested.
+ bSkipMirror = false;
+ }
+ }
+ assert((bInHF || nEvenPage) && "Impossible - why couldn't the move happen?");
+ assert((bInHF || nEvenPage == rSh.GetVirtPageNum()) && "Unexpected move");
+ }
+ else
+ {
+ if (bHeader)
+ bInHF = rSh.GotoHeaderText();
+ else
+ bInHF = rSh.GotoFooterText();
+ assert(bInHF && "shouldn't have a problem going to text when no mirroring");
+ }
+
+ // Allow wizard to be re-run: delete previously wizard-inserted page number.
+ // Now that the cursor may have moved to a different page, try delete again.
+ ppMark = rIDMA.findMark(sBookmarkName + OUString::number(rSh.GetVirtPageNum()));
+ if (ppMark != rIDMA.getAllMarksEnd() && *ppMark)
+ {
+ SwPaM aDeleteOldPageNum((*ppMark)->GetMarkStart(), (*ppMark)->GetMarkEnd());
+ rDoc->getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum);
+ }
+
+ SwTextNode* pTextNode = rSh.GetCursor()->GetPoint()->GetNode().GetTextNode();
+
+ // Insert new line if there is already text in header/footer
+ if (pTextNode && !pTextNode->GetText().isEmpty())
+ {
+ rDoc->getIDocumentContentOperations().SplitNode(*rSh.GetCursor()->GetPoint(), false);
+
+ // Go back to start of header/footer
+ if (bHeader)
+ rSh.GotoHeaderText();
+ else
+ rSh.GotoFooterText();
+ }
+
+ // Set alignment for the new line
+ switch (pDlg->GetPageNumberAlignment())
+ {
+ case 0:
+ {
+ SvxAdjustItem aAdjustItem(SvxAdjust::Left, RES_PARATR_ADJUST);
+ rSh.SetAttrItem(aAdjustItem);
+ break;
+ }
+ case 1:
+ {
+ SvxAdjustItem aAdjustItem(SvxAdjust::Center, RES_PARATR_ADJUST);
+ rSh.SetAttrItem(aAdjustItem);
+ break;
+ }
+ case 2:
+ {
+ SvxAdjustItem aAdjustItem(SvxAdjust::Right, RES_PARATR_ADJUST);
+ rSh.SetAttrItem(aAdjustItem);
+ break;
+ }
+ }
+
+ sal_Int32 nStartContentIndex = rSh.GetCursor()->Start()->GetContentIndex();
+ assert(!nStartContentIndex && "earlier split node if not empty, but not zero?");
+
+ // Insert page number
+ SwFieldMgr aMgr(pShell);
+ SwInsertField_Data aData(SwFieldTypesEnum::PageNumber, 0,
+ OUString(), OUString(), SVX_NUM_PAGEDESC);
+ aMgr.InsertField(aData);
+ if (pDlg->GetIncludePageTotal())
+ {
+ rDoc->getIDocumentContentOperations().InsertString(*rSh.GetCursor(), " / ");
+ SwInsertField_Data aPageTotalData(SwFieldTypesEnum::DocumentStatistics, DS_PAGE,
+ OUString(), OUString(), SVX_NUM_PAGEDESC);
+ aMgr.InsertField(aPageTotalData);
+ }
+
+ // Mark inserted fields with a bookmark - so it can be found/removed if re-run
+ SwPaM aNewBookmarkPaM(*rSh.GetCursor()->Start());
+ aNewBookmarkPaM.SetMark();
+ assert(aNewBookmarkPaM.GetPointContentNode() && "only SetContent on content node");
+ aNewBookmarkPaM.Start()->SetContent(nStartContentIndex);
+ rIDMA.makeMark(aNewBookmarkPaM,
+ sBookmarkName + OUString::number(rSh.GetVirtPageNum()),
+ IDocumentMarkAccess::MarkType::BOOKMARK,
+ sw::mark::InsertMode::New);
+
+ // Mirror on the even pages
+ if (!bSkipMirror && bCreateMirror
+ && rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/true))
+ {
+ assert(nEvenPage && "what? no even page and yet we got here?");
+ ppMark = rIDMA.findMark(sBookmarkName + OUString::number(rSh.GetVirtPageNum()));
+ if (ppMark != rIDMA.getAllMarksEnd() && *ppMark)
+ {
+ SwPaM aDeleteOldPageNum((*ppMark)->GetMarkStart(), (*ppMark)->GetMarkEnd());
+ rDoc->getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum);
+ }
+
+ pTextNode = rSh.GetCursor()->GetPoint()->GetNode().GetTextNode();
+
+ // Insert new line if there is already text in header/footer
+ if (pTextNode && !pTextNode->GetText().isEmpty())
+ {
+ rDoc->getIDocumentContentOperations().SplitNode(
+ *rSh.GetCursor()->GetPoint(), false);
+ // Go back to start of header/footer
+ rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/true);
+ }
+
+ // mirror the adjustment
+ assert(pDlg->GetPageNumberAlignment() != 1 && "cannot have Center and bMirror");
+ SvxAdjust eAdjust = SvxAdjust::Left;
+ if (!pDlg->GetPageNumberAlignment())
+ eAdjust = SvxAdjust::Right;
+ SvxAdjustItem aMirrorAdjustItem(eAdjust, RES_PARATR_ADJUST);
+ rSh.SetAttrItem(aMirrorAdjustItem);
+
+ nStartContentIndex = rSh.GetCursor()->Start()->GetContentIndex();
+
+ // Insert page number
+ SwFieldMgr aEvenMgr(pShell);
+ aEvenMgr.InsertField(aData);
+ if (pDlg->GetIncludePageTotal())
+ {
+ rDoc->getIDocumentContentOperations().InsertString(*rSh.GetCursor(), " / ");
+ SwInsertField_Data aPageTotalData(SwFieldTypesEnum::DocumentStatistics,
+ DS_PAGE, OUString(), OUString(),
+ SVX_NUM_PAGEDESC);
+ aMgr.InsertField(aPageTotalData);
+ }
+
+ // Mark inserted fields with a bookmark - so it can be found/removed if re-run
+ SwPaM aNewEvenBookmarkPaM(*rSh.GetCursor()->Start());
+ aNewEvenBookmarkPaM.SetMark();
+ aNewEvenBookmarkPaM.Start()->SetContent(nStartContentIndex);
+ rIDMA.makeMark(aNewEvenBookmarkPaM,
+ sBookmarkName + OUString::number(rSh.GetVirtPageNum()),
+ IDocumentMarkAccess::MarkType::BOOKMARK,
+ sw::mark::InsertMode::New);
+ }
+
+ rSh.SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent);
+ rSh.EndAllAction();
+ rSh.LockView(false);
+ rDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_PAGE_NUMBER, nullptr);
+ }
+ pDlg->disposeOnce();
+ });
+ rReq.Done();
+ }
+ break;
+ case FN_UPDATE_TEXT_FORMFIELD:
+ {
+ // This updates a single fieldmark under the current cursor.
+ OUString aFieldType;
+ const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pFieldType)
+ {
+ aFieldType = pFieldType->GetValue();
+ }
+ OUString aFieldCommandPrefix;
+ const SfxStringItem* pFieldCommandPrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ if (pFieldCommandPrefix)
+ {
+ aFieldCommandPrefix = pFieldCommandPrefix->GetValue();
+ }
+ uno::Sequence<beans::PropertyValue> aField;
+ const SfxUnoAnyItem* pFields = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_3);
+ if (pFields)
+ {
+ pFields->GetValue() >>= aField;
+ }
+
+ IDocumentMarkAccess& rIDMA = *rSh.getIDocumentMarkAccess();
+ SwPosition& rCursor = *rSh.GetCursor()->GetPoint();
+ sw::mark::IFieldmark* pFieldmark = rIDMA.getInnerFieldmarkFor(rCursor);
+ if (!pFieldmark)
+ {
+ break;
+ }
+
+ if (pFieldmark->GetFieldname() != aFieldType)
+ {
+ break;
+ }
+
+ auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM);
+ if (itParam == pFieldmark->GetParameters()->end())
+ {
+ break;
+ }
+
+ OUString aCommand;
+ itParam->second >>= aCommand;
+ if (!aCommand.startsWith(aFieldCommandPrefix))
+ {
+ break;
+ }
+
+ rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_FORM_FIELD, nullptr);
+ rSh.StartAction();
+ comphelper::SequenceAsHashMap aMap(aField);
+ itParam->second = aMap["FieldCommand"];
+ SwPaM aPaM(pFieldmark->GetMarkPos(), pFieldmark->GetOtherMarkPos());
+ aPaM.Normalize();
+ // Skip field start & separator.
+ aPaM.GetPoint()->AdjustContent(2);
+ // Skip field end.
+ aPaM.GetMark()->AdjustContent(-1);
+ rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPaM);
+ OUString aFieldResult;
+ aMap["FieldResult"] >>= aFieldResult;
+ SwTranslateHelper::PasteHTMLToPaM(rSh, &aPaM, aFieldResult.toUtf8());
+
+ rSh.EndAction();
+ rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_FORM_FIELD, nullptr);
}
break;
default:
@@ -804,7 +1474,7 @@ void SwTextShell::StateField( SfxItemSet &rSet )
rSet.InvalidateItem( FN_DELETE_COMMENT );
rSet.InvalidateItem( FN_HIDE_NOTE );
}
- // tdf#137568 do not offer comment formating, if no comments are present
+ // tdf#137568 do not offer comment formatting, if no comments are present
if (!pPostItMgr || !pPostItMgr->HasNotes())
rSet.DisableItem( FN_FORMAT_ALL_NOTES );
}
@@ -833,6 +1503,16 @@ void SwTextShell::StateField( SfxItemSet &rSet )
}
break;
+ case FN_UPDATE_SEL_FIELD:
+ {
+ pField = rSh.GetCurField();
+
+ if (!pField)
+ rSet.DisableItem( nWhich );
+ }
+
+ break;
+
case FN_EXECUTE_MACROFIELD:
{
if(!bGetField)
@@ -853,11 +1533,11 @@ void SwTextShell::StateField( SfxItemSet &rSet )
}
else
{
- SfxViewFrame* pVFrame = GetView().GetViewFrame();
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
//#i5788# prevent closing of the field dialog while a modal dialog ( Input field dialog ) is active
- if(!pVFrame->IsInModalMode() &&
- pVFrame->KnowsChildWindow(FN_INSERT_FIELD) && !pVFrame->HasChildWindow(FN_INSERT_FIELD_DATA_ONLY) )
- rSet.Put(SfxBoolItem( FN_INSERT_FIELD, pVFrame->HasChildWindow(nWhich)));
+ if(!rVFrame.IsInModalMode() &&
+ rVFrame.KnowsChildWindow(FN_INSERT_FIELD) && !rVFrame.HasChildWindow(FN_INSERT_FIELD_DATA_ONLY) )
+ rSet.Put(SfxBoolItem( FN_INSERT_FIELD, rVFrame.HasChildWindow(nWhich)));
else
rSet.DisableItem(FN_INSERT_FIELD);
}
@@ -866,8 +1546,8 @@ void SwTextShell::StateField( SfxItemSet &rSet )
case FN_INSERT_REF_FIELD:
{
- SfxViewFrame* pVFrame = GetView().GetViewFrame();
- if ( !pVFrame->KnowsChildWindow(FN_INSERT_FIELD)
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ if ( !rVFrame.KnowsChildWindow(FN_INSERT_FIELD)
|| rSh.CursorInsideInputField() )
{
rSet.DisableItem(FN_INSERT_REF_FIELD);
@@ -882,7 +1562,7 @@ void SwTextShell::StateField( SfxItemSet &rSet )
}
else
{
- rSet.Put(SfxBoolItem( nWhich, GetView().GetViewFrame()->HasChildWindow(FN_INSERT_FIELD)));
+ rSet.Put(SfxBoolItem( nWhich, GetView().GetViewFrame().HasChildWindow(FN_INSERT_FIELD)));
}
break;
@@ -914,8 +1594,11 @@ void SwTextShell::StateField( SfxItemSet &rSet )
{
rSet.DisableItem(nWhich);
}
- // tdf#86188 Allow disabling comment insertion on footnote/endnote for better OOXML interoperability
- else if ( rSh.IsCursorInFootnote() && !officecfg::Office::Compatibility::View::AllowCommentsInFootnotes::get() )
+ // tdf#86188, tdf#135794: Allow disabling comment insertion
+ // on footnote/endnote/header/frames for better OOXML interoperability
+ else if (!officecfg::Office::Compatibility::View::AllowCommentsInFootnotes::get() &&
+ (rSh.IsCursorInFootnote() || rSh.IsInHeaderFooter() ||
+ rSh.GetCurrFlyFrame(/*bCalcFrame=*/false)))
{
rSet.DisableItem(nWhich);
}
@@ -949,13 +1632,12 @@ void SwTextShell::StateField( SfxItemSet &rSet )
{
// Check whether we are in a text form field
SwPosition aCursorPos(*rSh.GetCursor()->GetPoint());
- sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aCursorPos);
+ sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aCursorPos);
if ((!pFieldBM || pFieldBM->GetFieldname() != ODF_FORMTEXT)
- && aCursorPos.nContent.GetIndex() > 0)
+ && aCursorPos.GetContentIndex() > 0)
{
- SwPosition aPos(aCursorPos);
- --aPos.nContent;
- pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aPos);
+ SwPosition aPos(*aCursorPos.GetContentNode(), aCursorPos.GetContentIndex() - 1);
+ pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos);
}
if (pFieldBM && pFieldBM->GetFieldname() == ODF_FORMTEXT &&
(aCursorPos > pFieldBM->GetMarkStart() && aCursorPos < pFieldBM->GetMarkEnd() ))
@@ -975,7 +1657,8 @@ void SwTextShell::InsertHyperlink(const SvxHyperlinkItem& rHlnkItem)
const OUString& rName = rHlnkItem.GetName();
const OUString& rURL = rHlnkItem.GetURL();
const OUString& rTarget = rHlnkItem.GetTargetFrame();
- sal_uInt16 nType = static_cast<sal_uInt16>(rHlnkItem.GetInsertMode());
+ const OUString& rReplacementText = rHlnkItem.GetReplacementText();
+ sal_uInt16 nType = o3tl::narrowing<sal_uInt16>(rHlnkItem.GetInsertMode());
nType &= ~HLINK_HTMLMODE;
const SvxMacroTableDtor* pMacroTable = rHlnkItem.GetMacroTable();
@@ -985,11 +1668,10 @@ void SwTextShell::InsertHyperlink(const SvxHyperlinkItem& rHlnkItem)
return;
rSh.StartAction();
- SfxItemSet aSet(GetPool(), svl::Items<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT>{});
+ SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool());
rSh.GetCurAttr( aSet );
- const SfxPoolItem* pItem;
- if(SfxItemState::SET == aSet.GetItemState(RES_TXTATR_INETFMT, false, &pItem))
+ if(SfxItemState::SET == aSet.GetItemState(RES_TXTATR_INETFMT, false))
{
// Select links
rSh.SwCursorShell::SelectTextAttr(RES_TXTATR_INETFMT, false);
@@ -1014,7 +1696,19 @@ void SwTextShell::InsertHyperlink(const SvxHyperlinkItem& rHlnkItem)
aINetFormat.SetMacro(SvMacroItemId::OnMouseOut, *pMacro);
}
rSh.SttSelect();
- rSh.InsertURL( aINetFormat, rName, true );
+ // inserting mention
+ if (comphelper::LibreOfficeKit::isActive() && !rReplacementText.isEmpty())
+ {
+ SwPaM* pCursorPos = rSh.GetCursor();
+ // move cursor backwards to select @mention
+ for(int i=0; i < rReplacementText.getLength(); i++)
+ pCursorPos->Move(fnMoveBackward);
+ rSh.InsertURL( aINetFormat, rName, false );
+ }
+ else
+ {
+ rSh.InsertURL( aINetFormat, rName, true );
+ }
rSh.EndSelect();
}
break;