xref: /core/sw/source/core/unocore/unofield.cxx (revision 9ff648c6)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <config_features.h>
21 
22 #include <sal/config.h>
23 #include <editeng/outlobj.hxx>
24 #include <algorithm>
25 #include <memory>
26 
27 #include <unofield.hxx>
28 #include <unofieldcoll.hxx>
29 #include <swtypes.hxx>
30 #include <cmdid.h>
31 #include <doc.hxx>
32 #include <IDocumentFieldsAccess.hxx>
33 #include <IDocumentStatistics.hxx>
34 #include <IDocumentStylePoolAccess.hxx>
35 #include <IDocumentLayoutAccess.hxx>
36 #include <IDocumentState.hxx>
37 #include <hints.hxx>
38 #include <fmtfld.hxx>
39 #include <txtfld.hxx>
40 #include <ndtxt.hxx>
41 #include <unomap.hxx>
42 #include <unoprnms.hxx>
43 #include <unotextrange.hxx>
44 #include <unotextcursor.hxx>
45 #include <unocoll.hxx>
46 #include <sfx2/linkmgr.hxx>
47 #include <docstat.hxx>
48 #include <editsh.hxx>
49 #include <viewsh.hxx>
50 #include <comphelper/servicehelper.hxx>
51 #include <comphelper/string.hxx>
52 #include <comphelper/types.hxx>
53 #include <cppuhelper/supportsservice.hxx>
54 #include <com/sun/star/util/Time.hpp>
55 #include <com/sun/star/util/DateTime.hpp>
56 #include <com/sun/star/util/Date.hpp>
57 #include <com/sun/star/beans/XFastPropertySet.hpp>
58 #include <com/sun/star/beans/XPropertyStateChangeListener.hpp>
59 #include <com/sun/star/beans/PropertyAttribute.hpp>
60 #include <com/sun/star/beans/XPropertyContainer.hpp>
61 
62 //undef to prevent error (from sfx2/docfile.cxx)
63 #undef SEQUENCE
64 #include <com/sun/star/text/SetVariableType.hpp>
65 #include <com/sun/star/text/WrapTextMode.hpp>
66 #include <com/sun/star/text/TextContentAnchorType.hpp>
67 #include <com/sun/star/text/PageNumberType.hpp>
68 #include <unocrsr.hxx>
69 #include <authfld.hxx>
70 #include <flddat.hxx>
71 #include <dbfld.hxx>
72 #include <usrfld.hxx>
73 #include <docufld.hxx>
74 #include <expfld.hxx>
75 #include <chpfld.hxx>
76 #include <flddropdown.hxx>
77 #include <poolfmt.hxx>
78 #include <strings.hrc>
79 #include <pagedesc.hxx>
80 #include <docary.hxx>
81 #include <reffld.hxx>
82 #include <ddefld.hxx>
83 #include <SwStyleNameMapper.hxx>
84 #include <swunohelper.hxx>
85 #include <unofldmid.h>
86 #include <scriptinfo.hxx>
87 #include <tools/datetime.hxx>
88 #include <tools/urlobj.hxx>
89 #include <svl/itemprop.hxx>
90 #include <svl/listener.hxx>
91 #include <svx/dataaccessdescriptor.hxx>
92 #include <o3tl/any.hxx>
93 #include <osl/mutex.hxx>
94 #include <vcl/svapp.hxx>
95 #include <textapi.hxx>
96 #include <editeng/outliner.hxx>
97 #include <docsh.hxx>
98 #include <fmtmeta.hxx>
99 #include <calbck.hxx>
100 #include <rtl/strbuf.hxx>
101 #include <editeng/outlobj.hxx>
102 #include <vector>
103 
104 using namespace ::com::sun::star;
105 using namespace nsSwDocInfoSubType;
106 
107 // case-corrected version of the first part for the service names (see #i67811)
108 #define COM_TEXT_FLDMASTER_CC   "com.sun.star.text.fieldmaster."
109 
110 // note: this thing is indexed as an array, so do not insert/remove entries!
111 static const sal_uInt16 aDocInfoSubTypeFromService[] =
112 {
113     DI_CHANGE | DI_SUB_AUTHOR,  //PROPERTY_MAP_FLDTYP_DOCINFO_CHANGE_AUTHOR
114     DI_CHANGE | DI_SUB_DATE,    //PROPERTY_MAP_FLDTYP_DOCINFO_CHANGE_DATE_TIME
115     DI_EDIT | DI_SUB_TIME,      //PROPERTY_MAP_FLDTYP_DOCINFO_EDIT_TIME
116     DI_COMMENT,                 //PROPERTY_MAP_FLDTYP_DOCINFO_DESCRIPTION
117     DI_CREATE | DI_SUB_AUTHOR,  //PROPERTY_MAP_FLDTYP_DOCINFO_CREATE_AUTHOR
118     DI_CREATE | DI_SUB_DATE,    //PROPERTY_MAP_FLDTYP_DOCINFO_CREATE_DATE_TIME
119     0,                          //DUMMY
120     0,                          //DUMMY
121     0,                          //DUMMY
122     0,                          //DUMMY
123     DI_CUSTOM,                  //PROPERTY_MAP_FLDTYP_DOCINFO_CUSTOM
124     DI_PRINT | DI_SUB_AUTHOR,   //PROPERTY_MAP_FLDTYP_DOCINFO_PRINT_AUTHOR
125     DI_PRINT | DI_SUB_DATE,     //PROPERTY_MAP_FLDTYP_DOCINFO_PRINT_DATE_TIME
126     DI_KEYS,                    //PROPERTY_MAP_FLDTYP_DOCINFO_KEY_WORDS
127     DI_THEMA,                   //PROPERTY_MAP_FLDTYP_DOCINFO_SUBJECT
128     DI_TITLE,                   //PROPERTY_MAP_FLDTYP_DOCINFO_TITLE
129     DI_DOCNO                    //PROPERTY_MAP_FLDTYP_DOCINFO_REVISION
130 };
131 
132 struct ServiceIdResId
133 {
134     SwFieldIds const    nResId;
135     SwServiceType const nServiceId;
136 };
137 
138 static const ServiceIdResId aServiceToRes[] =
139 {
140     {SwFieldIds::DateTime,           SwServiceType::FieldTypeDateTime              },
141     {SwFieldIds::User,               SwServiceType::FieldTypeUser                  },
142     {SwFieldIds::SetExp,             SwServiceType::FieldTypeSetExp                },
143     {SwFieldIds::GetExp,             SwServiceType::FieldTypeGetExp                },
144     {SwFieldIds::Filename,           SwServiceType::FieldTypeFileName              },
145     {SwFieldIds::PageNumber,         SwServiceType::FieldTypePageNum               },
146     {SwFieldIds::Author,             SwServiceType::FieldTypeAuthor                },
147     {SwFieldIds::Chapter,            SwServiceType::FieldTypeChapter               },
148     {SwFieldIds::GetRef,             SwServiceType::FieldTypeGetReference          },
149     {SwFieldIds::HiddenText,         SwServiceType::FieldTypeConditionedText       },
150     {SwFieldIds::Postit,             SwServiceType::FieldTypeAnnotation            },
151     {SwFieldIds::Input,              SwServiceType::FieldTypeInput                 },
152     {SwFieldIds::Macro,              SwServiceType::FieldTypeMacro                 },
153     {SwFieldIds::Dde,                SwServiceType::FieldTypeDDE                   },
154     {SwFieldIds::HiddenPara,         SwServiceType::FieldTypeHiddenPara            },
155     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfo               },
156     {SwFieldIds::TemplateName,       SwServiceType::FieldTypeTemplateName          },
157     {SwFieldIds::ExtUser,            SwServiceType::FieldTypeUserExt               },
158     {SwFieldIds::RefPageSet,         SwServiceType::FieldTypeRefPageSet            },
159     {SwFieldIds::RefPageGet,         SwServiceType::FieldTypeRefPageGet            },
160     {SwFieldIds::JumpEdit,           SwServiceType::FieldTypeJumpEdit              },
161     {SwFieldIds::Script,             SwServiceType::FieldTypeScript                },
162     {SwFieldIds::DbNextSet,          SwServiceType::FieldTypeDatabaseNextSet       },
163     {SwFieldIds::DbNumSet,           SwServiceType::FieldTypeDatabaseNumSet        },
164     {SwFieldIds::DbSetNumber,        SwServiceType::FieldTypeDatabaseSetNum        },
165     {SwFieldIds::Database,           SwServiceType::FieldTypeDatabase              },
166     {SwFieldIds::DatabaseName,       SwServiceType::FieldTypeDatabaseName          },
167     {SwFieldIds::DocStat,            SwServiceType::FieldTypePageCount             },
168     {SwFieldIds::DocStat,            SwServiceType::FieldTypeParagraphCount        },
169     {SwFieldIds::DocStat,            SwServiceType::FieldTypeWordCount             },
170     {SwFieldIds::DocStat,            SwServiceType::FieldTypeCharacterCount        },
171     {SwFieldIds::DocStat,            SwServiceType::FieldTypeTableCount            },
172     {SwFieldIds::DocStat,            SwServiceType::FieldTypeGraphicObjectCount    },
173     {SwFieldIds::DocStat,            SwServiceType::FieldTypeEmbeddedObjectCount   },
174     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfoChangeAuthor   },
175     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfoChangeDateTime },
176     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfoEditTime       },
177     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfoDescription    },
178     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfoCreateAuthor   },
179     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfoCreateDateTime },
180     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfoCustom         },
181     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfoPrintAuthor    },
182     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfoPrintDateTime  },
183     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfoKeywords       },
184     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfoSubject        },
185     {SwFieldIds::DocInfo,            SwServiceType::FieldTypeDocInfoTitle          },
186     {SwFieldIds::Input,              SwServiceType::FieldTypeInputUser             },
187     {SwFieldIds::HiddenText,         SwServiceType::FieldTypeHiddenText            },
188     {SwFieldIds::TableOfAuthorities, SwServiceType::FieldTypeBibliography          },
189     {SwFieldIds::CombinedChars,      SwServiceType::FieldTypeCombinedCharacters    },
190     {SwFieldIds::Dropdown,           SwServiceType::FieldTypeDropdown              },
191     {SwFieldIds::Table,              SwServiceType::FieldTypeTableFormula          }
192 };
193 
194 static SwFieldIds lcl_ServiceIdToResId(SwServiceType nServiceId)
195 {
196     for (size_t i=0; i<SAL_N_ELEMENTS(aServiceToRes); ++i)
197         if (aServiceToRes[i].nServiceId == nServiceId)
198             return aServiceToRes[i].nResId;
199 #if OSL_DEBUG_LEVEL > 0
200     OSL_FAIL("service id not found");
201 #endif
202     return SwFieldIds::Unknown;
203 }
204 
205 static SwServiceType lcl_GetServiceForField( const SwField& rField )
206 {
207     const SwFieldIds nWhich = rField.Which();
208     SwServiceType nSrvId = SwServiceType::Invalid;
209     //special handling for some fields
210     switch( nWhich )
211     {
212     case SwFieldIds::Input:
213         if( INP_USR == (rField.GetSubType() & 0x00ff) )
214             nSrvId = SwServiceType::FieldTypeInputUser;
215         break;
216 
217     case SwFieldIds::DocInfo:
218         {
219             const sal_uInt16 nSubType = rField.GetSubType();
220             switch( nSubType & 0xff )
221             {
222             case DI_CHANGE:
223                 nSrvId = ((nSubType&0x300) == DI_SUB_AUTHOR)
224                         ? SwServiceType::FieldTypeDocInfoChangeAuthor
225                         : SwServiceType::FieldTypeDocInfoChangeDateTime;
226                 break;
227             case DI_CREATE:
228                 nSrvId = ((nSubType&0x300) == DI_SUB_AUTHOR)
229                         ? SwServiceType::FieldTypeDocInfoCreateAuthor
230                         : SwServiceType::FieldTypeDocInfoCreateDateTime;
231                 break;
232             case DI_PRINT:
233                 nSrvId = ((nSubType&0x300) == DI_SUB_AUTHOR)
234                         ? SwServiceType::FieldTypeDocInfoPrintAuthor
235                         : SwServiceType::FieldTypeDocInfoPrintDateTime;
236                 break;
237             case DI_EDIT:   nSrvId = SwServiceType::FieldTypeDocInfoEditTime;break;
238             case DI_COMMENT:nSrvId = SwServiceType::FieldTypeDocInfoDescription;break;
239             case DI_KEYS:   nSrvId = SwServiceType::FieldTypeDocInfoKeywords;break;
240             case DI_THEMA:  nSrvId = SwServiceType::FieldTypeDocInfoSubject;  break;
241             case DI_TITLE:  nSrvId = SwServiceType::FieldTypeDocInfoTitle;    break;
242             case DI_DOCNO:  nSrvId = SwServiceType::FieldTypeDocInfoRevision; break;
243             case DI_CUSTOM: nSrvId = SwServiceType::FieldTypeDocInfoCustom;   break;
244             }
245         }
246         break;
247 
248     case SwFieldIds::HiddenText:
249         nSrvId = TYP_CONDTXTFLD == rField.GetSubType()
250                         ? SwServiceType::FieldTypeConditionedText
251                         : SwServiceType::FieldTypeHiddenText;
252         break;
253 
254     case SwFieldIds::DocStat:
255         {
256             switch( rField.GetSubType() )
257             {
258             case DS_PAGE: nSrvId = SwServiceType::FieldTypePageCount; break;
259             case DS_PARA: nSrvId = SwServiceType::FieldTypeParagraphCount; break;
260             case DS_WORD: nSrvId = SwServiceType::FieldTypeWordCount     ; break;
261             case DS_CHAR: nSrvId = SwServiceType::FieldTypeCharacterCount; break;
262             case DS_TBL:  nSrvId = SwServiceType::FieldTypeTableCount    ; break;
263             case DS_GRF:  nSrvId = SwServiceType::FieldTypeGraphicObjectCount; break;
264             case DS_OLE:  nSrvId = SwServiceType::FieldTypeEmbeddedObjectCount; break;
265             }
266         }
267         break;
268     default: break;
269     }
270     if( SwServiceType::Invalid == nSrvId )
271     {
272         for( const ServiceIdResId* pMap = aServiceToRes;
273                 SwFieldIds::Unknown != pMap->nResId; ++pMap )
274             if( nWhich == pMap->nResId )
275             {
276                 nSrvId = pMap->nServiceId;
277                 break;
278             }
279     }
280 #if OSL_DEBUG_LEVEL > 0
281     if( SwServiceType::Invalid == nSrvId )
282         OSL_FAIL("resid not found");
283 #endif
284     return nSrvId;
285 }
286 
287 static sal_uInt16 lcl_GetPropMapIdForFieldType( SwFieldIds nWhich )
288 {
289     sal_uInt16 nId;
290     switch( nWhich )
291     {
292     case SwFieldIds::User:     nId = PROPERTY_MAP_FLDMSTR_USER;            break;
293     case SwFieldIds::Database: nId = PROPERTY_MAP_FLDMSTR_DATABASE;        break;
294     case SwFieldIds::SetExp:   nId = PROPERTY_MAP_FLDMSTR_SET_EXP;         break;
295     case SwFieldIds::Dde:      nId = PROPERTY_MAP_FLDMSTR_DDE;             break;
296     case SwFieldIds::TableOfAuthorities:
297                                nId = PROPERTY_MAP_FLDMSTR_BIBLIOGRAPHY;    break;
298     default:                   nId = PROPERTY_MAP_FLDMSTR_DUMMY0;
299     }
300     return nId;
301 }
302 
303 static sal_Int32 lcl_PropName2TokenPos(const OUString& rPropertyName)
304 {
305     if (rPropertyName == UNO_NAME_DDE_COMMAND_TYPE)
306         return 0;
307 
308     if (rPropertyName == UNO_NAME_DDE_COMMAND_FILE)
309         return 1;
310 
311     if (rPropertyName == UNO_NAME_DDE_COMMAND_ELEMENT)
312         return 2;
313 
314     if (rPropertyName == UNO_NAME_IS_AUTOMATIC_UPDATE)
315         return 3;
316 
317     return SAL_MAX_INT32;
318 }
319 
320 static sal_uInt16 GetFieldTypeMId( const OUString& rProperty, const SwFieldType& rTyp )
321 {
322     sal_uInt16 nId = lcl_GetPropMapIdForFieldType( rTyp.Which() );
323     const SfxItemPropertySet* pSet = aSwMapProvider.GetPropertySet( nId );
324     if( !pSet )
325         nId = USHRT_MAX;
326     else
327     {
328         const SfxItemPropertySimpleEntry* pEntry = pSet->getPropertyMap().getByName(rProperty);
329         nId = pEntry ? pEntry->nWID : USHRT_MAX;
330     }
331     return nId;
332 }
333 
334 static sal_uInt16 lcl_GetPropertyMapOfService( SwServiceType nServiceId )
335 {
336     sal_uInt16 nRet;
337     switch ( nServiceId)
338     {
339     case SwServiceType::FieldTypeDateTime: nRet = PROPERTY_MAP_FLDTYP_DATETIME; break;
340     case SwServiceType::FieldTypeUser: nRet = PROPERTY_MAP_FLDTYP_USER; break;
341     case SwServiceType::FieldTypeSetExp: nRet = PROPERTY_MAP_FLDTYP_SET_EXP; break;
342     case SwServiceType::FieldTypeGetExp: nRet = PROPERTY_MAP_FLDTYP_GET_EXP; break;
343     case SwServiceType::FieldTypeFileName: nRet = PROPERTY_MAP_FLDTYP_FILE_NAME; break;
344     case SwServiceType::FieldTypePageNum: nRet = PROPERTY_MAP_FLDTYP_PAGE_NUM; break;
345     case SwServiceType::FieldTypeAuthor: nRet = PROPERTY_MAP_FLDTYP_AUTHOR; break;
346     case SwServiceType::FieldTypeChapter: nRet = PROPERTY_MAP_FLDTYP_CHAPTER; break;
347     case SwServiceType::FieldTypeGetReference: nRet = PROPERTY_MAP_FLDTYP_GET_REFERENCE; break;
348     case SwServiceType::FieldTypeConditionedText: nRet = PROPERTY_MAP_FLDTYP_CONDITIONED_TEXT; break;
349     case SwServiceType::FieldTypeAnnotation: nRet = PROPERTY_MAP_FLDTYP_ANNOTATION; break;
350     case SwServiceType::FieldTypeInputUser:
351     case SwServiceType::FieldTypeInput: nRet = PROPERTY_MAP_FLDTYP_INPUT; break;
352     case SwServiceType::FieldTypeMacro: nRet = PROPERTY_MAP_FLDTYP_MACRO; break;
353     case SwServiceType::FieldTypeDDE: nRet = PROPERTY_MAP_FLDTYP_DDE; break;
354     case SwServiceType::FieldTypeHiddenPara: nRet = PROPERTY_MAP_FLDTYP_HIDDEN_PARA; break;
355     case SwServiceType::FieldTypeDocInfo: nRet = PROPERTY_MAP_FLDTYP_DOC_INFO; break;
356     case SwServiceType::FieldTypeTemplateName: nRet = PROPERTY_MAP_FLDTYP_TEMPLATE_NAME; break;
357     case SwServiceType::FieldTypeUserExt: nRet = PROPERTY_MAP_FLDTYP_USER_EXT; break;
358     case SwServiceType::FieldTypeRefPageSet: nRet = PROPERTY_MAP_FLDTYP_REF_PAGE_SET; break;
359     case SwServiceType::FieldTypeRefPageGet: nRet = PROPERTY_MAP_FLDTYP_REF_PAGE_GET; break;
360     case SwServiceType::FieldTypeJumpEdit: nRet = PROPERTY_MAP_FLDTYP_JUMP_EDIT; break;
361     case SwServiceType::FieldTypeScript: nRet = PROPERTY_MAP_FLDTYP_SCRIPT; break;
362     case SwServiceType::FieldTypeDatabaseNextSet: nRet = PROPERTY_MAP_FLDTYP_DATABASE_NEXT_SET; break;
363     case SwServiceType::FieldTypeDatabaseNumSet: nRet = PROPERTY_MAP_FLDTYP_DATABASE_NUM_SET; break;
364     case SwServiceType::FieldTypeDatabaseSetNum: nRet = PROPERTY_MAP_FLDTYP_DATABASE_SET_NUM; break;
365     case SwServiceType::FieldTypeDatabase: nRet = PROPERTY_MAP_FLDTYP_DATABASE; break;
366     case SwServiceType::FieldTypeDatabaseName: nRet = PROPERTY_MAP_FLDTYP_DATABASE_NAME; break;
367     case SwServiceType::FieldTypeTableFormula: nRet = PROPERTY_MAP_FLDTYP_TABLE_FORMULA; break;
368     case SwServiceType::FieldTypePageCount:
369     case SwServiceType::FieldTypeParagraphCount:
370     case SwServiceType::FieldTypeWordCount:
371     case SwServiceType::FieldTypeCharacterCount:
372     case SwServiceType::FieldTypeTableCount:
373     case SwServiceType::FieldTypeGraphicObjectCount:
374     case SwServiceType::FieldTypeEmbeddedObjectCount: nRet = PROPERTY_MAP_FLDTYP_DOCSTAT; break;
375     case SwServiceType::FieldTypeDocInfoChangeAuthor:
376     case SwServiceType::FieldTypeDocInfoCreateAuthor:
377     case SwServiceType::FieldTypeDocInfoPrintAuthor: nRet = PROPERTY_MAP_FLDTYP_DOCINFO_AUTHOR; break;
378     case SwServiceType::FieldTypeDocInfoChangeDateTime:
379     case SwServiceType::FieldTypeDocInfoCreateDateTime:
380     case SwServiceType::FieldTypeDocInfoPrintDateTime: nRet = PROPERTY_MAP_FLDTYP_DOCINFO_DATE_TIME; break;
381     case SwServiceType::FieldTypeDocInfoEditTime: nRet = PROPERTY_MAP_FLDTYP_DOCINFO_EDIT_TIME; break;
382     case SwServiceType::FieldTypeDocInfoCustom: nRet = PROPERTY_MAP_FLDTYP_DOCINFO_CUSTOM; break;
383     case SwServiceType::FieldTypeDocInfoDescription:
384     case SwServiceType::FieldTypeDocInfoKeywords:
385     case SwServiceType::FieldTypeDocInfoSubject:
386     case SwServiceType::FieldTypeDocInfoTitle: nRet = PROPERTY_MAP_FLDTYP_DOCINFO_MISC; break;
387     case SwServiceType::FieldTypeDocInfoRevision: nRet = PROPERTY_MAP_FLDTYP_DOCINFO_REVISION; break;
388     case SwServiceType::FieldTypeBibliography: nRet = PROPERTY_MAP_FLDTYP_BIBLIOGRAPHY; break;
389     case SwServiceType::FieldTypeDummy0:
390     case SwServiceType::FieldTypeCombinedCharacters: nRet = PROPERTY_MAP_FLDTYP_COMBINED_CHARACTERS; break;
391     case SwServiceType::FieldTypeDropdown: nRet = PROPERTY_MAP_FLDTYP_DROPDOWN; break;
392     case SwServiceType::FieldTypeDummy4:
393     case SwServiceType::FieldTypeDummy5:
394     case SwServiceType::FieldTypeDummy6:
395     case SwServiceType::FieldTypeDummy7:
396                 nRet = PROPERTY_MAP_FLDTYP_DUMMY_0; break;
397     case SwServiceType::FieldMasterUser: nRet = PROPERTY_MAP_FLDMSTR_USER; break;
398     case SwServiceType::FieldMasterDDE: nRet = PROPERTY_MAP_FLDMSTR_DDE; break;
399     case SwServiceType::FieldMasterSetExp: nRet = PROPERTY_MAP_FLDMSTR_SET_EXP; break;
400     case SwServiceType::FieldMasterDatabase: nRet = PROPERTY_MAP_FLDMSTR_DATABASE; break;
401     case SwServiceType::FieldMasterBibliography: nRet = PROPERTY_MAP_FLDMSTR_BIBLIOGRAPHY; break;
402     case SwServiceType::FieldMasterDummy2:
403     case SwServiceType::FieldMasterDummy3:
404     case SwServiceType::FieldMasterDummy4:
405     case SwServiceType::FieldMasterDummy5: nRet = PROPERTY_MAP_FLDMSTR_DUMMY0; break;
406     case SwServiceType::FieldTypeHiddenText: nRet = PROPERTY_MAP_FLDTYP_HIDDEN_TEXT; break;
407     default:
408         OSL_FAIL( "wrong service id" );
409         nRet = USHRT_MAX;
410     }
411     return nRet;
412 }
413 
414 class SwXFieldMaster::Impl
415     : public SvtListener
416 {
417 private:
418     ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
419 
420 public:
421     uno::WeakReference<uno::XInterface> m_wThis;
422     ::comphelper::OInterfaceContainerHelper2 m_EventListeners;
423 
424     SwDoc*          m_pDoc;
425     SwFieldType* m_pType;
426 
427     SwFieldIds const      m_nResTypeId;
428 
429     OUString        m_sParam1;  // Content / Database / NumberingSeparator
430     OUString        m_sParam2;  // -    /DataTablename
431     OUString        m_sParam3;  // -    /DataFieldName
432     OUString        m_sParam5;  // -    /DataBaseURL
433     double          m_fParam1;  // Value / -
434     sal_Int8        m_nParam1;  // ChapterNumberingLevel
435     bool            m_bParam1;  // IsExpression
436     sal_Int32       m_nParam2;
437 
438     Impl(SwPageDesc* const pPageDesc, SwDoc* pDoc, SwFieldIds nResId)
439         : m_EventListeners(m_Mutex)
440         , m_pDoc(pDoc)
441         , m_pType(nullptr)
442         , m_nResTypeId(nResId)
443         , m_fParam1(0.0)
444         , m_nParam1(-1)
445         , m_bParam1(false)
446         , m_nParam2(0)
447     {
448         StartListening(pPageDesc->GetNotifier());
449     }
450 
451     Impl(SwFieldType* const pType, SwDoc* pDoc, SwFieldIds nResId)
452         : m_EventListeners(m_Mutex)
453         , m_pDoc(pDoc)
454         , m_pType(pType)
455         , m_nResTypeId(nResId)
456         , m_fParam1(0.0)
457         , m_nParam1(-1)
458         , m_bParam1(false)
459         , m_nParam2(0)
460     {
461         StartListening(m_pType->GetNotifier());
462     }
463     void SetFieldType(SwFieldType* pType)
464     {
465         EndListeningAll();
466         m_pType = pType;
467         StartListening(m_pType->GetNotifier());
468     }
469 protected:
470     virtual void Notify(const SfxHint& rHint) override;
471 };
472 
473 namespace
474 {
475     class theSwXFieldMasterUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXFieldMasterUnoTunnelId > {};
476 }
477 
478 const uno::Sequence< sal_Int8 > & SwXFieldMaster::getUnoTunnelId()
479 {
480     return theSwXFieldMasterUnoTunnelId::get().getSeq();
481 }
482 
483 sal_Int64 SAL_CALL
484 SwXFieldMaster::getSomething(const uno::Sequence< sal_Int8 >& rId)
485 {
486     return ::sw::UnoTunnelImpl<SwXFieldMaster>(rId, this);
487 }
488 
489 OUString SAL_CALL
490 SwXFieldMaster::getImplementationName()
491 {
492     return OUString("SwXFieldMaster");
493 }
494 
495 namespace
496 {
497 
498 OUString getServiceName(const SwFieldIds aId)
499 {
500     const sal_Char* pEntry;
501     switch (aId)
502     {
503         case SwFieldIds::User:
504             pEntry = "User";
505             break;
506         case SwFieldIds::Database:
507             pEntry = "Database";
508             break;
509         case SwFieldIds::SetExp:
510             pEntry = "SetExpression";
511             break;
512         case SwFieldIds::Dde:
513             pEntry = "DDE";
514             break;
515         case SwFieldIds::TableOfAuthorities:
516             pEntry = "Bibliography";
517             break;
518         default:
519             return OUString();
520     }
521 
522     return "com.sun.star.text.fieldmaster." + OUString::createFromAscii(pEntry);
523 }
524 
525 }
526 
527 sal_Bool SAL_CALL SwXFieldMaster::supportsService(const OUString& rServiceName)
528 {
529     return cppu::supportsService(this, rServiceName);
530 }
531 
532 uno::Sequence< OUString > SAL_CALL
533 SwXFieldMaster::getSupportedServiceNames()
534 {
535     uno::Sequence< OUString > aRet(2);
536     OUString* pArray = aRet.getArray();
537     pArray[0] = "com.sun.star.text.TextFieldMaster";
538     pArray[1] = getServiceName(m_pImpl->m_nResTypeId);
539     return aRet;
540 }
541 
542 SwXFieldMaster::SwXFieldMaster(SwDoc *const pDoc, SwFieldIds const nResId)
543     : m_pImpl(new Impl(pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD), pDoc, nResId))
544 {
545 }
546 
547 SwXFieldMaster::SwXFieldMaster(SwFieldType& rType, SwDoc * pDoc)
548     : m_pImpl(new Impl(&rType, pDoc, rType.Which()))
549 {
550 }
551 
552 SwXFieldMaster::~SwXFieldMaster()
553 {
554 }
555 
556 uno::Reference<beans::XPropertySet>
557 SwXFieldMaster::CreateXFieldMaster(SwDoc * pDoc, SwFieldType *const pType,
558         SwFieldIds nResId)
559 {
560     // re-use existing SwXFieldMaster
561     uno::Reference<beans::XPropertySet> xFM;
562     if (pType)
563     {
564         xFM = pType->GetXObject();
565     }
566     if (!xFM.is())
567     {
568         SwXFieldMaster *const pFM( pType
569                 ? new SwXFieldMaster(*pType, pDoc)
570                 : new SwXFieldMaster(pDoc, nResId));
571         xFM.set(pFM);
572         if (pType)
573         {
574             pType->SetXObject(xFM);
575         }
576         // need a permanent Reference to initialize m_wThis
577         pFM->m_pImpl->m_wThis = xFM;
578     }
579     return xFM;
580 }
581 
582 uno::Reference<beans::XPropertySetInfo> SAL_CALL
583 SwXFieldMaster::getPropertySetInfo()
584 {
585     SolarMutexGuard aGuard;
586     uno::Reference< beans::XPropertySetInfo >  aRef =
587                         aSwMapProvider.GetPropertySet(
588             lcl_GetPropMapIdForFieldType(m_pImpl->m_nResTypeId))->getPropertySetInfo();
589     return aRef;
590 }
591 
592 void SAL_CALL SwXFieldMaster::setPropertyValue(
593         const OUString& rPropertyName, const uno::Any& rValue)
594 {
595     SolarMutexGuard aGuard;
596     SwFieldType* pType = GetFieldType(true);
597     if(pType)
598     {
599         bool bSetValue = true;
600         if( rPropertyName == UNO_NAME_SUB_TYPE )
601         {
602             const std::vector<OUString>& rExtraArr(
603                     SwStyleNameMapper::GetExtraUINameArray());
604             const OUString sTypeName = pType->GetName();
605             static sal_uInt16 nIds[] =
606             {
607                 RES_POOLCOLL_LABEL_DRAWING - RES_POOLCOLL_EXTRA_BEGIN,
608                 RES_POOLCOLL_LABEL_ABB - RES_POOLCOLL_EXTRA_BEGIN,
609                 RES_POOLCOLL_LABEL_TABLE - RES_POOLCOLL_EXTRA_BEGIN,
610                 RES_POOLCOLL_LABEL_FRAME- RES_POOLCOLL_EXTRA_BEGIN,
611                 RES_POOLCOLL_LABEL_FIGURE - RES_POOLCOLL_EXTRA_BEGIN,
612                 0
613             };
614             for(const sal_uInt16 * pIds = nIds; *pIds; ++pIds)
615             {
616                 if(sTypeName == rExtraArr[ *pIds ] )
617                 {
618                     bSetValue = false;
619                     break;
620                 }
621             }
622         }
623         if ( bSetValue )
624         {
625             // nothing special to be done here for the properties
626             // UNO_NAME_DATA_BASE_NAME and UNO_NAME_DATA_BASE_URL.
627             // We just call PutValue (empty string is allowed).
628             // Thus the last property set will be used as Data Source.
629 
630             const sal_uInt16 nMemberValueId = GetFieldTypeMId( rPropertyName, *pType );
631             if ( USHRT_MAX == nMemberValueId )
632             {
633                 throw beans::UnknownPropertyException(
634                     "Unknown property: " + rPropertyName,
635                     static_cast< cppu::OWeakObject * >( this ) );
636             }
637 
638             pType->PutValue( rValue, nMemberValueId );
639             if ( pType->Which() == SwFieldIds::User )
640             {
641                 // trigger update of User field in order to get depending Input Fields updated.
642                 pType->UpdateFields();
643             }
644 
645         }
646     }
647     else if (m_pImpl->m_pDoc && rPropertyName == UNO_NAME_NAME)
648     {
649         OUString sTypeName;
650         rValue >>= sTypeName;
651         SwFieldType * pType2 = m_pImpl->m_pDoc->getIDocumentFieldsAccess().GetFieldType(
652                 m_pImpl->m_nResTypeId, sTypeName, false);
653 
654         if(pType2 ||
655             (SwFieldIds::SetExp == m_pImpl->m_nResTypeId &&
656             ( sTypeName == SwResId(STR_POOLCOLL_LABEL_TABLE) ||
657               sTypeName == SwResId(STR_POOLCOLL_LABEL_DRAWING) ||
658               sTypeName == SwResId(STR_POOLCOLL_LABEL_FRAME) ||
659               sTypeName == SwResId(STR_POOLCOLL_LABEL_ABB) ||
660               sTypeName == SwResId(STR_POOLCOLL_LABEL_FIGURE) )))
661         {
662             throw lang::IllegalArgumentException();
663         }
664 
665         switch (m_pImpl->m_nResTypeId)
666         {
667             case SwFieldIds::User :
668             {
669                 SwUserFieldType aType(m_pImpl->m_pDoc, sTypeName);
670                 pType2 = m_pImpl->m_pDoc->getIDocumentFieldsAccess().InsertFieldType(aType);
671                 static_cast<SwUserFieldType*>(pType2)->SetContent(m_pImpl->m_sParam1);
672                 static_cast<SwUserFieldType*>(pType2)->SetValue(m_pImpl->m_fParam1);
673                 static_cast<SwUserFieldType*>(pType2)->SetType(m_pImpl->m_bParam1
674                     ? nsSwGetSetExpType::GSE_EXPR : nsSwGetSetExpType::GSE_STRING);
675             }
676             break;
677             case SwFieldIds::Dde :
678             {
679                 SwDDEFieldType aType(sTypeName, m_pImpl->m_sParam1,
680                     m_pImpl->m_bParam1 ? SfxLinkUpdateMode::ALWAYS : SfxLinkUpdateMode::ONCALL);
681                 pType2 = m_pImpl->m_pDoc->getIDocumentFieldsAccess().InsertFieldType(aType);
682             }
683             break;
684             case SwFieldIds::SetExp :
685             {
686                 SwSetExpFieldType aType(m_pImpl->m_pDoc, sTypeName);
687                 if (!m_pImpl->m_sParam1.isEmpty())
688                     aType.SetDelimiter(OUString(m_pImpl->m_sParam1[0]));
689                 if (m_pImpl->m_nParam1 > -1 && m_pImpl->m_nParam1 < MAXLEVEL)
690                     aType.SetOutlineLvl(m_pImpl->m_nParam1);
691                 pType2 = m_pImpl->m_pDoc->getIDocumentFieldsAccess().InsertFieldType(aType);
692             }
693             break;
694             case SwFieldIds::Database :
695             {
696                 rValue >>= m_pImpl->m_sParam3;
697                 pType2 = GetFieldType();
698             }
699             break;
700             default: break;
701         }
702         if (!pType2)
703         {
704             throw uno::RuntimeException("no field type found!", *this);
705         }
706         m_pImpl->SetFieldType(pType2);
707     }
708     else
709     {
710         switch (m_pImpl->m_nResTypeId)
711         {
712         case SwFieldIds::User:
713             if(rPropertyName == UNO_NAME_CONTENT)
714                 rValue >>= m_pImpl->m_sParam1;
715             else if(rPropertyName == UNO_NAME_VALUE)
716             {
717                 if(rValue.getValueType() != ::cppu::UnoType<double>::get())
718                     throw lang::IllegalArgumentException();
719                 rValue >>= m_pImpl->m_fParam1;
720             }
721             else if(rPropertyName == UNO_NAME_IS_EXPRESSION)
722             {
723                 if(rValue.getValueType() != cppu::UnoType<bool>::get())
724                     throw lang::IllegalArgumentException();
725                 rValue >>= m_pImpl->m_bParam1;
726             }
727 
728             break;
729         case SwFieldIds::Database:
730             if(rPropertyName == UNO_NAME_DATA_BASE_NAME)
731                 rValue >>= m_pImpl->m_sParam1;
732             else if(rPropertyName == UNO_NAME_DATA_TABLE_NAME)
733                 rValue >>= m_pImpl->m_sParam2;
734             else if(rPropertyName == UNO_NAME_DATA_COLUMN_NAME)
735                 rValue >>= m_pImpl->m_sParam3;
736             else if(rPropertyName == UNO_NAME_DATA_COMMAND_TYPE)
737                 rValue >>= m_pImpl->m_nParam2;
738             if(rPropertyName == UNO_NAME_DATA_BASE_URL)
739                 rValue >>= m_pImpl->m_sParam5;
740 
741             if (  (   !m_pImpl->m_sParam1.isEmpty()
742                    || !m_pImpl->m_sParam5.isEmpty())
743                 && !m_pImpl->m_sParam2.isEmpty()
744                 && !m_pImpl->m_sParam3.isEmpty())
745             {
746                 GetFieldType();
747             }
748             break;
749         case  SwFieldIds::SetExp:
750             if(rPropertyName == UNO_NAME_NUMBERING_SEPARATOR)
751                 rValue >>= m_pImpl->m_sParam1;
752             else if(rPropertyName == UNO_NAME_CHAPTER_NUMBERING_LEVEL)
753                 rValue >>= m_pImpl->m_nParam1;
754             break;
755         case SwFieldIds::Dde:
756             {
757                 sal_Int32 nPart = lcl_PropName2TokenPos(rPropertyName);
758                 if(nPart  < 3 )
759                 {
760                     if (m_pImpl->m_sParam1.isEmpty())
761                     {
762                         m_pImpl->m_sParam1
763                             = OUStringLiteral1(sfx2::cTokenSeparator)
764                             + OUStringLiteral1(sfx2::cTokenSeparator);
765                     }
766                     OUString sTmp;
767                     rValue >>= sTmp;
768                     sal_Int32 nIndex(0);
769                     sal_Int32 nStart(0);
770                     while (nIndex < m_pImpl->m_sParam1.getLength())
771                     {
772                         if (m_pImpl->m_sParam1[nIndex] == sfx2::cTokenSeparator)
773                         {
774                             if (0 == nPart)
775                                 break;
776                             nStart = nIndex + 1;
777                             --nPart;
778                         }
779                         ++nIndex;
780                     }
781                     assert(0 == nPart);
782                     m_pImpl->m_sParam1 = m_pImpl->m_sParam1.replaceAt(
783                             nStart, nIndex - nStart, sTmp);
784                 }
785                 else if(3 == nPart)
786                 {
787                     rValue >>= m_pImpl->m_bParam1;
788                 }
789             }
790             break;
791         default:
792             throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
793         }
794     }
795 }
796 
797 SwFieldType* SwXFieldMaster::GetFieldType(bool const bDontCreate) const
798 {
799     if (!bDontCreate && SwFieldIds::Database == m_pImpl->m_nResTypeId
800         && !m_pImpl->m_pType && m_pImpl->m_pDoc)
801     {
802         SwDBData aData;
803 
804         // set DataSource
805         svx::ODataAccessDescriptor aAcc;
806         if (!m_pImpl->m_sParam1.isEmpty())
807             aAcc[svx::DataAccessDescriptorProperty::DataSource]        <<= m_pImpl->m_sParam1; // DataBaseName
808         else if (!m_pImpl->m_sParam5.isEmpty())
809             aAcc[svx::DataAccessDescriptorProperty::DatabaseLocation]  <<= m_pImpl->m_sParam5; // DataBaseURL
810         aData.sDataSource = aAcc.getDataSource();
811 
812         aData.sCommand = m_pImpl->m_sParam2;
813         aData.nCommandType = m_pImpl->m_nParam2;
814 
815         SwDBFieldType aType(m_pImpl->m_pDoc, m_pImpl->m_sParam3, aData);
816         SwFieldType *const pType = m_pImpl->m_pDoc->getIDocumentFieldsAccess().InsertFieldType(aType);
817         m_pImpl->SetFieldType(pType);
818     }
819     return m_pImpl->m_pType;
820 }
821 
822 uno::Any SAL_CALL
823 SwXFieldMaster::getPropertyValue(const OUString& rPropertyName)
824 {
825     SolarMutexGuard aGuard;
826     uno::Any aRet;
827     SwFieldType* pType = GetFieldType(true);
828     if( rPropertyName == UNO_NAME_INSTANCE_NAME )
829     {
830         OUString sName;
831         if(pType)
832             SwXTextFieldMasters::getInstanceName(*pType, sName);
833         aRet <<= sName;
834     }
835     else if(pType)
836     {
837         if(rPropertyName == UNO_NAME_NAME)
838         {
839             aRet <<= SwXFieldMaster::GetProgrammaticName(*pType, *m_pImpl->m_pDoc);
840         }
841         else if(rPropertyName == UNO_NAME_DEPENDENT_TEXT_FIELDS)
842         {
843             //fill all text fields into a sequence
844             std::vector<SwFormatField*>  aFieldArr;
845             SwIterator<SwFormatField,SwFieldType> aIter( *pType );
846             SwFormatField* pField = aIter.First();
847             while(pField)
848             {
849                 if(pField->IsFieldInDoc())
850                     aFieldArr.push_back(pField);
851                 pField = aIter.Next();
852             }
853 
854             uno::Sequence<uno::Reference <text::XDependentTextField> > aRetSeq(aFieldArr.size());
855             uno::Reference<text::XDependentTextField>* pRetSeq = aRetSeq.getArray();
856             for(size_t i = 0; i < aFieldArr.size(); ++i)
857             {
858                 pField = aFieldArr[i];
859                 uno::Reference<text::XTextField> const xField =
860                     SwXTextField::CreateXTextField(m_pImpl->m_pDoc, pField);
861 
862                 pRetSeq[i].set(xField, uno::UNO_QUERY);
863             }
864             aRet <<= aRetSeq;
865         }
866         else
867         {
868             //TODO: add properties for the other field types
869             const sal_uInt16 nMId = GetFieldTypeMId( rPropertyName, *pType );
870             if (USHRT_MAX == nMId)
871             {
872                 throw beans::UnknownPropertyException(
873                         "Unknown property: " + rPropertyName,
874                         static_cast<cppu::OWeakObject *>(this));
875             }
876             pType->QueryValue( aRet, nMId );
877 
878             if (rPropertyName == UNO_NAME_DATA_BASE_NAME ||
879                 rPropertyName == UNO_NAME_DATA_BASE_URL)
880             {
881                 OUString aDataSource;
882                 aRet >>= aDataSource;
883                 aRet <<= OUString();
884 
885                 OUString *pStr = nullptr;     // only one of this properties will return
886                                         // a non-empty string.
887                 INetURLObject aObj;
888                 aObj.SetURL( aDataSource );
889                 bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid;
890                 if (bIsURL && rPropertyName == UNO_NAME_DATA_BASE_URL)
891                     pStr = &aDataSource;        // DataBaseURL
892                 else if (!bIsURL && rPropertyName == UNO_NAME_DATA_BASE_NAME)
893                     pStr = &aDataSource;        // DataBaseName
894 
895                 if (pStr)
896                     aRet <<= *pStr;
897             }
898         }
899     }
900     else
901     {
902         if(rPropertyName == UNO_NAME_DATA_COMMAND_TYPE)
903             aRet <<= m_pImpl->m_nParam2;
904         else if(rPropertyName == UNO_NAME_DEPENDENT_TEXT_FIELDS )
905         {
906             uno::Sequence<uno::Reference <text::XDependentTextField> > aRetSeq(0);
907             aRet <<= aRetSeq;
908         }
909         else
910         {
911             switch (m_pImpl->m_nResTypeId)
912             {
913             case SwFieldIds::User:
914                 if( rPropertyName == UNO_NAME_CONTENT )
915                     aRet <<= m_pImpl->m_sParam1;
916                 else if(rPropertyName == UNO_NAME_VALUE)
917                     aRet <<= m_pImpl->m_fParam1;
918                 else if(rPropertyName == UNO_NAME_IS_EXPRESSION)
919                     aRet <<= m_pImpl->m_bParam1;
920                 break;
921             case SwFieldIds::Database:
922                 if(rPropertyName == UNO_NAME_DATA_BASE_NAME ||
923                    rPropertyName == UNO_NAME_DATA_BASE_URL)
924                 {
925                      // only one of these properties returns a non-empty string.
926                     INetURLObject aObj;
927                     aObj.SetURL(m_pImpl->m_sParam5); // SetSmartURL
928                     bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid;
929                     if (bIsURL && rPropertyName == UNO_NAME_DATA_BASE_URL)
930                         aRet <<= m_pImpl->m_sParam5; // DataBaseURL
931                     else if ( rPropertyName == UNO_NAME_DATA_BASE_NAME)
932                         aRet <<= m_pImpl->m_sParam1; // DataBaseName
933                 }
934                 else if(rPropertyName == UNO_NAME_DATA_TABLE_NAME)
935                     aRet <<= m_pImpl->m_sParam2;
936                 else if(rPropertyName == UNO_NAME_DATA_COLUMN_NAME)
937                     aRet <<= m_pImpl->m_sParam3;
938                 break;
939             case SwFieldIds::SetExp:
940                 if(rPropertyName == UNO_NAME_NUMBERING_SEPARATOR)
941                     aRet <<= m_pImpl->m_sParam1;
942                 else if(rPropertyName == UNO_NAME_CHAPTER_NUMBERING_LEVEL)
943                     aRet <<= m_pImpl->m_nParam1;
944                 break;
945             case SwFieldIds::Dde:
946                 {
947                     const sal_Int32 nPart = lcl_PropName2TokenPos(rPropertyName);
948                     if(nPart  < 3 )
949                         aRet <<= m_pImpl->m_sParam1.getToken(nPart, sfx2::cTokenSeparator);
950                     else if(3 == nPart)
951                         aRet <<= m_pImpl->m_bParam1;
952                 }
953                 break;
954             default:
955                 throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
956             }
957         }
958     }
959     return aRet;
960 }
961 
962 void SwXFieldMaster::addPropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
963 {
964     OSL_FAIL("not implemented");
965 }
966 
967 void SwXFieldMaster::removePropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
968 {
969     OSL_FAIL("not implemented");
970 }
971 
972 void SwXFieldMaster::addVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
973 {
974     OSL_FAIL("not implemented");
975 }
976 
977 void SwXFieldMaster::removeVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
978 {
979     OSL_FAIL("not implemented");
980 }
981 
982 void SAL_CALL SwXFieldMaster::dispose()
983 {
984     SolarMutexGuard aGuard;
985     SwFieldType *const pFieldType = GetFieldType(true);
986     if (!pFieldType)
987         throw uno::RuntimeException();
988     size_t nTypeIdx = SIZE_MAX;
989     const SwFieldTypes* pTypes = m_pImpl->m_pDoc->getIDocumentFieldsAccess().GetFieldTypes();
990     for( size_t i = 0; i < pTypes->size(); i++ )
991     {
992         if((*pTypes)[i].get()== pFieldType)
993             nTypeIdx = i;
994     }
995 
996     // first delete all fields
997     SwIterator<SwFormatField,SwFieldType> aIter( *pFieldType );
998     SwFormatField* pField = aIter.First();
999     while(pField)
1000     {
1001         SwTextField *pTextField = pField->GetTextField();
1002         if(pTextField && pTextField->GetTextNode().GetNodes().IsDocNodes() )
1003         {
1004             SwTextField::DeleteTextField(*pTextField);
1005         }
1006         pField = aIter.Next();
1007     }
1008     // then delete FieldType
1009     m_pImpl->m_pDoc->getIDocumentFieldsAccess().RemoveFieldType(nTypeIdx);
1010 }
1011 
1012 void SAL_CALL SwXFieldMaster::addEventListener(
1013         const uno::Reference<lang::XEventListener> & xListener)
1014 {
1015     // no need to lock here as m_pImpl is const and container threadsafe
1016     m_pImpl->m_EventListeners.addInterface(xListener);
1017 }
1018 
1019 void SAL_CALL SwXFieldMaster::removeEventListener(
1020         const uno::Reference<lang::XEventListener> & xListener)
1021 {
1022     // no need to lock here as m_pImpl is const and container threadsafe
1023     m_pImpl->m_EventListeners.removeInterface(xListener);
1024 }
1025 
1026 void SwXFieldMaster::Impl::Notify(const SfxHint& rHint)
1027 {
1028     if(rHint.GetId() == SfxHintId::Dying)
1029     {
1030         m_pDoc = nullptr;
1031         m_pType = nullptr;
1032         uno::Reference<uno::XInterface> const xThis(m_wThis);
1033         if (!xThis.is())
1034         {   // fdo#72695: if UNO object is already dead, don't revive it with event
1035             return;
1036         }
1037         lang::EventObject const ev(xThis);
1038         m_EventListeners.disposeAndClear(ev);
1039     }
1040 }
1041 
1042 OUString SwXFieldMaster::GetProgrammaticName(const SwFieldType& rType, SwDoc& rDoc)
1043 {
1044     const OUString sName(rType.GetName());
1045     if(SwFieldIds::SetExp == rType.Which())
1046     {
1047         const SwFieldTypes* pTypes = rDoc.getIDocumentFieldsAccess().GetFieldTypes();
1048         for( size_t i = 0; i <= size_t(INIT_FLDTYPES); i++ )
1049         {
1050             if((*pTypes)[i].get() == &rType)
1051             {
1052                 return SwStyleNameMapper::GetProgName( sName, SwGetPoolIdFromName::TxtColl );
1053             }
1054         }
1055     }
1056     return sName;
1057 }
1058 
1059 OUString SwXFieldMaster::LocalizeFormula(
1060     const SwSetExpField& rField,
1061     const OUString& rFormula,
1062     bool bQuery)
1063 {
1064     const OUString sTypeName(rField.GetTyp()->GetName());
1065     const OUString sProgName(
1066         SwStyleNameMapper::GetProgName(sTypeName, SwGetPoolIdFromName::TxtColl ));
1067     if(sProgName != sTypeName)
1068     {
1069         const OUString sSource = bQuery ? sTypeName : sProgName;
1070         const OUString sDest = bQuery ? sProgName : sTypeName;
1071         if(rFormula.startsWith(sSource))
1072         {
1073             return sDest + rFormula.copy(sSource.getLength());
1074         }
1075     }
1076     return rFormula;
1077 }
1078 
1079 struct SwFieldProperties_Impl
1080 {
1081     OUString    sPar1;
1082     OUString    sPar2;
1083     OUString    sPar3;
1084     OUString    sPar4;
1085     Date            aDate;
1086     double          fDouble;
1087     uno::Sequence<beans::PropertyValue> aPropSeq;
1088     uno::Sequence<OUString> aStrings;
1089     std::unique_ptr<util::DateTime> pDateTime;
1090 
1091     sal_Int32       nSubType;
1092     sal_Int32       nFormat;
1093     sal_uInt16      nUSHORT1;
1094     sal_uInt16      nUSHORT2;
1095     sal_Int16       nSHORT1;
1096     sal_Int8        nByte1;
1097     bool            bFormatIsDefault;
1098     bool        bBool1;
1099     bool        bBool2;
1100     bool        bBool3;
1101     bool        bBool4;
1102 
1103     SwFieldProperties_Impl():
1104         aDate( Date::EMPTY ),
1105         fDouble(0.),
1106         nSubType(0),
1107         nFormat(0),
1108         nUSHORT1(0),
1109         nUSHORT2(0),
1110         nSHORT1(0),
1111         nByte1(0),
1112         bFormatIsDefault(true),
1113         bBool1(false),
1114         bBool2(false),
1115         bBool3(false),
1116         bBool4(true) //Automatic language
1117         {}
1118 };
1119 
1120 class SwXTextField::Impl
1121     : public SvtListener
1122 {
1123 private:
1124     ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
1125     SwFieldType* m_pFieldType;
1126     SwFormatField* m_pFormatField;
1127 
1128 public:
1129     uno::WeakReference<uno::XInterface> m_wThis;
1130     ::comphelper::OInterfaceContainerHelper2 m_EventListeners;
1131 
1132     SwDoc* m_pDoc;
1133     rtl::Reference<SwTextAPIObject> m_xTextObject;
1134     bool m_bCallUpdate;
1135     SwServiceType const m_nServiceId;
1136     OUString m_sTypeName;
1137     std::unique_ptr<SwFieldProperties_Impl> m_pProps;
1138 
1139     Impl(SwDoc *const pDoc, SwFormatField *const pFormat, SwServiceType nServiceId)
1140         : m_pFormatField(pFormat)
1141         , m_EventListeners(m_Mutex)
1142         , m_pDoc(pDoc)
1143         , m_bCallUpdate(false)
1144         , m_nServiceId(pFormat
1145                 ? lcl_GetServiceForField(*pFormat->GetField())
1146                 : nServiceId)
1147         , m_pProps(pFormat ? nullptr : new SwFieldProperties_Impl)
1148     {
1149         if(m_pFormatField)
1150             StartListening(m_pFormatField->GetNotifier());
1151     }
1152 
1153     virtual ~Impl() override
1154     {
1155         if (m_xTextObject.is())
1156         {
1157             m_xTextObject->DisposeEditSource();
1158         }
1159     }
1160 
1161     void SetFormatField(SwFormatField* pFormatField, SwDoc* pDoc)
1162     {
1163         m_pFormatField = pFormatField;
1164         m_pDoc = pDoc;
1165         if(m_pFormatField)
1166         {
1167             EndListeningAll();
1168             StartListening(m_pFormatField->GetNotifier());
1169         }
1170     }
1171     SwFormatField* GetFormatField()
1172     {
1173         return m_pFormatField;
1174     }
1175     bool IsDescriptor() const
1176     {
1177         return !m_pFormatField;
1178     }
1179     void Invalidate();
1180 
1181     const SwField* GetField() const;
1182 
1183     SwFieldType* GetFieldType() const
1184     {
1185         if (IsDescriptor())
1186             return m_pFieldType;
1187         return m_pFormatField->GetField()->GetTyp();
1188     }
1189     void SetFieldType(SwFieldType& rType)
1190     {
1191         EndListeningAll();
1192         m_pFieldType = &rType;
1193         StartListening(m_pFieldType->GetNotifier());
1194     }
1195     void ClearFieldType()
1196     {
1197         SvtListener::EndListeningAll();
1198         m_pFieldType = nullptr;
1199     }
1200     virtual void Notify(const SfxHint&) override;
1201 };
1202 
1203 namespace
1204 {
1205     class theSwXTextFieldUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextFieldUnoTunnelId > {};
1206 }
1207 
1208 const uno::Sequence< sal_Int8 > & SwXTextField::getUnoTunnelId()
1209 {
1210     return theSwXTextFieldUnoTunnelId::get().getSeq();
1211 }
1212 
1213 sal_Int64 SAL_CALL
1214 SwXTextField::getSomething(const uno::Sequence< sal_Int8 >& rId)
1215 {
1216     return ::sw::UnoTunnelImpl<SwXTextField>(rId, this);
1217 }
1218 
1219 SwXTextField::SwXTextField(
1220     SwServiceType nServiceId,
1221     SwDoc* pDoc)
1222     : m_pImpl(new Impl(pDoc, nullptr, nServiceId))
1223 {
1224     //Set visible as default!
1225     if ( SwServiceType::FieldTypeSetExp == nServiceId
1226          || SwServiceType::FieldTypeDatabaseSetNum == nServiceId
1227          || SwServiceType::FieldTypeDatabase == nServiceId
1228          || SwServiceType::FieldTypeDatabaseName == nServiceId )
1229     {
1230         m_pImpl->m_pProps->bBool2 = true;
1231     }
1232     else if(SwServiceType::FieldTypeTableFormula == nServiceId)
1233     {
1234         m_pImpl->m_pProps->bBool1 = true;
1235     }
1236     if(SwServiceType::FieldTypeSetExp == nServiceId)
1237     {
1238         m_pImpl->m_pProps->nUSHORT2 = USHRT_MAX;
1239     }
1240 }
1241 
1242 SwXTextField::SwXTextField(SwFormatField& rFormat, SwDoc & rDoc)
1243     : m_pImpl(new Impl(&rDoc, &rFormat, SwServiceType::Invalid))
1244 {
1245 }
1246 
1247 SwXTextField::~SwXTextField()
1248 {
1249 }
1250 
1251 uno::Reference<text::XTextField>
1252 SwXTextField::CreateXTextField(SwDoc *const pDoc, SwFormatField const* pFormat,
1253         SwServiceType nServiceId)
1254 {
1255     assert(!pFormat || pDoc);
1256     assert(pFormat || nServiceId != SwServiceType::Invalid);
1257     // re-use existing SwXTextField
1258     uno::Reference<text::XTextField> xField;
1259     if (pFormat)
1260     {
1261         xField = pFormat->GetXTextField();
1262     }
1263     if (!xField.is())
1264     {
1265         SwXTextField *const pField( pFormat
1266                 ? new SwXTextField(const_cast<SwFormatField&>(*pFormat), *pDoc)
1267                 : new SwXTextField(nServiceId, pDoc));
1268         xField.set(pField);
1269         if (pFormat)
1270         {
1271             const_cast<SwFormatField *>(pFormat)->SetXTextField(xField);
1272         }
1273         // need a permanent Reference to initialize m_wThis
1274         pField->m_pImpl->m_wThis = xField;
1275     }
1276     return xField;
1277 }
1278 
1279 SwServiceType SwXTextField::GetServiceId() const
1280 {
1281     return m_pImpl->m_nServiceId;
1282 }
1283 
1284 /** Convert between SwSetExpField with InputFlag false and InputFlag true.
1285     Unfortunately the InputFlag is exposed in the API as "Input" property
1286     and is mutable; in the UI and in ODF these are 2 different types of
1287     fields, so the API design is very questionable.
1288     In order to keep the mutable property, the whole thing has to be
1289     reconstructed from scratch, to replace the SwTextField hint with
1290     SwTextInputField or vice versa.
1291     The SwFormatField will be replaced - it must be, because the Which
1292     changes - but the SwXTextField *must not* be disposed in the operation,
1293     it has to be disconnected first and at the end connected to the
1294     new instance!
1295  */
1296 void SwXTextField::TransmuteLeadToInputField(SwSetExpField & rField)
1297 {
1298     assert(rField.GetFormatField()->Which() == (rField.GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD));
1299     uno::Reference<text::XTextField> const xField(
1300         rField.GetFormatField()->GetXTextField());
1301     SwXTextField *const pXField = xField.is()
1302         ? reinterpret_cast<SwXTextField*>(
1303             sal::static_int_cast<sal_IntPtr>(
1304                 uno::Reference<lang::XUnoTunnel>(xField, uno::UNO_QUERY_THROW)
1305                     ->getSomething(getUnoTunnelId())))
1306         : nullptr;
1307     if (pXField)
1308         pXField->m_pImpl->SetFormatField(nullptr, nullptr);
1309     SwTextField *const pOldAttr(rField.GetFormatField()->GetTextField());
1310     SwSetExpField tempField(rField);
1311     tempField.SetInputFlag(!rField.GetInputFlag());
1312     SwFormatField tempFormat(tempField);
1313     assert(tempFormat.GetField() != &rField);
1314     assert(tempFormat.GetField() != &tempField); // this copies it again?
1315     assert(tempFormat.Which() == (static_cast<SwSetExpField const*>(tempFormat.GetField())->GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD));
1316     SwTextNode & rNode(pOldAttr->GetTextNode());
1317     std::shared_ptr<SwPaM> pPamForTextField;
1318     IDocumentContentOperations & rIDCO(rNode.GetDoc()->getIDocumentContentOperations());
1319     SwTextField::GetPamForTextField(*pOldAttr, pPamForTextField);
1320     assert(pPamForTextField);
1321     sal_Int32 const nStart(pPamForTextField->Start()->nContent.GetIndex());
1322     rIDCO.DeleteAndJoin(*pPamForTextField);
1323     // ATTENTION: rField is dead now! hope nobody accesses it...
1324     bool bSuccess = rIDCO.InsertPoolItem(*pPamForTextField, tempFormat);
1325     assert(bSuccess);
1326     (void) bSuccess;
1327     SwTextField const* pNewAttr(rNode.GetFieldTextAttrAt(nStart, true));
1328     assert(pNewAttr);
1329     SwFormatField const& rNewFormat(pNewAttr->GetFormatField());
1330     assert(rNewFormat.Which() == (static_cast<SwSetExpField const*>(rNewFormat.GetField())->GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD));
1331     assert(static_cast<SwSetExpField const*>(rNewFormat.GetField())->GetInputFlag() == (dynamic_cast<SwTextInputField const*>(pNewAttr) != nullptr));
1332     if (xField.is())
1333     {
1334         pXField->m_pImpl->SetFormatField(const_cast<SwFormatField*>(&rNewFormat), rNode.GetDoc());
1335         const_cast<SwFormatField&>(rNewFormat).SetXTextField(xField);
1336     }
1337 }
1338 
1339 void SAL_CALL SwXTextField::attachTextFieldMaster(
1340         const uno::Reference< beans::XPropertySet > & xFieldMaster)
1341 {
1342     SolarMutexGuard aGuard;
1343 
1344     if (!m_pImpl->IsDescriptor())
1345         throw uno::RuntimeException();
1346     uno::Reference< lang::XUnoTunnel > xMasterTunnel(xFieldMaster, uno::UNO_QUERY);
1347     if (!xMasterTunnel.is())
1348         throw lang::IllegalArgumentException();
1349     SwXFieldMaster* pMaster = reinterpret_cast< SwXFieldMaster * >(
1350             sal::static_int_cast< sal_IntPtr >( xMasterTunnel->getSomething( SwXFieldMaster::getUnoTunnelId()) ));
1351 
1352     SwFieldType* pFieldType = pMaster ? pMaster->GetFieldType() : nullptr;
1353     if (!pFieldType ||
1354         pFieldType->Which() != lcl_ServiceIdToResId(m_pImpl->m_nServiceId))
1355     {
1356         throw lang::IllegalArgumentException();
1357     }
1358     m_pImpl->m_sTypeName = pFieldType->GetName();
1359     m_pImpl->SetFieldType(*pFieldType);
1360 }
1361 
1362 uno::Reference< beans::XPropertySet > SAL_CALL
1363 SwXTextField::getTextFieldMaster()
1364 {
1365     SolarMutexGuard aGuard;
1366     SwFieldType* pType = m_pImpl->GetFieldType();
1367     uno::Reference<beans::XPropertySet> const xRet(
1368             SwXFieldMaster::CreateXFieldMaster(m_pImpl->m_pDoc, pType));
1369     return xRet;
1370 }
1371 
1372 OUString SAL_CALL SwXTextField::getPresentation(sal_Bool bShowCommand)
1373 {
1374     SolarMutexGuard aGuard;
1375 
1376     SwField const*const pField = m_pImpl->GetField();
1377     if (!pField)
1378     {
1379         throw uno::RuntimeException();
1380     }
1381     return bShowCommand ? pField->GetFieldName() : pField->ExpandField(true, nullptr);
1382 }
1383 
1384 void SAL_CALL SwXTextField::attach(
1385         const uno::Reference< text::XTextRange > & xTextRange)
1386 {
1387     SolarMutexGuard aGuard;
1388     if (m_pImpl->IsDescriptor())
1389     {
1390     uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
1391     SwXTextRange* pRange = nullptr;
1392     OTextCursorHelper* pCursor = nullptr;
1393     if(xRangeTunnel.is())
1394     {
1395         pRange  = reinterpret_cast< SwXTextRange * >(
1396                 sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXTextRange::getUnoTunnelId()) ));
1397         pCursor = reinterpret_cast< OTextCursorHelper * >(
1398                 sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( OTextCursorHelper::getUnoTunnelId()) ));
1399     }
1400 
1401     SwDoc* pDoc = pRange ? &pRange->GetDoc() : pCursor ? pCursor->GetDoc() : nullptr;
1402     // if a FieldMaster was attached, then the document is already fixed!
1403     // NOTE: sw.SwXAutoTextEntry unoapi test depends on m_pDoc = 0 being valid
1404     if (!pDoc || (m_pImpl->m_pDoc && m_pImpl->m_pDoc != pDoc))
1405         throw lang::IllegalArgumentException();
1406 
1407     SwUnoInternalPaM aPam(*pDoc);
1408     // this now needs to return TRUE
1409     ::sw::XTextRangeToSwPaM(aPam, xTextRange);
1410     std::unique_ptr<SwField> xField;
1411     switch (m_pImpl->m_nServiceId)
1412     {
1413         case SwServiceType::FieldTypeAnnotation:
1414             {
1415                 SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Postit);
1416 
1417                 DateTime aDateTime( DateTime::EMPTY );
1418                 if (m_pImpl->m_pProps->pDateTime)
1419                 {
1420                     aDateTime = *(m_pImpl->m_pProps->pDateTime);
1421                 }
1422                 SwPostItField* pPostItField = new SwPostItField(
1423                     static_cast<SwPostItFieldType*>(pFieldType),
1424                     m_pImpl->m_pProps->sPar1, // author
1425                     m_pImpl->m_pProps->sPar2, // content
1426                     m_pImpl->m_pProps->sPar3, // author's initials
1427                     m_pImpl->m_pProps->sPar4, // name
1428                     aDateTime );
1429                 if ( m_pImpl->m_xTextObject.is() )
1430                 {
1431                     pPostItField->SetTextObject( m_pImpl->m_xTextObject->CreateText() );
1432                     pPostItField->SetPar2(m_pImpl->m_xTextObject->GetText());
1433                 }
1434                 xField.reset(pPostItField);
1435             }
1436             break;
1437         case SwServiceType::FieldTypeScript:
1438         {
1439             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Script);
1440             xField.reset(new SwScriptField(static_cast<SwScriptFieldType*>(pFieldType),
1441                     m_pImpl->m_pProps->sPar1, m_pImpl->m_pProps->sPar2,
1442                     m_pImpl->m_pProps->bBool1));
1443         }
1444         break;
1445         case SwServiceType::FieldTypeDateTime:
1446         {
1447             sal_uInt16 nSub = 0;
1448             if (m_pImpl->m_pProps->bBool1)
1449                 nSub |= FIXEDFLD;
1450             if (m_pImpl->m_pProps->bBool2)
1451                 nSub |= DATEFLD;
1452             else
1453                 nSub |= TIMEFLD;
1454             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DateTime);
1455             SwDateTimeField *const pDTField = new SwDateTimeField(
1456                     static_cast<SwDateTimeFieldType*>(pFieldType),
1457                         nSub, m_pImpl->m_pProps->nFormat);
1458             xField.reset(pDTField);
1459             if (m_pImpl->m_pProps->fDouble > 0.)
1460             {
1461                 pDTField->SetValue(m_pImpl->m_pProps->fDouble);
1462             }
1463             if (m_pImpl->m_pProps->pDateTime)
1464             {
1465                 uno::Any aVal; aVal <<= *m_pImpl->m_pProps->pDateTime;
1466                 xField->PutValue( aVal, FIELD_PROP_DATE_TIME );
1467             }
1468             pDTField->SetOffset(m_pImpl->m_pProps->nSubType);
1469         }
1470         break;
1471         case SwServiceType::FieldTypeFileName:
1472         {
1473             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Filename);
1474             sal_Int32 nFormat = m_pImpl->m_pProps->nFormat;
1475             if (m_pImpl->m_pProps->bBool2)
1476                 nFormat |= FF_FIXED;
1477             SwFileNameField *const pFNField = new SwFileNameField(
1478                     static_cast<SwFileNameFieldType*>(pFieldType), nFormat);
1479             xField.reset(pFNField);
1480             if (!m_pImpl->m_pProps->sPar3.isEmpty())
1481                 pFNField->SetExpansion(m_pImpl->m_pProps->sPar3);
1482             uno::Any aFormat;
1483             aFormat <<= m_pImpl->m_pProps->nFormat;
1484             xField->PutValue( aFormat, FIELD_PROP_FORMAT );
1485         }
1486         break;
1487         case SwServiceType::FieldTypeTemplateName:
1488         {
1489             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::TemplateName);
1490             xField.reset(new SwTemplNameField(static_cast<SwTemplNameFieldType*>(pFieldType),
1491                                         m_pImpl->m_pProps->nFormat));
1492             uno::Any aFormat;
1493             aFormat <<= m_pImpl->m_pProps->nFormat;
1494             xField->PutValue(aFormat, FIELD_PROP_FORMAT);
1495         }
1496         break;
1497         case SwServiceType::FieldTypeChapter:
1498         {
1499             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Chapter);
1500             SwChapterField *const pChapterField = new SwChapterField(
1501                     static_cast<SwChapterFieldType*>(pFieldType),
1502                     m_pImpl->m_pProps->nUSHORT1);
1503             xField.reset(pChapterField);
1504             pChapterField->SetLevel(m_pImpl->m_pProps->nByte1);
1505             uno::Any aVal;
1506             aVal <<= static_cast<sal_Int16>(m_pImpl->m_pProps->nUSHORT1);
1507             xField->PutValue(aVal, FIELD_PROP_USHORT1 );
1508         }
1509         break;
1510         case SwServiceType::FieldTypeAuthor:
1511         {
1512             long nFormat = m_pImpl->m_pProps->bBool1 ? AF_NAME : AF_SHORTCUT;
1513             if (m_pImpl->m_pProps->bBool2)
1514                 nFormat |= AF_FIXED;
1515 
1516             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Author);
1517             SwAuthorField *const pAuthorField = new SwAuthorField(
1518                     static_cast<SwAuthorFieldType*>(pFieldType), nFormat);
1519             xField.reset(pAuthorField);
1520             pAuthorField->SetExpansion(m_pImpl->m_pProps->sPar1);
1521         }
1522         break;
1523         case SwServiceType::FieldTypeConditionedText:
1524         case SwServiceType::FieldTypeHiddenText:
1525         {
1526             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::HiddenText);
1527             SwHiddenTextField *const pHTField = new SwHiddenTextField(
1528                     static_cast<SwHiddenTextFieldType*>(pFieldType),
1529                     m_pImpl->m_pProps->sPar1,
1530                     m_pImpl->m_pProps->sPar2, m_pImpl->m_pProps->sPar3,
1531                     static_cast<sal_uInt16>(SwServiceType::FieldTypeHiddenText == m_pImpl->m_nServiceId ?
1532                          TYP_HIDDENTXTFLD : TYP_CONDTXTFLD));
1533             xField.reset(pHTField);
1534             pHTField->SetValue(m_pImpl->m_pProps->bBool1);
1535             uno::Any aVal;
1536             aVal <<= m_pImpl->m_pProps->sPar4;
1537             xField->PutValue(aVal, FIELD_PROP_PAR4 );
1538         }
1539         break;
1540         case SwServiceType::FieldTypeHiddenPara:
1541         {
1542             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::HiddenPara);
1543             SwHiddenParaField *const pHPField = new SwHiddenParaField(
1544                     static_cast<SwHiddenParaFieldType*>(pFieldType),
1545                     m_pImpl->m_pProps->sPar1);
1546             xField.reset(pHPField);
1547             pHPField->SetHidden(m_pImpl->m_pProps->bBool1);
1548         }
1549         break;
1550         case SwServiceType::FieldTypeGetReference:
1551         {
1552             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::GetRef);
1553             xField.reset(new SwGetRefField(static_cast<SwGetRefFieldType*>(pFieldType),
1554                         m_pImpl->m_pProps->sPar1,
1555                         m_pImpl->m_pProps->sPar4,
1556                         0,
1557                         0,
1558                         0));
1559             if (!m_pImpl->m_pProps->sPar3.isEmpty())
1560                 static_cast<SwGetRefField*>(xField.get())->SetExpand(m_pImpl->m_pProps->sPar3);
1561             uno::Any aVal;
1562             aVal <<= static_cast<sal_Int16>(m_pImpl->m_pProps->nUSHORT1);
1563             xField->PutValue(aVal, FIELD_PROP_USHORT1 );
1564             aVal <<= static_cast<sal_Int16>(m_pImpl->m_pProps->nUSHORT2);
1565             xField->PutValue(aVal, FIELD_PROP_USHORT2 );
1566             aVal <<= m_pImpl->m_pProps->nSHORT1;
1567             xField->PutValue(aVal, FIELD_PROP_SHORT1 );
1568         }
1569         break;
1570         case SwServiceType::FieldTypeJumpEdit:
1571         {
1572             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::JumpEdit);
1573             xField.reset(new SwJumpEditField(static_cast<SwJumpEditFieldType*>(pFieldType),
1574                     m_pImpl->m_pProps->nUSHORT1, m_pImpl->m_pProps->sPar2,
1575                     m_pImpl->m_pProps->sPar1));
1576         }
1577         break;
1578         case SwServiceType::FieldTypeDocInfoChangeAuthor:
1579         case SwServiceType::FieldTypeDocInfoChangeDateTime:
1580         case SwServiceType::FieldTypeDocInfoEditTime:
1581         case SwServiceType::FieldTypeDocInfoDescription:
1582         case SwServiceType::FieldTypeDocInfoCreateAuthor:
1583         case SwServiceType::FieldTypeDocInfoCreateDateTime:
1584         case SwServiceType::FieldTypeDocInfoCustom:
1585         case SwServiceType::FieldTypeDocInfoPrintAuthor:
1586         case SwServiceType::FieldTypeDocInfoPrintDateTime:
1587         case SwServiceType::FieldTypeDocInfoKeywords:
1588         case SwServiceType::FieldTypeDocInfoSubject:
1589         case SwServiceType::FieldTypeDocInfoTitle:
1590         case SwServiceType::FieldTypeDocInfoRevision:
1591         case SwServiceType::FieldTypeDocInfo:
1592         {
1593             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DocInfo);
1594             sal_uInt16 nSubType = aDocInfoSubTypeFromService[
1595                     static_cast<sal_uInt16>(m_pImpl->m_nServiceId) - sal_uInt16(SwServiceType::FieldTypeDocInfoChangeAuthor)];
1596             if (SwServiceType::FieldTypeDocInfoChangeDateTime == m_pImpl->m_nServiceId ||
1597                 SwServiceType::FieldTypeDocInfoCreateDateTime == m_pImpl->m_nServiceId ||
1598                 SwServiceType::FieldTypeDocInfoPrintDateTime == m_pImpl->m_nServiceId ||
1599                 SwServiceType::FieldTypeDocInfoEditTime == m_pImpl->m_nServiceId)
1600             {
1601                 if (m_pImpl->m_pProps->bBool2) //IsDate
1602                 {
1603                     nSubType &= 0xf0ff;
1604                     nSubType |= DI_SUB_DATE;
1605                 }
1606                 else
1607                 {
1608                     nSubType &= 0xf0ff;
1609                     nSubType |= DI_SUB_TIME;
1610                 }
1611             }
1612             if (m_pImpl->m_pProps->bBool1)
1613                 nSubType |= DI_SUB_FIXED;
1614             xField.reset(new SwDocInfoField(
1615                     static_cast<SwDocInfoFieldType*>(pFieldType), nSubType,
1616                     m_pImpl->m_pProps->sPar4, m_pImpl->m_pProps->nFormat));
1617             if (!m_pImpl->m_pProps->sPar3.isEmpty())
1618                 static_cast<SwDocInfoField*>(xField.get())->SetExpansion(m_pImpl->m_pProps->sPar3);
1619         }
1620         break;
1621         case SwServiceType::FieldTypeUserExt:
1622         {
1623             sal_Int32 nFormat = 0;
1624             if (m_pImpl->m_pProps->bBool1)
1625                 nFormat = AF_FIXED;
1626 
1627             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::ExtUser);
1628             SwExtUserField *const pEUField = new SwExtUserField(
1629                 static_cast<SwExtUserFieldType*>(pFieldType),
1630                 m_pImpl->m_pProps->nUSHORT1, nFormat);
1631             xField.reset(pEUField);
1632             pEUField->SetExpansion(m_pImpl->m_pProps->sPar1);
1633         }
1634         break;
1635         case SwServiceType::FieldTypeUser:
1636         {
1637             SwFieldType* pFieldType =
1638                 pDoc->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::User, m_pImpl->m_sTypeName, true);
1639             if (!pFieldType)
1640                 throw uno::RuntimeException();
1641             sal_uInt16 nUserSubType = (m_pImpl->m_pProps->bBool1)
1642                 ? nsSwExtendedSubType::SUB_INVISIBLE : 0;
1643             if (m_pImpl->m_pProps->bBool2)
1644                 nUserSubType |= nsSwExtendedSubType::SUB_CMD;
1645             if (m_pImpl->m_pProps->bFormatIsDefault &&
1646                 nsSwGetSetExpType::GSE_STRING == static_cast<SwUserFieldType*>(pFieldType)->GetType())
1647             {
1648                 m_pImpl->m_pProps->nFormat = -1;
1649             }
1650             xField.reset(new SwUserField(static_cast<SwUserFieldType*>(pFieldType),
1651                                 nUserSubType,
1652                                 m_pImpl->m_pProps->nFormat));
1653         }
1654         break;
1655         case SwServiceType::FieldTypeRefPageSet:
1656         {
1657             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::RefPageSet);
1658             xField.reset(new SwRefPageSetField( static_cast<SwRefPageSetFieldType*>(pFieldType),
1659                                 m_pImpl->m_pProps->nUSHORT1,
1660                                 m_pImpl->m_pProps->bBool1 ));
1661         }
1662         break;
1663         case SwServiceType::FieldTypeRefPageGet:
1664         {
1665             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::RefPageGet);
1666             SwRefPageGetField *const pRGField = new SwRefPageGetField(
1667                     static_cast<SwRefPageGetFieldType*>(pFieldType),
1668                     m_pImpl->m_pProps->nUSHORT1 );
1669             xField.reset(pRGField);
1670             pRGField->SetText(m_pImpl->m_pProps->sPar1, nullptr);
1671         }
1672         break;
1673         case SwServiceType::FieldTypePageNum:
1674         {
1675             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::PageNumber);
1676             SwPageNumberField *const pPNField = new SwPageNumberField(
1677                 static_cast<SwPageNumberFieldType*>(pFieldType), PG_RANDOM,
1678                 m_pImpl->m_pProps->nFormat,
1679                 m_pImpl->m_pProps->nUSHORT1);
1680             xField.reset(pPNField);
1681             pPNField->SetUserString(m_pImpl->m_pProps->sPar1);
1682             uno::Any aVal;
1683             aVal <<= m_pImpl->m_pProps->nSubType;
1684             xField->PutValue( aVal, FIELD_PROP_SUBTYPE );
1685         }
1686         break;
1687         case SwServiceType::FieldTypeDDE:
1688         {
1689             SwFieldType* pFieldType =
1690                 pDoc->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::Dde, m_pImpl->m_sTypeName, true);
1691             if (!pFieldType)
1692                 throw uno::RuntimeException();
1693             xField.reset(new SwDDEField( static_cast<SwDDEFieldType*>(pFieldType) ));
1694         }
1695         break;
1696         case SwServiceType::FieldTypeDatabaseName:
1697         {
1698             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DatabaseName);
1699             SwDBData aData;
1700             aData.sDataSource = m_pImpl->m_pProps->sPar1;
1701             aData.sCommand = m_pImpl->m_pProps->sPar2;
1702             aData.nCommandType = m_pImpl->m_pProps->nSHORT1;
1703             xField.reset(new SwDBNameField(static_cast<SwDBNameFieldType*>(pFieldType), aData));
1704             sal_uInt16  nSubType = xField->GetSubType();
1705             if (m_pImpl->m_pProps->bBool2)
1706                 nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
1707             else
1708                 nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
1709             xField->SetSubType(nSubType);
1710         }
1711         break;
1712         case SwServiceType::FieldTypeDatabaseNextSet:
1713         {
1714             SwDBData aData;
1715             aData.sDataSource = m_pImpl->m_pProps->sPar1;
1716             aData.sCommand = m_pImpl->m_pProps->sPar2;
1717             aData.nCommandType = m_pImpl->m_pProps->nSHORT1;
1718             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DbNextSet);
1719             xField.reset(new SwDBNextSetField(static_cast<SwDBNextSetFieldType*>(pFieldType),
1720                     m_pImpl->m_pProps->sPar3, aData));
1721         }
1722         break;
1723         case SwServiceType::FieldTypeDatabaseNumSet:
1724         {
1725             SwDBData aData;
1726             aData.sDataSource = m_pImpl->m_pProps->sPar1;
1727             aData.sCommand = m_pImpl->m_pProps->sPar2;
1728             aData.nCommandType = m_pImpl->m_pProps->nSHORT1;
1729             xField.reset(new SwDBNumSetField( static_cast<SwDBNumSetFieldType*>(
1730                 pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DbNumSet)),
1731                 m_pImpl->m_pProps->sPar3,
1732                 OUString::number(m_pImpl->m_pProps->nFormat),
1733                 aData ));
1734         }
1735         break;
1736         case SwServiceType::FieldTypeDatabaseSetNum:
1737         {
1738             SwDBData aData;
1739             aData.sDataSource = m_pImpl->m_pProps->sPar1;
1740             aData.sCommand = m_pImpl->m_pProps->sPar2;
1741             aData.nCommandType = m_pImpl->m_pProps->nSHORT1;
1742             SwDBSetNumberField *const pDBSNField =
1743                 new SwDBSetNumberField(static_cast<SwDBSetNumberFieldType*>(
1744                         pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DbSetNumber)), aData,
1745                     m_pImpl->m_pProps->nUSHORT1);
1746             xField.reset(pDBSNField);
1747             pDBSNField->SetSetNumber(m_pImpl->m_pProps->nFormat);
1748             sal_uInt16 nSubType = xField->GetSubType();
1749             if (m_pImpl->m_pProps->bBool2)
1750                 nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
1751             else
1752                 nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
1753             xField->SetSubType(nSubType);
1754         }
1755         break;
1756         case SwServiceType::FieldTypeDatabase:
1757         {
1758             SwFieldType* pFieldType =
1759                 pDoc->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::Database, m_pImpl->m_sTypeName, false);
1760             if (!pFieldType)
1761                 throw uno::RuntimeException();
1762             xField.reset(new SwDBField(static_cast<SwDBFieldType*>(pFieldType),
1763                     m_pImpl->m_pProps->nFormat));
1764             static_cast<SwDBField*>(xField.get())->InitContent(m_pImpl->m_pProps->sPar1);
1765             sal_uInt16  nSubType = xField->GetSubType();
1766             if (m_pImpl->m_pProps->bBool2)
1767                 nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
1768             else
1769                 nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
1770             xField->SetSubType(nSubType);
1771         }
1772         break;
1773         case SwServiceType::FieldTypeSetExp:
1774         {
1775             SwFieldType* pFieldType =
1776                 pDoc->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::SetExp, m_pImpl->m_sTypeName, true);
1777             if (!pFieldType)
1778                 throw uno::RuntimeException();
1779             // detect the field type's sub type and set an appropriate number format
1780             if (m_pImpl->m_pProps->bFormatIsDefault &&
1781                 nsSwGetSetExpType::GSE_STRING == static_cast<SwSetExpFieldType*>(pFieldType)->GetType())
1782             {
1783                 m_pImpl->m_pProps->nFormat = -1;
1784             }
1785             SwSetExpField *const pSEField = new SwSetExpField(
1786                 static_cast<SwSetExpFieldType*>(pFieldType),
1787                 m_pImpl->m_pProps->sPar2,
1788                 m_pImpl->m_pProps->nUSHORT2 != USHRT_MAX ?  //#i79471# the field can have a number format or a number_ing_ format
1789                 m_pImpl->m_pProps->nUSHORT2 : m_pImpl->m_pProps->nFormat);
1790             xField.reset(pSEField);
1791 
1792             sal_uInt16  nSubType = xField->GetSubType();
1793             if (m_pImpl->m_pProps->bBool2)
1794                 nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
1795             else
1796                 nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
1797             if (m_pImpl->m_pProps->bBool3)
1798                 nSubType |= nsSwExtendedSubType::SUB_CMD;
1799             else
1800                 nSubType &= ~nsSwExtendedSubType::SUB_CMD;
1801             xField->SetSubType(nSubType);
1802             pSEField->SetSeqNumber(m_pImpl->m_pProps->nUSHORT1);
1803             pSEField->SetInputFlag(m_pImpl->m_pProps->bBool1);
1804             pSEField->SetPromptText(m_pImpl->m_pProps->sPar3);
1805             if (!m_pImpl->m_pProps->sPar4.isEmpty())
1806                 pSEField->ChgExpStr(m_pImpl->m_pProps->sPar4, nullptr);
1807 
1808         }
1809         break;
1810         case SwServiceType::FieldTypeGetExp:
1811         {
1812             sal_uInt16 nSubType;
1813             switch (m_pImpl->m_pProps->nSubType)
1814             {
1815                 case text::SetVariableType::STRING: nSubType = nsSwGetSetExpType::GSE_STRING;   break;
1816                 case text::SetVariableType::VAR:        nSubType = nsSwGetSetExpType::GSE_EXPR;  break;
1817                 //case text::SetVariableType::SEQUENCE:   nSubType = nsSwGetSetExpType::GSE_SEQ;  break;
1818                 case text::SetVariableType::FORMULA:    nSubType = nsSwGetSetExpType::GSE_FORMULA; break;
1819                 default:
1820                     OSL_FAIL("wrong value");
1821                     nSubType = nsSwGetSetExpType::GSE_EXPR;
1822             }
1823             //make sure the SubType matches the field type
1824             SwFieldType* pSetExpField = pDoc->getIDocumentFieldsAccess().GetFieldType(
1825                     SwFieldIds::SetExp, m_pImpl->m_pProps->sPar1, false);
1826             bool bSetGetExpFieldUninitialized = false;
1827             if (pSetExpField)
1828             {
1829                 if (nSubType != nsSwGetSetExpType::GSE_STRING &&
1830                     static_cast< SwSetExpFieldType* >(pSetExpField)->GetType() == nsSwGetSetExpType::GSE_STRING)
1831                 nSubType = nsSwGetSetExpType::GSE_STRING;
1832             }
1833             else
1834                 bSetGetExpFieldUninitialized = true; // #i82544#
1835 
1836             if (m_pImpl->m_pProps->bBool2)
1837                 nSubType |= nsSwExtendedSubType::SUB_CMD;
1838             else
1839                 nSubType &= ~nsSwExtendedSubType::SUB_CMD;
1840             SwGetExpField *const pGEField = new SwGetExpField(
1841                     static_cast<SwGetExpFieldType*>(
1842                         pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::GetExp)),
1843                     m_pImpl->m_pProps->sPar1, nSubType,
1844                     m_pImpl->m_pProps->nFormat);
1845             xField.reset(pGEField);
1846             //TODO: evaluate SubType!
1847             if (!m_pImpl->m_pProps->sPar4.isEmpty())
1848                 pGEField->ChgExpStr(m_pImpl->m_pProps->sPar4, nullptr);
1849             // #i82544#
1850             if (bSetGetExpFieldUninitialized)
1851                 pGEField->SetLateInitialization();
1852         }
1853         break;
1854         case SwServiceType::FieldTypeInputUser:
1855         case SwServiceType::FieldTypeInput:
1856         {
1857             SwFieldType* pFieldType =
1858                 pDoc->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::Input, m_pImpl->m_sTypeName, true);
1859             if (!pFieldType)
1860                 throw uno::RuntimeException();
1861             sal_uInt16 nInpSubType =
1862                 sal::static_int_cast<sal_uInt16>(
1863                     SwServiceType::FieldTypeInputUser == m_pImpl->m_nServiceId
1864                         ? INP_USR : INP_TXT);
1865             SwInputField * pTextField =
1866                 new SwInputField(static_cast<SwInputFieldType*>(pFieldType),
1867                                  m_pImpl->m_pProps->sPar1,
1868                                  m_pImpl->m_pProps->sPar2,
1869                                  nInpSubType);
1870             pTextField->SetHelp(m_pImpl->m_pProps->sPar3);
1871             pTextField->SetToolTip(m_pImpl->m_pProps->sPar4);
1872 
1873             xField.reset(pTextField);
1874         }
1875         break;
1876         case SwServiceType::FieldTypeMacro:
1877         {
1878             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Macro);
1879             OUString aName;
1880 
1881             // support for Scripting Framework macros
1882             if (!m_pImpl->m_pProps->sPar4.isEmpty())
1883             {
1884                 aName = m_pImpl->m_pProps->sPar4;
1885             }
1886             else
1887             {
1888                 SwMacroField::CreateMacroString(aName,
1889                     m_pImpl->m_pProps->sPar1, m_pImpl->m_pProps->sPar3);
1890             }
1891             xField.reset(new SwMacroField(static_cast<SwMacroFieldType*>(pFieldType), aName,
1892                                     m_pImpl->m_pProps->sPar2));
1893         }
1894         break;
1895         case SwServiceType::FieldTypePageCount:
1896         case SwServiceType::FieldTypeParagraphCount:
1897         case SwServiceType::FieldTypeWordCount:
1898         case SwServiceType::FieldTypeCharacterCount:
1899         case SwServiceType::FieldTypeTableCount:
1900         case SwServiceType::FieldTypeGraphicObjectCount:
1901         case SwServiceType::FieldTypeEmbeddedObjectCount:
1902         {
1903             sal_uInt16 nSubType = DS_PAGE;
1904             switch (m_pImpl->m_nServiceId)
1905             {
1906                 case SwServiceType::FieldTypeParagraphCount       : nSubType = DS_PARA; break;
1907                 case SwServiceType::FieldTypeWordCount            : nSubType = DS_WORD; break;
1908                 case SwServiceType::FieldTypeCharacterCount       : nSubType = DS_CHAR; break;
1909                 case SwServiceType::FieldTypeTableCount           : nSubType = DS_TBL;  break;
1910                 case SwServiceType::FieldTypeGraphicObjectCount  : nSubType = DS_GRF;  break;
1911                 case SwServiceType::FieldTypeEmbeddedObjectCount : nSubType = DS_OLE;  break;
1912                 default: break;
1913             }
1914             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DocStat);
1915             xField.reset(new SwDocStatField(
1916                     static_cast<SwDocStatFieldType*>(pFieldType),
1917                     nSubType, m_pImpl->m_pProps->nUSHORT2));
1918         }
1919         break;
1920         case SwServiceType::FieldTypeBibliography:
1921         {
1922             SwAuthorityFieldType const type(pDoc);
1923             xField.reset(new SwAuthorityField(static_cast<SwAuthorityFieldType*>(
1924                         pDoc->getIDocumentFieldsAccess().InsertFieldType(type)),
1925                     OUString()));
1926             if (m_pImpl->m_pProps->aPropSeq.hasElements())
1927             {
1928                 uno::Any aVal;
1929                 aVal <<= m_pImpl->m_pProps->aPropSeq;
1930                 xField->PutValue( aVal, FIELD_PROP_PROP_SEQ );
1931             }
1932         }
1933         break;
1934         case SwServiceType::FieldTypeCombinedCharacters:
1935             // create field
1936             xField.reset(new SwCombinedCharField( static_cast<SwCombinedCharFieldType*>(
1937                         pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::CombinedChars)),
1938                         m_pImpl->m_pProps->sPar1));
1939             break;
1940         case SwServiceType::FieldTypeDropdown:
1941         {
1942             SwDropDownField *const pDDField = new SwDropDownField(
1943                 static_cast<SwDropDownFieldType *>(
1944                     pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Dropdown)));
1945             xField.reset(pDDField);
1946 
1947             pDDField->SetItems(m_pImpl->m_pProps->aStrings);
1948             pDDField->SetSelectedItem(m_pImpl->m_pProps->sPar1);
1949             pDDField->SetName(m_pImpl->m_pProps->sPar2);
1950             pDDField->SetHelp(m_pImpl->m_pProps->sPar3);
1951             pDDField->SetToolTip(m_pImpl->m_pProps->sPar4);
1952         }
1953         break;
1954 
1955         case SwServiceType::FieldTypeTableFormula:
1956         {
1957             // create field
1958             sal_uInt16 nType = nsSwGetSetExpType::GSE_FORMULA;
1959             if (m_pImpl->m_pProps->bBool1)
1960             {
1961                 nType |= nsSwExtendedSubType::SUB_CMD;
1962                 if (m_pImpl->m_pProps->bFormatIsDefault)
1963                     m_pImpl->m_pProps->nFormat = -1;
1964             }
1965             xField.reset(new SwTableField( static_cast<SwTableFieldType*>(
1966                 pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Table)),
1967                 m_pImpl->m_pProps->sPar2,
1968                 nType,
1969                 m_pImpl->m_pProps->nFormat));
1970             static_cast<SwTableField*>(xField.get())->ChgExpStr(m_pImpl->m_pProps->sPar1);
1971         }
1972         break;
1973         default: OSL_FAIL("What kind of type is that?");
1974     }
1975 
1976     if (!xField)
1977         throw uno::RuntimeException("no SwField created?");
1978 
1979     xField->SetAutomaticLanguage(!m_pImpl->m_pProps->bBool4);
1980     SwFormatField aFormat(*xField);
1981 
1982     UnoActionContext aCont(pDoc);
1983     if (aPam.HasMark() &&
1984         m_pImpl->m_nServiceId != SwServiceType::FieldTypeAnnotation)
1985     {
1986         pDoc->getIDocumentContentOperations().DeleteAndJoin(aPam);
1987     }
1988 
1989     SwXTextCursor const*const pTextCursor(dynamic_cast<SwXTextCursor*>(pCursor));
1990     const bool bForceExpandHints(
1991         pTextCursor
1992         && pTextCursor->IsAtEndOfMeta() );
1993     const SetAttrMode nInsertFlags =
1994         bForceExpandHints
1995         ? SetAttrMode::FORCEHINTEXPAND
1996         : SetAttrMode::DEFAULT;
1997 
1998     if (*aPam.GetPoint() != *aPam.GetMark() &&
1999         m_pImpl->m_nServiceId == SwServiceType::FieldTypeAnnotation)
2000     {
2001         // Make sure we always insert the field at the end
2002         SwPaM aEnd(*aPam.End(), *aPam.End());
2003         pDoc->getIDocumentContentOperations().InsertPoolItem(aEnd, aFormat, nInsertFlags);
2004     }
2005     else
2006         pDoc->getIDocumentContentOperations().InsertPoolItem(aPam, aFormat, nInsertFlags);
2007 
2008     SwTextAttr* pTextAttr = aPam.GetNode().GetTextNode()->GetFieldTextAttrAt( aPam.GetPoint()->nContent.GetIndex()-1, true );
2009 
2010     // What about updating the fields? (see fldmgr.cxx)
2011     if (!pTextAttr)
2012         throw uno::RuntimeException("no SwTextAttr inserted?");  // could theoretically happen, if paragraph is full
2013 
2014     const SwFormatField& rField = pTextAttr->GetFormatField();
2015     m_pImpl->SetFormatField(const_cast<SwFormatField*>(&rField), pDoc);
2016 
2017     if ( pTextAttr->Which() == RES_TXTATR_ANNOTATION
2018          && *aPam.GetPoint() != *aPam.GetMark() )
2019     {
2020         // create annotation mark
2021         const SwPostItField* pPostItField = dynamic_cast< const SwPostItField* >(pTextAttr->GetFormatField().GetField());
2022         OSL_ENSURE( pPostItField != nullptr, "<SwXTextField::attachToRange(..)> - annotation field missing!" );
2023         if ( pPostItField != nullptr )
2024         {
2025             IDocumentMarkAccess* pMarksAccess = pDoc->getIDocumentMarkAccess();
2026             pMarksAccess->makeAnnotationMark( aPam, pPostItField->GetName() );
2027         }
2028     }
2029 
2030     xField.reset();
2031 
2032     assert(m_pImpl->GetFormatField());
2033     m_pImpl->m_pDoc = pDoc;
2034     m_pImpl->GetFormatField()->SetXTextField(this);
2035     m_pImpl->m_wThis = *this;
2036     m_pImpl->ClearFieldType();
2037     m_pImpl->m_pProps.reset();
2038     if (m_pImpl->m_bCallUpdate)
2039         update();
2040     }
2041     else if ( !m_pImpl->IsDescriptor()
2042               && m_pImpl->m_pDoc != nullptr
2043               && m_pImpl->m_nServiceId == SwServiceType::FieldTypeAnnotation )
2044     {
2045         SwUnoInternalPaM aIntPam( *m_pImpl->m_pDoc );
2046         if ( !::sw::XTextRangeToSwPaM( aIntPam, xTextRange ) )
2047             throw lang::IllegalArgumentException();
2048 
2049         // nothing to do, if the text range only covers the former annotation field
2050         if ( aIntPam.Start()->nNode != aIntPam.End()->nNode
2051              || aIntPam.Start()->nContent.GetIndex() != aIntPam.End()->nContent.GetIndex()-1 )
2052         {
2053             UnoActionContext aCont( m_pImpl->m_pDoc );
2054             // insert copy of annotation at new text range
2055             std::unique_ptr<SwPostItField> pPostItField(static_cast< SwPostItField* >(m_pImpl->GetFormatField()->GetField()->CopyField().release()));
2056             SwFormatField aFormatField( *pPostItField );
2057             pPostItField.reset();
2058             SwPaM aEnd( *aIntPam.End(), *aIntPam.End() );
2059             m_pImpl->m_pDoc->getIDocumentContentOperations().InsertPoolItem( aEnd, aFormatField );
2060             // delete former annotation
2061             {
2062                 const SwTextField* pTextField = m_pImpl->GetFormatField()->GetTextField();
2063                 SwTextNode& rTextNode = *pTextField->GetpTextNode();
2064                 SwPaM aPam( rTextNode, pTextField->GetStart() );
2065                 aPam.SetMark();
2066                 aPam.Move();
2067                 m_pImpl->m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aPam);
2068             }
2069             // keep inserted annotation
2070             {
2071                 SwTextField* pTextAttr = aEnd.GetNode().GetTextNode()->GetFieldTextAttrAt( aEnd.End()->nContent.GetIndex()-1, true );
2072                 if ( pTextAttr != nullptr )
2073                 {
2074                     m_pImpl->SetFormatField(const_cast<SwFormatField*>(&pTextAttr->GetFormatField()), m_pImpl->m_pDoc);
2075 
2076                     if ( *aIntPam.GetPoint() != *aIntPam.GetMark() )
2077                     {
2078                         // create annotation mark
2079                         const SwPostItField* pField = dynamic_cast< const SwPostItField* >(pTextAttr->GetFormatField().GetField());
2080                         OSL_ENSURE( pField != nullptr, "<SwXTextField::attach(..)> - annotation field missing!" );
2081                         if ( pField != nullptr )
2082                         {
2083                             IDocumentMarkAccess* pMarksAccess = aIntPam.GetDoc()->getIDocumentMarkAccess();
2084                             pMarksAccess->makeAnnotationMark( aIntPam, pField->GetName() );
2085                         }
2086                     }
2087                 }
2088             }
2089         }
2090 
2091     }
2092     else
2093         throw lang::IllegalArgumentException();
2094 }
2095 
2096 uno::Reference< text::XTextRange > SAL_CALL
2097 SwXTextField::getAnchor()
2098 {
2099     SolarMutexGuard aGuard;
2100 
2101     SwField const*const pField = m_pImpl->GetField();
2102     if (!pField)
2103         return nullptr;
2104 
2105     const SwTextField* pTextField = m_pImpl->GetFormatField()->GetTextField();
2106     if (!pTextField)
2107         throw uno::RuntimeException();
2108 
2109     std::shared_ptr< SwPaM > pPamForTextField;
2110     SwTextField::GetPamForTextField(*pTextField, pPamForTextField);
2111     if (pPamForTextField == nullptr)
2112         return nullptr;
2113 
2114     // If this is a postit field, then return the range of its annotation mark if it has one.
2115     if (pField->Which() == SwFieldIds::Postit)
2116     {
2117         const SwPostItField* pPostItField = static_cast<const SwPostItField*>(pField);
2118         IDocumentMarkAccess* pMarkAccess = m_pImpl->m_pDoc->getIDocumentMarkAccess();
2119         for (IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAnnotationMarksBegin(); ppMark != pMarkAccess->getAnnotationMarksEnd(); ++ppMark)
2120         {
2121             if ((*ppMark)->GetName() == pPostItField->GetName())
2122             {
2123                 pPamForTextField.reset(new SwPaM((*ppMark)->GetMarkStart(), (*ppMark)->GetMarkEnd()));
2124                 break;
2125             }
2126         }
2127     }
2128 
2129     uno::Reference<text::XTextRange> xRange = SwXTextRange::CreateXTextRange(
2130             *m_pImpl->m_pDoc, *(pPamForTextField->GetPoint()), pPamForTextField->GetMark());
2131     return xRange;
2132 }
2133 
2134 void SAL_CALL SwXTextField::dispose()
2135 {
2136     SolarMutexGuard aGuard;
2137     SwField const*const pField = m_pImpl->GetField();
2138     if(pField && m_pImpl->m_pDoc)
2139     {
2140         UnoActionContext aContext(m_pImpl->m_pDoc);
2141         assert(m_pImpl->GetFormatField()->GetTextField() && "<SwXTextField::dispose()> - missing <SwTextField> --> crash");
2142         SwTextField::DeleteTextField(*(m_pImpl->GetFormatField()->GetTextField()));
2143     }
2144 
2145     if (m_pImpl->m_xTextObject.is())
2146     {
2147         m_pImpl->m_xTextObject->DisposeEditSource();
2148         m_pImpl->m_xTextObject.clear();
2149     }
2150     m_pImpl->Invalidate();
2151 }
2152 
2153 void SAL_CALL SwXTextField::addEventListener(
2154         const uno::Reference<lang::XEventListener> & xListener)
2155 {
2156     // no need to lock here as m_pImpl is const and container threadsafe
2157     m_pImpl->m_EventListeners.addInterface(xListener);
2158 }
2159 
2160 void SAL_CALL SwXTextField::removeEventListener(
2161         const uno::Reference<lang::XEventListener> & xListener)
2162 {
2163     // no need to lock here as m_pImpl is const and container threadsafe
2164     m_pImpl->m_EventListeners.removeInterface(xListener);
2165 }
2166 
2167 uno::Reference< beans::XPropertySetInfo > SAL_CALL
2168 SwXTextField::getPropertySetInfo()
2169 {
2170     SolarMutexGuard aGuard;
2171     // no static
2172     uno::Reference< beans::XPropertySetInfo >  aRef;
2173     if (m_pImpl->m_nServiceId == SwServiceType::Invalid)
2174     {
2175         throw uno::RuntimeException();
2176     }
2177     const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(
2178                     lcl_GetPropertyMapOfService(m_pImpl->m_nServiceId));
2179     const uno::Reference<beans::XPropertySetInfo>& xInfo = pPropSet->getPropertySetInfo();
2180     // extend PropertySetInfo!
2181     const uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties();
2182     aRef = new SfxExtItemPropertySetInfo(
2183         aSwMapProvider.GetPropertyMapEntries(PROPERTY_MAP_PARAGRAPH_EXTENSIONS),
2184         aPropSeq );
2185     return aRef;
2186 }
2187 
2188 void SAL_CALL
2189 SwXTextField::setPropertyValue(
2190         const OUString& rPropertyName, const uno::Any& rValue)
2191 {
2192     SolarMutexGuard aGuard;
2193     SwField const*const pField = m_pImpl->GetField();
2194     const SfxItemPropertySet* _pPropSet = aSwMapProvider.GetPropertySet(
2195                 lcl_GetPropertyMapOfService(m_pImpl->m_nServiceId));
2196     const SfxItemPropertySimpleEntry*   pEntry = _pPropSet->getPropertyMap().getByName(rPropertyName);
2197 
2198     if (!pEntry)
2199         throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
2200     if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
2201         throw beans::PropertyVetoException( "Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
2202 
2203     if(pField)
2204     {
2205         // special treatment for mail merge fields
2206         const SwFieldIds nWhich = pField->Which();
2207         if( SwFieldIds::Database == nWhich &&
2208             (rPropertyName == UNO_NAME_DATA_BASE_NAME ||
2209             rPropertyName == UNO_NAME_DATA_BASE_URL||
2210             rPropertyName == UNO_NAME_DATA_TABLE_NAME||
2211             rPropertyName == UNO_NAME_DATA_COLUMN_NAME))
2212         {
2213             // here a new field type must be created and the field must
2214             // be registered at the new type
2215             OSL_FAIL("not implemented");
2216         }
2217         else
2218         {
2219             SwDoc * pDoc = m_pImpl->m_pDoc;
2220             assert(pDoc);
2221             const SwTextField* pTextField = m_pImpl->GetFormatField()->GetTextField();
2222             if(!pTextField)
2223                 throw uno::RuntimeException();
2224             SwPosition aPosition( pTextField->GetTextNode() );
2225             aPosition.nContent = pTextField->GetStart();
2226             pDoc->getIDocumentFieldsAccess().PutValueToField( aPosition, rValue, pEntry->nWID);
2227         }
2228 
2229         //#i100374# notify SwPostIt about new field content
2230         if (SwFieldIds::Postit == nWhich && !m_pImpl->IsDescriptor())
2231         {
2232             m_pImpl->GetFormatField()->Broadcast(
2233                     SwFormatFieldHint( nullptr, SwFormatFieldHintWhich::CHANGED ));
2234         }
2235 
2236         // fdo#42073 notify SwTextField about changes of the expanded string
2237         if (m_pImpl->GetFormatField()->GetTextField())
2238         {
2239             m_pImpl->GetFormatField()->GetTextField()->ExpandTextField();
2240         }
2241 
2242         //#i100374# changing a document field should set the modify flag
2243         SwDoc* pDoc = m_pImpl->m_pDoc;
2244         if (pDoc)
2245             pDoc->getIDocumentState().SetModified();
2246 
2247     }
2248     else if (m_pImpl->m_pProps)
2249     {
2250         bool* pBool = nullptr;
2251         switch(pEntry->nWID)
2252         {
2253         case FIELD_PROP_PAR1:
2254             rValue >>= m_pImpl->m_pProps->sPar1;
2255             break;
2256         case FIELD_PROP_PAR2:
2257             rValue >>= m_pImpl->m_pProps->sPar2;
2258             break;
2259         case FIELD_PROP_PAR3:
2260             rValue >>= m_pImpl->m_pProps->sPar3;
2261             break;
2262         case FIELD_PROP_PAR4:
2263             rValue >>= m_pImpl->m_pProps->sPar4;
2264             break;
2265         case FIELD_PROP_FORMAT:
2266             rValue >>= m_pImpl->m_pProps->nFormat;
2267             m_pImpl->m_pProps->bFormatIsDefault = false;
2268             break;
2269         case FIELD_PROP_SUBTYPE:
2270             m_pImpl->m_pProps->nSubType = SWUnoHelper::GetEnumAsInt32(rValue);
2271             break;
2272         case FIELD_PROP_BYTE1 :
2273             rValue >>= m_pImpl->m_pProps->nByte1;
2274             break;
2275         case FIELD_PROP_BOOL1 :
2276             pBool = &m_pImpl->m_pProps->bBool1;
2277             break;
2278         case FIELD_PROP_BOOL2 :
2279             pBool = &m_pImpl->m_pProps->bBool2;
2280             break;
2281         case FIELD_PROP_BOOL3 :
2282             pBool = &m_pImpl->m_pProps->bBool3;
2283             break;
2284         case FIELD_PROP_BOOL4:
2285             pBool = &m_pImpl->m_pProps->bBool4;
2286         break;
2287         case FIELD_PROP_DATE :
2288         {
2289             auto aTemp = o3tl::tryAccess<util::Date>(rValue);
2290             if(!aTemp)
2291                 throw lang::IllegalArgumentException();
2292 
2293             m_pImpl->m_pProps->aDate = Date(aTemp->Day, aTemp->Month, aTemp->Year);
2294         }
2295         break;
2296         case FIELD_PROP_USHORT1:
2297         case FIELD_PROP_USHORT2:
2298             {
2299                 sal_Int16 nVal = 0;
2300                 rValue >>= nVal;
2301                 if( FIELD_PROP_USHORT1 == pEntry->nWID)
2302                     m_pImpl->m_pProps->nUSHORT1 = nVal;
2303                 else
2304                     m_pImpl->m_pProps->nUSHORT2 = nVal;
2305             }
2306             break;
2307         case FIELD_PROP_SHORT1:
2308             rValue >>= m_pImpl->m_pProps->nSHORT1;
2309             break;
2310         case FIELD_PROP_DOUBLE:
2311             if(rValue.getValueType() != ::cppu::UnoType<double>::get())
2312                 throw lang::IllegalArgumentException();
2313             rValue >>= m_pImpl->m_pProps->fDouble;
2314             break;
2315 
2316         case FIELD_PROP_DATE_TIME :
2317             if (!m_pImpl->m_pProps->pDateTime)
2318                 m_pImpl->m_pProps->pDateTime.reset( new util::DateTime );
2319             rValue >>= *m_pImpl->m_pProps->pDateTime;
2320             break;
2321         case FIELD_PROP_PROP_SEQ:
2322             rValue >>= m_pImpl->m_pProps->aPropSeq;
2323             break;
2324         case FIELD_PROP_STRINGS:
2325             rValue >>= m_pImpl->m_pProps->aStrings;
2326             break;
2327         }
2328         if (pBool)
2329         {
2330             auto b = o3tl::tryAccess<bool>(rValue);
2331             if( !b )
2332                 throw lang::IllegalArgumentException();
2333             *pBool = *b;
2334 
2335         }
2336     }
2337     else
2338         throw uno::RuntimeException();
2339 }
2340 
2341 uno::Any SAL_CALL SwXTextField::getPropertyValue(const OUString& rPropertyName)
2342 {
2343     SolarMutexGuard aGuard;
2344     uno::Any aRet;
2345     SwField const*const pField = m_pImpl->GetField();
2346     const SfxItemPropertySet* _pPropSet = aSwMapProvider.GetPropertySet(
2347                 lcl_GetPropertyMapOfService(m_pImpl->m_nServiceId));
2348     const SfxItemPropertySimpleEntry*   pEntry = _pPropSet->getPropertyMap().getByName(rPropertyName);
2349     if(!pEntry )
2350     {
2351         const SfxItemPropertySet* _pParaPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH_EXTENSIONS);
2352         pEntry = _pParaPropSet->getPropertyMap().getByName(rPropertyName);
2353     }
2354     if (!pEntry)
2355         throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
2356 
2357     switch( pEntry->nWID )
2358     {
2359     case FN_UNO_TEXT_WRAP:
2360         aRet <<= text::WrapTextMode_NONE;
2361         break;
2362     case FN_UNO_ANCHOR_TYPE:
2363         aRet <<= text::TextContentAnchorType_AS_CHARACTER;
2364         break;
2365     case FN_UNO_ANCHOR_TYPES:
2366         {
2367             uno::Sequence<text::TextContentAnchorType> aTypes(1);
2368             text::TextContentAnchorType* pArray = aTypes.getArray();
2369             pArray[0] = text::TextContentAnchorType_AS_CHARACTER;
2370             aRet <<= aTypes;
2371         }
2372         break;
2373 
2374     default:
2375         if( pField )
2376         {
2377             if (FIELD_PROP_IS_FIELD_USED      == pEntry->nWID ||
2378                 FIELD_PROP_IS_FIELD_DISPLAYED == pEntry->nWID)
2379             {
2380                 bool bIsFieldUsed       = false;
2381                 bool bIsFieldDisplayed  = false;
2382 
2383                 // in order to have the information about fields
2384                 // correctly evaluated the document needs a layout
2385                 // (has to be already formatted)
2386                 SwDoc *pDoc = m_pImpl->m_pDoc;
2387                 SwViewShell *pViewShell = nullptr;
2388                 SwEditShell *pEditShell = nullptr;
2389                 if( pDoc )
2390                 {
2391                     pViewShell = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
2392                     pEditShell = pDoc->GetEditShell();
2393                 }
2394 
2395                 if (pEditShell)
2396                     pEditShell->CalcLayout();
2397                 else if (pViewShell) // a page preview has no SwEditShell it should only have a view shell
2398                     pViewShell->CalcLayout();
2399                 else
2400                     throw uno::RuntimeException();
2401 
2402                 // get text node for the text field
2403                 const SwFormatField *pFieldFormat =
2404                     (m_pImpl->GetField()) ? m_pImpl->GetFormatField() : nullptr;
2405                 const SwTextField* pTextField = pFieldFormat
2406                     ? m_pImpl->GetFormatField()->GetTextField() : nullptr;
2407                 if(!pTextField)
2408                     throw uno::RuntimeException();
2409                 const SwTextNode& rTextNode = pTextField->GetTextNode();
2410 
2411                 // skip fields that are currently not in the document
2412                 // e.g. fields in undo or redo array
2413                 if (rTextNode.GetNodes().IsDocNodes())
2414                 {
2415                     bool bFrame = 0 != rTextNode.FindLayoutRect().Width(); // or so
2416                     bool bHidden = rTextNode.IsHidden();
2417                     if ( !bHidden )
2418                     {
2419                         sal_Int32 nHiddenStart;
2420                         sal_Int32 nHiddenEnd;
2421                         bHidden = SwScriptInfo::GetBoundsOfHiddenRange( pTextField->GetTextNode(),
2422                                         pTextField->GetStart(),
2423                                         nHiddenStart, nHiddenEnd );
2424                     }
2425 
2426                     // !bFrame && !bHidden: most probably a field in an unused page style
2427 
2428                     // FME: Problem: hidden field in unused page template =>
2429                     // bIsFieldUsed = true
2430                     // bIsFieldDisplayed = false
2431                     bIsFieldUsed       = bFrame || bHidden;
2432                     bIsFieldDisplayed  = bIsFieldUsed && !bHidden;
2433                 }
2434                 aRet <<= (FIELD_PROP_IS_FIELD_USED == pEntry->nWID) ? bIsFieldUsed : bIsFieldDisplayed;
2435             }
2436             else
2437                 pField->QueryValue( aRet, pEntry->nWID );
2438         }
2439         else if (m_pImpl->m_pProps)     // currently just a descriptor...
2440         {
2441             switch(pEntry->nWID)
2442             {
2443             case FIELD_PROP_TEXT:
2444                 {
2445                     if (!m_pImpl->m_xTextObject.is())
2446                     {
2447                         m_pImpl->m_xTextObject
2448                             = new SwTextAPIObject( std::make_unique<SwTextAPIEditSource>(m_pImpl->m_pDoc) );
2449                     }
2450 
2451                     uno::Reference<text::XText> xText(m_pImpl->m_xTextObject.get());
2452                     aRet <<= xText;
2453                     break;
2454                 }
2455             case FIELD_PROP_PAR1:
2456                 aRet <<= m_pImpl->m_pProps->sPar1;
2457                 break;
2458             case FIELD_PROP_PAR2:
2459                 aRet <<= m_pImpl->m_pProps->sPar2;
2460                 break;
2461             case FIELD_PROP_PAR3:
2462                 aRet <<= m_pImpl->m_pProps->sPar3;
2463                 break;
2464             case FIELD_PROP_PAR4:
2465                 aRet <<= m_pImpl->m_pProps->sPar4;
2466                 break;
2467             case FIELD_PROP_FORMAT:
2468                 aRet <<= m_pImpl->m_pProps->nFormat;
2469                 break;
2470             case FIELD_PROP_SUBTYPE:
2471                 aRet <<= m_pImpl->m_pProps->nSubType;
2472                 break;
2473             case FIELD_PROP_BYTE1 :
2474                 aRet <<= m_pImpl->m_pProps->nByte1;
2475                 break;
2476             case FIELD_PROP_BOOL1 :
2477                 aRet <<= m_pImpl->m_pProps->bBool1;
2478                 break;
2479             case FIELD_PROP_BOOL2 :
2480                 aRet <<= m_pImpl->m_pProps->bBool2;
2481                 break;
2482             case FIELD_PROP_BOOL3 :
2483                 aRet <<= m_pImpl->m_pProps->bBool3;
2484                 break;
2485             case FIELD_PROP_BOOL4 :
2486                 aRet <<= m_pImpl->m_pProps->bBool4;
2487                 break;
2488             case FIELD_PROP_DATE :
2489                 aRet <<= m_pImpl->m_pProps->aDate.GetUNODate();
2490                 break;
2491             case FIELD_PROP_USHORT1:
2492                 aRet <<= static_cast<sal_Int16>(m_pImpl->m_pProps->nUSHORT1);
2493                 break;
2494             case FIELD_PROP_USHORT2:
2495                 aRet <<= static_cast<sal_Int16>(m_pImpl->m_pProps->nUSHORT2);
2496                 break;
2497             case FIELD_PROP_SHORT1:
2498                 aRet <<= m_pImpl->m_pProps->nSHORT1;
2499                 break;
2500             case FIELD_PROP_DOUBLE:
2501                 aRet <<= m_pImpl->m_pProps->fDouble;
2502                 break;
2503             case FIELD_PROP_DATE_TIME :
2504                 if (m_pImpl->m_pProps->pDateTime)
2505                     aRet <<= *m_pImpl->m_pProps->pDateTime;
2506                 break;
2507             case FIELD_PROP_PROP_SEQ:
2508                 aRet <<= m_pImpl->m_pProps->aPropSeq;
2509                 break;
2510             case FIELD_PROP_STRINGS:
2511                 aRet <<= m_pImpl->m_pProps->aStrings;
2512                 break;
2513             case FIELD_PROP_IS_FIELD_USED:
2514             case FIELD_PROP_IS_FIELD_DISPLAYED:
2515                 aRet <<= false;
2516                 break;
2517             }
2518         }
2519         else
2520             throw uno::RuntimeException();
2521     }
2522     return aRet;
2523 }
2524 
2525 void SwXTextField::addPropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
2526 {
2527     OSL_FAIL("not implemented");
2528 }
2529 
2530 void SwXTextField::removePropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
2531 {
2532     OSL_FAIL("not implemented");
2533 }
2534 
2535 void SwXTextField::addVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
2536 {
2537     OSL_FAIL("not implemented");
2538 }
2539 
2540 void SwXTextField::removeVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
2541 {
2542     OSL_FAIL("not implemented");
2543 }
2544 
2545 void SAL_CALL SwXTextField::update()
2546 {
2547     SolarMutexGuard aGuard;
2548     SwField * pField = const_cast<SwField*>(m_pImpl->GetField());
2549     if (pField)
2550     {
2551         switch(pField->Which())
2552         {
2553             case SwFieldIds::DateTime:
2554             static_cast<SwDateTimeField*>(pField)->SetDateTime( ::DateTime( ::DateTime::SYSTEM ) );
2555             break;
2556 
2557             case SwFieldIds::ExtUser:
2558             {
2559                 SwExtUserField* pExtUserField = static_cast<SwExtUserField*>(pField);
2560                 pExtUserField->SetExpansion( SwExtUserFieldType::Expand(
2561                                             pExtUserField->GetSubType() ) );
2562             }
2563             break;
2564 
2565             case SwFieldIds::Author:
2566             {
2567                 SwAuthorField* pAuthorField = static_cast<SwAuthorField*>(pField);
2568                 pAuthorField->SetExpansion( SwAuthorFieldType::Expand(
2569                                             pAuthorField->GetFormat() ) );
2570             }
2571             break;
2572 
2573             case SwFieldIds::Filename:
2574             {
2575                 SwFileNameField* pFileNameField = static_cast<SwFileNameField*>(pField);
2576                 pFileNameField->SetExpansion( static_cast<SwFileNameFieldType*>(pField->GetTyp())->Expand(
2577                                             pFileNameField->GetFormat() ) );
2578             }
2579             break;
2580 
2581             case SwFieldIds::DocInfo:
2582             {
2583                     SwDocInfoField* pDocInfField = static_cast<SwDocInfoField*>(pField);
2584                     pDocInfField->SetExpansion( static_cast<SwDocInfoFieldType*>(pField->GetTyp())->Expand(
2585                                                 pDocInfField->GetSubType(),
2586                                                 pDocInfField->GetFormat(),
2587                                                 pDocInfField->GetLanguage(),
2588                                                 pDocInfField->GetName() ) );
2589             }
2590             break;
2591             default: break;
2592         }
2593         // Text formatting has to be triggered.
2594         m_pImpl->GetFormatField()->ModifyNotification(nullptr, nullptr);
2595     }
2596     else
2597         m_pImpl->m_bCallUpdate = true;
2598 }
2599 
2600 OUString SAL_CALL SwXTextField::getImplementationName()
2601 {
2602     return OUString("SwXTextField");
2603 }
2604 
2605 static OUString OldNameToNewName_Impl( const OUString &rOld )
2606 {
2607     static const char aOldNamePart1[] = ".TextField.DocInfo.";
2608     static const char aOldNamePart2[] = ".TextField.";
2609     OUString sServiceNameCC( rOld );
2610     sal_Int32 nIdx = sServiceNameCC.indexOf( aOldNamePart1 );
2611     if (nIdx >= 0)
2612         sServiceNameCC = sServiceNameCC.replaceAt( nIdx, strlen(aOldNamePart1), ".textfield.docinfo." );
2613     nIdx = sServiceNameCC.indexOf( aOldNamePart2 );
2614     if (nIdx >= 0)
2615         sServiceNameCC = sServiceNameCC.replaceAt( nIdx, strlen(aOldNamePart2), ".textfield." );
2616     return sServiceNameCC;
2617 }
2618 
2619 sal_Bool SAL_CALL SwXTextField::supportsService(const OUString& rServiceName)
2620 {
2621     return cppu::supportsService(this, rServiceName);
2622 }
2623 
2624 uno::Sequence< OUString > SAL_CALL SwXTextField::getSupportedServiceNames()
2625 {
2626     const OUString sServiceName =
2627         SwXServiceProvider::GetProviderName(m_pImpl->m_nServiceId);
2628 
2629     // case-corrected version of service-name (see #i67811)
2630     // (need to supply both because of compatibility to older versions)
2631     const OUString sServiceNameCC(  OldNameToNewName_Impl( sServiceName ) );
2632     sal_Int32 nLen = sServiceName == sServiceNameCC ? 2 : 3;
2633 
2634     uno::Sequence< OUString > aRet( nLen );
2635     OUString* pArray = aRet.getArray();
2636     *pArray++ = sServiceName;
2637     if (nLen == 3)
2638         *pArray++ = sServiceNameCC;
2639     *pArray++ = "com.sun.star.text.TextContent";
2640     return aRet;
2641 }
2642 
2643 void SwXTextField::Impl::Invalidate()
2644 {
2645     EndListeningAll();
2646     m_pFormatField = nullptr;
2647     m_pDoc = nullptr;
2648     uno::Reference<uno::XInterface> const xThis(m_wThis);
2649     if (!xThis.is())
2650     {   // fdo#72695: if UNO object is already dead, don't revive it with event
2651         return;
2652     }
2653     lang::EventObject const ev(xThis);
2654     m_EventListeners.disposeAndClear(ev);
2655 }
2656 
2657 void SwXTextField::Impl::Notify(const SfxHint& rHint)
2658 {
2659 
2660     if(rHint.GetId() == SfxHintId::Dying)
2661         Invalidate();
2662     else if (auto pLegacyHint = dynamic_cast<const sw::LegacyModifyHint*>(&rHint))
2663     {
2664         switch(pLegacyHint->m_pOld ? pLegacyHint->m_pOld->Which() : 0)
2665         {
2666             case RES_REMOVE_UNO_OBJECT:
2667             case RES_OBJECTDYING:
2668                 Invalidate();
2669                 break;
2670         }
2671     }
2672 }
2673 
2674 const SwField* SwXTextField::Impl::GetField() const
2675 {
2676     return IsDescriptor() ? nullptr : m_pFormatField->GetField();
2677 }
2678 
2679 OUString SwXTextFieldMasters::getImplementationName()
2680 {
2681     return OUString("SwXTextFieldMasters");
2682 }
2683 
2684 sal_Bool SwXTextFieldMasters::supportsService(const OUString& rServiceName)
2685 {
2686     return cppu::supportsService(this, rServiceName);
2687 }
2688 
2689 uno::Sequence< OUString > SwXTextFieldMasters::getSupportedServiceNames()
2690 {
2691     uno::Sequence<OUString> aRet { "com.sun.star.text.TextFieldMasters" };
2692     return aRet;
2693 }
2694 
2695 SwXTextFieldMasters::SwXTextFieldMasters(SwDoc* _pDoc) :
2696     SwUnoCollection(_pDoc)
2697 {
2698 }
2699 
2700 SwXTextFieldMasters::~SwXTextFieldMasters()
2701 {
2702 
2703 }
2704 
2705 /*
2706     Iteration over non-standard field types
2707     USER/SETEXP/DDE/DATABASE
2708     Thus the names are:
2709     "com.sun.star.text.fieldmaster.User" + <field type name>
2710     "com.sun.star.text.fieldmaster.DDE" + <field type name>
2711     "com.sun.star.text.fieldmaster.SetExpression" + <field type name>
2712     "com.sun.star.text.fieldmaster.DataBase" + <field type name>
2713 
2714     If too much, maybe one could leave out the "com.sun.star.text".
2715  */
2716 static SwFieldIds lcl_GetIdByName( OUString& rName, OUString& rTypeName )
2717 {
2718     if (rName.startsWithIgnoreAsciiCase(COM_TEXT_FLDMASTER_CC))
2719         rName = rName.copy(RTL_CONSTASCII_LENGTH(COM_TEXT_FLDMASTER_CC));
2720 
2721     SwFieldIds nResId = SwFieldIds::Unknown;
2722     sal_Int32 nIdx = 0;
2723     rTypeName = rName.getToken( 0, '.', nIdx );
2724     if (rTypeName == "User")
2725         nResId = SwFieldIds::User;
2726     else if (rTypeName == "DDE")
2727         nResId = SwFieldIds::Dde;
2728     else if (rTypeName == "SetExpression")
2729     {
2730         nResId = SwFieldIds::SetExp;
2731 
2732         const OUString sFieldTypName( rName.getToken( 0, '.', nIdx ));
2733         const OUString sUIName( SwStyleNameMapper::GetSpecialExtraUIName( sFieldTypName ) );
2734 
2735         if( sUIName != sFieldTypName )
2736             rName = comphelper::string::setToken(rName, 1, '.', sUIName);
2737     }
2738     else if (rTypeName.equalsIgnoreAsciiCase("DataBase"))
2739     {
2740         rName = rName.copy(RTL_CONSTASCII_LENGTH("DataBase."));
2741         if (!rName.isEmpty())
2742         {
2743             // #i51815#
2744             rName = "DataBase." + rName;
2745             nResId = SwFieldIds::Database;
2746         }
2747     }
2748     else if (rTypeName == "Bibliography")
2749         nResId = SwFieldIds::TableOfAuthorities;
2750     return nResId;
2751 }
2752 
2753 uno::Any SwXTextFieldMasters::getByName(const OUString& rName)
2754 {
2755     SolarMutexGuard aGuard;
2756     if(!GetDoc())
2757         throw uno::RuntimeException();
2758 
2759     OUString sName(rName), sTypeName;
2760     const SwFieldIds nResId = lcl_GetIdByName( sName, sTypeName );
2761     if( SwFieldIds::Unknown == nResId )
2762         throw container::NoSuchElementException(
2763             "SwXTextFieldMasters::getByName(" + rName + ")",
2764             css::uno::Reference<css::uno::XInterface>());
2765 
2766     sName = sName.copy(std::min(sTypeName.getLength()+1, sName.getLength()));
2767     SwFieldType* pType = GetDoc()->getIDocumentFieldsAccess().GetFieldType(nResId, sName, true);
2768     if(!pType)
2769         throw container::NoSuchElementException(
2770             "SwXTextFieldMasters::getByName(" + rName + ")",
2771             css::uno::Reference<css::uno::XInterface>());
2772 
2773     uno::Reference<beans::XPropertySet> const xRet(
2774             SwXFieldMaster::CreateXFieldMaster(GetDoc(), pType));
2775     return uno::makeAny(xRet);
2776 }
2777 
2778 bool SwXTextFieldMasters::getInstanceName(
2779     const SwFieldType& rFieldType, OUString& rName)
2780 {
2781     OUString sField;
2782 
2783     switch( rFieldType.Which() )
2784     {
2785     case SwFieldIds::User:
2786         sField = "User." + rFieldType.GetName();
2787         break;
2788     case SwFieldIds::Dde:
2789         sField = "DDE." + rFieldType.GetName();
2790         break;
2791 
2792     case SwFieldIds::SetExp:
2793         sField = "SetExpression." + SwStyleNameMapper::GetSpecialExtraProgName( rFieldType.GetName() );
2794         break;
2795 
2796     case SwFieldIds::Database:
2797         sField = "DataBase." + rFieldType.GetName().replaceAll(OUStringLiteral1(DB_DELIM), ".");
2798         break;
2799 
2800     case SwFieldIds::TableOfAuthorities:
2801         sField = "Bibliography";
2802         break;
2803 
2804     default:
2805         return false;
2806     }
2807 
2808     rName += COM_TEXT_FLDMASTER_CC + sField;
2809     return true;
2810 }
2811 
2812 uno::Sequence< OUString > SwXTextFieldMasters::getElementNames()
2813 {
2814     SolarMutexGuard aGuard;
2815     if(!GetDoc())
2816         throw uno::RuntimeException();
2817 
2818     const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
2819     const size_t nCount = pFieldTypes->size();
2820 
2821     std::vector<OUString> aFieldNames;
2822     for( size_t i = 0; i < nCount; ++i )
2823     {
2824         SwFieldType& rFieldType = *((*pFieldTypes)[i]);
2825 
2826         OUString sFieldName;
2827         if (SwXTextFieldMasters::getInstanceName(rFieldType, sFieldName))
2828         {
2829             aFieldNames.push_back(sFieldName);
2830         }
2831     }
2832 
2833     return comphelper::containerToSequence(aFieldNames);
2834 }
2835 
2836 sal_Bool SwXTextFieldMasters::hasByName(const OUString& rName)
2837 {
2838     SolarMutexGuard aGuard;
2839     if(!GetDoc())
2840         throw uno::RuntimeException();
2841 
2842     OUString sName(rName), sTypeName;
2843     const SwFieldIds nResId = lcl_GetIdByName( sName, sTypeName );
2844     bool bRet = false;
2845     if( SwFieldIds::Unknown != nResId )
2846     {
2847         sName = sName.copy(std::min(sTypeName.getLength()+1, sName.getLength()));
2848         bRet = nullptr != GetDoc()->getIDocumentFieldsAccess().GetFieldType(nResId, sName, true);
2849     }
2850     return bRet;
2851 }
2852 
2853 uno::Type  SwXTextFieldMasters::getElementType()
2854 {
2855     return cppu::UnoType<beans::XPropertySet>::get();
2856 
2857 }
2858 
2859 sal_Bool SwXTextFieldMasters::hasElements()
2860 {
2861     SolarMutexGuard aGuard;
2862     if(!IsValid())
2863         throw uno::RuntimeException();
2864     return true;
2865 }
2866 
2867 class SwXTextFieldTypes::Impl
2868 {
2869 private:
2870     ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
2871 
2872 public:
2873     ::comphelper::OInterfaceContainerHelper2 m_RefreshListeners;
2874 
2875     Impl() : m_RefreshListeners(m_Mutex) { }
2876 };
2877 
2878 OUString SwXTextFieldTypes::getImplementationName()
2879 {
2880     return OUString("SwXTextFieldTypes");
2881 }
2882 
2883 sal_Bool SwXTextFieldTypes::supportsService(const OUString& rServiceName)
2884 {
2885     return cppu::supportsService(this, rServiceName);
2886 }
2887 
2888 uno::Sequence< OUString > SwXTextFieldTypes::getSupportedServiceNames()
2889 {
2890     uno::Sequence<OUString> aRet { "com.sun.star.text.TextFields" };
2891     return aRet;
2892 }
2893 
2894 SwXTextFieldTypes::SwXTextFieldTypes(SwDoc* _pDoc)
2895     : SwUnoCollection (_pDoc)
2896     , m_pImpl(new Impl)
2897 {
2898 }
2899 
2900 SwXTextFieldTypes::~SwXTextFieldTypes()
2901 {
2902 }
2903 
2904 void SwXTextFieldTypes::Invalidate()
2905 {
2906     SwUnoCollection::Invalidate();
2907     lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(*this));
2908     m_pImpl->m_RefreshListeners.disposeAndClear(ev);
2909 }
2910 
2911 uno::Reference< container::XEnumeration >  SwXTextFieldTypes::createEnumeration()
2912 {
2913     SolarMutexGuard aGuard;
2914     if(!IsValid())
2915         throw uno::RuntimeException();
2916     return new SwXFieldEnumeration(*GetDoc());
2917 }
2918 
2919 uno::Type  SwXTextFieldTypes::getElementType()
2920 {
2921     return cppu::UnoType<text::XDependentTextField>::get();
2922 }
2923 
2924 sal_Bool SwXTextFieldTypes::hasElements()
2925 {
2926     SolarMutexGuard aGuard;
2927     if(!IsValid())
2928         throw uno::RuntimeException();
2929     return true; // they always exist
2930 }
2931 
2932 void SAL_CALL SwXTextFieldTypes::refresh()
2933 {
2934     {
2935         SolarMutexGuard aGuard;
2936         if (!IsValid())
2937             throw uno::RuntimeException();
2938         UnoActionContext aContext(GetDoc());
2939         GetDoc()->getIDocumentStatistics().UpdateDocStat( false, true );
2940         GetDoc()->getIDocumentFieldsAccess().UpdateFields(false);
2941     }
2942     // call refresh listeners (without SolarMutex locked)
2943     lang::EventObject const event(static_cast< ::cppu::OWeakObject*>(this));
2944     m_pImpl->m_RefreshListeners.notifyEach(
2945             & util::XRefreshListener::refreshed, event);
2946 }
2947 
2948 void SAL_CALL SwXTextFieldTypes::addRefreshListener(
2949         const uno::Reference<util::XRefreshListener> & xListener)
2950 {
2951     // no need to lock here as m_pImpl is const and container threadsafe
2952     m_pImpl->m_RefreshListeners.addInterface(xListener);
2953 }
2954 
2955 void SAL_CALL SwXTextFieldTypes::removeRefreshListener(
2956         const uno::Reference<util::XRefreshListener> & xListener)
2957 {
2958     // no need to lock here as m_pImpl is const and container threadsafe
2959     m_pImpl->m_RefreshListeners.removeInterface(xListener);
2960 }
2961 
2962 class SwXFieldEnumeration::Impl
2963     : public SvtListener
2964 {
2965 public:
2966     SwDoc* m_pDoc;
2967     std::vector<uno::Reference<text::XTextField>> m_Items;
2968     sal_Int32 m_nNextIndex;  ///< index of next element to be returned
2969 
2970     explicit Impl(SwDoc& rDoc)
2971         : m_pDoc(&rDoc)
2972         , m_nNextIndex(0)
2973     {
2974         StartListening(rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier());
2975     }
2976 
2977     virtual void Notify(const SfxHint& rHint) override
2978     {
2979         if(rHint.GetId() == SfxHintId::Dying)
2980             m_pDoc = nullptr;
2981     }
2982 };
2983 
2984 OUString SAL_CALL
2985 SwXFieldEnumeration::getImplementationName()
2986 {
2987     return OUString("SwXFieldEnumeration");
2988 }
2989 
2990 sal_Bool SAL_CALL SwXFieldEnumeration::supportsService(const OUString& rServiceName)
2991 {
2992     return cppu::supportsService(this, rServiceName);
2993 }
2994 
2995 uno::Sequence<OUString> SAL_CALL
2996 SwXFieldEnumeration::getSupportedServiceNames()
2997 {
2998     return { "com.sun.star.text.FieldEnumeration" };
2999 }
3000 
3001 SwXFieldEnumeration::SwXFieldEnumeration(SwDoc & rDoc)
3002     : m_pImpl(new Impl(rDoc))
3003 {
3004     // build sequence
3005     m_pImpl->m_Items.clear();
3006 
3007     const SwFieldTypes* pFieldTypes = m_pImpl->m_pDoc->getIDocumentFieldsAccess().GetFieldTypes();
3008     const size_t nCount = pFieldTypes->size();
3009     for(size_t nType = 0;  nType < nCount;  ++nType)
3010     {
3011         const SwFieldType *pCurType = (*pFieldTypes)[nType].get();
3012         SwIterator<SwFormatField,SwFieldType> aIter( *pCurType );
3013         const SwFormatField* pCurFieldFormat = aIter.First();
3014         while (pCurFieldFormat)
3015         {
3016             const SwTextField *pTextField = pCurFieldFormat->GetTextField();
3017             // skip fields that are currently not in the document
3018             // e.g. fields in undo or redo array
3019             bool bSkip = !pTextField ||
3020                          !pTextField->GetpTextNode()->GetNodes().IsDocNodes();
3021             if (!bSkip)
3022                 m_pImpl->m_Items.push_back( SwXTextField::CreateXTextField(
3023                         m_pImpl->m_pDoc, pCurFieldFormat));
3024             pCurFieldFormat = aIter.Next();
3025         }
3026     }
3027     // now handle meta-fields, which are not SwFields
3028     const std::vector< uno::Reference<text::XTextField> > MetaFields(
3029            m_pImpl->m_pDoc->GetMetaFieldManager().getMetaFields() );
3030     for (const auto & rMetaField : MetaFields)
3031     {
3032         m_pImpl->m_Items.push_back( rMetaField );
3033     }
3034 }
3035 
3036 SwXFieldEnumeration::~SwXFieldEnumeration()
3037 {
3038 }
3039 
3040 sal_Bool SAL_CALL SwXFieldEnumeration::hasMoreElements()
3041 {
3042     SolarMutexGuard aGuard;
3043 
3044     return m_pImpl->m_nNextIndex < static_cast<sal_Int32>(m_pImpl->m_Items.size());
3045 }
3046 
3047 uno::Any SAL_CALL SwXFieldEnumeration::nextElement()
3048 {
3049     SolarMutexGuard aGuard;
3050 
3051     if (m_pImpl->m_nNextIndex >= static_cast<sal_Int32>(m_pImpl->m_Items.size()))
3052         throw container::NoSuchElementException(
3053             "SwXFieldEnumeration::nextElement",
3054             css::uno::Reference<css::uno::XInterface>());
3055 
3056     uno::Reference< text::XTextField >  &rxField =
3057         m_pImpl->m_Items[ m_pImpl->m_nNextIndex++ ];
3058     uno::Any aRet;
3059     aRet <<= rxField;
3060     rxField = nullptr;  // free memory for item that is no longer used
3061     return aRet;
3062 }
3063 
3064 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
3065