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>
69 #include <flddropdown.hxx>
70 #include <strings.hrc>
72 #include <viewopt.hxx>
74 #include <unotools/useroptions.hxx>
75 #include <IDocumentContentOperations.hxx>
76 #include <translatehelper.hxx>
78 using namespace com::sun::star::uno
;
79 using namespace com::sun::star::container
;
80 using namespace com::sun::star::lang
;
81 using namespace com::sun::star::beans
;
82 using namespace com::sun::star::text
;
83 using namespace com::sun::star::style
;
84 using namespace com::sun::star::sdbc
;
85 using namespace ::com::sun::star
;
86 using namespace nsSwDocInfoSubType
;
92 GRP_DOC_END
= GRP_DOC_BEGIN
+ 12,
94 GRP_FKT_BEGIN
= GRP_DOC_END
,
95 GRP_FKT_END
= GRP_FKT_BEGIN
+ 8,
97 GRP_REF_BEGIN
= GRP_FKT_END
,
98 GRP_REF_END
= GRP_REF_BEGIN
+ 2,
100 GRP_REG_BEGIN
= GRP_REF_END
,
101 GRP_REG_END
= GRP_REG_BEGIN
+ 1,
103 GRP_DB_BEGIN
= GRP_REG_END
,
104 GRP_DB_END
= GRP_DB_BEGIN
+ 5,
106 GRP_VAR_BEGIN
= GRP_DB_END
,
107 GRP_VAR_END
= GRP_VAR_BEGIN
+ 9
112 GRP_WEB_DOC_BEGIN
= 0,
113 GRP_WEB_DOC_END
= GRP_WEB_DOC_BEGIN
+ 9,
115 GRP_WEB_FKT_BEGIN
= GRP_WEB_DOC_END
+ 2,
116 GRP_WEB_FKT_END
= GRP_WEB_FKT_BEGIN
+ 0, // the group is empty!
118 GRP_WEB_REF_BEGIN
= GRP_WEB_FKT_END
+ 6, // the group is empty!
119 GRP_WEB_REF_END
= GRP_WEB_REF_BEGIN
+ 0,
121 GRP_WEB_REG_BEGIN
= GRP_WEB_REF_END
+ 2,
122 GRP_WEB_REG_END
= GRP_WEB_REG_BEGIN
+ 1,
124 GRP_WEB_DB_BEGIN
= GRP_WEB_REG_END
, // the group is empty!
125 GRP_WEB_DB_END
= GRP_WEB_DB_BEGIN
+ 0,
127 GRP_WEB_VAR_BEGIN
= GRP_WEB_DB_END
+ 5,
128 GRP_WEB_VAR_END
= GRP_WEB_VAR_BEGIN
+ 1
131 const sal_uInt16 VF_COUNT
= 1; // { 0 }
132 const sal_uInt16 VF_USR_COUNT
= 2; // { 0, nsSwExtendedSubType::SUB_CMD }
133 const sal_uInt16 VF_DB_COUNT
= 1; // { nsSwExtendedSubType::SUB_OWN_FMT }
135 const TranslateId FLD_EU_ARY
[] =
154 const TranslateId FMT_AUTHOR_ARY
[] =
160 const TranslateId FLD_DATE_ARY
[] =
166 const TranslateId FLD_TIME_ARY
[] =
172 const TranslateId FMT_NUM_ARY
[] =
185 const TranslateId FMT_FF_ARY
[] =
195 const TranslateId FLD_STAT_ARY
[] =
206 const TranslateId FMT_CHAPTER_ARY
[] =
211 FMT_CHAPTER_NO_NOSEPARATOR
214 const TranslateId FLD_INPUT_ARY
[] =
219 const TranslateId FMT_MARK_ARY
[] =
228 const TranslateId FMT_REF_ARY
[] =
239 FMT_REF_NUMBER_NO_CONTEXT
,
240 FMT_REF_NUMBER_FULL_CONTEXT
243 const TranslateId FMT_REG_ARY
[] =
250 const TranslateId FMT_DBFLD_ARY
[] =
256 const TranslateId FMT_SETVAR_ARY
[] =
262 const TranslateId FMT_GETVAR_ARY
[] =
268 const TranslateId FMT_DDE_ARY
[] =
274 const TranslateId FLD_PAGEREF_ARY
[] =
280 const TranslateId FMT_USERVAR_ARY
[] =
288 // field types and subtypes
291 SwFieldTypesEnum nTypeId
;
293 const TranslateId
* pSubTypeResIds
;
294 size_t nSubTypeLength
;
296 const TranslateId
* pFormatResIds
;
297 size_t nFormatLength
;
302 // strings and formats
303 const SwFieldPack aSwFields
[] =
306 { SwFieldTypesEnum::ExtendedUser
, FLD_EU_ARY
, SAL_N_ELEMENTS(FLD_EU_ARY
), nullptr, 0 },
307 { SwFieldTypesEnum::Author
, nullptr, 0, FMT_AUTHOR_ARY
, SAL_N_ELEMENTS(FMT_AUTHOR_ARY
) },
308 { SwFieldTypesEnum::Date
, FLD_DATE_ARY
, SAL_N_ELEMENTS(FLD_DATE_ARY
), nullptr, 0 },
309 { SwFieldTypesEnum::Time
, FLD_TIME_ARY
, SAL_N_ELEMENTS(FLD_TIME_ARY
), nullptr, 0 },
310 { SwFieldTypesEnum::PageNumber
, nullptr, 0, FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) -1 },
311 { SwFieldTypesEnum::NextPage
, nullptr, 0, FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) },
312 { SwFieldTypesEnum::PreviousPage
, nullptr, 0, FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) },
313 { SwFieldTypesEnum::Filename
, nullptr, 0, FMT_FF_ARY
, SAL_N_ELEMENTS(FMT_FF_ARY
) },
314 { SwFieldTypesEnum::DocumentStatistics
, FLD_STAT_ARY
, SAL_N_ELEMENTS(FLD_STAT_ARY
), FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) -1 },
316 { SwFieldTypesEnum::Chapter
, nullptr, 0, FMT_CHAPTER_ARY
, SAL_N_ELEMENTS(FMT_CHAPTER_ARY
) },
317 { SwFieldTypesEnum::TemplateName
, nullptr, 0, FMT_FF_ARY
, SAL_N_ELEMENTS(FMT_FF_ARY
) },
318 { SwFieldTypesEnum::ParagraphSignature
, nullptr, 0, nullptr, 0 },
321 { SwFieldTypesEnum::ConditionalText
, nullptr, 0, nullptr, 0 },
322 { SwFieldTypesEnum::Dropdown
, nullptr, 0, nullptr, 0 },
323 { SwFieldTypesEnum::Input
, FLD_INPUT_ARY
, SAL_N_ELEMENTS(FLD_INPUT_ARY
), nullptr, 0 },
324 { SwFieldTypesEnum::Macro
, nullptr, 0, nullptr, 0 },
325 { SwFieldTypesEnum::JumpEdit
, nullptr, 0, FMT_MARK_ARY
, SAL_N_ELEMENTS(FMT_MARK_ARY
) },
326 { SwFieldTypesEnum::CombinedChars
, nullptr, 0, nullptr, 0 },
327 { SwFieldTypesEnum::HiddenText
, nullptr, 0, nullptr, 0 },
328 { SwFieldTypesEnum::HiddenParagraph
, nullptr, 0, nullptr, 0 },
331 { SwFieldTypesEnum::SetRef
, nullptr, 0, nullptr, 0 },
332 { SwFieldTypesEnum::GetRef
, nullptr, 0, FMT_REF_ARY
, SAL_N_ELEMENTS(FMT_REF_ARY
) },
335 { SwFieldTypesEnum::DocumentInfo
, nullptr, 0, FMT_REG_ARY
, SAL_N_ELEMENTS(FMT_REG_ARY
) },
338 { SwFieldTypesEnum::Database
, nullptr, 0, FMT_DBFLD_ARY
, SAL_N_ELEMENTS(FMT_DBFLD_ARY
) },
339 { SwFieldTypesEnum::DatabaseNextSet
, nullptr, 0, nullptr, 0 },
340 { SwFieldTypesEnum::DatabaseNumberSet
, nullptr, 0, nullptr, 0 },
341 { SwFieldTypesEnum::DatabaseSetNumber
, nullptr, 0, FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) - 2 },
342 { SwFieldTypesEnum::DatabaseName
, nullptr, 0, nullptr, 0 },
345 { SwFieldTypesEnum::Set
, nullptr, 0, FMT_SETVAR_ARY
, SAL_N_ELEMENTS(FMT_SETVAR_ARY
) },
347 { SwFieldTypesEnum::Get
, nullptr, 0, FMT_GETVAR_ARY
, SAL_N_ELEMENTS(FMT_GETVAR_ARY
) },
348 { SwFieldTypesEnum::DDE
, nullptr, 0, FMT_DDE_ARY
, SAL_N_ELEMENTS(FMT_DDE_ARY
) },
349 { SwFieldTypesEnum::Formel
, nullptr, 0, FMT_GETVAR_ARY
, SAL_N_ELEMENTS(FMT_GETVAR_ARY
) },
350 { SwFieldTypesEnum::Input
, FLD_INPUT_ARY
, SAL_N_ELEMENTS(FLD_INPUT_ARY
), nullptr, 0 },
351 { SwFieldTypesEnum::Sequence
, nullptr, 0, FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) - 2 },
352 { SwFieldTypesEnum::SetRefPage
, FLD_PAGEREF_ARY
, SAL_N_ELEMENTS(FLD_PAGEREF_ARY
),nullptr, 0 },
353 { SwFieldTypesEnum::GetRefPage
, nullptr, 0, FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) - 1 },
354 { SwFieldTypesEnum::User
, nullptr, 0, FMT_USERVAR_ARY
, SAL_N_ELEMENTS(FMT_USERVAR_ARY
) }
357 // access to the shell
358 static SwWrtShell
* lcl_GetShell()
360 if (SwView
* pView
= GetActiveView())
361 return pView
->GetWrtShellPtr();
365 static sal_uInt16
GetPackCount() { return SAL_N_ELEMENTS(aSwFields
); }
367 // FieldManager controls inserting and updating of fields
368 SwFieldMgr::SwFieldMgr(SwWrtShell
* pSh
) :
372 // determine current field if existing
376 SwFieldMgr::~SwFieldMgr()
380 // organise RefMark by names
381 bool SwFieldMgr::CanInsertRefMark( std::u16string_view rStr
)
384 SwWrtShell
*pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
385 OSL_ENSURE(pSh
, "no SwWrtShell found");
388 sal_uInt16 nCnt
= pSh
->GetCursorCnt();
390 // the last Cursor doesn't have to be a spanned selection
391 if( 1 < nCnt
&& !pSh
->SwCursorShell::HasSelection() )
394 bRet
= 2 > nCnt
&& nullptr == pSh
->GetRefMark( rStr
);
399 // access over ResIds
400 void SwFieldMgr::RemoveFieldType(SwFieldIds nResId
, const OUString
& rName
)
402 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
403 OSL_ENSURE(pSh
, "no SwWrtShell found");
405 pSh
->RemoveFieldType(nResId
, rName
);
408 size_t SwFieldMgr::GetFieldTypeCount() const
410 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
411 OSL_ENSURE(pSh
, "no SwWrtShell found");
412 return pSh
? pSh
->GetFieldTypeCount() : 0;
415 SwFieldType
* SwFieldMgr::GetFieldType(SwFieldIds nResId
, size_t nField
) const
417 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
418 OSL_ENSURE(pSh
, "no SwWrtShell found");
419 return pSh
? pSh
->GetFieldType(nField
, nResId
) : nullptr;
422 SwFieldType
* SwFieldMgr::GetFieldType(SwFieldIds nResId
, const OUString
& rName
) const
424 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
425 OSL_ENSURE(pSh
, "no SwWrtShell found");
426 return pSh
? pSh
->GetFieldType(nResId
, rName
) : nullptr;
429 // determine current field
430 SwField
* SwFieldMgr::GetCurField()
432 SwWrtShell
*pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
434 m_pCurField
= pSh
->GetCurField( true );
436 m_pCurField
= nullptr;
438 // initialise strings and format
447 // preprocess current values; determine parameter 1 and parameter 2
448 // as well as the format
449 const SwFieldTypesEnum nTypeId
= m_pCurField
->GetTypeId();
451 m_nCurFormat
= m_pCurField
->GetFormat();
452 m_aCurPar1
= m_pCurField
->GetPar1();
453 m_aCurPar2
= m_pCurField
->GetPar2();
457 case SwFieldTypesEnum::PageNumber
:
458 case SwFieldTypesEnum::NextPage
:
459 case SwFieldTypesEnum::PreviousPage
:
460 case SwFieldTypesEnum::GetRefPage
:
461 if( m_nCurFormat
== SVX_NUM_PAGEDESC
)
469 // provide group range
470 const SwFieldGroupRgn
& SwFieldMgr::GetGroupRange(bool bHtmlMode
, sal_uInt16 nGrpId
)
472 static SwFieldGroupRgn
const aRanges
[] =
474 { /* Document */ GRP_DOC_BEGIN
, GRP_DOC_END
},
475 { /* Functions */ GRP_FKT_BEGIN
, GRP_FKT_END
},
476 { /* Cross-Refs */ GRP_REF_BEGIN
, GRP_REF_END
},
477 { /* DocInfos */ GRP_REG_BEGIN
, GRP_REG_END
},
478 { /* Database */ GRP_DB_BEGIN
, GRP_DB_END
},
479 { /* User */ GRP_VAR_BEGIN
, GRP_VAR_END
}
481 static SwFieldGroupRgn
const aWebRanges
[] =
483 { /* Document */ GRP_WEB_DOC_BEGIN
, GRP_WEB_DOC_END
},
484 { /* Functions */ GRP_WEB_FKT_BEGIN
, GRP_WEB_FKT_END
},
485 { /* Cross-Refs */ GRP_WEB_REF_BEGIN
, GRP_WEB_REF_END
},
486 { /* DocInfos */ GRP_WEB_REG_BEGIN
, GRP_WEB_REG_END
},
487 { /* Database */ GRP_WEB_DB_BEGIN
, GRP_WEB_DB_END
},
488 { /* User */ GRP_WEB_VAR_BEGIN
, GRP_WEB_VAR_END
}
492 return aWebRanges
[nGrpId
];
494 return aRanges
[nGrpId
];
498 sal_uInt16
SwFieldMgr::GetGroup(SwFieldTypesEnum nTypeId
, sal_uInt16 nSubType
)
500 if (nTypeId
== SwFieldTypesEnum::SetInput
)
501 nTypeId
= SwFieldTypesEnum::Set
;
503 if (nTypeId
== SwFieldTypesEnum::Input
&& (nSubType
& INP_USR
))
504 nTypeId
= SwFieldTypesEnum::User
;
506 if (nTypeId
== SwFieldTypesEnum::FixedDate
)
507 nTypeId
= SwFieldTypesEnum::Date
;
509 if (nTypeId
== SwFieldTypesEnum::FixedTime
)
510 nTypeId
= SwFieldTypesEnum::Time
;
512 for (sal_uInt16 i
= GRP_DOC
; i
<= GRP_VAR
; i
++)
514 const SwFieldGroupRgn
& rRange
= GetGroupRange(false/*bHtmlMode*/, i
);
515 for (sal_uInt16 nPos
= rRange
.nStart
; nPos
< rRange
.nEnd
; nPos
++)
517 if (aSwFields
[nPos
].nTypeId
== nTypeId
)
524 // determine names to TypeId
525 // ACCESS over TYP_...
526 SwFieldTypesEnum
SwFieldMgr::GetTypeId(sal_uInt16 nPos
)
528 OSL_ENSURE(nPos
< ::GetPackCount(), "forbidden Pos");
529 return aSwFields
[ nPos
].nTypeId
;
532 const OUString
& SwFieldMgr::GetTypeStr(sal_uInt16 nPos
)
534 OSL_ENSURE(nPos
< ::GetPackCount(), "forbidden TypeId");
536 SwFieldTypesEnum nFieldWh
= aSwFields
[ nPos
].nTypeId
;
538 // special treatment for date/time fields (without var/fix)
539 if( SwFieldTypesEnum::Date
== nFieldWh
)
541 static OUString
g_aDate( SwResId( STR_DATEFLD
) );
544 if( SwFieldTypesEnum::Time
== nFieldWh
)
546 static OUString
g_aTime( SwResId( STR_TIMEFLD
) );
550 return SwFieldType::GetTypeStr( nFieldWh
);
553 // determine Pos in the list
554 sal_uInt16
SwFieldMgr::GetPos(SwFieldTypesEnum nTypeId
)
558 case SwFieldTypesEnum::FixedDate
: nTypeId
= SwFieldTypesEnum::Date
; break;
559 case SwFieldTypesEnum::FixedTime
: nTypeId
= SwFieldTypesEnum::Time
; break;
560 case SwFieldTypesEnum::SetInput
: nTypeId
= SwFieldTypesEnum::Set
; break;
561 case SwFieldTypesEnum::UserInput
: nTypeId
= SwFieldTypesEnum::User
; break;
565 for(sal_uInt16 i
= 0; i
< GetPackCount(); i
++)
566 if(aSwFields
[i
].nTypeId
== nTypeId
)
572 // localise subtypes of a field
573 void SwFieldMgr::GetSubTypes(SwFieldTypesEnum nTypeId
, std::vector
<OUString
>& rToFill
)
575 SwWrtShell
*pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
576 OSL_ENSURE(pSh
, "no SwWrtShell found");
580 const sal_uInt16 nPos
= GetPos(nTypeId
);
584 case SwFieldTypesEnum::SetRef
:
585 case SwFieldTypesEnum::GetRef
:
587 // references are no fields
588 pSh
->GetRefMarks( &rToFill
);
591 case SwFieldTypesEnum::Macro
:
595 case SwFieldTypesEnum::Input
:
597 rToFill
.push_back(SwResId(aSwFields
[nPos
].pSubTypeResIds
[0]));
598 [[fallthrough
]]; // move on at generic types
600 case SwFieldTypesEnum::DDE
:
601 case SwFieldTypesEnum::Sequence
:
602 case SwFieldTypesEnum::Formel
:
603 case SwFieldTypesEnum::Get
:
604 case SwFieldTypesEnum::Set
:
605 case SwFieldTypesEnum::User
:
608 const size_t nCount
= pSh
->GetFieldTypeCount();
609 for(size_t i
= 0; i
< nCount
; ++i
)
611 SwFieldType
* pFieldType
= pSh
->GetFieldType( i
);
612 const SwFieldIds nWhich
= pFieldType
->Which();
614 if((nTypeId
== SwFieldTypesEnum::DDE
&& pFieldType
->Which() == SwFieldIds::Dde
) ||
616 (nTypeId
== SwFieldTypesEnum::User
&& nWhich
== SwFieldIds::User
) ||
618 (nTypeId
== SwFieldTypesEnum::Get
&& nWhich
== SwFieldIds::SetExp
&&
619 !(static_cast<SwSetExpFieldType
*>(pFieldType
)->GetType() & nsSwGetSetExpType::GSE_SEQ
)) ||
621 (nTypeId
== SwFieldTypesEnum::Set
&& nWhich
== SwFieldIds::SetExp
&&
622 !(static_cast<SwSetExpFieldType
*>(pFieldType
)->GetType() & nsSwGetSetExpType::GSE_SEQ
)) ||
624 (nTypeId
== SwFieldTypesEnum::Sequence
&& nWhich
== SwFieldIds::SetExp
&&
625 (static_cast<SwSetExpFieldType
*>(pFieldType
)->GetType() & nsSwGetSetExpType::GSE_SEQ
)) ||
627 ((nTypeId
== SwFieldTypesEnum::Input
|| nTypeId
== SwFieldTypesEnum::Formel
) &&
628 (nWhich
== SwFieldIds::User
||
629 (nWhich
== SwFieldIds::SetExp
&&
630 !(static_cast<SwSetExpFieldType
*>(pFieldType
)->GetType() & nsSwGetSetExpType::GSE_SEQ
))) ) )
632 rToFill
.push_back(pFieldType
->GetName());
637 case SwFieldTypesEnum::DatabaseNextSet
:
638 case SwFieldTypesEnum::DatabaseNumberSet
:
639 case SwFieldTypesEnum::DatabaseName
:
640 case SwFieldTypesEnum::DatabaseSetNumber
:
646 if(nPos
!= USHRT_MAX
)
649 if (nTypeId
== SwFieldTypesEnum::DocumentInfo
)
650 nCount
= DI_SUBTYPE_END
- DI_SUBTYPE_BEGIN
;
652 nCount
= aSwFields
[nPos
].nSubTypeLength
;
654 for(sal_uInt16 i
= 0; i
< nCount
; ++i
)
657 if (nTypeId
== SwFieldTypesEnum::DocumentInfo
)
659 if ( i
== DI_CUSTOM
)
660 sNew
= SwResId(STR_CUSTOM_FIELD
);
662 sNew
= SwViewShell::GetShellRes()->aDocInfoLst
[i
];
665 sNew
= SwResId(aSwFields
[nPos
].pSubTypeResIds
[i
]);
667 rToFill
.push_back(sNew
);
675 // ACCESS over TYP_...
676 sal_uInt16
SwFieldMgr::GetFormatCount(SwFieldTypesEnum nTypeId
, bool bHtmlMode
) const
678 assert(nTypeId
< SwFieldTypesEnum::LAST
&& "forbidden TypeId");
680 const sal_uInt16 nPos
= GetPos(nTypeId
);
682 if (nPos
== USHRT_MAX
|| (bHtmlMode
&& nTypeId
== SwFieldTypesEnum::Set
))
685 sal_uInt16 nCount
= aSwFields
[nPos
].nFormatLength
;
687 if (nTypeId
== SwFieldTypesEnum::Filename
)
688 nCount
-= 2; // no range or template
690 const TranslateId
* pStart
= aSwFields
[nPos
].pFormatResIds
;
694 if (*pStart
== FMT_GETVAR_ARY
[0] || *pStart
== FMT_SETVAR_ARY
[0])
696 else if (*pStart
== FMT_USERVAR_ARY
[0])
698 else if (*pStart
== FMT_DBFLD_ARY
[0])
700 else if (*pStart
== FMT_NUM_ARY
[0])
703 if(m_xNumberingInfo
.is())
705 const Sequence
<sal_Int16
> aTypes
= m_xNumberingInfo
->getSupportedNumberingTypes();
706 // #i28073# it's not necessarily a sorted sequence
707 //skip all values below or equal to CHARS_LOWER_LETTER_N
708 nCount
+= std::count_if(aTypes
.begin(), aTypes
.end(),
709 [](sal_Int16 nCurrent
) { return nCurrent
> NumberingType::CHARS_LOWER_LETTER_N
; });
718 // determine FormatString to a type
719 OUString
SwFieldMgr::GetFormatStr(SwFieldTypesEnum nTypeId
, sal_uInt32 nFormatId
) const
721 assert(nTypeId
< SwFieldTypesEnum::LAST
&& "forbidden TypeId");
722 const sal_uInt16 nPos
= GetPos(nTypeId
);
724 if (nPos
== USHRT_MAX
)
727 const TranslateId
* pStart
= aSwFields
[nPos
].pFormatResIds
;
731 if (SwFieldTypesEnum::Author
== nTypeId
|| SwFieldTypesEnum::Filename
== nTypeId
)
732 nFormatId
&= ~static_cast<sal_uInt32
>(FF_FIXED
); // mask out Fixed-Flag
734 if (nFormatId
< aSwFields
[nPos
].nFormatLength
)
735 return SwResId(pStart
[nFormatId
]);
738 if (*pStart
== FMT_NUM_ARY
[0])
740 if (m_xNumberingInfo
.is())
742 const Sequence
<sal_Int16
> aTypes
= m_xNumberingInfo
->getSupportedNumberingTypes();
743 sal_Int32 nOffset
= aSwFields
[nPos
].nFormatLength
;
744 sal_uInt32 nValidEntry
= 0;
745 for (const sal_Int16 nCurrent
: aTypes
)
747 if(nCurrent
> NumberingType::CHARS_LOWER_LETTER_N
&&
748 (nCurrent
!= (NumberingType::BITMAP
| LINK_TOKEN
)))
750 if (nValidEntry
== nFormatId
- nOffset
)
752 sal_uInt32 n
= SvxNumberingTypeTable::FindIndex(nCurrent
);
753 if (n
!= RESARRAY_INDEX_NOTFOUND
)
755 aRet
= SvxNumberingTypeTable::GetString(n
);
759 aRet
= m_xNumberingInfo
->getNumberingIdentifier( nCurrent
);
772 // determine FormatId from Pseudo-ID
773 sal_uInt16
SwFieldMgr::GetFormatId(SwFieldTypesEnum nTypeId
, sal_uInt32 nFormatId
) const
775 sal_uInt16 nId
= o3tl::narrowing
<sal_uInt16
>(nFormatId
);
778 case SwFieldTypesEnum::DocumentInfo
:
780 TranslateId sId
= aSwFields
[GetPos(nTypeId
)].pFormatResIds
[nFormatId
];
781 if (sId
== FMT_REG_AUTHOR
)
783 else if (sId
== FMT_REG_TIME
)
785 else if (sId
== FMT_REG_DATE
)
789 case SwFieldTypesEnum::PageNumber
:
790 case SwFieldTypesEnum::NextPage
:
791 case SwFieldTypesEnum::PreviousPage
:
792 case SwFieldTypesEnum::DocumentStatistics
:
793 case SwFieldTypesEnum::DatabaseSetNumber
:
794 case SwFieldTypesEnum::Sequence
:
795 case SwFieldTypesEnum::GetRefPage
:
797 sal_uInt16 nPos
= GetPos(nTypeId
);
798 if (nFormatId
< aSwFields
[nPos
].nFormatLength
)
800 const TranslateId sId
= aSwFields
[nPos
].pFormatResIds
[nFormatId
];
801 if (sId
== FMT_NUM_ABC
)
802 nId
= SVX_NUM_CHARS_UPPER_LETTER
;
803 else if (sId
== FMT_NUM_SABC
)
804 nId
= SVX_NUM_CHARS_LOWER_LETTER
;
805 else if (sId
== FMT_NUM_ROMAN
)
806 nId
= SVX_NUM_ROMAN_UPPER
;
807 else if (sId
== FMT_NUM_SROMAN
)
808 nId
= SVX_NUM_ROMAN_LOWER
;
809 else if (sId
== FMT_NUM_ARABIC
)
810 nId
= SVX_NUM_ARABIC
;
811 else if (sId
== FMT_NUM_PAGEDESC
)
812 nId
= SVX_NUM_PAGEDESC
;
813 else if (sId
== FMT_NUM_PAGESPECIAL
)
814 nId
= SVX_NUM_CHAR_SPECIAL
;
815 else if (sId
== FMT_NUM_ABC_N
)
816 nId
= SVX_NUM_CHARS_UPPER_LETTER_N
;
817 else if (sId
== FMT_NUM_SABC_N
)
818 nId
= SVX_NUM_CHARS_LOWER_LETTER_N
;
820 else if (m_xNumberingInfo
.is())
822 const Sequence
<sal_Int16
> aTypes
= m_xNumberingInfo
->getSupportedNumberingTypes();
823 sal_Int32 nOffset
= aSwFields
[nPos
].nFormatLength
;
824 sal_Int32 nValidEntry
= 0;
825 for (const sal_Int16 nCurrent
: aTypes
)
827 if (nCurrent
> NumberingType::CHARS_LOWER_LETTER_N
)
829 if (nValidEntry
== static_cast<sal_Int32
>(nFormatId
) - nOffset
)
840 case SwFieldTypesEnum::DDE
:
842 const TranslateId sId
= aSwFields
[GetPos(nTypeId
)].pFormatResIds
[nFormatId
];
843 if (sId
== FMT_DDE_NORMAL
)
844 nId
= static_cast<sal_uInt16
>(SfxLinkUpdateMode::ONCALL
);
845 else if (sId
== FMT_DDE_HOT
)
846 nId
= static_cast<sal_uInt16
>(SfxLinkUpdateMode::ALWAYS
);
855 bool SwFieldMgr::GoNextPrev( bool bNext
, SwFieldType
* pTyp
)
857 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
861 if( !pTyp
&& m_pCurField
)
863 const SwFieldTypesEnum nTypeId
= m_pCurField
->GetTypeId();
864 if( SwFieldTypesEnum::SetInput
== nTypeId
|| SwFieldTypesEnum::UserInput
== nTypeId
)
865 pTyp
= pSh
->GetFieldType( 0, SwFieldIds::Input
);
867 pTyp
= m_pCurField
->GetTyp();
870 if (pTyp
&& pTyp
->Which() == SwFieldIds::Database
)
872 // for fieldcommand-edit (hop to all DB fields)
873 return pSh
->MoveFieldType( nullptr, bNext
, SwFieldIds::Database
);
876 return pTyp
&& pSh
->MoveFieldType(pTyp
, bNext
);
879 // insert field types
880 void SwFieldMgr::InsertFieldType(SwFieldType
const & rType
)
882 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
883 OSL_ENSURE(pSh
, "no SwWrtShell found");
885 pSh
->InsertFieldType(rType
);
888 // determine current TypeId
889 SwFieldTypesEnum
SwFieldMgr::GetCurTypeId() const
891 return m_pCurField
? m_pCurField
->GetTypeId() : SwFieldTypesEnum::Unknown
;
894 // Over string insert field or update
895 bool SwFieldMgr::InsertField(
896 SwInsertField_Data
& rData
)
898 std::unique_ptr
<SwField
> pField
;
901 bool bPageVar
= false;
902 sal_uInt32 nFormatId
= rData
.m_nFormatId
;
903 sal_uInt16 nSubType
= rData
.m_nSubType
;
904 sal_Unicode cSeparator
= rData
.m_cSeparator
;
905 SwWrtShell
* pCurShell
= rData
.m_pSh
;
907 pCurShell
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
908 OSL_ENSURE(pCurShell
, "no SwWrtShell found");
912 switch (rData
.m_nTypeId
)
913 { // ATTENTION this field is inserted by a separate dialog
914 case SwFieldTypesEnum::Postit
:
916 SvtUserOptions aUserOpt
;
917 SwPostItFieldType
* pType
= static_cast<SwPostItFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::Postit
));
921 rData
.m_sPar1
, // author
922 rData
.m_sPar2
, // content
923 aUserOpt
.GetID(), // author's initials
925 DateTime(DateTime::SYSTEM
) ));
928 case SwFieldTypesEnum::Script
:
930 SwScriptFieldType
* pType
=
931 static_cast<SwScriptFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::Script
));
932 pField
.reset(new SwScriptField(pType
, rData
.m_sPar1
, rData
.m_sPar2
, static_cast<bool>(nFormatId
)));
936 case SwFieldTypesEnum::CombinedChars
:
938 SwCombinedCharFieldType
* pType
= static_cast<SwCombinedCharFieldType
*>(
939 pCurShell
->GetFieldType( 0, SwFieldIds::CombinedChars
));
940 pField
.reset(new SwCombinedCharField( pType
, rData
.m_sPar1
));
944 case SwFieldTypesEnum::Authority
:
946 SwAuthorityFieldType
* pType
=
947 static_cast<SwAuthorityFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::TableOfAuthorities
));
950 SwAuthorityFieldType
const type(pCurShell
->GetDoc());
951 pType
= static_cast<SwAuthorityFieldType
*>(
952 pCurShell
->InsertFieldType(type
));
954 pField
.reset(new SwAuthorityField(pType
, rData
.m_sPar1
));
958 case SwFieldTypesEnum::Date
:
959 case SwFieldTypesEnum::Time
:
961 sal_uInt16 nSub
= static_cast< sal_uInt16
>(rData
.m_nTypeId
== SwFieldTypesEnum::Date
? DATEFLD
: TIMEFLD
);
962 nSub
|= nSubType
== DATE_VAR
? 0 : FIXEDFLD
;
964 SwDateTimeFieldType
* pTyp
=
965 static_cast<SwDateTimeFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::DateTime
) );
966 pField
.reset(new SwDateTimeField(pTyp
, nSub
, nFormatId
));
967 pField
->SetPar2(rData
.m_sPar2
);
971 case SwFieldTypesEnum::Filename
:
973 SwFileNameFieldType
* pTyp
=
974 static_cast<SwFileNameFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::Filename
) );
975 pField
.reset(new SwFileNameField(pTyp
, nFormatId
));
979 case SwFieldTypesEnum::TemplateName
:
981 SwTemplNameFieldType
* pTyp
=
982 static_cast<SwTemplNameFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::TemplateName
) );
983 pField
.reset(new SwTemplNameField(pTyp
, nFormatId
));
987 case SwFieldTypesEnum::Chapter
:
989 sal_uInt16 nByte
= o3tl::narrowing
<sal_uInt16
>(rData
.m_sPar2
.toInt32());
990 SwChapterFieldType
* pTyp
=
991 static_cast<SwChapterFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::Chapter
) );
992 pField
.reset(new SwChapterField(pTyp
, nFormatId
));
993 nByte
= std::max(sal_uInt16(1), nByte
);
994 nByte
= std::min(nByte
, sal_uInt16(MAXLEVEL
));
996 static_cast<SwChapterField
*>(pField
.get())->SetLevel(static_cast<sal_uInt8
>(nByte
));
1000 case SwFieldTypesEnum::NextPage
:
1001 case SwFieldTypesEnum::PreviousPage
:
1002 case SwFieldTypesEnum::PageNumber
:
1004 short nOff
= static_cast<short>(rData
.m_sPar2
.toInt32());
1006 if(rData
.m_nTypeId
== SwFieldTypesEnum::NextPage
)
1008 if( SVX_NUM_CHAR_SPECIAL
== nFormatId
)
1014 else if(rData
.m_nTypeId
== SwFieldTypesEnum::PreviousPage
)
1016 if( SVX_NUM_CHAR_SPECIAL
== nFormatId
)
1023 nSubType
= PG_RANDOM
;
1025 SwPageNumberFieldType
* pTyp
=
1026 static_cast<SwPageNumberFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::PageNumber
) );
1027 pField
.reset(new SwPageNumberField(pTyp
, nSubType
, nFormatId
, nOff
));
1029 if( SVX_NUM_CHAR_SPECIAL
== nFormatId
&&
1030 ( PG_PREV
== nSubType
|| PG_NEXT
== nSubType
) )
1031 static_cast<SwPageNumberField
*>(pField
.get())->SetUserString( rData
.m_sPar2
);
1035 case SwFieldTypesEnum::DocumentStatistics
:
1037 SwDocStatFieldType
* pTyp
=
1038 static_cast<SwDocStatFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::DocStat
) );
1039 pField
.reset(new SwDocStatField(pTyp
, nSubType
, nFormatId
));
1043 case SwFieldTypesEnum::Author
:
1045 SwAuthorFieldType
* pTyp
=
1046 static_cast<SwAuthorFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::Author
) );
1047 pField
.reset(new SwAuthorField(pTyp
, nFormatId
));
1051 case SwFieldTypesEnum::ConditionalText
:
1052 case SwFieldTypesEnum::HiddenText
:
1054 SwHiddenTextFieldType
* pTyp
=
1055 static_cast<SwHiddenTextFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::HiddenText
) );
1056 pField
.reset(new SwHiddenTextField(pTyp
, true, rData
.m_sPar1
, rData
.m_sPar2
, false, rData
.m_nTypeId
));
1061 case SwFieldTypesEnum::HiddenParagraph
:
1063 SwHiddenParaFieldType
* pTyp
=
1064 static_cast<SwHiddenParaFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::HiddenPara
) );
1065 pField
.reset(new SwHiddenParaField(pTyp
, rData
.m_sPar1
));
1070 case SwFieldTypesEnum::SetRef
:
1072 if( !rData
.m_sPar1
.isEmpty() && CanInsertRefMark( rData
.m_sPar1
) )
1074 const OUString
& rRefmarkText
= rData
.m_sPar2
;
1075 SwPaM
* pCursorPos
= pCurShell
->GetCursor();
1076 pCurShell
->StartAction();
1077 bool bHadMark
= pCursorPos
->HasMark();
1078 // If we have no selection and the refmark text is provided, then the text is
1079 // expected to be HTML.
1080 if (!bHadMark
&& !rRefmarkText
.isEmpty())
1082 // Split node to remember where the start position is.
1083 bool bSuccess
= pCurShell
->GetDoc()->getIDocumentContentOperations().SplitNode(
1084 *pCursorPos
->GetPoint(), /*bChkTableStart=*/false);
1087 SwPaM
aRefmarkPam(*pCursorPos
->GetPoint());
1088 aRefmarkPam
.Move(fnMoveBackward
, GoInContent
);
1090 // Paste HTML content.
1091 SwTranslateHelper::PasteHTMLToPaM(
1092 *pCurShell
, pCursorPos
, rRefmarkText
.toUtf8(), /*bSetSelection=*/true);
1094 // Undo the above SplitNode().
1095 aRefmarkPam
.SetMark();
1096 aRefmarkPam
.Move(fnMoveForward
, GoInContent
);
1097 pCurShell
->GetDoc()->getIDocumentContentOperations().DeleteAndJoin(
1099 *aRefmarkPam
.GetMark() = *pCursorPos
->GetPoint();
1100 *pCursorPos
= aRefmarkPam
;
1104 pCurShell
->SetAttrItem( SwFormatRefMark( rData
.m_sPar1
) );
1106 if (!bHadMark
&& !rRefmarkText
.isEmpty())
1108 pCursorPos
->DeleteMark();
1110 pCurShell
->EndAction();
1116 case SwFieldTypesEnum::GetRef
:
1118 SwGetRefFieldType
* pTyp
=
1119 static_cast<SwGetRefFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::GetRef
) );
1120 sal_uInt16 nSeqNo
= o3tl::narrowing
<sal_uInt16
>(rData
.m_sPar2
.toInt32());
1121 OUString sReferenceLanguage
;
1122 // handle language-variant formats
1123 if (nFormatId
>= SAL_N_ELEMENTS(FMT_REF_ARY
))
1125 LanguageType nLang
= GetCurrLanguage();
1126 if (nLang
== LANGUAGE_HUNGARIAN
)
1128 if (nFormatId
>= SAL_N_ELEMENTS(FMT_REF_ARY
) * 2)
1129 sReferenceLanguage
= "Hu";
1131 sReferenceLanguage
= "hu";
1133 nFormatId
%= SAL_N_ELEMENTS(FMT_REF_ARY
);
1135 pField
.reset(new SwGetRefField(pTyp
, rData
.m_sPar1
, sReferenceLanguage
, nSubType
, nSeqNo
, nFormatId
));
1140 case SwFieldTypesEnum::DDE
:
1142 //JP 28.08.95: DDE-Topics/-Items can have blanks in their names!
1143 // That's not yet considered here.
1144 sal_Int32 nIndex
= 0;
1145 OUString sCmd
= rData
.m_sPar2
.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator
), &nIndex
);
1146 if (nIndex
>=0 && ++nIndex
<sCmd
.getLength())
1148 sCmd
= sCmd
.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator
), &nIndex
);
1151 SwDDEFieldType
aType( rData
.m_sPar1
, sCmd
, static_cast<SfxLinkUpdateMode
>(nFormatId
) );
1152 SwDDEFieldType
* pTyp
= static_cast<SwDDEFieldType
*>( pCurShell
->InsertFieldType( aType
) );
1153 pField
.reset(new SwDDEField( pTyp
));
1157 case SwFieldTypesEnum::Macro
:
1159 SwMacroFieldType
* pTyp
=
1160 static_cast<SwMacroFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::Macro
));
1162 pField
.reset(new SwMacroField(pTyp
, rData
.m_sPar1
, rData
.m_sPar2
));
1167 case SwFieldTypesEnum::Internet
:
1169 SwFormatINetFormat
aFormat( rData
.m_sPar1
, m_sCurFrame
);
1170 return pCurShell
->InsertURL( aFormat
, rData
.m_sPar2
);
1173 case SwFieldTypesEnum::JumpEdit
:
1175 SwJumpEditFieldType
* pTyp
=
1176 static_cast<SwJumpEditFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::JumpEdit
));
1178 pField
.reset(new SwJumpEditField(pTyp
, nFormatId
, rData
.m_sPar1
, rData
.m_sPar2
));
1182 case SwFieldTypesEnum::DocumentInfo
:
1184 SwDocInfoFieldType
* pTyp
= static_cast<SwDocInfoFieldType
*>( pCurShell
->GetFieldType(
1185 0, SwFieldIds::DocInfo
) );
1186 pField
.reset(new SwDocInfoField(pTyp
, nSubType
, rData
.m_sPar1
, nFormatId
));
1190 case SwFieldTypesEnum::ExtendedUser
:
1192 SwExtUserFieldType
* pTyp
= static_cast<SwExtUserFieldType
*>( pCurShell
->GetFieldType(
1193 0, SwFieldIds::ExtUser
) );
1194 pField
.reset(new SwExtUserField(pTyp
, nSubType
, nFormatId
));
1198 case SwFieldTypesEnum::Database
:
1200 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1204 if (rData
.m_sPar1
.indexOf(DB_DELIM
)<0)
1206 aDBData
= pCurShell
->GetDBData();
1207 sPar1
= rData
.m_sPar1
;
1211 sal_Int32 nIdx
{ 0 };
1212 aDBData
.sDataSource
= rData
.m_sPar1
.getToken(0, DB_DELIM
, nIdx
);
1213 aDBData
.sCommand
= rData
.m_sPar1
.getToken(0, DB_DELIM
, nIdx
);
1214 aDBData
.nCommandType
= o3tl::toInt32(o3tl::getToken(rData
.m_sPar1
, 0, DB_DELIM
, nIdx
));
1215 sPar1
= rData
.m_sPar1
.getToken(0, DB_DELIM
, nIdx
);
1218 if(!aDBData
.sDataSource
.isEmpty() && pCurShell
->GetDBData() != aDBData
)
1219 pCurShell
->ChgDBData(aDBData
);
1221 SwDBFieldType
* pTyp
= static_cast<SwDBFieldType
*>(pCurShell
->InsertFieldType(
1222 SwDBFieldType(pCurShell
->GetDoc(), sPar1
, aDBData
) ) );
1223 pField
.reset(new SwDBField(pTyp
));
1224 pField
->SetSubType(nSubType
);
1226 if( !(nSubType
& nsSwExtendedSubType::SUB_OWN_FMT
) ) // determine database format
1228 Reference
< XDataSource
> xSource
;
1229 rData
.m_aDBDataSource
>>= xSource
;
1230 Reference
<XConnection
> xConnection
;
1231 rData
.m_aDBConnection
>>= xConnection
;
1232 Reference
<XPropertySet
> xColumn
;
1233 rData
.m_aDBColumn
>>= xColumn
;
1236 nFormatId
= SwDBManager::GetColumnFormat(xSource
, xConnection
, xColumn
,
1237 pCurShell
->GetNumberFormatter(), GetCurrLanguage() );
1240 nFormatId
= pCurShell
->GetDBManager()->GetColumnFormat(
1241 aDBData
.sDataSource
, aDBData
.sCommand
, sPar1
,
1242 pCurShell
->GetNumberFormatter(), GetCurrLanguage() );
1244 pField
->ChangeFormat( nFormatId
);
1251 case SwFieldTypesEnum::DatabaseSetNumber
:
1252 case SwFieldTypesEnum::DatabaseNumberSet
:
1253 case SwFieldTypesEnum::DatabaseNextSet
:
1254 case SwFieldTypesEnum::DatabaseName
:
1256 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1259 // extract DBName from rData.m_sPar1. Format: DBName.TableName.CommandType.ExpStrg
1260 sal_Int32 nTablePos
= rData
.m_sPar1
.indexOf(DB_DELIM
);
1261 sal_Int32 nExpPos
= -1;
1265 aDBData
.sDataSource
= rData
.m_sPar1
.copy(0, nTablePos
++);
1266 sal_Int32 nCmdTypePos
= rData
.m_sPar1
.indexOf(DB_DELIM
, nTablePos
);
1269 aDBData
.sCommand
= rData
.m_sPar1
.copy(nTablePos
, nCmdTypePos
++ - nTablePos
);
1270 nExpPos
= rData
.m_sPar1
.indexOf(DB_DELIM
, nCmdTypePos
);
1273 aDBData
.nCommandType
= o3tl::toInt32(rData
.m_sPar1
.subView(nCmdTypePos
, nExpPos
++ - nCmdTypePos
));
1281 else if (nTablePos
>=0)
1284 OUString sPar1
= rData
.m_sPar1
.copy(nPos
);
1286 if (!aDBData
.sDataSource
.isEmpty() && pCurShell
->GetDBData() != aDBData
)
1287 pCurShell
->ChgDBData(aDBData
);
1289 switch(rData
.m_nTypeId
)
1291 case SwFieldTypesEnum::DatabaseName
:
1293 SwDBNameFieldType
* pTyp
=
1294 static_cast<SwDBNameFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::DatabaseName
));
1295 pField
.reset(new SwDBNameField(pTyp
, aDBData
));
1299 case SwFieldTypesEnum::DatabaseNextSet
:
1301 SwDBNextSetFieldType
* pTyp
= static_cast<SwDBNextSetFieldType
*>(pCurShell
->GetFieldType(
1302 0, SwFieldIds::DbNextSet
) );
1303 pField
.reset(new SwDBNextSetField(pTyp
, sPar1
, aDBData
));
1307 case SwFieldTypesEnum::DatabaseNumberSet
:
1309 SwDBNumSetFieldType
* pTyp
= static_cast<SwDBNumSetFieldType
*>( pCurShell
->GetFieldType(
1310 0, SwFieldIds::DbNumSet
) );
1311 pField
.reset(new SwDBNumSetField( pTyp
, sPar1
, rData
.m_sPar2
, aDBData
));
1315 case SwFieldTypesEnum::DatabaseSetNumber
:
1317 SwDBSetNumberFieldType
* pTyp
= static_cast<SwDBSetNumberFieldType
*>(
1318 pCurShell
->GetFieldType(0, SwFieldIds::DbSetNumber
) );
1319 pField
.reset(new SwDBSetNumberField( pTyp
, aDBData
, nFormatId
));
1329 case SwFieldTypesEnum::User
:
1331 SwUserFieldType
* pTyp
=
1332 static_cast<SwUserFieldType
*>( pCurShell
->GetFieldType(SwFieldIds::User
, rData
.m_sPar1
) );
1337 pTyp
= static_cast<SwUserFieldType
*>( pCurShell
->InsertFieldType(
1338 SwUserFieldType(pCurShell
->GetDoc(), rData
.m_sPar1
)) );
1340 if (pTyp
->GetContent(nFormatId
) != rData
.m_sPar2
)
1341 pTyp
->SetContent(rData
.m_sPar2
, nFormatId
);
1342 pField
.reset(new SwUserField(pTyp
, 0, nFormatId
));
1343 if (pField
->GetSubType() != nSubType
)
1344 pField
->SetSubType(nSubType
);
1349 case SwFieldTypesEnum::Input
:
1351 if ((nSubType
& 0x00ff) == INP_VAR
)
1353 SwSetExpFieldType
* pTyp
= static_cast<SwSetExpFieldType
*>(
1354 pCurShell
->GetFieldType(SwFieldIds::SetExp
, rData
.m_sPar1
) );
1356 // no Expression Type with this name existing -> create
1359 std::unique_ptr
<SwSetExpField
> pExpField(
1360 new SwSetExpField(pTyp
, OUString(), nFormatId
));
1362 // Don't change type of SwSetExpFieldType:
1363 sal_uInt16 nOldSubType
= pExpField
->GetSubType();
1364 pExpField
->SetSubType(nOldSubType
| (nSubType
& 0xff00));
1366 pExpField
->SetPromptText(rData
.m_sPar2
);
1367 pExpField
->SetInputFlag(true) ;
1369 pField
= std::move(pExpField
);
1376 SwInputFieldType
* pTyp
=
1377 static_cast<SwInputFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::Input
) );
1380 new SwInputField( pTyp
, rData
.m_sPar1
, rData
.m_sPar2
, nSubType
|nsSwExtendedSubType::SUB_INVISIBLE
, nFormatId
));
1385 case SwFieldTypesEnum::Set
:
1387 if (rData
.m_sPar2
.isEmpty()) // empty variables are not allowed
1390 SwSetExpFieldType
* pTyp
= static_cast<SwSetExpFieldType
*>( pCurShell
->InsertFieldType(
1391 SwSetExpFieldType(pCurShell
->GetDoc(), rData
.m_sPar1
) ) );
1393 std::unique_ptr
<SwSetExpField
> pExpField(new SwSetExpField( pTyp
, rData
.m_sPar2
, nFormatId
));
1394 pExpField
->SetSubType(nSubType
);
1395 pExpField
->SetPar2(rData
.m_sPar2
);
1397 pField
= std::move(pExpField
);
1401 case SwFieldTypesEnum::Sequence
:
1403 SwSetExpFieldType
* pTyp
= static_cast<SwSetExpFieldType
*>( pCurShell
->InsertFieldType(
1404 SwSetExpFieldType(pCurShell
->GetDoc(), rData
.m_sPar1
, nsSwGetSetExpType::GSE_SEQ
)));
1406 sal_uInt8 nLevel
= static_cast< sal_uInt8
>(nSubType
& 0xff);
1408 pTyp
->SetOutlineLvl(nLevel
);
1409 if (nLevel
!= 0x7f && cSeparator
== 0)
1412 pTyp
->SetDelimiter(OUString(cSeparator
));
1413 pField
.reset(new SwSetExpField(pTyp
, rData
.m_sPar2
, nFormatId
));
1418 case SwFieldTypesEnum::Get
:
1420 // is there a corresponding SetField
1421 SwSetExpFieldType
* pSetTyp
= static_cast<SwSetExpFieldType
*>(
1422 pCurShell
->GetFieldType(SwFieldIds::SetExp
, rData
.m_sPar1
));
1426 SwGetExpFieldType
* pTyp
= static_cast<SwGetExpFieldType
*>( pCurShell
->GetFieldType(
1427 0, SwFieldIds::GetExp
) );
1428 pField
.reset( new SwGetExpField(pTyp
, rData
.m_sPar1
, pSetTyp
->GetType(), nFormatId
) );
1429 pField
->SetSubType(nSubType
| pSetTyp
->GetType());
1437 case SwFieldTypesEnum::Formel
:
1439 if(pCurShell
->GetFrameType(nullptr,false) & FrameTypeFlags::TABLE
)
1441 pCurShell
->StartAllAction();
1443 SvNumberFormatter
* pFormatter
= pCurShell
->GetDoc()->GetNumberFormatter();
1444 const SvNumberformat
* pEntry
= pFormatter
->GetEntry(nFormatId
);
1448 SfxStringItem
aFormat(FN_NUMBER_FORMAT
, pEntry
->GetFormatstring());
1449 pCurShell
->GetView().GetViewFrame().GetDispatcher()->
1450 ExecuteList(FN_NUMBER_FORMAT
, SfxCallMode::SYNCHRON
,
1454 SfxItemSetFixed
<RES_BOXATR_FORMULA
, RES_BOXATR_FORMULA
> aBoxSet( pCurShell
->GetAttrPool() );
1456 OUString
sFormula(comphelper::string::stripStart(rData
.m_sPar2
, ' '));
1457 if ( sFormula
.startsWith("=") )
1459 sFormula
= sFormula
.copy(1);
1462 aBoxSet
.Put( SwTableBoxFormula( sFormula
));
1463 pCurShell
->SetTableBoxFormulaAttrs( aBoxSet
);
1464 pCurShell
->UpdateTable();
1466 pCurShell
->EndAllAction();
1472 SwGetExpFieldType
* pTyp
= static_cast<SwGetExpFieldType
*>(
1473 pCurShell
->GetFieldType(0, SwFieldIds::GetExp
) );
1474 pField
.reset( new SwGetExpField(pTyp
, rData
.m_sPar2
, nsSwGetSetExpType::GSE_FORMULA
, nFormatId
) );
1475 pField
->SetSubType(nSubType
);
1480 case SwFieldTypesEnum::SetRefPage
:
1481 pField
.reset( new SwRefPageSetField( static_cast<SwRefPageSetFieldType
*>(
1482 pCurShell
->GetFieldType( 0, SwFieldIds::RefPageSet
) ),
1483 static_cast<short>(rData
.m_sPar2
.toInt32()), 0 != nSubType
) );
1487 case SwFieldTypesEnum::GetRefPage
:
1488 pField
.reset( new SwRefPageGetField( static_cast<SwRefPageGetFieldType
*>(
1489 pCurShell
->GetFieldType( 0, SwFieldIds::RefPageGet
) ), nFormatId
) );
1492 case SwFieldTypesEnum::Dropdown
:
1494 pField
.reset( new SwDropDownField(pCurShell
->GetFieldType( 0, SwFieldIds::Dropdown
)) );
1495 const sal_Int32 nTokenCount
= comphelper::string::getTokenCount(rData
.m_sPar2
, DB_DELIM
);
1496 Sequence
<OUString
> aEntries(nTokenCount
);
1497 OUString
* pArray
= aEntries
.getArray();
1498 for(sal_Int32 nToken
= 0, nIdx
= 0; nToken
< nTokenCount
; nToken
++)
1499 pArray
[nToken
] = rData
.m_sPar2
.getToken(0, DB_DELIM
, nIdx
);
1500 static_cast<SwDropDownField
*>(pField
.get())->SetItems(aEntries
);
1501 static_cast<SwDropDownField
*>(pField
.get())->SetName(rData
.m_sPar1
);
1505 // Insert Paragraph Signature field by signing the paragraph.
1506 // The resulting field is really a metadata field, created and added via signing.
1507 case SwFieldTypesEnum::ParagraphSignature
:
1508 pCurShell
->SignParagraph();
1512 { OSL_ENSURE(false, "wrong field type");
1516 OSL_ENSURE(pField
, "field not available");
1518 //the auto language flag has to be set prior to the language!
1519 pField
->SetAutomaticLanguage(rData
.m_bIsAutomaticLanguage
);
1520 LanguageType nLang
= GetCurrLanguage();
1521 pField
->SetLanguage(nLang
);
1524 pCurShell
->StartAllAction();
1526 bool const isSuccess
= pCurShell
->InsertField2(*pField
, rData
.m_oAnnotationRange
? &*rData
.m_oAnnotationRange
: nullptr);
1530 if (SwFieldTypesEnum::Input
== rData
.m_nTypeId
)
1534 // start dialog, not before the field is inserted tdf#99529
1535 pCurShell
->Left(SwCursorSkipMode::Chars
, false,
1536 (INP_VAR
== (nSubType
& 0xff) || pCurShell
->GetViewOptions()->IsFieldName()) ? 1 : 2,
1538 pCurShell
->StartInputFieldDlg(pField
.get(), false, true, rData
.m_pParent
);
1540 pCurShell
->Pop(SwCursorShell::PopMode::DeleteCurrent
);
1543 if (bExp
&& m_bEvalExp
)
1545 pCurShell
->UpdateExpFields(true);
1550 pCurShell
->Left(SwCursorSkipMode::Chars
, false, 1, false );
1551 pCurShell
->UpdateOneField(*pField
);
1552 pCurShell
->Right(SwCursorSkipMode::Chars
, false, 1, false );
1556 static_cast<SwRefPageGetFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::RefPageGet
))->UpdateFields();
1558 else if (SwFieldTypesEnum::GetRef
== rData
.m_nTypeId
)
1560 pField
->GetTyp()->UpdateFields();
1564 // delete temporary field
1567 pCurShell
->EndAllAction();
1572 void SwFieldMgr::UpdateCurField(sal_uInt32 nFormat
,
1573 const OUString
& rPar1
,
1574 const OUString
& rPar2
,
1575 std::unique_ptr
<SwField
> pTmpField
)
1578 OSL_ENSURE(m_pCurField
, "no field at CursorPos");
1581 pTmpField
= m_pCurField
->CopyField();
1583 SwFieldType
* pType
= pTmpField
->GetTyp();
1584 const SwFieldTypesEnum nTypeId
= pTmpField
->GetTypeId();
1586 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
1587 OSL_ENSURE(pSh
, "no SwWrtShell found");
1590 pSh
->StartAllAction();
1592 bool bSetPar2
= true;
1593 bool bSetPar1
= true;
1594 OUString
sPar2( rPar2
);
1599 case SwFieldTypesEnum::DDE
:
1601 // DDE-Topics/-Items can have blanks in their names!
1602 // That's not yet considered here!
1603 sal_Int32 nIndex
= 0;
1604 sPar2
= sPar2
.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator
), &nIndex
);
1605 if (nIndex
>=0 && ++nIndex
<sPar2
.getLength())
1607 sPar2
= sPar2
.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator
), &nIndex
);
1612 case SwFieldTypesEnum::Chapter
:
1614 sal_uInt16 nByte
= o3tl::narrowing
<sal_uInt16
>(rPar2
.toInt32());
1615 nByte
= std::max(sal_uInt16(1), nByte
);
1616 nByte
= std::min(nByte
, sal_uInt16(MAXLEVEL
));
1618 static_cast<SwChapterField
*>(pTmpField
.get())->SetLevel(static_cast<sal_uInt8
>(nByte
));
1623 case SwFieldTypesEnum::Script
:
1624 static_cast<SwScriptField
*>(pTmpField
.get())->SetCodeURL(static_cast<bool>(nFormat
));
1627 case SwFieldTypesEnum::NextPage
:
1628 if( SVX_NUM_CHAR_SPECIAL
== nFormat
)
1630 static_cast<SwPageNumberField
*>(m_pCurField
)->SetUserString( sPar2
);
1635 if( nFormat
+ 2 == SVX_NUM_PAGEDESC
)
1636 nFormat
= SVX_NUM_PAGEDESC
;
1637 short nOff
= static_cast<short>(sPar2
.toInt32());
1639 sPar2
= OUString::number(nOff
);
1643 case SwFieldTypesEnum::PreviousPage
:
1644 if( SVX_NUM_CHAR_SPECIAL
== nFormat
)
1646 static_cast<SwPageNumberField
*>(m_pCurField
)->SetUserString( sPar2
);
1651 if( nFormat
+ 2 == SVX_NUM_PAGEDESC
)
1652 nFormat
= SVX_NUM_PAGEDESC
;
1653 short nOff
= static_cast<short>(sPar2
.toInt32());
1655 sPar2
= OUString::number(nOff
);
1659 case SwFieldTypesEnum::PageNumber
:
1660 case SwFieldTypesEnum::GetRefPage
:
1661 if( nFormat
+ 2 == SVX_NUM_PAGEDESC
)
1662 nFormat
= SVX_NUM_PAGEDESC
;
1665 case SwFieldTypesEnum::GetRef
:
1668 static_cast<SwGetRefField
*>(pTmpField
.get())->SetSubType( o3tl::narrowing
<sal_uInt16
>(rPar2
.toInt32()) );
1669 const sal_Int32 nPos
= rPar2
.indexOf( '|' );
1671 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 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 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: */