Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / uibase / fldui / fldmgr.cxx
blob636e2b99058a03d818c1f3f11501425f3e67ae83
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
23 #include <cmdid.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>
50 #include <view.hxx>
51 #include <wrtsh.hxx>
52 #include <doc.hxx>
53 #include <swmodule.hxx>
54 #include <fmtinfmt.hxx>
55 #include <cellatr.hxx>
56 #include <dbmgr.hxx>
57 #include <shellres.hxx>
58 #include <fldbas.hxx>
59 #include <docufld.hxx>
60 #include <chpfld.hxx>
61 #include <ddefld.hxx>
62 #include <expfld.hxx>
63 #include <reffld.hxx>
64 #include <usrfld.hxx>
65 #include <dbfld.hxx>
66 #include <authfld.hxx>
67 #include <flddat.hxx>
68 #include <fldmgr.hxx>
69 #include <flddropdown.hxx>
70 #include <strings.hrc>
71 #include <tox.hxx>
72 #include <viewopt.hxx>
73 #include <txmsrt.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;
88 // groups of fields
89 enum
91 GRP_DOC_BEGIN = 0,
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
110 enum
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[] =
137 FLD_EU_COMPANY,
138 FLD_EU_GIVENNAME,
139 FLD_EU_SURNAME,
140 FLD_EU_INITIALS,
141 FLD_EU_STREET,
142 FLD_EU_COUNTRY,
143 FLD_EU_POSTCODE,
144 FLD_EU_TOWN,
145 FLD_EU_TITLE,
146 FLD_EU_POS,
147 FLD_EU_TELPERSONAL,
148 FLD_EU_TELWORK,
149 FLD_EU_FAX,
150 FLD_EU_EMAIL,
151 FLD_EU_REGION
154 const TranslateId FMT_AUTHOR_ARY[] =
156 FMT_AUTHOR_NAME,
157 FMT_AUTHOR_SCUT
160 const TranslateId FLD_DATE_ARY[] =
162 FLD_DATE_FIX,
163 FLD_DATE_STD,
166 const TranslateId FLD_TIME_ARY[] =
168 FLD_TIME_FIX,
169 FLD_TIME_STD
172 const TranslateId FMT_NUM_ARY[] =
174 FMT_NUM_ABC,
175 FMT_NUM_SABC,
176 FMT_NUM_ABC_N,
177 FMT_NUM_SABC_N,
178 FMT_NUM_ROMAN,
179 FMT_NUM_SROMAN,
180 FMT_NUM_ARABIC,
181 FMT_NUM_PAGEDESC,
182 FMT_NUM_PAGESPECIAL
185 const TranslateId FMT_FF_ARY[] =
187 FMT_FF_NAME,
188 FMT_FF_PATHNAME,
189 FMT_FF_PATH,
190 FMT_FF_NAME_NOEXT,
191 FMT_FF_UI_NAME,
192 FMT_FF_UI_RANGE
195 const TranslateId FLD_STAT_ARY[] =
197 FLD_STAT_PAGE,
198 FLD_STAT_PARA,
199 FLD_STAT_WORD,
200 FLD_STAT_CHAR,
201 FLD_STAT_TABLE,
202 FLD_STAT_GRF,
203 FLD_STAT_OBJ
206 const TranslateId FMT_CHAPTER_ARY[] =
208 FMT_CHAPTER_NO,
209 FMT_CHAPTER_NAME,
210 FMT_CHAPTER_NAMENO,
211 FMT_CHAPTER_NO_NOSEPARATOR
214 const TranslateId FLD_INPUT_ARY[] =
216 FLD_INPUT_TEXT
219 const TranslateId FMT_MARK_ARY[] =
221 FMT_MARK_TEXT,
222 FMT_MARK_TABLE,
223 FMT_MARK_FRAME,
224 FMT_MARK_GRAFIC,
225 FMT_MARK_OLE
228 const TranslateId FMT_REF_ARY[] =
230 FMT_REF_PAGE,
231 FMT_REF_CHAPTER,
232 FMT_REF_TEXT,
233 FMT_REF_UPDOWN,
234 FMT_REF_PAGE_PGDSC,
235 FMT_REF_ONLYNUMBER,
236 FMT_REF_ONLYCAPTION,
237 FMT_REF_ONLYSEQNO,
238 FMT_REF_NUMBER,
239 FMT_REF_NUMBER_NO_CONTEXT,
240 FMT_REF_NUMBER_FULL_CONTEXT
243 const TranslateId FMT_REG_ARY[] =
245 FMT_REG_AUTHOR,
246 FMT_REG_TIME,
247 FMT_REG_DATE
250 const TranslateId FMT_DBFLD_ARY[] =
252 FMT_DBFLD_DB,
253 FMT_DBFLD_SYS
256 const TranslateId FMT_SETVAR_ARY[] =
258 FMT_SETVAR_SYS,
259 FMT_SETVAR_TEXT
262 const TranslateId FMT_GETVAR_ARY[] =
264 FMT_GETVAR_TEXT,
265 FMT_GETVAR_NAME
268 const TranslateId FMT_DDE_ARY[] =
270 FMT_DDE_NORMAL,
271 FMT_DDE_HOT
274 const TranslateId FLD_PAGEREF_ARY[] =
276 FLD_PAGEREF_OFF,
277 FLD_PAGEREF_ON
280 const TranslateId FMT_USERVAR_ARY[] =
282 FMT_USERVAR_TEXT,
283 FMT_USERVAR_CMD
286 namespace {
288 // field types and subtypes
289 struct SwFieldPack
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[] =
305 // Document
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 },
320 // Functions
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 },
330 // Cross-References
331 { SwFieldTypesEnum::SetRef, nullptr, 0, nullptr, 0 },
332 { SwFieldTypesEnum::GetRef, nullptr, 0, FMT_REF_ARY, SAL_N_ELEMENTS(FMT_REF_ARY) },
334 // DocInformation
335 { SwFieldTypesEnum::DocumentInfo, nullptr, 0, FMT_REG_ARY, SAL_N_ELEMENTS(FMT_REG_ARY) },
337 // Database
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 },
344 // Variables
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();
362 return nullptr;
365 static sal_uInt16 GetPackCount() { return SAL_N_ELEMENTS(aSwFields); }
367 // FieldManager controls inserting and updating of fields
368 SwFieldMgr::SwFieldMgr(SwWrtShell* pSh ) :
369 m_pWrtShell(pSh),
370 m_bEvalExp(true)
372 // determine current field if existing
373 GetCurField();
376 SwFieldMgr::~SwFieldMgr()
380 // organise RefMark by names
381 bool SwFieldMgr::CanInsertRefMark( std::u16string_view rStr )
383 bool bRet = false;
384 SwWrtShell *pSh = m_pWrtShell ? m_pWrtShell : lcl_GetShell();
385 OSL_ENSURE(pSh, "no SwWrtShell found");
386 if(pSh)
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() )
392 --nCnt;
394 bRet = 2 > nCnt && nullptr == pSh->GetRefMark( rStr );
396 return bRet;
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");
404 if( pSh )
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();
433 if ( pSh )
434 m_pCurField = pSh->GetCurField( true );
435 else
436 m_pCurField = nullptr;
438 // initialise strings and format
439 m_aCurPar1.clear();
440 m_aCurPar2.clear();
441 m_sCurFrame.clear();
442 m_nCurFormat = 0;
444 if(!m_pCurField)
445 return nullptr;
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();
455 switch( nTypeId )
457 case SwFieldTypesEnum::PageNumber:
458 case SwFieldTypesEnum::NextPage:
459 case SwFieldTypesEnum::PreviousPage:
460 case SwFieldTypesEnum::GetRefPage:
461 if( m_nCurFormat == SVX_NUM_PAGEDESC )
462 m_nCurFormat -= 2;
463 break;
464 default: break;
466 return m_pCurField;
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 }
491 if (bHtmlMode)
492 return aWebRanges[nGrpId];
493 else
494 return aRanges[nGrpId];
497 // determine GroupId
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)
518 return i;
521 return USHRT_MAX;
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 ) );
542 return g_aDate;
544 if( SwFieldTypesEnum::Time == nFieldWh )
546 static OUString g_aTime( SwResId( STR_TIMEFLD ) );
547 return g_aTime;
550 return SwFieldType::GetTypeStr( nFieldWh );
553 // determine Pos in the list
554 sal_uInt16 SwFieldMgr::GetPos(SwFieldTypesEnum nTypeId)
556 switch( 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;
562 default: break;
565 for(sal_uInt16 i = 0; i < GetPackCount(); i++)
566 if(aSwFields[i].nTypeId == nTypeId)
567 return i;
569 return USHRT_MAX;
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");
577 if(!pSh)
578 return;
580 const sal_uInt16 nPos = GetPos(nTypeId);
582 switch(nTypeId)
584 case SwFieldTypesEnum::SetRef:
585 case SwFieldTypesEnum::GetRef:
587 // references are no fields
588 pSh->GetRefMarks( &rToFill );
589 break;
591 case SwFieldTypesEnum::Macro:
593 break;
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());
635 break;
637 case SwFieldTypesEnum::DatabaseNextSet:
638 case SwFieldTypesEnum::DatabaseNumberSet:
639 case SwFieldTypesEnum::DatabaseName:
640 case SwFieldTypesEnum::DatabaseSetNumber:
641 break;
643 default:
645 // static SubTypes
646 if(nPos != USHRT_MAX)
648 sal_uInt16 nCount;
649 if (nTypeId == SwFieldTypesEnum::DocumentInfo)
650 nCount = DI_SUBTYPE_END - DI_SUBTYPE_BEGIN;
651 else
652 nCount = aSwFields[nPos].nSubTypeLength;
654 for(sal_uInt16 i = 0; i < nCount; ++i)
656 OUString sNew;
657 if (nTypeId == SwFieldTypesEnum::DocumentInfo)
659 if ( i == DI_CUSTOM )
660 sNew = SwResId(STR_CUSTOM_FIELD);
661 else
662 sNew = SwViewShell::GetShellRes()->aDocInfoLst[i];
664 else
665 sNew = SwResId(aSwFields[nPos].pSubTypeResIds[i]);
667 rToFill.push_back(sNew);
674 // determine format
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))
683 return 0;
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;
691 if (!pStart)
692 return nCount;
694 if (*pStart == FMT_GETVAR_ARY[0] || *pStart == FMT_SETVAR_ARY[0])
695 return VF_COUNT;
696 else if (*pStart == FMT_USERVAR_ARY[0])
697 return VF_USR_COUNT;
698 else if (*pStart == FMT_DBFLD_ARY[0])
699 return VF_DB_COUNT;
700 else if (*pStart == FMT_NUM_ARY[0])
702 GetNumberingInfo();
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; });
711 return nCount;
714 return nCount;
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)
725 return OUString();
727 const TranslateId* pStart = aSwFields[nPos].pFormatResIds;
728 if (!pStart)
729 return OUString();
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]);
737 OUString aRet;
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);
757 else
759 aRet = m_xNumberingInfo->getNumberingIdentifier( nCurrent );
761 break;
763 ++nValidEntry;
769 return aRet;
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);
776 switch( nTypeId )
778 case SwFieldTypesEnum::DocumentInfo:
780 TranslateId sId = aSwFields[GetPos(nTypeId)].pFormatResIds[nFormatId];
781 if (sId == FMT_REG_AUTHOR)
782 nId = DI_SUB_AUTHOR;
783 else if (sId == FMT_REG_TIME)
784 nId = DI_SUB_TIME;
785 else if (sId == FMT_REG_DATE)
786 nId = DI_SUB_DATE;
787 break;
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)
831 nId = nCurrent;
832 break;
834 ++nValidEntry;
838 break;
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);
847 break;
849 default: break;
851 return nId;
854 // Traveling
855 bool SwFieldMgr::GoNextPrev( bool bNext, SwFieldType* pTyp )
857 SwWrtShell* pSh = m_pWrtShell ? m_pWrtShell : ::lcl_GetShell();
858 if(!pSh)
859 return false;
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 );
866 else
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");
884 if(pSh)
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;
899 bool bExp = false;
900 bool bTable = false;
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;
906 if(!pCurShell)
907 pCurShell = m_pWrtShell ? m_pWrtShell : ::lcl_GetShell();
908 OSL_ENSURE(pCurShell, "no SwWrtShell found");
909 if(!pCurShell)
910 return false;
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));
918 pField.reset(
919 new SwPostItField(
920 pType,
921 rData.m_sPar1, // author
922 rData.m_sPar2, // content
923 aUserOpt.GetID(), // author's initials
924 OUString(), // name
925 DateTime(DateTime::SYSTEM) ));
927 break;
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)));
933 break;
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 ));
942 break;
944 case SwFieldTypesEnum::Authority:
946 SwAuthorityFieldType* pType =
947 static_cast<SwAuthorityFieldType*>(pCurShell->GetFieldType(0, SwFieldIds::TableOfAuthorities));
948 if (!pType)
950 SwAuthorityFieldType const type(pCurShell->GetDoc());
951 pType = static_cast<SwAuthorityFieldType*>(
952 pCurShell->InsertFieldType(type));
954 pField.reset(new SwAuthorityField(pType, rData.m_sPar1));
956 break;
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);
968 break;
971 case SwFieldTypesEnum::Filename:
973 SwFileNameFieldType* pTyp =
974 static_cast<SwFileNameFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::Filename) );
975 pField.reset(new SwFileNameField(pTyp, nFormatId));
976 break;
979 case SwFieldTypesEnum::TemplateName:
981 SwTemplNameFieldType* pTyp =
982 static_cast<SwTemplNameFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::TemplateName) );
983 pField.reset(new SwTemplNameField(pTyp, nFormatId));
984 break;
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));
995 nByte -= 1;
996 static_cast<SwChapterField*>(pField.get())->SetLevel(static_cast<sal_uInt8>(nByte));
997 break;
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 )
1009 nOff = 1;
1010 else
1011 nOff += 1;
1012 nSubType = PG_NEXT;
1014 else if(rData.m_nTypeId == SwFieldTypesEnum::PreviousPage)
1016 if( SVX_NUM_CHAR_SPECIAL == nFormatId )
1017 nOff = -1;
1018 else
1019 nOff -= 1;
1020 nSubType = PG_PREV;
1022 else
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 );
1032 break;
1035 case SwFieldTypesEnum::DocumentStatistics:
1037 SwDocStatFieldType* pTyp =
1038 static_cast<SwDocStatFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::DocStat) );
1039 pField.reset(new SwDocStatField(pTyp, nSubType, nFormatId));
1040 break;
1043 case SwFieldTypesEnum::Author:
1045 SwAuthorFieldType* pTyp =
1046 static_cast<SwAuthorFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::Author) );
1047 pField.reset(new SwAuthorField(pTyp, nFormatId));
1048 break;
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));
1057 bExp = true;
1058 break;
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));
1066 bExp = true;
1067 break;
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);
1085 if (bSuccess)
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(
1098 aRefmarkPam);
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();
1111 return true;
1113 return false;
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";
1130 else
1131 sReferenceLanguage = "hu";
1133 nFormatId %= SAL_N_ELEMENTS(FMT_REF_ARY);
1135 pField.reset(new SwGetRefField(pTyp, rData.m_sPar1, sReferenceLanguage, nSubType, nSeqNo, nFormatId));
1136 bExp = true;
1137 break;
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 ));
1154 break;
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));
1164 break;
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));
1179 break;
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));
1187 break;
1190 case SwFieldTypesEnum::ExtendedUser:
1192 SwExtUserFieldType* pTyp = static_cast<SwExtUserFieldType*>( pCurShell->GetFieldType(
1193 0, SwFieldIds::ExtUser) );
1194 pField.reset(new SwExtUserField(pTyp, nSubType, nFormatId));
1195 break;
1198 case SwFieldTypesEnum::Database:
1200 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1201 SwDBData aDBData;
1202 OUString sPar1;
1204 if (rData.m_sPar1.indexOf(DB_DELIM)<0)
1206 aDBData = pCurShell->GetDBData();
1207 sPar1 = rData.m_sPar1;
1209 else
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;
1234 if(xColumn.is())
1236 nFormatId = SwDBManager::GetColumnFormat(xSource, xConnection, xColumn,
1237 pCurShell->GetNumberFormatter(), GetCurrLanguage() );
1239 else
1240 nFormatId = pCurShell->GetDBManager()->GetColumnFormat(
1241 aDBData.sDataSource, aDBData.sCommand, sPar1,
1242 pCurShell->GetNumberFormatter(), GetCurrLanguage() );
1244 pField->ChangeFormat( nFormatId );
1246 bExp = true;
1247 #endif
1248 break;
1251 case SwFieldTypesEnum::DatabaseSetNumber:
1252 case SwFieldTypesEnum::DatabaseNumberSet:
1253 case SwFieldTypesEnum::DatabaseNextSet:
1254 case SwFieldTypesEnum::DatabaseName:
1256 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1257 SwDBData aDBData;
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;
1263 if (nTablePos>=0)
1265 aDBData.sDataSource = rData.m_sPar1.copy(0, nTablePos++);
1266 sal_Int32 nCmdTypePos = rData.m_sPar1.indexOf(DB_DELIM, nTablePos);
1267 if (nCmdTypePos>=0)
1269 aDBData.sCommand = rData.m_sPar1.copy(nTablePos, nCmdTypePos++ - nTablePos);
1270 nExpPos = rData.m_sPar1.indexOf(DB_DELIM, nCmdTypePos);
1271 if (nExpPos>=0)
1273 aDBData.nCommandType = o3tl::toInt32(rData.m_sPar1.subView(nCmdTypePos, nExpPos++ - nCmdTypePos));
1278 sal_Int32 nPos = 0;
1279 if (nExpPos>=0)
1280 nPos = nExpPos;
1281 else if (nTablePos>=0)
1282 nPos = nTablePos;
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));
1297 break;
1299 case SwFieldTypesEnum::DatabaseNextSet:
1301 SwDBNextSetFieldType* pTyp = static_cast<SwDBNextSetFieldType*>(pCurShell->GetFieldType(
1302 0, SwFieldIds::DbNextSet) );
1303 pField.reset(new SwDBNextSetField(pTyp, sPar1, aDBData));
1304 bExp = true;
1305 break;
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));
1312 bExp = true;
1313 break;
1315 case SwFieldTypesEnum::DatabaseSetNumber:
1317 SwDBSetNumberFieldType* pTyp = static_cast<SwDBSetNumberFieldType*>(
1318 pCurShell->GetFieldType(0, SwFieldIds::DbSetNumber) );
1319 pField.reset(new SwDBSetNumberField( pTyp, aDBData, nFormatId));
1320 bExp = true;
1321 break;
1323 default: break;
1325 #endif
1326 break;
1329 case SwFieldTypesEnum::User:
1331 SwUserFieldType* pTyp =
1332 static_cast<SwUserFieldType*>( pCurShell->GetFieldType(SwFieldIds::User, rData.m_sPar1) );
1334 // only if existing
1335 if(!pTyp)
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);
1345 bTable = true;
1346 break;
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
1357 if(pTyp)
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) ;
1368 bExp = true;
1369 pField = std::move(pExpField);
1371 else
1372 return false;
1374 else
1376 SwInputFieldType* pTyp =
1377 static_cast<SwInputFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::Input) );
1379 pField.reset(
1380 new SwInputField( pTyp, rData.m_sPar1, rData.m_sPar2, nSubType|nsSwExtendedSubType::SUB_INVISIBLE, nFormatId));
1382 break;
1385 case SwFieldTypesEnum::Set:
1387 if (rData.m_sPar2.isEmpty()) // empty variables are not allowed
1388 return false;
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);
1396 bExp = true;
1397 pField = std::move(pExpField);
1398 break;
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)
1410 cSeparator = '.';
1412 pTyp->SetDelimiter(OUString(cSeparator));
1413 pField.reset(new SwSetExpField(pTyp, rData.m_sPar2, nFormatId));
1414 bExp = true;
1415 break;
1418 case SwFieldTypesEnum::Get:
1420 // is there a corresponding SetField
1421 SwSetExpFieldType* pSetTyp = static_cast<SwSetExpFieldType*>(
1422 pCurShell->GetFieldType(SwFieldIds::SetExp, rData.m_sPar1));
1424 if(pSetTyp)
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());
1430 bExp = true;
1432 else
1433 return false;
1434 break;
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);
1446 if (pEntry)
1448 SfxStringItem aFormat(FN_NUMBER_FORMAT, pEntry->GetFormatstring());
1449 pCurShell->GetView().GetViewFrame().GetDispatcher()->
1450 ExecuteList(FN_NUMBER_FORMAT, SfxCallMode::SYNCHRON,
1451 { &aFormat });
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();
1467 return true;
1470 else
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);
1476 bExp = true;
1478 break;
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 ) );
1484 bPageVar = true;
1485 break;
1487 case SwFieldTypesEnum::GetRefPage:
1488 pField.reset( new SwRefPageGetField( static_cast<SwRefPageGetFieldType*>(
1489 pCurShell->GetFieldType( 0, SwFieldIds::RefPageGet ) ), nFormatId ) );
1490 bPageVar = true;
1491 break;
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);
1503 break;
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();
1509 return true;
1511 default:
1512 { OSL_ENSURE(false, "wrong field type");
1513 return false;
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);
1523 // insert
1524 pCurShell->StartAllAction();
1526 bool const isSuccess = pCurShell->InsertField2(*pField, rData.m_oAnnotationRange ? &*rData.m_oAnnotationRange : nullptr);
1528 if (isSuccess)
1530 if (SwFieldTypesEnum::Input == rData.m_nTypeId)
1532 pCurShell->Push();
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,
1537 false);
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);
1548 if (bTable)
1550 pCurShell->Left(SwCursorSkipMode::Chars, false, 1, false );
1551 pCurShell->UpdateOneField(*pField);
1552 pCurShell->Right(SwCursorSkipMode::Chars, false, 1, false );
1554 else if (bPageVar)
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
1565 pField.reset();
1567 pCurShell->EndAllAction();
1568 return isSuccess;
1571 // fields update
1572 void SwFieldMgr::UpdateCurField(sal_uInt32 nFormat,
1573 const OUString& rPar1,
1574 const OUString& rPar2,
1575 std::unique_ptr<SwField> pTmpField)
1577 // change format
1578 OSL_ENSURE(m_pCurField, "no field at CursorPos");
1580 if (!pTmpField)
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");
1588 if(!pSh)
1589 return;
1590 pSh->StartAllAction();
1592 bool bSetPar2 = true;
1593 bool bSetPar1 = true;
1594 OUString sPar2( rPar2 );
1596 // Order to Format
1597 switch( nTypeId )
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);
1609 break;
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));
1617 nByte -= 1;
1618 static_cast<SwChapterField*>(pTmpField.get())->SetLevel(static_cast<sal_uInt8>(nByte));
1619 bSetPar2 = false;
1620 break;
1623 case SwFieldTypesEnum::Script:
1624 static_cast<SwScriptField*>(pTmpField.get())->SetCodeURL(static_cast<bool>(nFormat));
1625 break;
1627 case SwFieldTypesEnum::NextPage:
1628 if( SVX_NUM_CHAR_SPECIAL == nFormat )
1630 static_cast<SwPageNumberField*>(m_pCurField)->SetUserString( sPar2 );
1631 sPar2 = "1";
1633 else
1635 if( nFormat + 2 == SVX_NUM_PAGEDESC )
1636 nFormat = SVX_NUM_PAGEDESC;
1637 short nOff = static_cast<short>(sPar2.toInt32());
1638 nOff += 1;
1639 sPar2 = OUString::number(nOff);
1641 break;
1643 case SwFieldTypesEnum::PreviousPage:
1644 if( SVX_NUM_CHAR_SPECIAL == nFormat )
1646 static_cast<SwPageNumberField*>(m_pCurField)->SetUserString( sPar2 );
1647 sPar2 = "-1";
1649 else
1651 if( nFormat + 2 == SVX_NUM_PAGEDESC )
1652 nFormat = SVX_NUM_PAGEDESC;
1653 short nOff = static_cast<short>(sPar2.toInt32());
1654 nOff -= 1;
1655 sPar2 = OUString::number(nOff);
1657 break;
1659 case SwFieldTypesEnum::PageNumber:
1660 case SwFieldTypesEnum::GetRefPage:
1661 if( nFormat + 2 == SVX_NUM_PAGEDESC )
1662 nFormat = SVX_NUM_PAGEDESC;
1663 break;
1665 case SwFieldTypesEnum::GetRef:
1667 bSetPar2 = false;
1668 static_cast<SwGetRefField*>(pTmpField.get())->SetSubType( o3tl::narrowing<sal_uInt16>(rPar2.toInt32()) );
1669 const sal_Int32 nPos = rPar2.indexOf( '|' );
1670 if( nPos>=0 )
1671 static_cast<SwGetRefField*>(pTmpField.get())->SetSeqNo( o3tl::narrowing<sal_uInt16>(o3tl::toInt32(rPar2.subView( nPos + 1 ))));
1673 break;
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;
1685 break;
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
1697 // others.
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;
1709 break;
1712 else
1714 if (xTempEntry->GetAuthorField(eField) != pAuthorityField->GetFieldText(eField))
1716 bEquivalent = false;
1717 break;
1722 if (bEquivalent)
1724 break;
1727 if( pAuthorityType->ChangeEntryContent( xTempEntry.get() ) )
1729 pType->UpdateFields();
1730 pSh->SetModified();
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
1736 bSetPar2 = false;
1738 break;
1739 default: break;
1742 // set format
1743 // setup format before SetPar2 because of NumberFormatter!
1744 pTmpField->ChangeFormat(nFormat);
1746 if( bSetPar1 )
1747 pTmpField->SetPar1( rPar1 );
1748 if( bSetPar2 )
1749 pTmpField->SetPar2( sPar2 );
1751 // kick off update
1752 if(nTypeId == SwFieldTypesEnum::DDE ||
1753 nTypeId == SwFieldTypesEnum::User ||
1754 nTypeId == SwFieldTypesEnum::UserInput)
1756 pType->UpdateFields();
1757 pSh->SetModified();
1759 else {
1760 // mb: #32157
1761 pSh->SwEditShell::UpdateOneField(*pTmpField);
1762 GetCurField();
1765 pTmpField.reset();
1767 pSh->EndAllAction();
1770 // explicitly evaluate ExpressionFields
1771 void SwFieldMgr::EvalExpFields(SwWrtShell* pSh)
1773 if (pSh == nullptr)
1774 pSh = m_pWrtShell ? m_pWrtShell : ::lcl_GetShell();
1776 if(pSh)
1778 pSh->StartAllAction();
1779 pSh->UpdateExpFields(true);
1780 pSh->EndAllAction();
1783 LanguageType SwFieldMgr::GetCurrLanguage() const
1785 SwWrtShell* pSh = m_pWrtShell ? m_pWrtShell : ::lcl_GetShell();
1786 if( pSh )
1787 return pSh->GetCurLang();
1788 return SvtSysLocale().GetLanguageTag().getLanguageType();
1791 void SwFieldType::GetFieldName_()
1793 static const TranslateId coFieldNms[] =
1795 FLD_DATE_STD,
1796 FLD_TIME_STD,
1797 STR_FILENAMEFLD,
1798 STR_DBNAMEFLD,
1799 STR_CHAPTERFLD,
1800 STR_PAGENUMBERFLD,
1801 STR_DOCSTATFLD,
1802 STR_AUTHORFLD,
1803 STR_SETFLD,
1804 STR_GETFLD,
1805 STR_FORMELFLD,
1806 STR_HIDDENTXTFLD,
1807 STR_SETREFFLD,
1808 STR_GETREFFLD,
1809 STR_DDEFLD,
1810 STR_MACROFLD,
1811 STR_INPUTFLD,
1812 STR_HIDDENPARAFLD,
1813 STR_DOCINFOFLD,
1814 STR_DBFLD,
1815 STR_USERFLD,
1816 STR_POSTITFLD,
1817 STR_TEMPLNAMEFLD,
1818 STR_SEQFLD,
1819 STR_DBNEXTSETFLD,
1820 STR_DBNUMSETFLD,
1821 STR_DBSETNUMBERFLD,
1822 STR_CONDTXTFLD,
1823 STR_NEXTPAGEFLD,
1824 STR_PREVPAGEFLD,
1825 STR_EXTUSERFLD,
1826 FLD_DATE_FIX,
1827 FLD_TIME_FIX,
1828 STR_SETINPUTFLD,
1829 STR_USRINPUTFLD,
1830 STR_SETREFPAGEFLD,
1831 STR_GETREFPAGEFLD,
1832 STR_INTERNETFLD,
1833 STR_JUMPEDITFLD,
1834 STR_SCRIPTFLD,
1835 STR_AUTHORITY,
1836 STR_COMBINED_CHARS,
1837 STR_DROPDOWN,
1838 STR_CUSTOM_FIELD,
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)
1854 bool bRet = false;
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 );
1863 bRet = true;
1866 return bRet;
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 );
1886 if ( xUrl.is() )
1888 m_sMacroName = xUrl->getName();
1892 sal_uInt32 SwFieldMgr::GetDefaultFormat(SwFieldTypesEnum nTypeId, bool bIsText, SvNumberFormatter* pFormatter)
1894 SvNumFormatType nDefFormat;
1896 switch (nTypeId)
1898 case SwFieldTypesEnum::Time:
1899 case SwFieldTypesEnum::Date:
1901 nDefFormat = (nTypeId == SwFieldTypesEnum::Date) ? SvNumFormatType::DATE : SvNumFormatType::TIME;
1903 break;
1905 default:
1906 if (bIsText)
1908 nDefFormat = SvNumFormatType::TEXT;
1910 else
1912 nDefFormat = SvNumFormatType::ALL;
1914 break;
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: */