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
