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 <config_features.h>
21 #include <config_fuzzers.h>
24 #include <hintids.hxx>
25 #include <svl/numformat.hxx>
26 #include <svl/stritem.hxx>
27 #include <com/sun/star/text/DefaultNumberingProvider.hpp>
28 #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
29 #include <com/sun/star/text/XNumberingTypeInfo.hpp>
30 #include <com/sun/star/style/NumberingType.hpp>
31 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include <com/sun/star/sdbc/XConnection.hpp>
33 #include <com/sun/star/sdbc/XDataSource.hpp>
34 #include <com/sun/star/uri/UriReferenceFactory.hpp>
35 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
36 #include <comphelper/processfactory.hxx>
37 #include <comphelper/string.hxx>
38 #include <o3tl/string_view.hxx>
39 #include <tools/resary.hxx>
40 #include <osl/diagnose.h>
41 #include <sfx2/dispatch.hxx>
42 #include <sfx2/linkmgr.hxx>
43 #include <sfx2/app.hxx>
44 #include <sfx2/viewfrm.hxx>
45 #include <svx/strarray.hxx>
46 #include <fmtrfmrk.hxx>
47 #include <svl/zforlist.hxx>
48 #include <svl/zformat.hxx>
49 #include <vcl/mnemonic.hxx>
53 #include <swmodule.hxx>
54 #include <fmtinfmt.hxx>
55 #include <cellatr.hxx>
57 #include <shellres.hxx>
59 #include <docufld.hxx>
66 #include <authfld.hxx>
71 #include <flddropdown.hxx>
72 #include <strings.hrc>
74 #include <viewopt.hxx>
76 #include <unotools/useroptions.hxx>
77 #include <IDocumentContentOperations.hxx>
78 #include <translatehelper.hxx>
80 using namespace com::sun::star::uno
;
81 using namespace com::sun::star::container
;
82 using namespace com::sun::star::beans
;
83 using namespace com::sun::star::text
;
84 using namespace com::sun::star::style
;
85 using namespace com::sun::star::sdbc
;
86 using namespace ::com::sun::star
;
87 using namespace nsSwDocInfoSubType
;
93 GRP_DOC_END
= GRP_DOC_BEGIN
+ 12,
95 GRP_FKT_BEGIN
= GRP_DOC_END
,
96 GRP_FKT_END
= GRP_FKT_BEGIN
+ 8,
98 GRP_REF_BEGIN
= GRP_FKT_END
,
99 GRP_REF_END
= GRP_REF_BEGIN
+ 2,
101 GRP_REG_BEGIN
= GRP_REF_END
,
102 GRP_REG_END
= GRP_REG_BEGIN
+ 1,
104 GRP_DB_BEGIN
= GRP_REG_END
,
105 GRP_DB_END
= GRP_DB_BEGIN
+ 5,
107 GRP_VAR_BEGIN
= GRP_DB_END
,
108 GRP_VAR_END
= GRP_VAR_BEGIN
+ 9
113 GRP_WEB_DOC_BEGIN
= 0,
114 GRP_WEB_DOC_END
= GRP_WEB_DOC_BEGIN
+ 9,
116 GRP_WEB_FKT_BEGIN
= GRP_WEB_DOC_END
+ 2,
117 GRP_WEB_FKT_END
= GRP_WEB_FKT_BEGIN
+ 0, // the group is empty!
119 GRP_WEB_REF_BEGIN
= GRP_WEB_FKT_END
+ 6, // the group is empty!
120 GRP_WEB_REF_END
= GRP_WEB_REF_BEGIN
+ 0,
122 GRP_WEB_REG_BEGIN
= GRP_WEB_REF_END
+ 2,
123 GRP_WEB_REG_END
= GRP_WEB_REG_BEGIN
+ 1,
125 GRP_WEB_DB_BEGIN
= GRP_WEB_REG_END
, // the group is empty!
126 GRP_WEB_DB_END
= GRP_WEB_DB_BEGIN
+ 0,
128 GRP_WEB_VAR_BEGIN
= GRP_WEB_DB_END
+ 5,
129 GRP_WEB_VAR_END
= GRP_WEB_VAR_BEGIN
+ 1
132 const sal_uInt16 VF_COUNT
= 1; // { 0 }
133 const sal_uInt16 VF_USR_COUNT
= 2; // { 0, nsSwExtendedSubType::SUB_CMD }
134 const sal_uInt16 VF_DB_COUNT
= 1; // { nsSwExtendedSubType::SUB_OWN_FMT }
136 const TranslateId FLD_EU_ARY
[] =
155 const TranslateId FMT_AUTHOR_ARY
[] =
161 const TranslateId FLD_DATE_ARY
[] =
167 const TranslateId FLD_TIME_ARY
[] =
173 const TranslateId FMT_NUM_ARY
[] =
186 const TranslateId FMT_FF_ARY
[] =
196 const TranslateId FLD_STAT_ARY
[] =
207 const TranslateId FMT_CHAPTER_ARY
[] =
212 FMT_CHAPTER_NO_NOSEPARATOR
215 const TranslateId FLD_INPUT_ARY
[] =
220 const TranslateId FMT_MARK_ARY
[] =
229 const TranslateId FMT_REF_ARY
[] =
240 FMT_REF_NUMBER_NO_CONTEXT
,
241 FMT_REF_NUMBER_FULL_CONTEXT
244 const TranslateId FMT_REG_ARY
[] =
251 const TranslateId FMT_DBFLD_ARY
[] =
257 const TranslateId FMT_SETVAR_ARY
[] =
263 const TranslateId FMT_GETVAR_ARY
[] =
269 const TranslateId FMT_DDE_ARY
[] =
275 const TranslateId FLD_PAGEREF_ARY
[] =
281 const TranslateId FMT_USERVAR_ARY
[] =
289 // field types and subtypes
292 SwFieldTypesEnum nTypeId
;
294 const TranslateId
* pSubTypeResIds
;
295 size_t nSubTypeLength
;
297 const TranslateId
* pFormatResIds
;
298 size_t nFormatLength
;
303 // strings and formats
304 const SwFieldPack aSwFields
[] =
307 { SwFieldTypesEnum::ExtendedUser
, FLD_EU_ARY
, std::size(FLD_EU_ARY
), nullptr, 0 },
308 { SwFieldTypesEnum::Author
, nullptr, 0, FMT_AUTHOR_ARY
, std::size(FMT_AUTHOR_ARY
) },
309 { SwFieldTypesEnum::Date
, FLD_DATE_ARY
, std::size(FLD_DATE_ARY
), nullptr, 0 },
310 { SwFieldTypesEnum::Time
, FLD_TIME_ARY
, std::size(FLD_TIME_ARY
), nullptr, 0 },
311 { SwFieldTypesEnum::PageNumber
, nullptr, 0, FMT_NUM_ARY
, std::size(FMT_NUM_ARY
) -1 },
312 { SwFieldTypesEnum::NextPage
, nullptr, 0, FMT_NUM_ARY
, std::size(FMT_NUM_ARY
) },
313 { SwFieldTypesEnum::PreviousPage
, nullptr, 0, FMT_NUM_ARY
, std::size(FMT_NUM_ARY
) },
314 { SwFieldTypesEnum::Filename
, nullptr, 0, FMT_FF_ARY
, std::size(FMT_FF_ARY
) },
315 { SwFieldTypesEnum::DocumentStatistics
, FLD_STAT_ARY
, std::size(FLD_STAT_ARY
), FMT_NUM_ARY
, std::size(FMT_NUM_ARY
) -1 },
317 { SwFieldTypesEnum::Chapter
, nullptr, 0, FMT_CHAPTER_ARY
, std::size(FMT_CHAPTER_ARY
) },
318 { SwFieldTypesEnum::TemplateName
, nullptr, 0, FMT_FF_ARY
, std::size(FMT_FF_ARY
) },
319 { SwFieldTypesEnum::ParagraphSignature
, nullptr, 0, nullptr, 0 },
322 { SwFieldTypesEnum::ConditionalText
, nullptr, 0, nullptr, 0 },
323 { SwFieldTypesEnum::Dropdown
, nullptr, 0, nullptr, 0 },
324 { SwFieldTypesEnum::Input
, FLD_INPUT_ARY
, std::size(FLD_INPUT_ARY
), nullptr, 0 },
325 { SwFieldTypesEnum::Macro
, nullptr, 0, nullptr, 0 },
326 { SwFieldTypesEnum::JumpEdit
, nullptr, 0, FMT_MARK_ARY
, std::size(FMT_MARK_ARY
) },
327 { SwFieldTypesEnum::CombinedChars
, nullptr, 0, nullptr, 0 },
328 { SwFieldTypesEnum::HiddenText
, nullptr, 0, nullptr, 0 },
329 { SwFieldTypesEnum::HiddenParagraph
, nullptr, 0, nullptr, 0 },
332 { SwFieldTypesEnum::SetRef
, nullptr, 0, nullptr, 0 },
333 { SwFieldTypesEnum::GetRef
, nullptr, 0, FMT_REF_ARY
, std::size(FMT_REF_ARY
) },
336 { SwFieldTypesEnum::DocumentInfo
, nullptr, 0, FMT_REG_ARY
, std::size(FMT_REG_ARY
) },
339 { SwFieldTypesEnum::Database
, nullptr, 0, FMT_DBFLD_ARY
, std::size(FMT_DBFLD_ARY
) },
340 { SwFieldTypesEnum::DatabaseNextSet
, nullptr, 0, nullptr, 0 },
341 { SwFieldTypesEnum::DatabaseNumberSet
, nullptr, 0, nullptr, 0 },
342 { SwFieldTypesEnum::DatabaseSetNumber
, nullptr, 0, FMT_NUM_ARY
, std::size(FMT_NUM_ARY
) - 2 },
343 { SwFieldTypesEnum::DatabaseName
, nullptr, 0, nullptr, 0 },
346 { SwFieldTypesEnum::Set
, nullptr, 0, FMT_SETVAR_ARY
, std::size(FMT_SETVAR_ARY
) },
348 { SwFieldTypesEnum::Get
, nullptr, 0, FMT_GETVAR_ARY
, std::size(FMT_GETVAR_ARY
) },
349 { SwFieldTypesEnum::DDE
, nullptr, 0, FMT_DDE_ARY
, std::size(FMT_DDE_ARY
) },
350 { SwFieldTypesEnum::Formel
, nullptr, 0, FMT_GETVAR_ARY
, std::size(FMT_GETVAR_ARY
) },
351 { SwFieldTypesEnum::Input
, FLD_INPUT_ARY
, std::size(FLD_INPUT_ARY
), nullptr, 0 },
352 { SwFieldTypesEnum::Sequence
, nullptr, 0, FMT_NUM_ARY
, std::size(FMT_NUM_ARY
) - 2 },
353 { SwFieldTypesEnum::SetRefPage
, FLD_PAGEREF_ARY
, std::size(FLD_PAGEREF_ARY
),nullptr, 0 },
354 { SwFieldTypesEnum::GetRefPage
, nullptr, 0, FMT_NUM_ARY
, std::size(FMT_NUM_ARY
) - 1 },
355 { SwFieldTypesEnum::User
, nullptr, 0, FMT_USERVAR_ARY
, std::size(FMT_USERVAR_ARY
) }
358 // access to the shell
359 static SwWrtShell
* lcl_GetShell()
361 if (SwView
* pView
= GetActiveView())
362 return pView
->GetWrtShellPtr();
366 static sal_uInt16
GetPackCount() { return SAL_N_ELEMENTS(aSwFields
); }
368 // FieldManager controls inserting and updating of fields
369 SwFieldMgr::SwFieldMgr(SwWrtShell
* pSh
) :
373 // determine current field if existing
377 SwFieldMgr::~SwFieldMgr()
381 // organise RefMark by names
382 bool SwFieldMgr::CanInsertRefMark( std::u16string_view rStr
)
385 SwWrtShell
*pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
386 OSL_ENSURE(pSh
, "no SwWrtShell found");
389 sal_uInt16 nCnt
= pSh
->GetCursorCnt();
391 // the last Cursor doesn't have to be a spanned selection
392 if( 1 < nCnt
&& !pSh
->SwCursorShell::HasSelection() )
395 bRet
= 2 > nCnt
&& nullptr == pSh
->GetRefMark( rStr
);
400 // access over ResIds
401 void SwFieldMgr::RemoveFieldType(SwFieldIds nResId
, const OUString
& rName
)
403 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
404 OSL_ENSURE(pSh
, "no SwWrtShell found");
406 pSh
->RemoveFieldType(nResId
, rName
);
409 size_t SwFieldMgr::GetFieldTypeCount() const
411 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
412 OSL_ENSURE(pSh
, "no SwWrtShell found");
413 return pSh
? pSh
->GetFieldTypeCount() : 0;
416 SwFieldType
* SwFieldMgr::GetFieldType(SwFieldIds nResId
, size_t nField
) const
418 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
419 OSL_ENSURE(pSh
, "no SwWrtShell found");
420 return pSh
? pSh
->GetFieldType(nField
, nResId
) : nullptr;
423 SwFieldType
* SwFieldMgr::GetFieldType(SwFieldIds nResId
, const OUString
& rName
) const
425 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
426 OSL_ENSURE(pSh
, "no SwWrtShell found");
427 return pSh
? pSh
->GetFieldType(nResId
, rName
) : nullptr;
430 // determine current field
431 SwField
* SwFieldMgr::GetCurField()
433 SwWrtShell
*pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
435 m_pCurField
= pSh
->GetCurField( true );
437 m_pCurField
= nullptr;
439 // initialise strings and format
447 // preprocess current values; determine parameter 1 and parameter 2
449 m_aCurPar1
= m_pCurField
->GetPar1();
450 m_aCurPar2
= m_pCurField
->GetPar2();
455 // provide group range
456 const SwFieldGroupRgn
& SwFieldMgr::GetGroupRange(bool bHtmlMode
, sal_uInt16 nGrpId
)
458 static SwFieldGroupRgn
const aRanges
[] =
460 { /* Document */ GRP_DOC_BEGIN
, GRP_DOC_END
},
461 { /* Functions */ GRP_FKT_BEGIN
, GRP_FKT_END
},
462 { /* Cross-Refs */ GRP_REF_BEGIN
, GRP_REF_END
},
463 { /* DocInfos */ GRP_REG_BEGIN
, GRP_REG_END
},
464 { /* Database */ GRP_DB_BEGIN
, GRP_DB_END
},
465 { /* User */ GRP_VAR_BEGIN
, GRP_VAR_END
}
467 static SwFieldGroupRgn
const aWebRanges
[] =
469 { /* Document */ GRP_WEB_DOC_BEGIN
, GRP_WEB_DOC_END
},
470 { /* Functions */ GRP_WEB_FKT_BEGIN
, GRP_WEB_FKT_END
},
471 { /* Cross-Refs */ GRP_WEB_REF_BEGIN
, GRP_WEB_REF_END
},
472 { /* DocInfos */ GRP_WEB_REG_BEGIN
, GRP_WEB_REG_END
},
473 { /* Database */ GRP_WEB_DB_BEGIN
, GRP_WEB_DB_END
},
474 { /* User */ GRP_WEB_VAR_BEGIN
, GRP_WEB_VAR_END
}
478 return aWebRanges
[nGrpId
];
480 return aRanges
[nGrpId
];
484 sal_uInt16
SwFieldMgr::GetGroup(SwFieldTypesEnum nTypeId
, sal_uInt16 nSubType
)
486 if (nTypeId
== SwFieldTypesEnum::SetInput
)
487 nTypeId
= SwFieldTypesEnum::Set
;
489 if (nTypeId
== SwFieldTypesEnum::Input
&& (nSubType
& INP_USR
))
490 nTypeId
= SwFieldTypesEnum::User
;
492 if (nTypeId
== SwFieldTypesEnum::FixedDate
)
493 nTypeId
= SwFieldTypesEnum::Date
;
495 if (nTypeId
== SwFieldTypesEnum::FixedTime
)
496 nTypeId
= SwFieldTypesEnum::Time
;
498 for (sal_uInt16 i
= GRP_DOC
; i
<= GRP_VAR
; i
++)
500 const SwFieldGroupRgn
& rRange
= GetGroupRange(false/*bHtmlMode*/, i
);
501 for (sal_uInt16 nPos
= rRange
.nStart
; nPos
< rRange
.nEnd
; nPos
++)
503 if (aSwFields
[nPos
].nTypeId
== nTypeId
)
510 // determine names to TypeId
511 // ACCESS over TYP_...
512 SwFieldTypesEnum
SwFieldMgr::GetTypeId(sal_uInt16 nPos
)
514 OSL_ENSURE(nPos
< ::GetPackCount(), "forbidden Pos");
515 return aSwFields
[ nPos
].nTypeId
;
518 const OUString
& SwFieldMgr::GetTypeStr(sal_uInt16 nPos
)
520 OSL_ENSURE(nPos
< ::GetPackCount(), "forbidden TypeId");
522 SwFieldTypesEnum nFieldWh
= aSwFields
[ nPos
].nTypeId
;
524 // special treatment for date/time fields (without var/fix)
525 if( SwFieldTypesEnum::Date
== nFieldWh
)
527 static OUString
g_aDate( SwResId( STR_DATEFLD
) );
530 if( SwFieldTypesEnum::Time
== nFieldWh
)
532 static OUString
g_aTime( SwResId( STR_TIMEFLD
) );
536 return SwFieldType::GetTypeStr( nFieldWh
);
539 // determine Pos in the list
540 sal_uInt16
SwFieldMgr::GetPos(SwFieldTypesEnum nTypeId
)
544 case SwFieldTypesEnum::FixedDate
: nTypeId
= SwFieldTypesEnum::Date
; break;
545 case SwFieldTypesEnum::FixedTime
: nTypeId
= SwFieldTypesEnum::Time
; break;
546 case SwFieldTypesEnum::SetInput
: nTypeId
= SwFieldTypesEnum::Set
; break;
547 case SwFieldTypesEnum::UserInput
: nTypeId
= SwFieldTypesEnum::User
; break;
551 for(sal_uInt16 i
= 0; i
< GetPackCount(); i
++)
552 if(aSwFields
[i
].nTypeId
== nTypeId
)
558 // localise subtypes of a field
559 void SwFieldMgr::GetSubTypes(SwFieldTypesEnum nTypeId
, std::vector
<OUString
>& rToFill
)
561 SwWrtShell
*pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
562 OSL_ENSURE(pSh
, "no SwWrtShell found");
566 const sal_uInt16 nPos
= GetPos(nTypeId
);
570 case SwFieldTypesEnum::SetRef
:
571 case SwFieldTypesEnum::GetRef
:
573 // references are no fields
574 pSh
->GetRefMarks( &rToFill
);
577 case SwFieldTypesEnum::Macro
:
581 case SwFieldTypesEnum::Input
:
583 rToFill
.push_back(SwResId(aSwFields
[nPos
].pSubTypeResIds
[0]));
584 [[fallthrough
]]; // move on at generic types
586 case SwFieldTypesEnum::DDE
:
587 case SwFieldTypesEnum::Sequence
:
588 case SwFieldTypesEnum::Formel
:
589 case SwFieldTypesEnum::Get
:
590 case SwFieldTypesEnum::Set
:
591 case SwFieldTypesEnum::User
:
594 const size_t nCount
= pSh
->GetFieldTypeCount();
595 for(size_t i
= 0; i
< nCount
; ++i
)
597 SwFieldType
* pFieldType
= pSh
->GetFieldType( i
);
598 const SwFieldIds nWhich
= pFieldType
->Which();
600 if((nTypeId
== SwFieldTypesEnum::DDE
&& pFieldType
->Which() == SwFieldIds::Dde
) ||
602 (nTypeId
== SwFieldTypesEnum::User
&& nWhich
== SwFieldIds::User
) ||
604 (nTypeId
== SwFieldTypesEnum::Get
&& nWhich
== SwFieldIds::SetExp
&&
605 !(static_cast<SwSetExpFieldType
*>(pFieldType
)->GetType() & nsSwGetSetExpType::GSE_SEQ
)) ||
607 (nTypeId
== SwFieldTypesEnum::Set
&& nWhich
== SwFieldIds::SetExp
&&
608 !(static_cast<SwSetExpFieldType
*>(pFieldType
)->GetType() & nsSwGetSetExpType::GSE_SEQ
)) ||
610 (nTypeId
== SwFieldTypesEnum::Sequence
&& nWhich
== SwFieldIds::SetExp
&&
611 (static_cast<SwSetExpFieldType
*>(pFieldType
)->GetType() & nsSwGetSetExpType::GSE_SEQ
)) ||
613 ((nTypeId
== SwFieldTypesEnum::Input
|| nTypeId
== SwFieldTypesEnum::Formel
) &&
614 (nWhich
== SwFieldIds::User
||
615 (nWhich
== SwFieldIds::SetExp
&&
616 !(static_cast<SwSetExpFieldType
*>(pFieldType
)->GetType() & nsSwGetSetExpType::GSE_SEQ
))) ) )
618 rToFill
.push_back(pFieldType
->GetName());
623 case SwFieldTypesEnum::DatabaseNextSet
:
624 case SwFieldTypesEnum::DatabaseNumberSet
:
625 case SwFieldTypesEnum::DatabaseName
:
626 case SwFieldTypesEnum::DatabaseSetNumber
:
632 if(nPos
!= USHRT_MAX
)
635 if (nTypeId
== SwFieldTypesEnum::DocumentInfo
)
636 nCount
= DI_SUBTYPE_END
- DI_SUBTYPE_BEGIN
;
638 nCount
= aSwFields
[nPos
].nSubTypeLength
;
640 for(sal_uInt16 i
= 0; i
< nCount
; ++i
)
643 if (nTypeId
== SwFieldTypesEnum::DocumentInfo
)
645 if ( i
== DI_CUSTOM
)
646 sNew
= SwResId(STR_CUSTOM_FIELD
);
648 sNew
= SwViewShell::GetShellRes()->aDocInfoLst
[i
];
651 sNew
= SwResId(aSwFields
[nPos
].pSubTypeResIds
[i
]);
653 rToFill
.push_back(sNew
);
661 // ACCESS over TYP_...
662 sal_uInt16
SwFieldMgr::GetFormatCount(SwFieldTypesEnum nTypeId
, bool bHtmlMode
) const
664 assert(nTypeId
< SwFieldTypesEnum::LAST
&& "forbidden TypeId");
666 const sal_uInt16 nPos
= GetPos(nTypeId
);
668 if (nPos
== USHRT_MAX
|| (bHtmlMode
&& nTypeId
== SwFieldTypesEnum::Set
))
671 sal_uInt16 nCount
= aSwFields
[nPos
].nFormatLength
;
673 if (nTypeId
== SwFieldTypesEnum::Filename
)
674 nCount
-= 2; // no range or template
676 const TranslateId
* pStart
= aSwFields
[nPos
].pFormatResIds
;
680 if (*pStart
== FMT_GETVAR_ARY
[0] || *pStart
== FMT_SETVAR_ARY
[0])
682 else if (*pStart
== FMT_USERVAR_ARY
[0])
684 else if (*pStart
== FMT_DBFLD_ARY
[0])
686 else if (*pStart
== FMT_NUM_ARY
[0])
689 if(m_xNumberingInfo
.is())
691 const Sequence
<sal_Int16
> aTypes
= m_xNumberingInfo
->getSupportedNumberingTypes();
692 // #i28073# it's not necessarily a sorted sequence
693 //skip all values below or equal to CHARS_LOWER_LETTER_N
694 nCount
+= std::count_if(aTypes
.begin(), aTypes
.end(),
695 [](sal_Int16 nCurrent
) { return nCurrent
> NumberingType::CHARS_LOWER_LETTER_N
; });
704 // determine FormatString to a type
705 OUString
SwFieldMgr::GetFormatStr(SwFieldTypesEnum nTypeId
, sal_uInt32 nFormatId
) const
707 assert(nTypeId
< SwFieldTypesEnum::LAST
&& "forbidden TypeId");
708 const sal_uInt16 nPos
= GetPos(nTypeId
);
710 if (nPos
== USHRT_MAX
)
713 const TranslateId
* pStart
= aSwFields
[nPos
].pFormatResIds
;
717 if (SwFieldTypesEnum::Author
== nTypeId
|| SwFieldTypesEnum::Filename
== nTypeId
)
718 nFormatId
&= ~static_cast<sal_uInt32
>(FF_FIXED
); // mask out Fixed-Flag
720 if (nFormatId
< aSwFields
[nPos
].nFormatLength
)
721 return SwResId(pStart
[nFormatId
]);
724 if (*pStart
== FMT_NUM_ARY
[0])
726 if (m_xNumberingInfo
.is())
728 const Sequence
<sal_Int16
> aTypes
= m_xNumberingInfo
->getSupportedNumberingTypes();
729 sal_Int32 nOffset
= aSwFields
[nPos
].nFormatLength
;
730 sal_uInt32 nValidEntry
= 0;
731 for (const sal_Int16 nCurrent
: aTypes
)
733 if(nCurrent
> NumberingType::CHARS_LOWER_LETTER_N
&&
734 (nCurrent
!= (NumberingType::BITMAP
| LINK_TOKEN
)))
736 if (nValidEntry
== nFormatId
- nOffset
)
738 sal_uInt32 n
= SvxNumberingTypeTable::FindIndex(nCurrent
);
739 if (n
!= RESARRAY_INDEX_NOTFOUND
)
741 aRet
= SvxNumberingTypeTable::GetString(n
);
745 aRet
= m_xNumberingInfo
->getNumberingIdentifier( nCurrent
);
758 // determine FormatId from Pseudo-ID
759 sal_uInt16
SwFieldMgr::GetFormatId(SwFieldTypesEnum nTypeId
, sal_uInt32 nFormatId
) const
761 sal_uInt16 nId
= o3tl::narrowing
<sal_uInt16
>(nFormatId
);
764 case SwFieldTypesEnum::DocumentInfo
:
766 TranslateId sId
= aSwFields
[GetPos(nTypeId
)].pFormatResIds
[nFormatId
];
767 if (sId
== FMT_REG_AUTHOR
)
769 else if (sId
== FMT_REG_TIME
)
771 else if (sId
== FMT_REG_DATE
)
775 case SwFieldTypesEnum::PageNumber
:
776 case SwFieldTypesEnum::NextPage
:
777 case SwFieldTypesEnum::PreviousPage
:
778 case SwFieldTypesEnum::DocumentStatistics
:
779 case SwFieldTypesEnum::DatabaseSetNumber
:
780 case SwFieldTypesEnum::Sequence
:
781 case SwFieldTypesEnum::GetRefPage
:
783 sal_uInt16 nPos
= GetPos(nTypeId
);
784 if (nFormatId
< aSwFields
[nPos
].nFormatLength
)
786 const TranslateId sId
= aSwFields
[nPos
].pFormatResIds
[nFormatId
];
787 if (sId
== FMT_NUM_ABC
)
788 nId
= SVX_NUM_CHARS_UPPER_LETTER
;
789 else if (sId
== FMT_NUM_SABC
)
790 nId
= SVX_NUM_CHARS_LOWER_LETTER
;
791 else if (sId
== FMT_NUM_ROMAN
)
792 nId
= SVX_NUM_ROMAN_UPPER
;
793 else if (sId
== FMT_NUM_SROMAN
)
794 nId
= SVX_NUM_ROMAN_LOWER
;
795 else if (sId
== FMT_NUM_ARABIC
)
796 nId
= SVX_NUM_ARABIC
;
797 else if (sId
== FMT_NUM_PAGEDESC
)
798 nId
= SVX_NUM_PAGEDESC
;
799 else if (sId
== FMT_NUM_PAGESPECIAL
)
800 nId
= SVX_NUM_CHAR_SPECIAL
;
801 else if (sId
== FMT_NUM_ABC_N
)
802 nId
= SVX_NUM_CHARS_UPPER_LETTER_N
;
803 else if (sId
== FMT_NUM_SABC_N
)
804 nId
= SVX_NUM_CHARS_LOWER_LETTER_N
;
806 else if (m_xNumberingInfo
.is())
808 const Sequence
<sal_Int16
> aTypes
= m_xNumberingInfo
->getSupportedNumberingTypes();
809 sal_Int32 nOffset
= aSwFields
[nPos
].nFormatLength
;
810 sal_Int32 nValidEntry
= 0;
811 for (const sal_Int16 nCurrent
: aTypes
)
813 if (nCurrent
> NumberingType::CHARS_LOWER_LETTER_N
)
815 if (nValidEntry
== static_cast<sal_Int32
>(nFormatId
) - nOffset
)
826 case SwFieldTypesEnum::DDE
:
828 const TranslateId sId
= aSwFields
[GetPos(nTypeId
)].pFormatResIds
[nFormatId
];
829 if (sId
== FMT_DDE_NORMAL
)
830 nId
= static_cast<sal_uInt16
>(SfxLinkUpdateMode::ONCALL
);
831 else if (sId
== FMT_DDE_HOT
)
832 nId
= static_cast<sal_uInt16
>(SfxLinkUpdateMode::ALWAYS
);
841 bool SwFieldMgr::GoNextPrev( bool bNext
, SwFieldType
* pTyp
)
843 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
847 if( !pTyp
&& m_pCurField
)
849 const SwFieldTypesEnum nTypeId
= m_pCurField
->GetTypeId();
850 if( SwFieldTypesEnum::SetInput
== nTypeId
|| SwFieldTypesEnum::UserInput
== nTypeId
)
851 pTyp
= pSh
->GetFieldType( 0, SwFieldIds::Input
);
853 pTyp
= m_pCurField
->GetTyp();
856 if (pTyp
&& pTyp
->Which() == SwFieldIds::Database
)
858 // for fieldcommand-edit (hop to all DB fields)
859 return pSh
->MoveFieldType( nullptr, bNext
, SwFieldIds::Database
);
862 return pTyp
&& pSh
->MoveFieldType(pTyp
, bNext
);
865 // insert field types
866 void SwFieldMgr::InsertFieldType(SwFieldType
const & rType
)
868 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
869 OSL_ENSURE(pSh
, "no SwWrtShell found");
871 pSh
->InsertFieldType(rType
);
874 // determine current TypeId
875 SwFieldTypesEnum
SwFieldMgr::GetCurTypeId() const
877 return m_pCurField
? m_pCurField
->GetTypeId() : SwFieldTypesEnum::Unknown
;
880 // Over string insert field or update
881 bool SwFieldMgr::InsertField(
882 SwInsertField_Data
& rData
)
884 std::unique_ptr
<SwField
> pField
;
887 bool bPageVar
= false;
888 sal_uInt32 nFormatId
= rData
.m_nFormatId
;
889 sal_uInt16 nSubType
= rData
.m_nSubType
;
890 sal_Unicode cSeparator
= rData
.m_cSeparator
;
891 SwWrtShell
* pCurShell
= rData
.m_pSh
;
893 pCurShell
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
894 OSL_ENSURE(pCurShell
, "no SwWrtShell found");
898 switch (rData
.m_nTypeId
)
899 { // ATTENTION this field is inserted by a separate dialog
900 case SwFieldTypesEnum::Postit
:
902 SvtUserOptions aUserOpt
;
903 SwPostItFieldType
* pType
= static_cast<SwPostItFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::Postit
));
907 rData
.m_sPar1
, // author
908 rData
.m_sPar2
, // content
909 aUserOpt
.GetID(), // author's initials
911 DateTime(DateTime::SYSTEM
) ));
914 case SwFieldTypesEnum::Script
:
916 SwScriptFieldType
* pType
=
917 static_cast<SwScriptFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::Script
));
918 pField
.reset(new SwScriptField(pType
, rData
.m_sPar1
, rData
.m_sPar2
, static_cast<bool>(nFormatId
)));
922 case SwFieldTypesEnum::CombinedChars
:
924 SwCombinedCharFieldType
* pType
= static_cast<SwCombinedCharFieldType
*>(
925 pCurShell
->GetFieldType( 0, SwFieldIds::CombinedChars
));
926 pField
.reset(new SwCombinedCharField( pType
, rData
.m_sPar1
));
930 case SwFieldTypesEnum::Authority
:
932 SwAuthorityFieldType
* pType
=
933 static_cast<SwAuthorityFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::TableOfAuthorities
));
936 SwAuthorityFieldType
const type(pCurShell
->GetDoc());
937 pType
= static_cast<SwAuthorityFieldType
*>(
938 pCurShell
->InsertFieldType(type
));
940 pField
.reset(new SwAuthorityField(pType
, rData
.m_sPar1
));
944 case SwFieldTypesEnum::Date
:
945 case SwFieldTypesEnum::Time
:
947 sal_uInt16 nSub
= static_cast< sal_uInt16
>(rData
.m_nTypeId
== SwFieldTypesEnum::Date
? DATEFLD
: TIMEFLD
);
948 nSub
|= nSubType
== DATE_VAR
? 0 : FIXEDFLD
;
950 SwDateTimeFieldType
* pTyp
=
951 static_cast<SwDateTimeFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::DateTime
) );
952 pField
.reset(new SwDateTimeField(pTyp
, nSub
, nFormatId
));
953 pField
->SetPar2(rData
.m_sPar2
);
957 case SwFieldTypesEnum::Filename
:
959 SwFileNameFieldType
* pTyp
=
960 static_cast<SwFileNameFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::Filename
) );
961 pField
.reset(new SwFileNameField(pTyp
, nFormatId
));
965 case SwFieldTypesEnum::TemplateName
:
967 SwTemplNameFieldType
* pTyp
=
968 static_cast<SwTemplNameFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::TemplateName
) );
969 pField
.reset(new SwTemplNameField(pTyp
, nFormatId
));
973 case SwFieldTypesEnum::Chapter
:
975 sal_uInt16 nByte
= o3tl::narrowing
<sal_uInt16
>(rData
.m_sPar2
.toInt32());
976 SwChapterFieldType
* pTyp
=
977 static_cast<SwChapterFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::Chapter
) );
978 pField
.reset(new SwChapterField(pTyp
, nFormatId
));
979 nByte
= std::max(sal_uInt16(1), nByte
);
980 nByte
= std::min(nByte
, sal_uInt16(MAXLEVEL
));
982 static_cast<SwChapterField
*>(pField
.get())->SetLevel(static_cast<sal_uInt8
>(nByte
));
986 case SwFieldTypesEnum::NextPage
:
987 case SwFieldTypesEnum::PreviousPage
:
988 case SwFieldTypesEnum::PageNumber
:
990 short nOff
= static_cast<short>(rData
.m_sPar2
.toInt32());
992 if(rData
.m_nTypeId
== SwFieldTypesEnum::NextPage
)
994 if( SVX_NUM_CHAR_SPECIAL
== nFormatId
)
1000 else if(rData
.m_nTypeId
== SwFieldTypesEnum::PreviousPage
)
1002 if( SVX_NUM_CHAR_SPECIAL
== nFormatId
)
1009 nSubType
= PG_RANDOM
;
1011 SwPageNumberFieldType
* pTyp
=
1012 static_cast<SwPageNumberFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::PageNumber
) );
1013 pField
.reset(new SwPageNumberField(pTyp
, nSubType
, nFormatId
, nOff
));
1015 if( SVX_NUM_CHAR_SPECIAL
== nFormatId
&&
1016 ( PG_PREV
== nSubType
|| PG_NEXT
== nSubType
) )
1017 static_cast<SwPageNumberField
*>(pField
.get())->SetUserString( rData
.m_sPar2
);
1021 case SwFieldTypesEnum::DocumentStatistics
:
1023 SwDocStatFieldType
* pTyp
=
1024 static_cast<SwDocStatFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::DocStat
) );
1025 pField
.reset(new SwDocStatField(pTyp
, nSubType
, nFormatId
));
1029 case SwFieldTypesEnum::Author
:
1031 SwAuthorFieldType
* pTyp
=
1032 static_cast<SwAuthorFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::Author
) );
1033 pField
.reset(new SwAuthorField(pTyp
, nFormatId
));
1037 case SwFieldTypesEnum::ConditionalText
:
1038 case SwFieldTypesEnum::HiddenText
:
1040 SwHiddenTextFieldType
* pTyp
=
1041 static_cast<SwHiddenTextFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::HiddenText
) );
1042 pField
.reset(new SwHiddenTextField(pTyp
, true, rData
.m_sPar1
, rData
.m_sPar2
, false, rData
.m_nTypeId
));
1047 case SwFieldTypesEnum::HiddenParagraph
:
1049 SwHiddenParaFieldType
* pTyp
=
1050 static_cast<SwHiddenParaFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::HiddenPara
) );
1051 pField
.reset(new SwHiddenParaField(pTyp
, rData
.m_sPar1
));
1056 case SwFieldTypesEnum::SetRef
:
1058 if( !rData
.m_sPar1
.isEmpty() && CanInsertRefMark( rData
.m_sPar1
) )
1060 const OUString
& rRefmarkText
= rData
.m_sPar2
;
1061 SwPaM
* pCursorPos
= pCurShell
->GetCursor();
1062 pCurShell
->StartAction();
1063 bool bHadMark
= pCursorPos
->HasMark();
1064 // If we have no selection and the refmark text is provided, then the text is
1065 // expected to be HTML.
1066 if (!bHadMark
&& !rRefmarkText
.isEmpty())
1068 // Split node to remember where the start position is.
1069 bool bSuccess
= pCurShell
->GetDoc()->getIDocumentContentOperations().SplitNode(
1070 *pCursorPos
->GetPoint(), /*bChkTableStart=*/false);
1073 SwPaM
aRefmarkPam(*pCursorPos
->GetPoint());
1074 aRefmarkPam
.Move(fnMoveBackward
, GoInContent
);
1076 // Paste HTML content.
1077 SwTranslateHelper::PasteHTMLToPaM(
1078 *pCurShell
, pCursorPos
, rRefmarkText
.toUtf8());
1080 // Undo the above SplitNode().
1081 aRefmarkPam
.SetMark();
1082 aRefmarkPam
.Move(fnMoveForward
, GoInContent
);
1083 pCurShell
->GetDoc()->getIDocumentContentOperations().DeleteAndJoin(
1085 *aRefmarkPam
.GetMark() = *pCursorPos
->GetPoint();
1086 *pCursorPos
= aRefmarkPam
;
1090 pCurShell
->SetAttrItem( SwFormatRefMark( rData
.m_sPar1
) );
1092 if (!bHadMark
&& !rRefmarkText
.isEmpty())
1094 pCursorPos
->DeleteMark();
1096 pCurShell
->EndAction();
1102 case SwFieldTypesEnum::GetRef
:
1104 SwGetRefFieldType
* pTyp
=
1105 static_cast<SwGetRefFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::GetRef
) );
1107 sal_uInt16 nSeqNo
= 0;
1108 sal_uInt16 nFlags
= 0;
1110 if (nSubType
== REF_STYLE
) nFlags
= o3tl::narrowing
<sal_uInt16
>(rData
.m_sPar2
.toInt32());
1111 else nSeqNo
= o3tl::narrowing
<sal_uInt16
>(rData
.m_sPar2
.toInt32());
1113 OUString sReferenceLanguage
;
1114 // handle language-variant formats
1115 if (nFormatId
>= SAL_N_ELEMENTS(FMT_REF_ARY
))
1117 LanguageType nLang
= GetCurrLanguage();
1118 if (nLang
== LANGUAGE_HUNGARIAN
)
1120 if (nFormatId
>= SAL_N_ELEMENTS(FMT_REF_ARY
) * 2)
1121 sReferenceLanguage
= "Hu";
1123 sReferenceLanguage
= "hu";
1125 nFormatId
%= SAL_N_ELEMENTS(FMT_REF_ARY
);
1128 pField
.reset(new SwGetRefField(pTyp
, rData
.m_sPar1
, sReferenceLanguage
, nSubType
, nSeqNo
, nFlags
, nFormatId
));
1133 case SwFieldTypesEnum::DDE
:
1135 //JP 28.08.95: DDE-Topics/-Items can have blanks in their names!
1136 // That's not yet considered here.
1137 sal_Int32 nIndex
= 0;
1138 OUString sCmd
= rData
.m_sPar2
.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator
), &nIndex
);
1139 if (nIndex
>=0 && ++nIndex
<sCmd
.getLength())
1141 sCmd
= sCmd
.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator
), &nIndex
);
1144 SwDDEFieldType
aType( rData
.m_sPar1
, sCmd
, static_cast<SfxLinkUpdateMode
>(nFormatId
) );
1145 SwDDEFieldType
* pTyp
= static_cast<SwDDEFieldType
*>( pCurShell
->InsertFieldType( aType
) );
1146 pField
.reset(new SwDDEField( pTyp
));
1150 case SwFieldTypesEnum::Macro
:
1152 SwMacroFieldType
* pTyp
=
1153 static_cast<SwMacroFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::Macro
));
1155 pField
.reset(new SwMacroField(pTyp
, rData
.m_sPar1
, rData
.m_sPar2
));
1160 case SwFieldTypesEnum::Internet
:
1162 SwFormatINetFormat
aFormat( rData
.m_sPar1
, m_sCurFrame
);
1163 return pCurShell
->InsertURL( aFormat
, rData
.m_sPar2
);
1166 case SwFieldTypesEnum::JumpEdit
:
1168 SwJumpEditFieldType
* pTyp
=
1169 static_cast<SwJumpEditFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::JumpEdit
));
1171 pField
.reset(new SwJumpEditField(pTyp
, nFormatId
, rData
.m_sPar1
, rData
.m_sPar2
));
1175 case SwFieldTypesEnum::DocumentInfo
:
1177 SwDocInfoFieldType
* pTyp
= static_cast<SwDocInfoFieldType
*>( pCurShell
->GetFieldType(
1178 0, SwFieldIds::DocInfo
) );
1179 pField
.reset(new SwDocInfoField(pTyp
, nSubType
, rData
.m_sPar1
, nFormatId
));
1183 case SwFieldTypesEnum::ExtendedUser
:
1185 SwExtUserFieldType
* pTyp
= static_cast<SwExtUserFieldType
*>( pCurShell
->GetFieldType(
1186 0, SwFieldIds::ExtUser
) );
1187 pField
.reset(new SwExtUserField(pTyp
, nSubType
, nFormatId
));
1191 case SwFieldTypesEnum::Database
:
1193 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1197 if (rData
.m_sPar1
.indexOf(DB_DELIM
)<0)
1199 aDBData
= pCurShell
->GetDBData();
1200 sPar1
= rData
.m_sPar1
;
1204 sal_Int32 nIdx
{ 0 };
1205 aDBData
.sDataSource
= rData
.m_sPar1
.getToken(0, DB_DELIM
, nIdx
);
1206 aDBData
.sCommand
= rData
.m_sPar1
.getToken(0, DB_DELIM
, nIdx
);
1207 aDBData
.nCommandType
= o3tl::toInt32(o3tl::getToken(rData
.m_sPar1
, 0, DB_DELIM
, nIdx
));
1208 sPar1
= rData
.m_sPar1
.getToken(0, DB_DELIM
, nIdx
);
1211 if(!aDBData
.sDataSource
.isEmpty() && pCurShell
->GetDBData() != aDBData
)
1212 pCurShell
->ChgDBData(aDBData
);
1214 SwDBFieldType
* pTyp
= static_cast<SwDBFieldType
*>(pCurShell
->InsertFieldType(
1215 SwDBFieldType(pCurShell
->GetDoc(), sPar1
, aDBData
) ) );
1216 pField
.reset(new SwDBField(pTyp
));
1217 pField
->SetSubType(nSubType
);
1219 if( !(nSubType
& nsSwExtendedSubType::SUB_OWN_FMT
) ) // determine database format
1221 Reference
< XDataSource
> xSource
;
1222 rData
.m_aDBDataSource
>>= xSource
;
1223 Reference
<XConnection
> xConnection
;
1224 rData
.m_aDBConnection
>>= xConnection
;
1225 Reference
<XPropertySet
> xColumn
;
1226 rData
.m_aDBColumn
>>= xColumn
;
1229 nFormatId
= SwDBManager::GetColumnFormat(xSource
, xConnection
, xColumn
,
1230 pCurShell
->GetNumberFormatter(), GetCurrLanguage() );
1233 nFormatId
= pCurShell
->GetDBManager()->GetColumnFormat(
1234 aDBData
.sDataSource
, aDBData
.sCommand
, sPar1
,
1235 pCurShell
->GetNumberFormatter(), GetCurrLanguage() );
1237 pField
->ChangeFormat( nFormatId
);
1244 case SwFieldTypesEnum::DatabaseSetNumber
:
1245 case SwFieldTypesEnum::DatabaseNumberSet
:
1246 case SwFieldTypesEnum::DatabaseNextSet
:
1247 case SwFieldTypesEnum::DatabaseName
:
1249 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1252 // extract DBName from rData.m_sPar1. Format: DBName.TableName.CommandType.ExpStrg
1253 sal_Int32 nTablePos
= rData
.m_sPar1
.indexOf(DB_DELIM
);
1254 sal_Int32 nExpPos
= -1;
1258 aDBData
.sDataSource
= rData
.m_sPar1
.copy(0, nTablePos
++);
1259 sal_Int32 nCmdTypePos
= rData
.m_sPar1
.indexOf(DB_DELIM
, nTablePos
);
1262 aDBData
.sCommand
= rData
.m_sPar1
.copy(nTablePos
, nCmdTypePos
++ - nTablePos
);
1263 nExpPos
= rData
.m_sPar1
.indexOf(DB_DELIM
, nCmdTypePos
);
1266 aDBData
.nCommandType
= o3tl::toInt32(rData
.m_sPar1
.subView(nCmdTypePos
, nExpPos
++ - nCmdTypePos
));
1274 else if (nTablePos
>=0)
1277 OUString sPar1
= rData
.m_sPar1
.copy(nPos
);
1279 if (!aDBData
.sDataSource
.isEmpty() && pCurShell
->GetDBData() != aDBData
)
1280 pCurShell
->ChgDBData(aDBData
);
1282 switch(rData
.m_nTypeId
)
1284 case SwFieldTypesEnum::DatabaseName
:
1286 SwDBNameFieldType
* pTyp
=
1287 static_cast<SwDBNameFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::DatabaseName
));
1288 pField
.reset(new SwDBNameField(pTyp
, aDBData
));
1292 case SwFieldTypesEnum::DatabaseNextSet
:
1294 SwDBNextSetFieldType
* pTyp
= static_cast<SwDBNextSetFieldType
*>(pCurShell
->GetFieldType(
1295 0, SwFieldIds::DbNextSet
) );
1296 pField
.reset(new SwDBNextSetField(pTyp
, sPar1
, aDBData
));
1300 case SwFieldTypesEnum::DatabaseNumberSet
:
1302 SwDBNumSetFieldType
* pTyp
= static_cast<SwDBNumSetFieldType
*>( pCurShell
->GetFieldType(
1303 0, SwFieldIds::DbNumSet
) );
1304 pField
.reset(new SwDBNumSetField( pTyp
, sPar1
, rData
.m_sPar2
, aDBData
));
1308 case SwFieldTypesEnum::DatabaseSetNumber
:
1310 SwDBSetNumberFieldType
* pTyp
= static_cast<SwDBSetNumberFieldType
*>(
1311 pCurShell
->GetFieldType(0, SwFieldIds::DbSetNumber
) );
1312 pField
.reset(new SwDBSetNumberField( pTyp
, aDBData
, nFormatId
));
1322 case SwFieldTypesEnum::User
:
1324 SwUserFieldType
* pTyp
=
1325 static_cast<SwUserFieldType
*>( pCurShell
->GetFieldType(SwFieldIds::User
, rData
.m_sPar1
) );
1330 pTyp
= static_cast<SwUserFieldType
*>( pCurShell
->InsertFieldType(
1331 SwUserFieldType(pCurShell
->GetDoc(), rData
.m_sPar1
)) );
1333 if (pTyp
->GetContent(nFormatId
) != rData
.m_sPar2
)
1334 pTyp
->SetContent(rData
.m_sPar2
, nFormatId
);
1335 pField
.reset(new SwUserField(pTyp
, 0, nFormatId
));
1336 if (pField
->GetSubType() != nSubType
)
1337 pField
->SetSubType(nSubType
);
1342 case SwFieldTypesEnum::Input
:
1344 if ((nSubType
& 0x00ff) == INP_VAR
)
1346 SwSetExpFieldType
* pTyp
= static_cast<SwSetExpFieldType
*>(
1347 pCurShell
->GetFieldType(SwFieldIds::SetExp
, rData
.m_sPar1
) );
1349 // no Expression Type with this name existing -> create
1352 std::unique_ptr
<SwSetExpField
> pExpField(
1353 new SwSetExpField(pTyp
, OUString(), nFormatId
));
1355 // Don't change type of SwSetExpFieldType:
1356 sal_uInt16 nOldSubType
= pExpField
->GetSubType();
1357 pExpField
->SetSubType(nOldSubType
| (nSubType
& 0xff00));
1359 pExpField
->SetPromptText(rData
.m_sPar2
);
1360 pExpField
->SetInputFlag(true) ;
1362 pField
= std::move(pExpField
);
1369 SwInputFieldType
* pTyp
=
1370 static_cast<SwInputFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::Input
) );
1373 new SwInputField( pTyp
, rData
.m_sPar1
, rData
.m_sPar2
, nSubType
|nsSwExtendedSubType::SUB_INVISIBLE
, nFormatId
));
1378 case SwFieldTypesEnum::Set
:
1380 if (rData
.m_sPar2
.isEmpty()) // empty variables are not allowed
1383 SwSetExpFieldType
* pTyp
= static_cast<SwSetExpFieldType
*>( pCurShell
->InsertFieldType(
1384 SwSetExpFieldType(pCurShell
->GetDoc(), rData
.m_sPar1
) ) );
1386 std::unique_ptr
<SwSetExpField
> pExpField(new SwSetExpField( pTyp
, rData
.m_sPar2
, nFormatId
));
1387 pExpField
->SetSubType(nSubType
);
1388 pExpField
->SetPar2(rData
.m_sPar2
);
1390 pField
= std::move(pExpField
);
1394 case SwFieldTypesEnum::Sequence
:
1396 SwSetExpFieldType
* pTyp
= static_cast<SwSetExpFieldType
*>( pCurShell
->InsertFieldType(
1397 SwSetExpFieldType(pCurShell
->GetDoc(), rData
.m_sPar1
, nsSwGetSetExpType::GSE_SEQ
)));
1399 sal_uInt8 nLevel
= static_cast< sal_uInt8
>(nSubType
& 0xff);
1401 pTyp
->SetOutlineLvl(nLevel
);
1402 if (nLevel
!= 0x7f && cSeparator
== 0)
1405 pTyp
->SetDelimiter(OUString(cSeparator
));
1406 pField
.reset(new SwSetExpField(pTyp
, rData
.m_sPar2
, nFormatId
));
1411 case SwFieldTypesEnum::Get
:
1413 // is there a corresponding SetField
1414 SwSetExpFieldType
* pSetTyp
= static_cast<SwSetExpFieldType
*>(
1415 pCurShell
->GetFieldType(SwFieldIds::SetExp
, rData
.m_sPar1
));
1419 SwGetExpFieldType
* pTyp
= static_cast<SwGetExpFieldType
*>( pCurShell
->GetFieldType(
1420 0, SwFieldIds::GetExp
) );
1421 pField
.reset( new SwGetExpField(pTyp
, rData
.m_sPar1
, pSetTyp
->GetType(), nFormatId
) );
1422 pField
->SetSubType(nSubType
| pSetTyp
->GetType());
1430 case SwFieldTypesEnum::Formel
:
1432 if(pCurShell
->GetFrameType(nullptr,false) & FrameTypeFlags::TABLE
)
1434 pCurShell
->StartAllAction();
1436 SvNumberFormatter
* pFormatter
= pCurShell
->GetDoc()->GetNumberFormatter();
1437 const SvNumberformat
* pEntry
= pFormatter
->GetEntry(nFormatId
);
1441 SfxStringItem
aFormat(FN_NUMBER_FORMAT
, pEntry
->GetFormatstring());
1442 pCurShell
->GetView().GetViewFrame().GetDispatcher()->
1443 ExecuteList(FN_NUMBER_FORMAT
, SfxCallMode::SYNCHRON
,
1447 SfxItemSet
aBoxSet(SfxItemSet::makeFixedSfxItemSet
<RES_BOXATR_FORMULA
, RES_BOXATR_FORMULA
>(pCurShell
->GetAttrPool()));
1449 OUString
sFormula(comphelper::string::stripStart(rData
.m_sPar2
, ' '));
1450 if ( sFormula
.startsWith("=") )
1452 sFormula
= sFormula
.copy(1);
1455 aBoxSet
.Put( SwTableBoxFormula( sFormula
));
1456 pCurShell
->SetTableBoxFormulaAttrs( aBoxSet
);
1457 pCurShell
->UpdateTable();
1459 pCurShell
->EndAllAction();
1465 SwGetExpFieldType
* pTyp
= static_cast<SwGetExpFieldType
*>(
1466 pCurShell
->GetFieldType(0, SwFieldIds::GetExp
) );
1467 pField
.reset( new SwGetExpField(pTyp
, rData
.m_sPar2
, nsSwGetSetExpType::GSE_FORMULA
, nFormatId
) );
1468 pField
->SetSubType(nSubType
);
1473 case SwFieldTypesEnum::SetRefPage
:
1474 pField
.reset( new SwRefPageSetField( static_cast<SwRefPageSetFieldType
*>(
1475 pCurShell
->GetFieldType( 0, SwFieldIds::RefPageSet
) ),
1476 static_cast<short>(rData
.m_sPar2
.toInt32()), 0 != nSubType
) );
1480 case SwFieldTypesEnum::GetRefPage
:
1481 pField
.reset( new SwRefPageGetField( static_cast<SwRefPageGetFieldType
*>(
1482 pCurShell
->GetFieldType( 0, SwFieldIds::RefPageGet
) ), nFormatId
) );
1485 case SwFieldTypesEnum::Dropdown
:
1487 pField
.reset( new SwDropDownField(pCurShell
->GetFieldType( 0, SwFieldIds::Dropdown
)) );
1488 const sal_Int32 nTokenCount
= comphelper::string::getTokenCount(rData
.m_sPar2
, DB_DELIM
);
1489 Sequence
<OUString
> aEntries(nTokenCount
);
1490 OUString
* pArray
= aEntries
.getArray();
1491 for(sal_Int32 nToken
= 0, nIdx
= 0; nToken
< nTokenCount
; nToken
++)
1492 pArray
[nToken
] = rData
.m_sPar2
.getToken(0, DB_DELIM
, nIdx
);
1493 static_cast<SwDropDownField
*>(pField
.get())->SetItems(aEntries
);
1494 static_cast<SwDropDownField
*>(pField
.get())->SetName(rData
.m_sPar1
);
1498 // Insert Paragraph Signature field by signing the paragraph.
1499 // The resulting field is really a metadata field, created and added via signing.
1500 case SwFieldTypesEnum::ParagraphSignature
:
1501 pCurShell
->SignParagraph();
1505 { OSL_ENSURE(false, "wrong field type");
1509 OSL_ENSURE(pField
, "field not available");
1511 //the auto language flag has to be set prior to the language!
1512 pField
->SetAutomaticLanguage(rData
.m_bIsAutomaticLanguage
);
1513 LanguageType nLang
= GetCurrLanguage();
1514 pField
->SetLanguage(nLang
);
1517 pCurShell
->StartAllAction();
1519 bool const isSuccess
= pCurShell
->InsertField2(*pField
, rData
.m_oAnnotationRange
? &*rData
.m_oAnnotationRange
: nullptr);
1523 if (SwFieldTypesEnum::Input
== rData
.m_nTypeId
)
1527 // start dialog, not before the field is inserted tdf#99529
1528 pCurShell
->Left(SwCursorSkipMode::Chars
, false,
1529 (INP_VAR
== (nSubType
& 0xff) || pCurShell
->GetViewOptions()->IsFieldName()) ? 1 : 2,
1531 pCurShell
->StartInputFieldDlg(pField
.get(), false, true, rData
.m_pParent
);
1533 pCurShell
->Pop(SwCursorShell::PopMode::DeleteCurrent
);
1536 if (bExp
&& m_bEvalExp
)
1538 pCurShell
->UpdateExpFields(true);
1543 pCurShell
->Left(SwCursorSkipMode::Chars
, false, 1, false );
1544 pCurShell
->UpdateOneField(*pField
);
1545 pCurShell
->Right(SwCursorSkipMode::Chars
, false, 1, false );
1549 static_cast<SwRefPageGetFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::RefPageGet
))->UpdateFields();
1551 else if (SwFieldTypesEnum::GetRef
== rData
.m_nTypeId
)
1553 pField
->GetTyp()->UpdateFields();
1557 // delete temporary field
1560 pCurShell
->EndAllAction();
1565 void SwFieldMgr::UpdateCurField(sal_uInt32 nFormat
,
1566 const OUString
& rPar1
,
1567 const OUString
& rPar2
,
1568 std::unique_ptr
<SwField
> pTmpField
)
1571 OSL_ENSURE(m_pCurField
, "no field at CursorPos");
1574 pTmpField
= m_pCurField
->CopyField();
1576 SwFieldType
* pType
= pTmpField
->GetTyp();
1577 const SwFieldTypesEnum nTypeId
= pTmpField
->GetTypeId();
1579 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
1580 OSL_ENSURE(pSh
, "no SwWrtShell found");
1583 pSh
->StartAllAction();
1585 bool bSetPar2
= true;
1586 bool bSetPar1
= true;
1587 OUString
sPar2( rPar2
);
1592 case SwFieldTypesEnum::DDE
:
1594 // DDE-Topics/-Items can have blanks in their names!
1595 // That's not yet considered here!
1596 sal_Int32 nIndex
= 0;
1597 sPar2
= sPar2
.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator
), &nIndex
);
1598 if (nIndex
>=0 && ++nIndex
<sPar2
.getLength())
1600 sPar2
= sPar2
.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator
), &nIndex
);
1605 case SwFieldTypesEnum::Chapter
:
1607 sal_uInt16 nByte
= o3tl::narrowing
<sal_uInt16
>(rPar2
.toInt32());
1608 nByte
= std::max(sal_uInt16(1), nByte
);
1609 nByte
= std::min(nByte
, sal_uInt16(MAXLEVEL
));
1611 static_cast<SwChapterField
*>(pTmpField
.get())->SetLevel(static_cast<sal_uInt8
>(nByte
));
1616 case SwFieldTypesEnum::Script
:
1617 static_cast<SwScriptField
*>(pTmpField
.get())->SetCodeURL(static_cast<bool>(nFormat
));
1620 case SwFieldTypesEnum::NextPage
:
1621 if( SVX_NUM_CHAR_SPECIAL
== nFormat
)
1623 static_cast<SwPageNumberField
*>(m_pCurField
)->SetUserString( sPar2
);
1628 if( nFormat
+ 2 == SVX_NUM_PAGEDESC
)
1629 nFormat
= SVX_NUM_PAGEDESC
;
1630 short nOff
= static_cast<short>(sPar2
.toInt32());
1632 sPar2
= OUString::number(nOff
);
1636 case SwFieldTypesEnum::PreviousPage
:
1637 if( SVX_NUM_CHAR_SPECIAL
== nFormat
)
1639 static_cast<SwPageNumberField
*>(m_pCurField
)->SetUserString( sPar2
);
1644 if( nFormat
+ 2 == SVX_NUM_PAGEDESC
)
1645 nFormat
= SVX_NUM_PAGEDESC
;
1646 short nOff
= static_cast<short>(sPar2
.toInt32());
1648 sPar2
= OUString::number(nOff
);
1652 case SwFieldTypesEnum::PageNumber
:
1653 case SwFieldTypesEnum::GetRefPage
:
1654 if( nFormat
+ 2 == SVX_NUM_PAGEDESC
)
1655 nFormat
= SVX_NUM_PAGEDESC
;
1658 case SwFieldTypesEnum::GetRef
:
1661 sal_Int16 nSubType
= o3tl::narrowing
<sal_uInt16
>(rPar2
.toInt32());
1662 static_cast<SwGetRefField
*>(pTmpField
.get())->SetSubType( nSubType
);
1663 const sal_Int32 nPos
= rPar2
.indexOf( '|' );
1667 static_cast<SwGetRefField
*>(pTmpField
.get())->SetFlags( o3tl::narrowing
<sal_uInt16
>(o3tl::toInt32(rPar2
.subView( nPos
+ 1 ))));
1670 static_cast<SwGetRefField
*>(pTmpField
.get())->SetSeqNo( o3tl::narrowing
<sal_uInt16
>(o3tl::toInt32(rPar2
.subView( nPos
+ 1 ))));
1674 case SwFieldTypesEnum::Dropdown
:
1676 sal_Int32 nTokenCount
= comphelper::string::getTokenCount(sPar2
, DB_DELIM
);
1677 Sequence
<OUString
> aEntries(nTokenCount
);
1678 OUString
* pArray
= aEntries
.getArray();
1679 for(sal_Int32 nToken
= 0, nIdx
= 0; nToken
< nTokenCount
; nToken
++)
1680 pArray
[nToken
] = sPar2
.getToken(0, DB_DELIM
, nIdx
);
1681 static_cast<SwDropDownField
*>(pTmpField
.get())->SetItems(aEntries
);
1682 static_cast<SwDropDownField
*>(pTmpField
.get())->SetName(rPar1
);
1683 bSetPar1
= bSetPar2
= false;
1686 case SwFieldTypesEnum::Authority
:
1688 //#i99069# changes to a bibliography field should change the field type
1689 SwAuthorityField
* pAuthorityField
= static_cast<SwAuthorityField
*>(pTmpField
.get());
1690 SwAuthorityFieldType
* pAuthorityType
= static_cast<SwAuthorityFieldType
*>(pType
);
1691 rtl::Reference
<SwAuthEntry
> xTempEntry(new SwAuthEntry
);
1692 for( sal_Int32 i
= 0, nIdx
= 0; i
< AUTH_FIELD_END
; ++i
)
1693 xTempEntry
->SetAuthorField( static_cast<ToxAuthorityField
>(i
),
1694 rPar1
.getToken( 0, TOX_STYLE_DELIMITER
, nIdx
));
1696 // If just the page number of the URL changed, then update the current field and not
1698 bool bEquivalent
= true;
1699 for (int i
= 0; i
< AUTH_FIELD_END
; ++i
)
1701 auto eField
= static_cast<ToxAuthorityField
>(i
);
1702 if (eField
== AUTH_FIELD_URL
)
1704 if (SwTOXAuthority::GetSourceURL(xTempEntry
->GetAuthorField(AUTH_FIELD_URL
))
1705 != SwTOXAuthority::GetSourceURL(
1706 pAuthorityField
->GetFieldText(AUTH_FIELD_URL
)))
1708 bEquivalent
= false;
1714 if (xTempEntry
->GetAuthorField(eField
) != pAuthorityField
->GetFieldText(eField
))
1716 bEquivalent
= false;
1727 if( pAuthorityType
->ChangeEntryContent( xTempEntry
.get() ) )
1729 pType
->UpdateFields();
1733 if( xTempEntry
->GetAuthorField( AUTH_FIELD_IDENTIFIER
) ==
1734 pAuthorityField
->GetFieldText( AUTH_FIELD_IDENTIFIER
) )
1735 bSetPar1
= false; //otherwise it's a new or changed entry, the field needs to be updated
1743 // setup format before SetPar2 because of NumberFormatter!
1744 pTmpField
->ChangeFormat(nFormat
);
1747 pTmpField
->SetPar1( rPar1
);
1749 pTmpField
->SetPar2( sPar2
);
1752 if(nTypeId
== SwFieldTypesEnum::DDE
||
1753 nTypeId
== SwFieldTypesEnum::User
||
1754 nTypeId
== SwFieldTypesEnum::UserInput
)
1756 pType
->UpdateFields();
1761 pSh
->SwEditShell::UpdateOneField(*pTmpField
);
1767 pSh
->EndAllAction();
1770 // explicitly evaluate ExpressionFields
1771 void SwFieldMgr::EvalExpFields(SwWrtShell
* pSh
)
1774 pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
1778 pSh
->StartAllAction();
1779 pSh
->UpdateExpFields(true);
1780 pSh
->EndAllAction();
1783 LanguageType
SwFieldMgr::GetCurrLanguage() const
1785 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
1787 return pSh
->GetCurLang();
1788 return SvtSysLocale().GetLanguageTag().getLanguageType();
1791 void SwFieldType::GetFieldName_()
1793 static const TranslateId coFieldNms
[] =
1839 STR_PARAGRAPH_SIGNATURE
1842 // insert infos for fields
1843 SwFieldType::s_pFieldNames
= new std::vector
<OUString
>;
1844 SwFieldType::s_pFieldNames
->reserve(SAL_N_ELEMENTS(coFieldNms
));
1845 for (const TranslateId
& id
: coFieldNms
)
1847 const OUString
aTmp(SwResId(id
));
1848 SwFieldType::s_pFieldNames
->push_back(MnemonicGenerator::EraseAllMnemonicChars( aTmp
));
1852 bool SwFieldMgr::ChooseMacro(weld::Window
* pDialogParent
)
1856 // choose script dialog
1857 OUString aScriptURL
= SfxApplication::ChooseScript(pDialogParent
);
1859 // the script selector dialog returns a valid script URL
1860 if ( !aScriptURL
.isEmpty() )
1862 SetMacroPath( aScriptURL
);
1869 void SwFieldMgr::SetMacroPath(const OUString
& rPath
)
1871 m_sMacroPath
= rPath
;
1872 m_sMacroName
= rPath
;
1874 // try to set sMacroName member variable by parsing the macro path
1875 // using the new URI parsing services
1877 const Reference
< XComponentContext
>& xContext
=
1878 ::comphelper::getProcessComponentContext();
1880 Reference
< uri::XUriReferenceFactory
>
1881 xFactory
= uri::UriReferenceFactory::create( xContext
);
1883 Reference
< uri::XVndSunStarScriptUrl
>
1884 xUrl( xFactory
->parse( m_sMacroPath
), UNO_QUERY
);
1888 m_sMacroName
= xUrl
->getName();
1892 sal_uInt32
SwFieldMgr::GetDefaultFormat(SwFieldTypesEnum nTypeId
, bool bIsText
, SvNumberFormatter
* pFormatter
)
1894 SvNumFormatType nDefFormat
;
1898 case SwFieldTypesEnum::Time
:
1899 case SwFieldTypesEnum::Date
:
1901 nDefFormat
= (nTypeId
== SwFieldTypesEnum::Date
) ? SvNumFormatType::DATE
: SvNumFormatType::TIME
;
1908 nDefFormat
= SvNumFormatType::TEXT
;
1912 nDefFormat
= SvNumFormatType::ALL
;
1917 return pFormatter
->GetStandardFormat(nDefFormat
, GetCurrLanguage());
1920 Reference
<XNumberingTypeInfo
> const & SwFieldMgr::GetNumberingInfo() const
1922 if(!m_xNumberingInfo
.is())
1924 const Reference
<XComponentContext
>& xContext( ::comphelper::getProcessComponentContext() );
1925 Reference
<XDefaultNumberingProvider
> xDefNum
= text::DefaultNumberingProvider::create(xContext
);
1926 const_cast<SwFieldMgr
*>(this)->m_xNumberingInfo
.set(xDefNum
, UNO_QUERY
);
1928 return m_xNumberingInfo
;
1931 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */