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>
23 #include <hintids.hxx>
24 #include <svl/stritem.hxx>
25 #include <com/sun/star/text/DefaultNumberingProvider.hpp>
26 #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
27 #include <com/sun/star/text/XNumberingTypeInfo.hpp>
28 #include <com/sun/star/style/NumberingType.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/sdbc/XConnection.hpp>
31 #include <com/sun/star/sdbc/XDataSource.hpp>
32 #include <com/sun/star/uri/UriReferenceFactory.hpp>
33 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
34 #include <comphelper/processfactory.hxx>
35 #include <comphelper/string.hxx>
36 #include <tools/resary.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <sfx2/linkmgr.hxx>
39 #include <sfx2/app.hxx>
40 #include <sfx2/viewfrm.hxx>
41 #include <svx/strarray.hxx>
42 #include <fmtrfmrk.hxx>
43 #include <svl/zforlist.hxx>
44 #include <svl/zformat.hxx>
45 #include <vcl/mnemonic.hxx>
49 #include <swmodule.hxx>
50 #include <fmtinfmt.hxx>
51 #include <cellatr.hxx>
53 #include <shellres.hxx>
55 #include <docufld.hxx>
62 #include <authfld.hxx>
65 #include <flddropdown.hxx>
66 #include <strings.hrc>
68 #include <viewopt.hxx>
69 #include <unotools/useroptions.hxx>
71 using namespace com::sun::star::uno
;
72 using namespace com::sun::star::container
;
73 using namespace com::sun::star::lang
;
74 using namespace com::sun::star::beans
;
75 using namespace com::sun::star::text
;
76 using namespace com::sun::star::style
;
77 using namespace com::sun::star::sdbc
;
78 using namespace ::com::sun::star
;
79 using namespace nsSwDocInfoSubType
;
85 GRP_DOC_END
= GRP_DOC_BEGIN
+ 12,
87 GRP_FKT_BEGIN
= GRP_DOC_END
,
88 GRP_FKT_END
= GRP_FKT_BEGIN
+ 8,
90 GRP_REF_BEGIN
= GRP_FKT_END
,
91 GRP_REF_END
= GRP_REF_BEGIN
+ 2,
93 GRP_REG_BEGIN
= GRP_REF_END
,
94 GRP_REG_END
= GRP_REG_BEGIN
+ 1,
96 GRP_DB_BEGIN
= GRP_REG_END
,
97 GRP_DB_END
= GRP_DB_BEGIN
+ 5,
99 GRP_VAR_BEGIN
= GRP_DB_END
,
100 GRP_VAR_END
= GRP_VAR_BEGIN
+ 9
105 GRP_WEB_DOC_BEGIN
= 0,
106 GRP_WEB_DOC_END
= GRP_WEB_DOC_BEGIN
+ 9,
108 GRP_WEB_FKT_BEGIN
= GRP_WEB_DOC_END
+ 2,
109 GRP_WEB_FKT_END
= GRP_WEB_FKT_BEGIN
+ 0, // the group is empty!
111 GRP_WEB_REF_BEGIN
= GRP_WEB_FKT_END
+ 6, // the group is empty!
112 GRP_WEB_REF_END
= GRP_WEB_REF_BEGIN
+ 0,
114 GRP_WEB_REG_BEGIN
= GRP_WEB_REF_END
+ 2,
115 GRP_WEB_REG_END
= GRP_WEB_REG_BEGIN
+ 1,
117 GRP_WEB_DB_BEGIN
= GRP_WEB_REG_END
, // the group is empty!
118 GRP_WEB_DB_END
= GRP_WEB_DB_BEGIN
+ 0,
120 GRP_WEB_VAR_BEGIN
= GRP_WEB_DB_END
+ 5,
121 GRP_WEB_VAR_END
= GRP_WEB_VAR_BEGIN
+ 1
124 const sal_uInt16 VF_COUNT
= 1; // { 0 }
125 const sal_uInt16 VF_USR_COUNT
= 2; // { 0, nsSwExtendedSubType::SUB_CMD }
126 const sal_uInt16 VF_DB_COUNT
= 1; // { nsSwExtendedSubType::SUB_OWN_FMT }
128 static const char* FLD_EU_ARY
[] =
147 static const char* FMT_AUTHOR_ARY
[] =
153 static const char* FLD_DATE_ARY
[] =
159 static const char* FLD_TIME_ARY
[] =
165 static const char* FMT_NUM_ARY
[] =
178 static const char* FMT_FF_ARY
[] =
188 static const char* FLD_STAT_ARY
[] =
199 static const char* FMT_CHAPTER_ARY
[] =
204 FMT_CHAPTER_NO_NOSEPARATOR
207 static const char* FLD_INPUT_ARY
[] =
212 static const char* FMT_MARK_ARY
[] =
221 static const char* FMT_REF_ARY
[] =
232 FMT_REF_NUMBER_NO_CONTEXT
,
233 FMT_REF_NUMBER_FULL_CONTEXT
236 static const char* FMT_REG_ARY
[] =
243 static const char* FMT_DBFLD_ARY
[] =
249 static const char* FMT_SETVAR_ARY
[] =
255 static const char* FMT_GETVAR_ARY
[] =
261 static const char* FMT_DDE_ARY
[] =
267 static const char* FLD_PAGEREF_ARY
[] =
273 static const char* FMT_USERVAR_ARY
[] =
281 // field types and subtypes
284 SwFieldTypesEnum nTypeId
;
286 const char** pSubTypeResIds
;
287 size_t nSubTypeLength
;
289 const char** pFormatResIds
;
290 size_t nFormatLength
;
295 // strings and formats
296 const SwFieldPack aSwFields
[] =
299 { SwFieldTypesEnum::ExtendedUser
, FLD_EU_ARY
, SAL_N_ELEMENTS(FLD_EU_ARY
), nullptr, 0 },
300 { SwFieldTypesEnum::Author
, nullptr, 0, FMT_AUTHOR_ARY
, SAL_N_ELEMENTS(FMT_AUTHOR_ARY
) },
301 { SwFieldTypesEnum::Date
, FLD_DATE_ARY
, SAL_N_ELEMENTS(FLD_DATE_ARY
), nullptr, 0 },
302 { SwFieldTypesEnum::Time
, FLD_TIME_ARY
, SAL_N_ELEMENTS(FLD_TIME_ARY
), nullptr, 0 },
303 { SwFieldTypesEnum::PageNumber
, nullptr, 0, FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) -1 },
304 { SwFieldTypesEnum::NextPage
, nullptr, 0, FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) },
305 { SwFieldTypesEnum::PreviousPage
, nullptr, 0, FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) },
306 { SwFieldTypesEnum::Filename
, nullptr, 0, FMT_FF_ARY
, SAL_N_ELEMENTS(FMT_FF_ARY
) },
307 { SwFieldTypesEnum::DocumentStatistics
, FLD_STAT_ARY
, SAL_N_ELEMENTS(FLD_STAT_ARY
), FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) -1 },
309 { SwFieldTypesEnum::Chapter
, nullptr, 0, FMT_CHAPTER_ARY
, SAL_N_ELEMENTS(FMT_CHAPTER_ARY
) },
310 { SwFieldTypesEnum::TemplateName
, nullptr, 0, FMT_FF_ARY
, SAL_N_ELEMENTS(FMT_FF_ARY
) },
311 { SwFieldTypesEnum::ParagraphSignature
, nullptr, 0, nullptr, 0 },
314 { SwFieldTypesEnum::ConditionalText
, nullptr, 0, nullptr, 0 },
315 { SwFieldTypesEnum::Dropdown
, nullptr, 0, nullptr, 0 },
316 { SwFieldTypesEnum::Input
, FLD_INPUT_ARY
, SAL_N_ELEMENTS(FLD_INPUT_ARY
), nullptr, 0 },
317 { SwFieldTypesEnum::Macro
, nullptr, 0, nullptr, 0 },
318 { SwFieldTypesEnum::JumpEdit
, nullptr, 0, FMT_MARK_ARY
, SAL_N_ELEMENTS(FMT_MARK_ARY
) },
319 { SwFieldTypesEnum::CombinedChars
, nullptr, 0, nullptr, 0 },
320 { SwFieldTypesEnum::HiddenText
, nullptr, 0, nullptr, 0 },
321 { SwFieldTypesEnum::HiddenParagraph
, nullptr, 0, nullptr, 0 },
324 { SwFieldTypesEnum::SetRef
, nullptr, 0, nullptr, 0 },
325 { SwFieldTypesEnum::GetRef
, nullptr, 0, FMT_REF_ARY
, SAL_N_ELEMENTS(FMT_REF_ARY
) },
328 { SwFieldTypesEnum::DocumentInfo
, nullptr, 0, FMT_REG_ARY
, SAL_N_ELEMENTS(FMT_REG_ARY
) },
331 { SwFieldTypesEnum::Database
, nullptr, 0, FMT_DBFLD_ARY
, SAL_N_ELEMENTS(FMT_DBFLD_ARY
) },
332 { SwFieldTypesEnum::DatabaseNextSet
, nullptr, 0, nullptr, 0 },
333 { SwFieldTypesEnum::DatabaseNumberSet
, nullptr, 0, nullptr, 0 },
334 { SwFieldTypesEnum::DatabaseSetNumber
, nullptr, 0, FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) - 2 },
335 { SwFieldTypesEnum::DatabaseName
, nullptr, 0, nullptr, 0 },
338 { SwFieldTypesEnum::Set
, nullptr, 0, FMT_SETVAR_ARY
, SAL_N_ELEMENTS(FMT_SETVAR_ARY
) },
340 { SwFieldTypesEnum::Get
, nullptr, 0, FMT_GETVAR_ARY
, SAL_N_ELEMENTS(FMT_GETVAR_ARY
) },
341 { SwFieldTypesEnum::DDE
, nullptr, 0, FMT_DDE_ARY
, SAL_N_ELEMENTS(FMT_DDE_ARY
) },
342 { SwFieldTypesEnum::Formel
, nullptr, 0, FMT_GETVAR_ARY
, SAL_N_ELEMENTS(FMT_GETVAR_ARY
) },
343 { SwFieldTypesEnum::Input
, FLD_INPUT_ARY
, SAL_N_ELEMENTS(FLD_INPUT_ARY
), nullptr, 0 },
344 { SwFieldTypesEnum::Sequence
, nullptr, 0, FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) - 2 },
345 { SwFieldTypesEnum::SetRefPage
, FLD_PAGEREF_ARY
, SAL_N_ELEMENTS(FLD_PAGEREF_ARY
),nullptr, 0 },
346 { SwFieldTypesEnum::GetRefPage
, nullptr, 0, FMT_NUM_ARY
, SAL_N_ELEMENTS(FMT_NUM_ARY
) - 1 },
347 { SwFieldTypesEnum::User
, nullptr, 0, FMT_USERVAR_ARY
, SAL_N_ELEMENTS(FMT_USERVAR_ARY
) }
350 // access to the shell
351 static SwWrtShell
* lcl_GetShell()
353 SwView
* pView
= ::GetActiveView();
354 if ( nullptr != pView
)
355 return pView
->GetWrtShellPtr();
356 OSL_FAIL("no current shell found!");
360 static sal_uInt16
GetPackCount() { return SAL_N_ELEMENTS(aSwFields
); }
362 // FieldManager controls inserting and updating of fields
363 SwFieldMgr::SwFieldMgr(SwWrtShell
* pSh
) :
367 // determine current field if existing
371 SwFieldMgr::~SwFieldMgr()
375 // organise RefMark by names
376 bool SwFieldMgr::CanInsertRefMark( const OUString
& rStr
)
379 SwWrtShell
*pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
380 OSL_ENSURE(pSh
, "no SwWrtShell found");
383 sal_uInt16 nCnt
= pSh
->GetCursorCnt();
385 // the last Cursor doesn't have to be a spanned selection
386 if( 1 < nCnt
&& !pSh
->SwCursorShell::HasSelection() )
389 bRet
= 2 > nCnt
&& nullptr == pSh
->GetRefMark( rStr
);
394 // access over ResIds
395 void SwFieldMgr::RemoveFieldType(SwFieldIds nResId
, const OUString
& rName
)
397 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
398 OSL_ENSURE(pSh
, "no SwWrtShell found");
400 pSh
->RemoveFieldType(nResId
, rName
);
403 size_t SwFieldMgr::GetFieldTypeCount() const
405 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
406 OSL_ENSURE(pSh
, "no SwWrtShell found");
407 return pSh
? pSh
->GetFieldTypeCount() : 0;
410 SwFieldType
* SwFieldMgr::GetFieldType(SwFieldIds nResId
, size_t nField
) const
412 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
413 OSL_ENSURE(pSh
, "no SwWrtShell found");
414 return pSh
? pSh
->GetFieldType(nField
, nResId
) : nullptr;
417 SwFieldType
* SwFieldMgr::GetFieldType(SwFieldIds nResId
, const OUString
& rName
) const
419 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
420 OSL_ENSURE(pSh
, "no SwWrtShell found");
421 return pSh
? pSh
->GetFieldType(nResId
, rName
) : nullptr;
424 // determine current field
425 SwField
* SwFieldMgr::GetCurField()
427 SwWrtShell
*pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
429 m_pCurField
= pSh
->GetCurField( true );
431 m_pCurField
= nullptr;
433 // initialise strings and format
442 // preprocess current values; determine parameter 1 and parameter 2
443 // as well as the format
444 const SwFieldTypesEnum nTypeId
= m_pCurField
->GetTypeId();
446 m_nCurFormat
= m_pCurField
->GetFormat();
447 m_aCurPar1
= m_pCurField
->GetPar1();
448 m_aCurPar2
= m_pCurField
->GetPar2();
452 case SwFieldTypesEnum::PageNumber
:
453 case SwFieldTypesEnum::NextPage
:
454 case SwFieldTypesEnum::PreviousPage
:
455 case SwFieldTypesEnum::GetRefPage
:
456 if( m_nCurFormat
== SVX_NUM_PAGEDESC
)
464 // provide group range
465 const SwFieldGroupRgn
& SwFieldMgr::GetGroupRange(bool bHtmlMode
, sal_uInt16 nGrpId
)
467 static SwFieldGroupRgn
const aRanges
[] =
469 { /* Document */ GRP_DOC_BEGIN
, GRP_DOC_END
},
470 { /* Functions */ GRP_FKT_BEGIN
, GRP_FKT_END
},
471 { /* Cross-Refs */ GRP_REF_BEGIN
, GRP_REF_END
},
472 { /* DocInfos */ GRP_REG_BEGIN
, GRP_REG_END
},
473 { /* Database */ GRP_DB_BEGIN
, GRP_DB_END
},
474 { /* User */ GRP_VAR_BEGIN
, GRP_VAR_END
}
476 static SwFieldGroupRgn
const aWebRanges
[] =
478 { /* Document */ GRP_WEB_DOC_BEGIN
, GRP_WEB_DOC_END
},
479 { /* Functions */ GRP_WEB_FKT_BEGIN
, GRP_WEB_FKT_END
},
480 { /* Cross-Refs */ GRP_WEB_REF_BEGIN
, GRP_WEB_REF_END
},
481 { /* DocInfos */ GRP_WEB_REG_BEGIN
, GRP_WEB_REG_END
},
482 { /* Database */ GRP_WEB_DB_BEGIN
, GRP_WEB_DB_END
},
483 { /* User */ GRP_WEB_VAR_BEGIN
, GRP_WEB_VAR_END
}
487 return aWebRanges
[nGrpId
];
489 return aRanges
[nGrpId
];
493 sal_uInt16
SwFieldMgr::GetGroup(SwFieldTypesEnum nTypeId
, sal_uInt16 nSubType
)
495 if (nTypeId
== SwFieldTypesEnum::SetInput
)
496 nTypeId
= SwFieldTypesEnum::Set
;
498 if (nTypeId
== SwFieldTypesEnum::Input
&& (nSubType
& INP_USR
))
499 nTypeId
= SwFieldTypesEnum::User
;
501 if (nTypeId
== SwFieldTypesEnum::FixedDate
)
502 nTypeId
= SwFieldTypesEnum::Date
;
504 if (nTypeId
== SwFieldTypesEnum::FixedTime
)
505 nTypeId
= SwFieldTypesEnum::Time
;
507 for (sal_uInt16 i
= GRP_DOC
; i
<= GRP_VAR
; i
++)
509 const SwFieldGroupRgn
& rRange
= GetGroupRange(false/*bHtmlMode*/, i
);
510 for (sal_uInt16 nPos
= rRange
.nStart
; nPos
< rRange
.nEnd
; nPos
++)
512 if (aSwFields
[nPos
].nTypeId
== nTypeId
)
519 // determine names to TypeId
520 // ACCESS over TYP_...
521 SwFieldTypesEnum
SwFieldMgr::GetTypeId(sal_uInt16 nPos
)
523 OSL_ENSURE(nPos
< ::GetPackCount(), "forbidden Pos");
524 return aSwFields
[ nPos
].nTypeId
;
527 OUString
SwFieldMgr::GetTypeStr(sal_uInt16 nPos
)
529 OSL_ENSURE(nPos
< ::GetPackCount(), "forbidden TypeId");
531 SwFieldTypesEnum nFieldWh
= aSwFields
[ nPos
].nTypeId
;
533 // special treatment for date/time fields (without var/fix)
534 if( SwFieldTypesEnum::Date
== nFieldWh
)
536 static OUString
g_aDate( SwResId( STR_DATEFLD
) );
539 if( SwFieldTypesEnum::Time
== nFieldWh
)
541 static OUString
g_aTime( SwResId( STR_TIMEFLD
) );
545 return SwFieldType::GetTypeStr( nFieldWh
);
548 // determine Pos in the list
549 sal_uInt16
SwFieldMgr::GetPos(SwFieldTypesEnum nTypeId
)
553 case SwFieldTypesEnum::FixedDate
: nTypeId
= SwFieldTypesEnum::Date
; break;
554 case SwFieldTypesEnum::FixedTime
: nTypeId
= SwFieldTypesEnum::Time
; break;
555 case SwFieldTypesEnum::SetInput
: nTypeId
= SwFieldTypesEnum::Set
; break;
556 case SwFieldTypesEnum::UserInput
: nTypeId
= SwFieldTypesEnum::User
; break;
560 for(sal_uInt16 i
= 0; i
< GetPackCount(); i
++)
561 if(aSwFields
[i
].nTypeId
== nTypeId
)
567 // localise subtypes of a field
568 void SwFieldMgr::GetSubTypes(SwFieldTypesEnum nTypeId
, std::vector
<OUString
>& rToFill
)
570 SwWrtShell
*pSh
= m_pWrtShell
? m_pWrtShell
: lcl_GetShell();
571 OSL_ENSURE(pSh
, "no SwWrtShell found");
575 const sal_uInt16 nPos
= GetPos(nTypeId
);
579 case SwFieldTypesEnum::SetRef
:
580 case SwFieldTypesEnum::GetRef
:
582 // references are no fields
583 pSh
->GetRefMarks( &rToFill
);
586 case SwFieldTypesEnum::Macro
:
590 case SwFieldTypesEnum::Input
:
592 rToFill
.push_back(SwResId(aSwFields
[nPos
].pSubTypeResIds
[0]));
593 [[fallthrough
]]; // move on at generic types
595 case SwFieldTypesEnum::DDE
:
596 case SwFieldTypesEnum::Sequence
:
597 case SwFieldTypesEnum::Formel
:
598 case SwFieldTypesEnum::Get
:
599 case SwFieldTypesEnum::Set
:
600 case SwFieldTypesEnum::User
:
603 const size_t nCount
= pSh
->GetFieldTypeCount();
604 for(size_t i
= 0; i
< nCount
; ++i
)
606 SwFieldType
* pFieldType
= pSh
->GetFieldType( i
);
607 const SwFieldIds nWhich
= pFieldType
->Which();
609 if((nTypeId
== SwFieldTypesEnum::DDE
&& pFieldType
->Which() == SwFieldIds::Dde
) ||
611 (nTypeId
== SwFieldTypesEnum::User
&& nWhich
== SwFieldIds::User
) ||
613 (nTypeId
== SwFieldTypesEnum::Get
&& nWhich
== SwFieldIds::SetExp
&&
614 !(static_cast<SwSetExpFieldType
*>(pFieldType
)->GetType() & nsSwGetSetExpType::GSE_SEQ
)) ||
616 (nTypeId
== SwFieldTypesEnum::Set
&& nWhich
== SwFieldIds::SetExp
&&
617 !(static_cast<SwSetExpFieldType
*>(pFieldType
)->GetType() & nsSwGetSetExpType::GSE_SEQ
)) ||
619 (nTypeId
== SwFieldTypesEnum::Sequence
&& nWhich
== SwFieldIds::SetExp
&&
620 (static_cast<SwSetExpFieldType
*>(pFieldType
)->GetType() & nsSwGetSetExpType::GSE_SEQ
)) ||
622 ((nTypeId
== SwFieldTypesEnum::Input
|| nTypeId
== SwFieldTypesEnum::Formel
) &&
623 (nWhich
== SwFieldIds::User
||
624 (nWhich
== SwFieldIds::SetExp
&&
625 !(static_cast<SwSetExpFieldType
*>(pFieldType
)->GetType() & nsSwGetSetExpType::GSE_SEQ
))) ) )
627 rToFill
.push_back(pFieldType
->GetName());
632 case SwFieldTypesEnum::DatabaseNextSet
:
633 case SwFieldTypesEnum::DatabaseNumberSet
:
634 case SwFieldTypesEnum::DatabaseName
:
635 case SwFieldTypesEnum::DatabaseSetNumber
:
641 if(nPos
!= USHRT_MAX
)
644 if (nTypeId
== SwFieldTypesEnum::DocumentInfo
)
645 nCount
= DI_SUBTYPE_END
- DI_SUBTYPE_BEGIN
;
647 nCount
= aSwFields
[nPos
].nSubTypeLength
;
649 for(sal_uInt16 i
= 0; i
< nCount
; ++i
)
652 if (nTypeId
== SwFieldTypesEnum::DocumentInfo
)
654 if ( i
== DI_CUSTOM
)
655 sNew
= SwResId(STR_CUSTOM_FIELD
);
657 sNew
= SwViewShell::GetShellRes()->aDocInfoLst
[i
];
660 sNew
= SwResId(aSwFields
[nPos
].pSubTypeResIds
[i
]);
662 rToFill
.push_back(sNew
);
670 // ACCESS over TYP_...
671 sal_uInt16
SwFieldMgr::GetFormatCount(SwFieldTypesEnum nTypeId
, bool bHtmlMode
) const
673 assert(nTypeId
< SwFieldTypesEnum::LAST
&& "forbidden TypeId");
675 const sal_uInt16 nPos
= GetPos(nTypeId
);
677 if (nPos
== USHRT_MAX
|| (bHtmlMode
&& nTypeId
== SwFieldTypesEnum::Set
))
680 sal_uInt16 nCount
= aSwFields
[nPos
].nFormatLength
;
682 if (nTypeId
== SwFieldTypesEnum::Filename
)
683 nCount
-= 2; // no range or template
685 const char** pStart
= aSwFields
[nPos
].pFormatResIds
;
689 if (strcmp(*pStart
, FMT_GETVAR_ARY
[0]) == 0 || strcmp(*pStart
, FMT_SETVAR_ARY
[0]) == 0)
691 else if (strcmp(*pStart
, FMT_USERVAR_ARY
[0]) == 0)
693 else if (strcmp(*pStart
, FMT_DBFLD_ARY
[0]) == 0)
695 else if (strcmp(*pStart
, FMT_NUM_ARY
[0]) == 0)
698 if(m_xNumberingInfo
.is())
700 Sequence
<sal_Int16
> aTypes
= m_xNumberingInfo
->getSupportedNumberingTypes();
701 // #i28073# it's not necessarily a sorted sequence
702 //skip all values below or equal to CHARS_LOWER_LETTER_N
703 nCount
+= std::count_if(aTypes
.begin(), aTypes
.end(),
704 [](sal_Int16 nCurrent
) { return nCurrent
> NumberingType::CHARS_LOWER_LETTER_N
; });
713 // determine FormatString to a type
714 OUString
SwFieldMgr::GetFormatStr(SwFieldTypesEnum nTypeId
, sal_uInt32 nFormatId
) const
716 assert(nTypeId
< SwFieldTypesEnum::LAST
&& "forbidden TypeId");
717 const sal_uInt16 nPos
= GetPos(nTypeId
);
719 if (nPos
== USHRT_MAX
)
722 const char** pStart
= aSwFields
[nPos
].pFormatResIds
;
726 if (SwFieldTypesEnum::Author
== nTypeId
|| SwFieldTypesEnum::Filename
== nTypeId
)
727 nFormatId
&= ~static_cast<sal_uInt32
>(FF_FIXED
); // mask out Fixed-Flag
729 if (nFormatId
< aSwFields
[nPos
].nFormatLength
)
730 return SwResId(pStart
[nFormatId
]);
733 if (*pStart
== FMT_NUM_ARY
[0])
735 if (m_xNumberingInfo
.is())
737 Sequence
<sal_Int16
> aTypes
= m_xNumberingInfo
->getSupportedNumberingTypes();
738 sal_Int32 nOffset
= aSwFields
[nPos
].nFormatLength
;
739 sal_uInt32 nValidEntry
= 0;
740 for (const sal_Int16 nCurrent
: aTypes
)
742 if(nCurrent
> NumberingType::CHARS_LOWER_LETTER_N
&&
743 (nCurrent
!= (NumberingType::BITMAP
| LINK_TOKEN
)))
745 if (nValidEntry
== nFormatId
- nOffset
)
747 sal_uInt32 n
= SvxNumberingTypeTable::FindIndex(nCurrent
);
748 if (n
!= RESARRAY_INDEX_NOTFOUND
)
750 aRet
= SvxNumberingTypeTable::GetString(n
);
754 aRet
= m_xNumberingInfo
->getNumberingIdentifier( nCurrent
);
767 // determine FormatId from Pseudo-ID
768 sal_uInt16
SwFieldMgr::GetFormatId(SwFieldTypesEnum nTypeId
, sal_uInt32 nFormatId
) const
770 sal_uInt16 nId
= static_cast<sal_uInt16
>(nFormatId
);
773 case SwFieldTypesEnum::DocumentInfo
:
775 const OString
sId(aSwFields
[GetPos(nTypeId
)].pFormatResIds
[nFormatId
]);
776 if (sId
== FMT_REG_AUTHOR
)
778 else if (sId
== FMT_REG_TIME
)
780 else if (sId
== FMT_REG_DATE
)
784 case SwFieldTypesEnum::PageNumber
:
785 case SwFieldTypesEnum::NextPage
:
786 case SwFieldTypesEnum::PreviousPage
:
787 case SwFieldTypesEnum::DocumentStatistics
:
788 case SwFieldTypesEnum::DatabaseSetNumber
:
789 case SwFieldTypesEnum::Sequence
:
790 case SwFieldTypesEnum::GetRefPage
:
792 sal_uInt16 nPos
= GetPos(nTypeId
);
793 if (nFormatId
< aSwFields
[nPos
].nFormatLength
)
795 const OString
sId(aSwFields
[nPos
].pFormatResIds
[nFormatId
]);
796 if (sId
== FMT_NUM_ABC
)
797 nId
= SVX_NUM_CHARS_UPPER_LETTER
;
798 else if (sId
== FMT_NUM_SABC
)
799 nId
= SVX_NUM_CHARS_LOWER_LETTER
;
800 else if (sId
== FMT_NUM_ROMAN
)
801 nId
= SVX_NUM_ROMAN_UPPER
;
802 else if (sId
== FMT_NUM_SROMAN
)
803 nId
= SVX_NUM_ROMAN_LOWER
;
804 else if (sId
== FMT_NUM_ARABIC
)
805 nId
= SVX_NUM_ARABIC
;
806 else if (sId
== FMT_NUM_PAGEDESC
)
807 nId
= SVX_NUM_PAGEDESC
;
808 else if (sId
== FMT_NUM_PAGESPECIAL
)
809 nId
= SVX_NUM_CHAR_SPECIAL
;
810 else if (sId
== FMT_NUM_ABC_N
)
811 nId
= SVX_NUM_CHARS_UPPER_LETTER_N
;
812 else if (sId
== FMT_NUM_SABC_N
)
813 nId
= SVX_NUM_CHARS_LOWER_LETTER_N
;
815 else if (m_xNumberingInfo
.is())
817 Sequence
<sal_Int16
> aTypes
= m_xNumberingInfo
->getSupportedNumberingTypes();
818 sal_Int32 nOffset
= aSwFields
[nPos
].nFormatLength
;
819 sal_Int32 nValidEntry
= 0;
820 for (const sal_Int16 nCurrent
: aTypes
)
822 if (nCurrent
> NumberingType::CHARS_LOWER_LETTER_N
)
824 if (nValidEntry
== static_cast<sal_Int32
>(nFormatId
) - nOffset
)
835 case SwFieldTypesEnum::DDE
:
837 const OString
sId(aSwFields
[GetPos(nTypeId
)].pFormatResIds
[nFormatId
]);
838 if (sId
== FMT_DDE_NORMAL
)
839 nId
= static_cast<sal_uInt16
>(SfxLinkUpdateMode::ONCALL
);
840 else if (sId
== FMT_DDE_HOT
)
841 nId
= static_cast<sal_uInt16
>(SfxLinkUpdateMode::ALWAYS
);
850 bool SwFieldMgr::GoNextPrev( bool bNext
, SwFieldType
* pTyp
)
852 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
856 if( !pTyp
&& m_pCurField
)
858 const SwFieldTypesEnum nTypeId
= m_pCurField
->GetTypeId();
859 if( SwFieldTypesEnum::SetInput
== nTypeId
|| SwFieldTypesEnum::UserInput
== nTypeId
)
860 pTyp
= pSh
->GetFieldType( 0, SwFieldIds::Input
);
862 pTyp
= m_pCurField
->GetTyp();
865 if (pTyp
&& pTyp
->Which() == SwFieldIds::Database
)
867 // for fieldcommand-edit (hop to all DB fields)
868 return pSh
->MoveFieldType( nullptr, bNext
, SwFieldIds::Database
);
871 return pTyp
&& pSh
->MoveFieldType(pTyp
, bNext
);
874 // insert field types
875 void SwFieldMgr::InsertFieldType(SwFieldType
const & rType
)
877 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
878 OSL_ENSURE(pSh
, "no SwWrtShell found");
880 pSh
->InsertFieldType(rType
);
883 // determine current TypeId
884 SwFieldTypesEnum
SwFieldMgr::GetCurTypeId() const
886 return m_pCurField
? m_pCurField
->GetTypeId() : SwFieldTypesEnum::Unknown
;
889 // Over string insert field or update
890 bool SwFieldMgr::InsertField(
891 const SwInsertField_Data
& rData
)
893 std::unique_ptr
<SwField
> pField
;
896 bool bPageVar
= false;
897 sal_uInt32 nFormatId
= rData
.m_nFormatId
;
898 sal_uInt16 nSubType
= rData
.m_nSubType
;
899 sal_Unicode cSeparator
= rData
.m_cSeparator
;
900 SwWrtShell
* pCurShell
= rData
.m_pSh
;
902 pCurShell
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
903 OSL_ENSURE(pCurShell
, "no SwWrtShell found");
907 switch (rData
.m_nTypeId
)
908 { // ATTENTION this field is inserted by a separate dialog
909 case SwFieldTypesEnum::Postit
:
911 SvtUserOptions aUserOpt
;
912 SwPostItFieldType
* pType
= static_cast<SwPostItFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::Postit
));
916 rData
.m_sPar1
, // author
917 rData
.m_sPar2
, // content
918 aUserOpt
.GetID(), // author's initials
920 DateTime(DateTime::SYSTEM
) ));
923 case SwFieldTypesEnum::Script
:
925 SwScriptFieldType
* pType
=
926 static_cast<SwScriptFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::Script
));
927 pField
.reset(new SwScriptField(pType
, rData
.m_sPar1
, rData
.m_sPar2
, static_cast<bool>(nFormatId
)));
931 case SwFieldTypesEnum::CombinedChars
:
933 SwCombinedCharFieldType
* pType
= static_cast<SwCombinedCharFieldType
*>(
934 pCurShell
->GetFieldType( 0, SwFieldIds::CombinedChars
));
935 pField
.reset(new SwCombinedCharField( pType
, rData
.m_sPar1
));
939 case SwFieldTypesEnum::Authority
:
941 SwAuthorityFieldType
* pType
=
942 static_cast<SwAuthorityFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::TableOfAuthorities
));
945 SwAuthorityFieldType
const type(pCurShell
->GetDoc());
946 pType
= static_cast<SwAuthorityFieldType
*>(
947 pCurShell
->InsertFieldType(type
));
949 pField
.reset(new SwAuthorityField(pType
, rData
.m_sPar1
));
953 case SwFieldTypesEnum::Date
:
954 case SwFieldTypesEnum::Time
:
956 sal_uInt16 nSub
= static_cast< sal_uInt16
>(rData
.m_nTypeId
== SwFieldTypesEnum::Date
? DATEFLD
: TIMEFLD
);
957 nSub
|= nSubType
== DATE_VAR
? 0 : FIXEDFLD
;
959 SwDateTimeFieldType
* pTyp
=
960 static_cast<SwDateTimeFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::DateTime
) );
961 pField
.reset(new SwDateTimeField(pTyp
, nSub
, nFormatId
));
962 pField
->SetPar2(rData
.m_sPar2
);
966 case SwFieldTypesEnum::Filename
:
968 SwFileNameFieldType
* pTyp
=
969 static_cast<SwFileNameFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::Filename
) );
970 pField
.reset(new SwFileNameField(pTyp
, nFormatId
));
974 case SwFieldTypesEnum::TemplateName
:
976 SwTemplNameFieldType
* pTyp
=
977 static_cast<SwTemplNameFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::TemplateName
) );
978 pField
.reset(new SwTemplNameField(pTyp
, nFormatId
));
982 case SwFieldTypesEnum::Chapter
:
984 sal_uInt16 nByte
= static_cast<sal_uInt16
>(rData
.m_sPar2
.toInt32());
985 SwChapterFieldType
* pTyp
=
986 static_cast<SwChapterFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::Chapter
) );
987 pField
.reset(new SwChapterField(pTyp
, nFormatId
));
988 nByte
= std::max(sal_uInt16(1), nByte
);
989 nByte
= std::min(nByte
, sal_uInt16(MAXLEVEL
));
991 static_cast<SwChapterField
*>(pField
.get())->SetLevel(static_cast<sal_uInt8
>(nByte
));
995 case SwFieldTypesEnum::NextPage
:
996 case SwFieldTypesEnum::PreviousPage
:
997 case SwFieldTypesEnum::PageNumber
:
999 short nOff
= static_cast<short>(rData
.m_sPar2
.toInt32());
1001 if(rData
.m_nTypeId
== SwFieldTypesEnum::NextPage
)
1003 if( SVX_NUM_CHAR_SPECIAL
== nFormatId
)
1009 else if(rData
.m_nTypeId
== SwFieldTypesEnum::PreviousPage
)
1011 if( SVX_NUM_CHAR_SPECIAL
== nFormatId
)
1018 nSubType
= PG_RANDOM
;
1020 SwPageNumberFieldType
* pTyp
=
1021 static_cast<SwPageNumberFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::PageNumber
) );
1022 pField
.reset(new SwPageNumberField(pTyp
, nSubType
, nFormatId
, nOff
));
1024 if( SVX_NUM_CHAR_SPECIAL
== nFormatId
&&
1025 ( PG_PREV
== nSubType
|| PG_NEXT
== nSubType
) )
1026 static_cast<SwPageNumberField
*>(pField
.get())->SetUserString( rData
.m_sPar2
);
1030 case SwFieldTypesEnum::DocumentStatistics
:
1032 SwDocStatFieldType
* pTyp
=
1033 static_cast<SwDocStatFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::DocStat
) );
1034 pField
.reset(new SwDocStatField(pTyp
, nSubType
, nFormatId
));
1038 case SwFieldTypesEnum::Author
:
1040 SwAuthorFieldType
* pTyp
=
1041 static_cast<SwAuthorFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::Author
) );
1042 pField
.reset(new SwAuthorField(pTyp
, nFormatId
));
1046 case SwFieldTypesEnum::ConditionalText
:
1047 case SwFieldTypesEnum::HiddenText
:
1049 SwHiddenTextFieldType
* pTyp
=
1050 static_cast<SwHiddenTextFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::HiddenText
) );
1051 pField
.reset(new SwHiddenTextField(pTyp
, true, rData
.m_sPar1
, rData
.m_sPar2
, false, rData
.m_nTypeId
));
1056 case SwFieldTypesEnum::HiddenParagraph
:
1058 SwHiddenParaFieldType
* pTyp
=
1059 static_cast<SwHiddenParaFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::HiddenPara
) );
1060 pField
.reset(new SwHiddenParaField(pTyp
, rData
.m_sPar1
));
1065 case SwFieldTypesEnum::SetRef
:
1067 if( !rData
.m_sPar1
.isEmpty() && CanInsertRefMark( rData
.m_sPar1
) )
1069 pCurShell
->SetAttrItem( SwFormatRefMark( rData
.m_sPar1
) );
1075 case SwFieldTypesEnum::GetRef
:
1077 SwGetRefFieldType
* pTyp
=
1078 static_cast<SwGetRefFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::GetRef
) );
1079 sal_uInt16 nSeqNo
= static_cast<sal_uInt16
>(rData
.m_sPar2
.toInt32());
1080 OUString sReferenceLanguage
;
1081 // handle language-variant formats
1082 if (nFormatId
>= SAL_N_ELEMENTS(FMT_REF_ARY
))
1084 LanguageType nLang
= GetCurrLanguage();
1085 if (nLang
== LANGUAGE_HUNGARIAN
)
1087 if (nFormatId
>= SAL_N_ELEMENTS(FMT_REF_ARY
) * 2)
1088 sReferenceLanguage
= "Hu";
1090 sReferenceLanguage
= "hu";
1092 nFormatId
%= SAL_N_ELEMENTS(FMT_REF_ARY
);
1094 pField
.reset(new SwGetRefField(pTyp
, rData
.m_sPar1
, sReferenceLanguage
, nSubType
, nSeqNo
, nFormatId
));
1099 case SwFieldTypesEnum::DDE
:
1101 //JP 28.08.95: DDE-Topics/-Items can have blanks in their names!
1102 // That's not yet considered here.
1103 sal_Int32 nIndex
= 0;
1104 OUString sCmd
= rData
.m_sPar2
.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator
), &nIndex
);
1105 if (nIndex
>=0 && ++nIndex
<sCmd
.getLength())
1107 sCmd
= sCmd
.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator
), &nIndex
);
1110 SwDDEFieldType
aType( rData
.m_sPar1
, sCmd
, static_cast<SfxLinkUpdateMode
>(nFormatId
) );
1111 SwDDEFieldType
* pTyp
= static_cast<SwDDEFieldType
*>( pCurShell
->InsertFieldType( aType
) );
1112 pField
.reset(new SwDDEField( pTyp
));
1116 case SwFieldTypesEnum::Macro
:
1118 SwMacroFieldType
* pTyp
=
1119 static_cast<SwMacroFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::Macro
));
1121 pField
.reset(new SwMacroField(pTyp
, rData
.m_sPar1
, rData
.m_sPar2
));
1126 case SwFieldTypesEnum::Internet
:
1128 SwFormatINetFormat
aFormat( rData
.m_sPar1
, m_sCurFrame
);
1129 return pCurShell
->InsertURL( aFormat
, rData
.m_sPar2
);
1132 case SwFieldTypesEnum::JumpEdit
:
1134 SwJumpEditFieldType
* pTyp
=
1135 static_cast<SwJumpEditFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::JumpEdit
));
1137 pField
.reset(new SwJumpEditField(pTyp
, nFormatId
, rData
.m_sPar1
, rData
.m_sPar2
));
1141 case SwFieldTypesEnum::DocumentInfo
:
1143 SwDocInfoFieldType
* pTyp
= static_cast<SwDocInfoFieldType
*>( pCurShell
->GetFieldType(
1144 0, SwFieldIds::DocInfo
) );
1145 pField
.reset(new SwDocInfoField(pTyp
, nSubType
, rData
.m_sPar1
, nFormatId
));
1149 case SwFieldTypesEnum::ExtendedUser
:
1151 SwExtUserFieldType
* pTyp
= static_cast<SwExtUserFieldType
*>( pCurShell
->GetFieldType(
1152 0, SwFieldIds::ExtUser
) );
1153 pField
.reset(new SwExtUserField(pTyp
, nSubType
, nFormatId
));
1157 case SwFieldTypesEnum::Database
:
1159 #if HAVE_FEATURE_DBCONNECTIVITY
1163 if (rData
.m_sPar1
.indexOf(DB_DELIM
)<0)
1165 aDBData
= pCurShell
->GetDBData();
1166 sPar1
= rData
.m_sPar1
;
1170 sal_Int32 nIdx
{ 0 };
1171 aDBData
.sDataSource
= rData
.m_sPar1
.getToken(0, DB_DELIM
, nIdx
);
1172 aDBData
.sCommand
= rData
.m_sPar1
.getToken(0, DB_DELIM
, nIdx
);
1173 aDBData
.nCommandType
= rData
.m_sPar1
.getToken(0, DB_DELIM
, nIdx
).toInt32();
1174 sPar1
= rData
.m_sPar1
.getToken(0, DB_DELIM
, nIdx
);
1177 if(!aDBData
.sDataSource
.isEmpty() && pCurShell
->GetDBData() != aDBData
)
1178 pCurShell
->ChgDBData(aDBData
);
1180 SwDBFieldType
* pTyp
= static_cast<SwDBFieldType
*>(pCurShell
->InsertFieldType(
1181 SwDBFieldType(pCurShell
->GetDoc(), sPar1
, aDBData
) ) );
1182 pField
.reset(new SwDBField(pTyp
));
1183 pField
->SetSubType(nSubType
);
1185 if( !(nSubType
& nsSwExtendedSubType::SUB_OWN_FMT
) ) // determine database format
1187 Reference
< XDataSource
> xSource
;
1188 rData
.m_aDBDataSource
>>= xSource
;
1189 Reference
<XConnection
> xConnection
;
1190 rData
.m_aDBConnection
>>= xConnection
;
1191 Reference
<XPropertySet
> xColumn
;
1192 rData
.m_aDBColumn
>>= xColumn
;
1195 nFormatId
= SwDBManager::GetColumnFormat(xSource
, xConnection
, xColumn
,
1196 pCurShell
->GetNumberFormatter(), GetCurrLanguage() );
1199 nFormatId
= pCurShell
->GetDBManager()->GetColumnFormat(
1200 aDBData
.sDataSource
, aDBData
.sCommand
, sPar1
,
1201 pCurShell
->GetNumberFormatter(), GetCurrLanguage() );
1203 pField
->ChangeFormat( nFormatId
);
1210 case SwFieldTypesEnum::DatabaseSetNumber
:
1211 case SwFieldTypesEnum::DatabaseNumberSet
:
1212 case SwFieldTypesEnum::DatabaseNextSet
:
1213 case SwFieldTypesEnum::DatabaseName
:
1215 #if HAVE_FEATURE_DBCONNECTIVITY
1218 // extract DBName from rData.m_sPar1. Format: DBName.TableName.CommandType.ExpStrg
1219 sal_Int32 nTablePos
= rData
.m_sPar1
.indexOf(DB_DELIM
);
1220 sal_Int32 nExpPos
= -1;
1224 aDBData
.sDataSource
= rData
.m_sPar1
.copy(0, nTablePos
++);
1225 sal_Int32 nCmdTypePos
= rData
.m_sPar1
.indexOf(DB_DELIM
, nTablePos
);
1228 aDBData
.sCommand
= rData
.m_sPar1
.copy(nTablePos
, nCmdTypePos
++ - nTablePos
);
1229 nExpPos
= rData
.m_sPar1
.indexOf(DB_DELIM
, nCmdTypePos
);
1232 aDBData
.nCommandType
= rData
.m_sPar1
.copy(nCmdTypePos
, nExpPos
++ - nCmdTypePos
).toInt32();
1240 else if (nTablePos
>=0)
1243 OUString sPar1
= rData
.m_sPar1
.copy(nPos
);
1245 if (!aDBData
.sDataSource
.isEmpty() && pCurShell
->GetDBData() != aDBData
)
1246 pCurShell
->ChgDBData(aDBData
);
1248 switch(rData
.m_nTypeId
)
1250 case SwFieldTypesEnum::DatabaseName
:
1252 SwDBNameFieldType
* pTyp
=
1253 static_cast<SwDBNameFieldType
*>(pCurShell
->GetFieldType(0, SwFieldIds::DatabaseName
));
1254 pField
.reset(new SwDBNameField(pTyp
, aDBData
));
1258 case SwFieldTypesEnum::DatabaseNextSet
:
1260 SwDBNextSetFieldType
* pTyp
= static_cast<SwDBNextSetFieldType
*>(pCurShell
->GetFieldType(
1261 0, SwFieldIds::DbNextSet
) );
1262 pField
.reset(new SwDBNextSetField(pTyp
, sPar1
, aDBData
));
1266 case SwFieldTypesEnum::DatabaseNumberSet
:
1268 SwDBNumSetFieldType
* pTyp
= static_cast<SwDBNumSetFieldType
*>( pCurShell
->GetFieldType(
1269 0, SwFieldIds::DbNumSet
) );
1270 pField
.reset(new SwDBNumSetField( pTyp
, sPar1
, rData
.m_sPar2
, aDBData
));
1274 case SwFieldTypesEnum::DatabaseSetNumber
:
1276 SwDBSetNumberFieldType
* pTyp
= static_cast<SwDBSetNumberFieldType
*>(
1277 pCurShell
->GetFieldType(0, SwFieldIds::DbSetNumber
) );
1278 pField
.reset(new SwDBSetNumberField( pTyp
, aDBData
, nFormatId
));
1288 case SwFieldTypesEnum::User
:
1290 SwUserFieldType
* pTyp
=
1291 static_cast<SwUserFieldType
*>( pCurShell
->GetFieldType(SwFieldIds::User
, rData
.m_sPar1
) );
1296 pTyp
= static_cast<SwUserFieldType
*>( pCurShell
->InsertFieldType(
1297 SwUserFieldType(pCurShell
->GetDoc(), rData
.m_sPar1
)) );
1299 if (pTyp
->GetContent(nFormatId
) != rData
.m_sPar2
)
1300 pTyp
->SetContent(rData
.m_sPar2
, nFormatId
);
1301 pField
.reset(new SwUserField(pTyp
, 0, nFormatId
));
1302 if (pField
->GetSubType() != nSubType
)
1303 pField
->SetSubType(nSubType
);
1308 case SwFieldTypesEnum::Input
:
1310 if ((nSubType
& 0x00ff) == INP_VAR
)
1312 SwSetExpFieldType
* pTyp
= static_cast<SwSetExpFieldType
*>(
1313 pCurShell
->GetFieldType(SwFieldIds::SetExp
, rData
.m_sPar1
) );
1315 // no Expression Type with this name existing -> create
1318 std::unique_ptr
<SwSetExpField
> pExpField(
1319 new SwSetExpField(pTyp
, OUString(), nFormatId
));
1321 // Don't change type of SwSetExpFieldType:
1322 sal_uInt16 nOldSubType
= pExpField
->GetSubType();
1323 pExpField
->SetSubType(nOldSubType
| (nSubType
& 0xff00));
1325 pExpField
->SetPromptText(rData
.m_sPar2
);
1326 pExpField
->SetInputFlag(true) ;
1328 pField
= std::move(pExpField
);
1335 SwInputFieldType
* pTyp
=
1336 static_cast<SwInputFieldType
*>( pCurShell
->GetFieldType(0, SwFieldIds::Input
) );
1339 new SwInputField( pTyp
, rData
.m_sPar1
, rData
.m_sPar2
, nSubType
|nsSwExtendedSubType::SUB_INVISIBLE
, nFormatId
));
1344 case SwFieldTypesEnum::Set
:
1346 if (rData
.m_sPar2
.isEmpty()) // empty variables are not allowed
1349 SwSetExpFieldType
* pTyp
= static_cast<SwSetExpFieldType
*>( pCurShell
->InsertFieldType(
1350 SwSetExpFieldType(pCurShell
->GetDoc(), rData
.m_sPar1
) ) );
1352 std::unique_ptr
<SwSetExpField
> pExpField(new SwSetExpField( pTyp
, rData
.m_sPar2
, nFormatId
));
1353 pExpField
->SetSubType(nSubType
);
1354 pExpField
->SetPar2(rData
.m_sPar2
);
1356 pField
= std::move(pExpField
);
1360 case SwFieldTypesEnum::Sequence
:
1362 SwSetExpFieldType
* pTyp
= static_cast<SwSetExpFieldType
*>( pCurShell
->InsertFieldType(
1363 SwSetExpFieldType(pCurShell
->GetDoc(), rData
.m_sPar1
, nsSwGetSetExpType::GSE_SEQ
)));
1365 sal_uInt8 nLevel
= static_cast< sal_uInt8
>(nSubType
& 0xff);
1367 pTyp
->SetOutlineLvl(nLevel
);
1368 if (nLevel
!= 0x7f && cSeparator
== 0)
1371 pTyp
->SetDelimiter(OUString(cSeparator
));
1372 pField
.reset(new SwSetExpField(pTyp
, rData
.m_sPar2
, nFormatId
));
1377 case SwFieldTypesEnum::Get
:
1379 // is there a corresponding SetField
1380 SwSetExpFieldType
* pSetTyp
= static_cast<SwSetExpFieldType
*>(
1381 pCurShell
->GetFieldType(SwFieldIds::SetExp
, rData
.m_sPar1
));
1385 SwGetExpFieldType
* pTyp
= static_cast<SwGetExpFieldType
*>( pCurShell
->GetFieldType(
1386 0, SwFieldIds::GetExp
) );
1387 pField
.reset( new SwGetExpField(pTyp
, rData
.m_sPar1
, pSetTyp
->GetType(), nFormatId
) );
1388 pField
->SetSubType(nSubType
| pSetTyp
->GetType());
1396 case SwFieldTypesEnum::Formel
:
1398 if(pCurShell
->GetFrameType(nullptr,false) & FrameTypeFlags::TABLE
)
1400 pCurShell
->StartAllAction();
1402 SvNumberFormatter
* pFormatter
= pCurShell
->GetDoc()->GetNumberFormatter();
1403 const SvNumberformat
* pEntry
= pFormatter
->GetEntry(nFormatId
);
1407 SfxStringItem
aFormat(FN_NUMBER_FORMAT
, pEntry
->GetFormatstring());
1408 pCurShell
->GetView().GetViewFrame()->GetDispatcher()->
1409 ExecuteList(FN_NUMBER_FORMAT
, SfxCallMode::SYNCHRON
,
1413 SfxItemSet
aBoxSet( pCurShell
->GetAttrPool(),
1414 svl::Items
<RES_BOXATR_FORMULA
, RES_BOXATR_FORMULA
>{} );
1416 OUString
sFormula(comphelper::string::stripStart(rData
.m_sPar2
, ' '));
1417 if ( sFormula
.startsWith("=") )
1419 sFormula
= sFormula
.copy(1);
1422 aBoxSet
.Put( SwTableBoxFormula( sFormula
));
1423 pCurShell
->SetTableBoxFormulaAttrs( aBoxSet
);
1424 pCurShell
->UpdateTable();
1426 pCurShell
->EndAllAction();
1432 SwGetExpFieldType
* pTyp
= static_cast<SwGetExpFieldType
*>(
1433 pCurShell
->GetFieldType(0, SwFieldIds::GetExp
) );
1434 pField
.reset( new SwGetExpField(pTyp
, rData
.m_sPar2
, nsSwGetSetExpType::GSE_FORMULA
, nFormatId
) );
1435 pField
->SetSubType(nSubType
);
1440 case SwFieldTypesEnum::SetRefPage
:
1441 pField
.reset( new SwRefPageSetField( static_cast<SwRefPageSetFieldType
*>(
1442 pCurShell
->GetFieldType( 0, SwFieldIds::RefPageSet
) ),
1443 static_cast<short>(rData
.m_sPar2
.toInt32()), 0 != nSubType
) );
1447 case SwFieldTypesEnum::GetRefPage
:
1448 pField
.reset( new SwRefPageGetField( static_cast<SwRefPageGetFieldType
*>(
1449 pCurShell
->GetFieldType( 0, SwFieldIds::RefPageGet
) ), nFormatId
) );
1452 case SwFieldTypesEnum::Dropdown
:
1454 pField
.reset( new SwDropDownField(pCurShell
->GetFieldType( 0, SwFieldIds::Dropdown
)) );
1455 const sal_Int32 nTokenCount
= comphelper::string::getTokenCount(rData
.m_sPar2
, DB_DELIM
);
1456 Sequence
<OUString
> aEntries(nTokenCount
);
1457 OUString
* pArray
= aEntries
.getArray();
1458 for(sal_Int32 nToken
= 0, nIdx
= 0; nToken
< nTokenCount
; nToken
++)
1459 pArray
[nToken
] = rData
.m_sPar2
.getToken(0, DB_DELIM
, nIdx
);
1460 static_cast<SwDropDownField
*>(pField
.get())->SetItems(aEntries
);
1461 static_cast<SwDropDownField
*>(pField
.get())->SetName(rData
.m_sPar1
);
1465 // Insert Paragraph Signature field by signing the paragraph.
1466 // The resulting field is really a metadata field, created and added via signing.
1467 case SwFieldTypesEnum::ParagraphSignature
:
1468 pCurShell
->SignParagraph();
1473 { OSL_ENSURE(false, "wrong field type");
1477 OSL_ENSURE(pField
, "field not available");
1479 //the auto language flag has to be set prior to the language!
1480 pField
->SetAutomaticLanguage(rData
.m_bIsAutomaticLanguage
);
1481 LanguageType nLang
= GetCurrLanguage();
1482 pField
->SetLanguage(nLang
);
1485 pCurShell
->StartAllAction();
1487 pCurShell
->Insert(*pField
, rData
.m_pAnnotationRange
.get());
1489 if (SwFieldTypesEnum::Input
== rData
.m_nTypeId
)
1493 // start dialog, not before the field is inserted tdf#99529
1494 pCurShell
->Left(CRSR_SKIP_CHARS
, false,
1495 (INP_VAR
== (nSubType
& 0xff) || pCurShell
->GetViewOptions()->IsFieldName()) ? 1 : 2,
1497 pCurShell
->StartInputFieldDlg(pField
.get(), false, true, rData
.m_pParent
);
1499 pCurShell
->Pop(SwCursorShell::PopMode::DeleteCurrent
);
1502 if(bExp
&& m_bEvalExp
)
1503 pCurShell
->UpdateExpFields(true);
1507 pCurShell
->Left(CRSR_SKIP_CHARS
, false, 1, false );
1508 pCurShell
->UpdateOneField(*pField
);
1509 pCurShell
->Right(CRSR_SKIP_CHARS
, false, 1, false );
1512 static_cast<SwRefPageGetFieldType
*>(pCurShell
->GetFieldType( 0, SwFieldIds::RefPageGet
))->UpdateFields();
1513 else if( SwFieldTypesEnum::GetRef
== rData
.m_nTypeId
)
1514 pField
->GetTyp()->UpdateFields();
1516 // delete temporary field
1519 pCurShell
->EndAllAction();
1524 void SwFieldMgr::UpdateCurField(sal_uInt32 nFormat
,
1525 const OUString
& rPar1
,
1526 const OUString
& rPar2
,
1527 std::unique_ptr
<SwField
> pTmpField
)
1530 OSL_ENSURE(m_pCurField
, "no field at CursorPos");
1533 pTmpField
= m_pCurField
->CopyField();
1535 SwFieldType
* pType
= pTmpField
->GetTyp();
1536 const SwFieldTypesEnum nTypeId
= pTmpField
->GetTypeId();
1538 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
1539 OSL_ENSURE(pSh
, "no SwWrtShell found");
1542 pSh
->StartAllAction();
1544 bool bSetPar2
= true;
1545 bool bSetPar1
= true;
1546 OUString
sPar2( rPar2
);
1551 case SwFieldTypesEnum::DDE
:
1553 // DDE-Topics/-Items can have blanks in their names!
1554 // That's not yet considered here!
1555 sal_Int32 nIndex
= 0;
1556 sPar2
= sPar2
.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator
), &nIndex
);
1557 if (nIndex
>=0 && ++nIndex
<sPar2
.getLength())
1559 sPar2
= sPar2
.replaceFirst(" ", OUStringChar(sfx2::cTokenSeparator
), &nIndex
);
1564 case SwFieldTypesEnum::Chapter
:
1566 sal_uInt16 nByte
= static_cast<sal_uInt16
>(rPar2
.toInt32());
1567 nByte
= std::max(sal_uInt16(1), nByte
);
1568 nByte
= std::min(nByte
, sal_uInt16(MAXLEVEL
));
1570 static_cast<SwChapterField
*>(pTmpField
.get())->SetLevel(static_cast<sal_uInt8
>(nByte
));
1575 case SwFieldTypesEnum::Script
:
1576 static_cast<SwScriptField
*>(pTmpField
.get())->SetCodeURL(static_cast<bool>(nFormat
));
1579 case SwFieldTypesEnum::NextPage
:
1580 if( SVX_NUM_CHAR_SPECIAL
== nFormat
)
1582 static_cast<SwPageNumberField
*>(m_pCurField
)->SetUserString( sPar2
);
1587 if( nFormat
+ 2 == SVX_NUM_PAGEDESC
)
1588 nFormat
= SVX_NUM_PAGEDESC
;
1589 short nOff
= static_cast<short>(sPar2
.toInt32());
1591 sPar2
= OUString::number(nOff
);
1595 case SwFieldTypesEnum::PreviousPage
:
1596 if( SVX_NUM_CHAR_SPECIAL
== nFormat
)
1598 static_cast<SwPageNumberField
*>(m_pCurField
)->SetUserString( sPar2
);
1603 if( nFormat
+ 2 == SVX_NUM_PAGEDESC
)
1604 nFormat
= SVX_NUM_PAGEDESC
;
1605 short nOff
= static_cast<short>(sPar2
.toInt32());
1607 sPar2
= OUString::number(nOff
);
1611 case SwFieldTypesEnum::PageNumber
:
1612 case SwFieldTypesEnum::GetRefPage
:
1613 if( nFormat
+ 2 == SVX_NUM_PAGEDESC
)
1614 nFormat
= SVX_NUM_PAGEDESC
;
1617 case SwFieldTypesEnum::GetRef
:
1620 static_cast<SwGetRefField
*>(pTmpField
.get())->SetSubType( static_cast<sal_uInt16
>(rPar2
.toInt32()) );
1621 const sal_Int32 nPos
= rPar2
.indexOf( '|' );
1623 static_cast<SwGetRefField
*>(pTmpField
.get())->SetSeqNo( static_cast<sal_uInt16
>(rPar2
.copy( nPos
+ 1 ).toInt32()));
1626 case SwFieldTypesEnum::Dropdown
:
1628 sal_Int32 nTokenCount
= comphelper::string::getTokenCount(sPar2
, DB_DELIM
);
1629 Sequence
<OUString
> aEntries(nTokenCount
);
1630 OUString
* pArray
= aEntries
.getArray();
1631 for(sal_Int32 nToken
= 0, nIdx
= 0; nToken
< nTokenCount
; nToken
++)
1632 pArray
[nToken
] = sPar2
.getToken(0, DB_DELIM
, nIdx
);
1633 static_cast<SwDropDownField
*>(pTmpField
.get())->SetItems(aEntries
);
1634 static_cast<SwDropDownField
*>(pTmpField
.get())->SetName(rPar1
);
1635 bSetPar1
= bSetPar2
= false;
1638 case SwFieldTypesEnum::Authority
:
1640 //#i99069# changes to a bibliography field should change the field type
1641 SwAuthorityField
* pAuthorityField
= static_cast<SwAuthorityField
*>(pTmpField
.get());
1642 SwAuthorityFieldType
* pAuthorityType
= static_cast<SwAuthorityFieldType
*>(pType
);
1643 rtl::Reference
<SwAuthEntry
> xTempEntry(new SwAuthEntry
);
1644 for( sal_Int32 i
= 0, nIdx
= 0; i
< AUTH_FIELD_END
; ++i
)
1645 xTempEntry
->SetAuthorField( static_cast<ToxAuthorityField
>(i
),
1646 rPar1
.getToken( 0, TOX_STYLE_DELIMITER
, nIdx
));
1647 if( pAuthorityType
->ChangeEntryContent( xTempEntry
.get() ) )
1649 pType
->UpdateFields();
1653 if( xTempEntry
->GetAuthorField( AUTH_FIELD_IDENTIFIER
) ==
1654 pAuthorityField
->GetFieldText( AUTH_FIELD_IDENTIFIER
) )
1655 bSetPar1
= false; //otherwise it's a new or changed entry, the field needs to be updated
1663 // setup format before SetPar2 because of NumberFormatter!
1664 pTmpField
->ChangeFormat(nFormat
);
1667 pTmpField
->SetPar1( rPar1
);
1669 pTmpField
->SetPar2( sPar2
);
1672 if(nTypeId
== SwFieldTypesEnum::DDE
||
1673 nTypeId
== SwFieldTypesEnum::User
||
1674 nTypeId
== SwFieldTypesEnum::UserInput
)
1676 pType
->UpdateFields();
1681 pSh
->SwEditShell::UpdateOneField(*pTmpField
);
1687 pSh
->EndAllAction();
1690 // explicitly evaluate ExpressionFields
1691 void SwFieldMgr::EvalExpFields(SwWrtShell
* pSh
)
1694 pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
1698 pSh
->StartAllAction();
1699 pSh
->UpdateExpFields(true);
1700 pSh
->EndAllAction();
1703 LanguageType
SwFieldMgr::GetCurrLanguage() const
1705 SwWrtShell
* pSh
= m_pWrtShell
? m_pWrtShell
: ::lcl_GetShell();
1707 return pSh
->GetCurLang();
1708 return SvtSysLocale().GetLanguageTag().getLanguageType();
1711 void SwFieldType::GetFieldName_()
1713 static const char* coFieldNms
[] =
1759 STR_PARAGRAPH_SIGNATURE
1762 // insert infos for fields
1763 SwFieldType::s_pFieldNames
= new std::vector
<OUString
>;
1764 SwFieldType::s_pFieldNames
->reserve(SAL_N_ELEMENTS(coFieldNms
));
1765 for (const char* id
: coFieldNms
)
1767 const OUString
aTmp(SwResId(id
));
1768 SwFieldType::s_pFieldNames
->push_back(MnemonicGenerator::EraseAllMnemonicChars( aTmp
));
1772 bool SwFieldMgr::ChooseMacro(weld::Window
* pDialogParent
)
1776 // choose script dialog
1777 OUString aScriptURL
= SfxApplication::ChooseScript(pDialogParent
);
1779 // the script selector dialog returns a valid script URL
1780 if ( !aScriptURL
.isEmpty() )
1782 SetMacroPath( aScriptURL
);
1789 void SwFieldMgr::SetMacroPath(const OUString
& rPath
)
1791 m_sMacroPath
= rPath
;
1792 m_sMacroName
= rPath
;
1794 // try to set sMacroName member variable by parsing the macro path
1795 // using the new URI parsing services
1797 Reference
< XComponentContext
> xContext
=
1798 ::comphelper::getProcessComponentContext();
1800 Reference
< uri::XUriReferenceFactory
>
1801 xFactory
= uri::UriReferenceFactory::create( xContext
);
1803 Reference
< uri::XVndSunStarScriptUrl
>
1804 xUrl( xFactory
->parse( m_sMacroPath
), UNO_QUERY
);
1808 m_sMacroName
= xUrl
->getName();
1812 sal_uInt32
SwFieldMgr::GetDefaultFormat(SwFieldTypesEnum nTypeId
, bool bIsText
, SvNumberFormatter
* pFormatter
)
1814 SvNumFormatType nDefFormat
;
1818 case SwFieldTypesEnum::Time
:
1819 case SwFieldTypesEnum::Date
:
1821 nDefFormat
= (nTypeId
== SwFieldTypesEnum::Date
) ? SvNumFormatType::DATE
: SvNumFormatType::TIME
;
1828 nDefFormat
= SvNumFormatType::TEXT
;
1832 nDefFormat
= SvNumFormatType::ALL
;
1837 return pFormatter
->GetStandardFormat(nDefFormat
, GetCurrLanguage());
1840 Reference
<XNumberingTypeInfo
> const & SwFieldMgr::GetNumberingInfo() const
1842 if(!m_xNumberingInfo
.is())
1844 Reference
<XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
1845 Reference
<XDefaultNumberingProvider
> xDefNum
= text::DefaultNumberingProvider::create(xContext
);
1846 const_cast<SwFieldMgr
*>(this)->m_xNumberingInfo
.set(xDefNum
, UNO_QUERY
);
1848 return m_xNumberingInfo
;
1851 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */