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 <textapi.hxx>
23
24 #include <hintids.hxx>
25 #include <com/sun/star/text/XText.hpp>
26 #include <com/sun/star/script/Converter.hpp>
27 #include <com/sun/star/text/PlaceholderType.hpp>
28 #include <com/sun/star/text/TemplateDisplayFormat.hpp>
29 #include <com/sun/star/text/PageNumberType.hpp>
30 #include <com/sun/star/text/FilenameDisplayFormat.hpp>
31 #include <com/sun/star/text/DocumentStatistic.hpp>
32 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
33 #include <com/sun/star/document/XDocumentProperties.hpp>
34 #include <com/sun/star/util/Date.hpp>
35 #include <com/sun/star/util/Duration.hpp>
36 #include <o3tl/any.hxx>
37 #include <unotools/localedatawrapper.hxx>
38 #include <editeng/unolingu.hxx>
39 #include <comphelper/processfactory.hxx>
40 #include <comphelper/string.hxx>
41 #include <tools/urlobj.hxx>
42 #include <vcl/svapp.hxx>
43 #include <svl/urihelper.hxx>
44 #include <unotools/useroptions.hxx>
45 #include <unotools/syslocale.hxx>
46 #include <svl/zforlist.hxx>
47 #include <libxml/xmlstring.h>
48 #include <libxml/xmlwriter.h>
49
50 #include <tools/time.hxx>
51 #include <tools/datetime.hxx>
52
53 #include <com/sun/star/util/DateTime.hpp>
54 #include <com/sun/star/util/Time.hpp>
55
56 #include <swmodule.hxx>
57 #include <sfx2/app.hxx>
58 #include <sfx2/docfile.hxx>
59 #include <sfx2/doctempl.hxx>
60 #include <fmtfld.hxx>
61 #include <txtfld.hxx>
62 #include <charfmt.hxx>
63 #include <docstat.hxx>
64 #include <pagedesc.hxx>
65 #include <fmtpdsc.hxx>
66 #include <doc.hxx>
67 #include <IDocumentFieldsAccess.hxx>
68 #include <IDocumentStatistics.hxx>
69 #include <IDocumentStylePoolAccess.hxx>
70 #include <IDocumentLayoutAccess.hxx>
71 #include <rootfrm.hxx>
72 #include <pagefrm.hxx>
73 #include <cntfrm.hxx>
74 #include <pam.hxx>
75 #include <viewsh.hxx>
76 #include <dbmgr.hxx>
77 #include <shellres.hxx>
78 #include <docufld.hxx>
79 #include <flddat.hxx>
80 #include <docfld.hxx>
81 #include <ndtxt.hxx>
82 #include <expfld.hxx>
83 #include <poolfmt.hxx>
84 #include <docsh.hxx>
85 #include <unofldmid.h>
86 #include <swunohelper.hxx>
87 #include <strings.hrc>
88
89 #include <editeng/outliner.hxx>
90 #include <editeng/outlobj.hxx>
91 #include <calbck.hxx>
92 #include <docary.hxx>
93 #include <hints.hxx>
94
95 #define URL_DECODE INetURLObject::DecodeMechanism::Unambiguous
96
97 using namespace ::com::sun::star;
98 using namespace ::com::sun::star::uno;
99 using namespace nsSwDocInfoSubType;
100
SwPageNumberFieldType()101 SwPageNumberFieldType::SwPageNumberFieldType()
102 : SwFieldType( SwFieldIds::PageNumber ),
103 m_nNumberingType( SVX_NUM_ARABIC ),
104 m_bVirtual( false )
105 {
106 }
107
Expand(SvxNumType nFormat,short nOff,sal_uInt16 const nPageNumber,sal_uInt16 const nMaxPage,const OUString & rUserStr,LanguageType nLang) const108 OUString SwPageNumberFieldType::Expand( SvxNumType nFormat, short nOff,
109 sal_uInt16 const nPageNumber, sal_uInt16 const nMaxPage,
110 const OUString& rUserStr, LanguageType nLang ) const
111 {
112 SvxNumType nTmpFormat = (SVX_NUM_PAGEDESC == nFormat) ? m_nNumberingType : nFormat;
113 int const nTmp = nPageNumber + nOff;
114
115 if (0 > nTmp || SVX_NUM_NUMBER_NONE == nTmpFormat || (!m_bVirtual && nTmp > nMaxPage))
116 return OUString();
117
118 if( SVX_NUM_CHAR_SPECIAL == nTmpFormat )
119 return rUserStr;
120
121 return FormatNumber( nTmp, nTmpFormat, nLang );
122 }
123
Copy() const124 std::unique_ptr<SwFieldType> SwPageNumberFieldType::Copy() const
125 {
126 std::unique_ptr<SwPageNumberFieldType> pTmp(new SwPageNumberFieldType());
127
128 pTmp->m_nNumberingType = m_nNumberingType;
129 pTmp->m_bVirtual = m_bVirtual;
130
131 return pTmp;
132 }
133
ChangeExpansion(SwDoc * pDoc,bool bVirt,const SvxNumType * pNumFormat)134 void SwPageNumberFieldType::ChangeExpansion( SwDoc* pDoc,
135 bool bVirt,
136 const SvxNumType* pNumFormat )
137 {
138 if( pNumFormat )
139 m_nNumberingType = *pNumFormat;
140
141 m_bVirtual = false;
142 if (bVirt && pDoc)
143 {
144 // check the flag since the layout NEVER sets it back
145 const SfxItemPool &rPool = pDoc->GetAttrPool();
146 for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_PAGEDESC))
147 {
148 auto pDesc = dynamic_cast<const SwFormatPageDesc*>(pItem);
149 if( pDesc && pDesc->GetNumOffset() && pDesc->GetDefinedIn() )
150 {
151 const SwContentNode* pNd = dynamic_cast<const SwContentNode*>( pDesc->GetDefinedIn() );
152 if( pNd )
153 {
154 if (SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti>(*pNd).First())
155 // sw_redlinehide: not sure if this should happen only if
156 // it's the first node, because that's where RES_PAGEDESC
157 // is effective?
158 m_bVirtual = true;
159 }
160 else if( dynamic_cast< const SwFormat* >(pDesc->GetDefinedIn()) != nullptr)
161 {
162 SwAutoFormatGetDocNode aGetHt( &pDoc->GetNodes() );
163 m_bVirtual = !pDesc->GetDefinedIn()->GetInfo( aGetHt );
164 break;
165 }
166 }
167 }
168 }
169 }
170
SwPageNumberField(SwPageNumberFieldType * pTyp,sal_uInt16 nSub,sal_uInt32 nFormat,short nOff,sal_uInt16 const nPageNumber,sal_uInt16 const nMaxPage)171 SwPageNumberField::SwPageNumberField(SwPageNumberFieldType* pTyp,
172 sal_uInt16 nSub, sal_uInt32 nFormat, short nOff,
173 sal_uInt16 const nPageNumber, sal_uInt16 const nMaxPage)
174 : SwField(pTyp, nFormat), m_nSubType(nSub), m_nOffset(nOff)
175 , m_nPageNumber(nPageNumber)
176 , m_nMaxPage(nMaxPage)
177 {
178 }
179
ChangeExpansion(sal_uInt16 const nPageNumber,sal_uInt16 const nMaxPage)180 void SwPageNumberField::ChangeExpansion(sal_uInt16 const nPageNumber,
181 sal_uInt16 const nMaxPage)
182 {
183 m_nPageNumber = nPageNumber;
184 m_nMaxPage = nMaxPage;
185 }
186
ExpandImpl(SwRootFrame const * const) const187 OUString SwPageNumberField::ExpandImpl(SwRootFrame const*const) const
188 {
189 OUString sRet;
190 SwPageNumberFieldType* pFieldType = static_cast<SwPageNumberFieldType*>(GetTyp());
191
192 if( PG_NEXT == m_nSubType && 1 != m_nOffset )
193 {
194 sRet = pFieldType->Expand(static_cast<SvxNumType>(GetFormat()), 1, m_nPageNumber, m_nMaxPage, m_sUserStr, GetLanguage());
195 if (!sRet.isEmpty())
196 {
197 sRet = pFieldType->Expand(static_cast<SvxNumType>(GetFormat()), m_nOffset, m_nPageNumber, m_nMaxPage, m_sUserStr, GetLanguage());
198 }
199 }
200 else if( PG_PREV == m_nSubType && -1 != m_nOffset )
201 {
202 sRet = pFieldType->Expand(static_cast<SvxNumType>(GetFormat()), -1, m_nPageNumber, m_nMaxPage, m_sUserStr, GetLanguage());
203 if (!sRet.isEmpty())
204 {
205 sRet = pFieldType->Expand(static_cast<SvxNumType>(GetFormat()), m_nOffset, m_nPageNumber, m_nMaxPage, m_sUserStr, GetLanguage());
206 }
207 }
208 else
209 sRet = pFieldType->Expand(static_cast<SvxNumType>(GetFormat()), m_nOffset, m_nPageNumber, m_nMaxPage, m_sUserStr, GetLanguage());
210 return sRet;
211 }
212
Copy() const213 std::unique_ptr<SwField> SwPageNumberField::Copy() const
214 {
215 std::unique_ptr<SwPageNumberField> pTmp(new SwPageNumberField(
216 static_cast<SwPageNumberFieldType*>(GetTyp()), m_nSubType,
217 GetFormat(), m_nOffset, m_nPageNumber, m_nMaxPage));
218 pTmp->SetLanguage( GetLanguage() );
219 pTmp->SetUserString( m_sUserStr );
220 return std::unique_ptr<SwField>(pTmp.release());
221 }
222
GetPar2() const223 OUString SwPageNumberField::GetPar2() const
224 {
225 return OUString::number(m_nOffset);
226 }
227
SetPar2(const OUString & rStr)228 void SwPageNumberField::SetPar2(const OUString& rStr)
229 {
230 m_nOffset = static_cast<short>(rStr.toInt32());
231 }
232
GetSubType() const233 sal_uInt16 SwPageNumberField::GetSubType() const
234 {
235 return m_nSubType;
236 }
237
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const238 bool SwPageNumberField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
239 {
240 switch( nWhichId )
241 {
242 case FIELD_PROP_FORMAT:
243 rAny <<= static_cast<sal_Int16>(GetFormat());
244 break;
245 case FIELD_PROP_USHORT1:
246 rAny <<= m_nOffset;
247 break;
248 case FIELD_PROP_SUBTYPE:
249 {
250 text::PageNumberType eType;
251 eType = text::PageNumberType_CURRENT;
252 if(m_nSubType == PG_PREV)
253 eType = text::PageNumberType_PREV;
254 else if(m_nSubType == PG_NEXT)
255 eType = text::PageNumberType_NEXT;
256 rAny <<= eType;
257 }
258 break;
259 case FIELD_PROP_PAR1:
260 rAny <<= m_sUserStr;
261 break;
262
263 default:
264 assert(false);
265 }
266 return true;
267 }
268
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)269 bool SwPageNumberField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
270 {
271 bool bRet = true;
272 sal_Int16 nSet = 0;
273 switch( nWhichId )
274 {
275 case FIELD_PROP_FORMAT:
276 rAny >>= nSet;
277
278 // TODO: where do the defines come from?
279 if(nSet <= SVX_NUM_PAGEDESC )
280 SetFormat(nSet);
281 break;
282 case FIELD_PROP_USHORT1:
283 rAny >>= nSet;
284 m_nOffset = nSet;
285 break;
286 case FIELD_PROP_SUBTYPE:
287 switch( static_cast<text::PageNumberType>(SWUnoHelper::GetEnumAsInt32( rAny )) )
288 {
289 case text::PageNumberType_CURRENT:
290 m_nSubType = PG_RANDOM;
291 break;
292 case text::PageNumberType_PREV:
293 m_nSubType = PG_PREV;
294 break;
295 case text::PageNumberType_NEXT:
296 m_nSubType = PG_NEXT;
297 break;
298 default:
299 bRet = false;
300 }
301 break;
302 case FIELD_PROP_PAR1:
303 rAny >>= m_sUserStr;
304 break;
305
306 default:
307 assert(false);
308 }
309 return bRet;
310 }
311
SwAuthorFieldType()312 SwAuthorFieldType::SwAuthorFieldType()
313 : SwFieldType( SwFieldIds::Author )
314 {
315 }
316
Expand(sal_uLong nFormat)317 OUString SwAuthorFieldType::Expand(sal_uLong nFormat)
318 {
319 SvtUserOptions& rOpt = SW_MOD()->GetUserOptions();
320 if((nFormat & 0xff) == AF_NAME)
321 return rOpt.GetFullName();
322
323 return rOpt.GetID();
324 }
325
Copy() const326 std::unique_ptr<SwFieldType> SwAuthorFieldType::Copy() const
327 {
328 return std::make_unique<SwAuthorFieldType>();
329 }
330
SwAuthorField(SwAuthorFieldType * pTyp,sal_uInt32 nFormat)331 SwAuthorField::SwAuthorField(SwAuthorFieldType* pTyp, sal_uInt32 nFormat)
332 : SwField(pTyp, nFormat)
333 {
334 m_aContent = SwAuthorFieldType::Expand(GetFormat());
335 }
336
ExpandImpl(SwRootFrame const * const) const337 OUString SwAuthorField::ExpandImpl(SwRootFrame const*const) const
338 {
339 if (!IsFixed())
340 const_cast<SwAuthorField*>(this)->m_aContent =
341 SwAuthorFieldType::Expand(GetFormat());
342
343 return m_aContent;
344 }
345
Copy() const346 std::unique_ptr<SwField> SwAuthorField::Copy() const
347 {
348 std::unique_ptr<SwAuthorField> pTmp(new SwAuthorField( static_cast<SwAuthorFieldType*>(GetTyp()),
349 GetFormat()));
350 pTmp->SetExpansion(m_aContent);
351 return std::unique_ptr<SwField>(pTmp.release());
352 }
353
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const354 bool SwAuthorField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
355 {
356 switch( nWhichId )
357 {
358 case FIELD_PROP_BOOL1:
359 rAny <<= (GetFormat() & 0xff) == AF_NAME;
360 break;
361
362 case FIELD_PROP_BOOL2:
363 rAny <<= IsFixed();
364 break;
365
366 case FIELD_PROP_PAR1:
367 rAny <<= m_aContent;
368 break;
369
370 default:
371 assert(false);
372 }
373 return true;
374 }
375
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)376 bool SwAuthorField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
377 {
378 switch( nWhichId )
379 {
380 case FIELD_PROP_BOOL1:
381 SetFormat( *o3tl::doAccess<bool>(rAny) ? AF_NAME : AF_SHORTCUT );
382 break;
383
384 case FIELD_PROP_BOOL2:
385 if( *o3tl::doAccess<bool>(rAny) )
386 SetFormat( GetFormat() | AF_FIXED);
387 else
388 SetFormat( GetFormat() & ~AF_FIXED);
389 break;
390
391 case FIELD_PROP_PAR1:
392 rAny >>= m_aContent;
393 break;
394
395 default:
396 assert(false);
397 }
398 return true;
399 }
400
SwFileNameFieldType(SwDoc * pDocument)401 SwFileNameFieldType::SwFileNameFieldType(SwDoc *pDocument)
402 : SwFieldType( SwFieldIds::Filename )
403 {
404 m_pDoc = pDocument;
405 }
406
Expand(sal_uLong nFormat) const407 OUString SwFileNameFieldType::Expand(sal_uLong nFormat) const
408 {
409 OUString aRet;
410 const SwDocShell* pDShell = m_pDoc->GetDocShell();
411 if( pDShell && pDShell->HasName() )
412 {
413 const INetURLObject& rURLObj = pDShell->GetMedium()->GetURLObject();
414 switch( nFormat & ~FF_FIXED )
415 {
416 case FF_PATH:
417 {
418 if( INetProtocol::File == rURLObj.GetProtocol() )
419 {
420 INetURLObject aTemp(rURLObj);
421 aTemp.removeSegment();
422 // last slash should belong to the pathname
423 aRet = aTemp.PathToFileName();
424 }
425 else
426 {
427 aRet = URIHelper::removePassword(
428 rURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ),
429 INetURLObject::EncodeMechanism::WasEncoded, URL_DECODE );
430 const sal_Int32 nPos = aRet.indexOf(rURLObj.GetLastName( URL_DECODE ));
431 if (nPos>=0)
432 {
433 aRet = aRet.copy(0, nPos);
434 }
435 }
436 }
437 break;
438
439 case FF_NAME:
440 aRet = rURLObj.GetLastName( INetURLObject::DecodeMechanism::WithCharset );
441 break;
442
443 case FF_NAME_NOEXT:
444 aRet = rURLObj.GetBase();
445 break;
446
447 default:
448 if( INetProtocol::File == rURLObj.GetProtocol() )
449 aRet = rURLObj.GetFull();
450 else
451 aRet = URIHelper::removePassword(
452 rURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ),
453 INetURLObject::EncodeMechanism::WasEncoded, URL_DECODE );
454 }
455 }
456 return aRet;
457 }
458
Copy() const459 std::unique_ptr<SwFieldType> SwFileNameFieldType::Copy() const
460 {
461 return std::make_unique<SwFileNameFieldType>(m_pDoc);
462 }
463
SwFileNameField(SwFileNameFieldType * pTyp,sal_uInt32 nFormat)464 SwFileNameField::SwFileNameField(SwFileNameFieldType* pTyp, sal_uInt32 nFormat)
465 : SwField(pTyp, nFormat)
466 {
467 m_aContent = static_cast<SwFileNameFieldType*>(GetTyp())->Expand(GetFormat());
468 }
469
ExpandImpl(SwRootFrame const * const) const470 OUString SwFileNameField::ExpandImpl(SwRootFrame const*const) const
471 {
472 if (!IsFixed())
473 const_cast<SwFileNameField*>(this)->m_aContent = static_cast<SwFileNameFieldType*>(GetTyp())->Expand(GetFormat());
474
475 return m_aContent;
476 }
477
Copy() const478 std::unique_ptr<SwField> SwFileNameField::Copy() const
479 {
480 std::unique_ptr<SwFileNameField> pTmp(
481 new SwFileNameField(static_cast<SwFileNameFieldType*>(GetTyp()), GetFormat()));
482 pTmp->SetExpansion(m_aContent);
483
484 return std::unique_ptr<SwField>(pTmp.release());
485 }
486
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const487 bool SwFileNameField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
488 {
489 switch( nWhichId )
490 {
491 case FIELD_PROP_FORMAT:
492 {
493 sal_Int16 nRet;
494 switch( GetFormat() &(~FF_FIXED) )
495 {
496 case FF_PATH:
497 nRet = text::FilenameDisplayFormat::PATH;
498 break;
499 case FF_NAME_NOEXT:
500 nRet = text::FilenameDisplayFormat::NAME;
501 break;
502 case FF_NAME:
503 nRet = text::FilenameDisplayFormat::NAME_AND_EXT;
504 break;
505 default: nRet = text::FilenameDisplayFormat::FULL;
506 }
507 rAny <<= nRet;
508 }
509 break;
510
511 case FIELD_PROP_BOOL2:
512 rAny <<= IsFixed();
513 break;
514
515 case FIELD_PROP_PAR3:
516 rAny <<= m_aContent;
517 break;
518
519 default:
520 assert(false);
521 }
522 return true;
523 }
524
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)525 bool SwFileNameField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
526 {
527 switch( nWhichId )
528 {
529 case FIELD_PROP_FORMAT:
530 {
531 //JP 24.10.2001: int32 because in UnoField.cxx a putvalue is
532 // called with a int32 value! But normally we need
533 // here only a int16
534 sal_Int32 nType = 0;
535 rAny >>= nType;
536 bool bFixed = IsFixed();
537 switch( nType )
538 {
539 case text::FilenameDisplayFormat::PATH:
540 nType = FF_PATH;
541 break;
542 case text::FilenameDisplayFormat::NAME:
543 nType = FF_NAME_NOEXT;
544 break;
545 case text::FilenameDisplayFormat::NAME_AND_EXT:
546 nType = FF_NAME;
547 break;
548 default: nType = FF_PATHNAME;
549 }
550 if(bFixed)
551 nType |= FF_FIXED;
552 SetFormat(nType);
553 }
554 break;
555
556 case FIELD_PROP_BOOL2:
557 if( *o3tl::doAccess<bool>(rAny) )
558 SetFormat( GetFormat() | FF_FIXED);
559 else
560 SetFormat( GetFormat() & ~FF_FIXED);
561 break;
562
563 case FIELD_PROP_PAR3:
564 rAny >>= m_aContent;
565 break;
566
567 default:
568 assert(false);
569 }
570 return true;
571 }
572
SwTemplNameFieldType(SwDoc * pDocument)573 SwTemplNameFieldType::SwTemplNameFieldType(SwDoc *pDocument)
574 : SwFieldType( SwFieldIds::TemplateName )
575 {
576 m_pDoc = pDocument;
577 }
578
Expand(sal_uLong nFormat) const579 OUString SwTemplNameFieldType::Expand(sal_uLong nFormat) const
580 {
581 OSL_ENSURE( nFormat < FF_END, "Expand: no valid Format!" );
582
583 OUString aRet;
584 SwDocShell *pDocShell(m_pDoc->GetDocShell());
585 OSL_ENSURE(pDocShell, "no SwDocShell");
586 if (pDocShell) {
587 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
588 pDocShell->GetModel(), uno::UNO_QUERY_THROW);
589 uno::Reference<document::XDocumentProperties> xDocProps(
590 xDPS->getDocumentProperties());
591 OSL_ENSURE(xDocProps.is(), "Doc has no DocumentProperties");
592
593 if( FF_UI_NAME == nFormat )
594 aRet = xDocProps->getTemplateName();
595 else if( !xDocProps->getTemplateURL().isEmpty() )
596 {
597 if( FF_UI_RANGE == nFormat )
598 {
599 // for getting region names!
600 SfxDocumentTemplates aFac;
601 OUString sTmp;
602 OUString sRegion;
603 aFac.GetLogicNames( xDocProps->getTemplateURL(), sRegion, sTmp );
604 aRet = sRegion;
605 }
606 else
607 {
608 INetURLObject aPathName( xDocProps->getTemplateURL() );
609 if( FF_NAME == nFormat )
610 aRet = aPathName.GetLastName(URL_DECODE);
611 else if( FF_NAME_NOEXT == nFormat )
612 aRet = aPathName.GetBase();
613 else
614 {
615 if( FF_PATH == nFormat )
616 {
617 aPathName.removeSegment();
618 aRet = aPathName.GetFull();
619 }
620 else
621 aRet = aPathName.GetFull();
622 }
623 }
624 }
625 }
626 return aRet;
627 }
628
Copy() const629 std::unique_ptr<SwFieldType> SwTemplNameFieldType::Copy() const
630 {
631 return std::make_unique<SwTemplNameFieldType>(m_pDoc);
632 }
633
SwTemplNameField(SwTemplNameFieldType * pTyp,sal_uInt32 nFormat)634 SwTemplNameField::SwTemplNameField(SwTemplNameFieldType* pTyp, sal_uInt32 nFormat)
635 : SwField(pTyp, nFormat)
636 {}
637
ExpandImpl(SwRootFrame const * const) const638 OUString SwTemplNameField::ExpandImpl(SwRootFrame const*const) const
639 {
640 return static_cast<SwTemplNameFieldType*>(GetTyp())->Expand(GetFormat());
641 }
642
Copy() const643 std::unique_ptr<SwField> SwTemplNameField::Copy() const
644 {
645 return std::make_unique<SwTemplNameField>(static_cast<SwTemplNameFieldType*>(GetTyp()), GetFormat());
646 }
647
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const648 bool SwTemplNameField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
649 {
650 switch ( nWhichId )
651 {
652 case FIELD_PROP_FORMAT:
653 {
654 sal_Int16 nRet;
655 switch( GetFormat() )
656 {
657 case FF_PATH: nRet = text::FilenameDisplayFormat::PATH; break;
658 case FF_NAME_NOEXT: nRet = text::FilenameDisplayFormat::NAME; break;
659 case FF_NAME: nRet = text::FilenameDisplayFormat::NAME_AND_EXT; break;
660 case FF_UI_RANGE: nRet = text::TemplateDisplayFormat::AREA; break;
661 case FF_UI_NAME: nRet = text::TemplateDisplayFormat::TITLE; break;
662 default: nRet = text::FilenameDisplayFormat::FULL;
663
664 }
665 rAny <<= nRet;
666 }
667 break;
668
669 default:
670 assert(false);
671 }
672 return true;
673 }
674
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)675 bool SwTemplNameField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
676 {
677 switch ( nWhichId )
678 {
679 case FIELD_PROP_FORMAT:
680 {
681 //JP 24.10.2001: int32 because in UnoField.cxx a putvalue is
682 // called with a int32 value! But normally we need
683 // here only a int16
684 sal_Int32 nType = 0;
685 rAny >>= nType;
686 switch( nType )
687 {
688 case text::FilenameDisplayFormat::PATH:
689 SetFormat(FF_PATH);
690 break;
691 case text::FilenameDisplayFormat::NAME:
692 SetFormat(FF_NAME_NOEXT);
693 break;
694 case text::FilenameDisplayFormat::NAME_AND_EXT:
695 SetFormat(FF_NAME);
696 break;
697 case text::TemplateDisplayFormat::AREA :
698 SetFormat(FF_UI_RANGE);
699 break;
700 case text::TemplateDisplayFormat::TITLE :
701 SetFormat(FF_UI_NAME);
702 break;
703 default: SetFormat(FF_PATHNAME);
704 }
705 }
706 break;
707
708 default:
709 assert(false);
710 }
711 return true;
712 }
713
SwDocStatFieldType(SwDoc * pDocument)714 SwDocStatFieldType::SwDocStatFieldType(SwDoc* pDocument)
715 : SwFieldType( SwFieldIds::DocStat ), m_nNumberingType( SVX_NUM_ARABIC )
716 {
717 m_pDoc = pDocument;
718 }
719
Expand(sal_uInt16 nSubType,SvxNumType nFormat) const720 OUString SwDocStatFieldType::Expand(sal_uInt16 nSubType, SvxNumType nFormat) const
721 {
722 sal_uInt32 nVal = 0;
723 const SwDocStat& rDStat = m_pDoc->getIDocumentStatistics().GetDocStat();
724 switch( nSubType )
725 {
726 case DS_TBL: nVal = rDStat.nTable; break;
727 case DS_GRF: nVal = rDStat.nGrf; break;
728 case DS_OLE: nVal = rDStat.nOLE; break;
729 case DS_PARA: nVal = rDStat.nPara; break;
730 case DS_WORD: nVal = rDStat.nWord; break;
731 case DS_CHAR: nVal = rDStat.nChar; break;
732 case DS_PAGE:
733 if( m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout() )
734 const_cast<SwDocStat &>(rDStat).nPage = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout()->GetPageNum();
735 nVal = rDStat.nPage;
736 if( SVX_NUM_PAGEDESC == nFormat )
737 nFormat = m_nNumberingType;
738 break;
739 default:
740 OSL_FAIL( "SwDocStatFieldType::Expand: unknown SubType" );
741 }
742
743 if( nVal <= SHRT_MAX )
744 return FormatNumber( nVal, nFormat );
745
746 return OUString::number( nVal );
747 }
748
Copy() const749 std::unique_ptr<SwFieldType> SwDocStatFieldType::Copy() const
750 {
751 return std::make_unique<SwDocStatFieldType>(m_pDoc);
752 }
753
754 /**
755 * @param pTyp
756 * @param nSub SubType
757 * @param nFormat
758 */
SwDocStatField(SwDocStatFieldType * pTyp,sal_uInt16 nSub,sal_uInt32 nFormat)759 SwDocStatField::SwDocStatField(SwDocStatFieldType* pTyp, sal_uInt16 nSub, sal_uInt32 nFormat)
760 : SwField(pTyp, nFormat),
761 m_nSubType(nSub)
762 {}
763
ExpandImpl(SwRootFrame const * const) const764 OUString SwDocStatField::ExpandImpl(SwRootFrame const*const) const
765 {
766 return static_cast<SwDocStatFieldType*>(GetTyp())->Expand(m_nSubType, static_cast<SvxNumType>(GetFormat()));
767 }
768
Copy() const769 std::unique_ptr<SwField> SwDocStatField::Copy() const
770 {
771 return std::make_unique<SwDocStatField>(
772 static_cast<SwDocStatFieldType*>(GetTyp()), m_nSubType, GetFormat() );
773 }
774
GetSubType() const775 sal_uInt16 SwDocStatField::GetSubType() const
776 {
777 return m_nSubType;
778 }
779
SetSubType(sal_uInt16 nSub)780 void SwDocStatField::SetSubType(sal_uInt16 nSub)
781 {
782 m_nSubType = nSub;
783 }
784
ChangeExpansion(const SwFrame * pFrame)785 void SwDocStatField::ChangeExpansion( const SwFrame* pFrame )
786 {
787 if( DS_PAGE == m_nSubType && SVX_NUM_PAGEDESC == GetFormat() )
788 static_cast<SwDocStatFieldType*>(GetTyp())->SetNumFormat(
789 pFrame->FindPageFrame()->GetPageDesc()->GetNumType().GetNumberingType() );
790 }
791
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const792 bool SwDocStatField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
793 {
794 switch ( nWhichId )
795 {
796 case FIELD_PROP_USHORT2:
797 rAny <<= static_cast<sal_Int16>(GetFormat());
798 break;
799
800 default:
801 assert(false);
802 }
803 return true;
804 }
805
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)806 bool SwDocStatField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
807 {
808 bool bRet = false;
809 switch ( nWhichId )
810 {
811 case FIELD_PROP_USHORT2:
812 {
813 sal_Int16 nSet = 0;
814 rAny >>= nSet;
815 if(nSet <= SVX_NUM_CHARS_LOWER_LETTER_N &&
816 nSet != SVX_NUM_CHAR_SPECIAL &&
817 nSet != SVX_NUM_BITMAP)
818 {
819 SetFormat(nSet);
820 bRet = true;
821 }
822 }
823 break;
824
825 default:
826 assert(false);
827 }
828 return bRet;
829 }
830
831 // Document info field type
832
SwDocInfoFieldType(SwDoc * pDc)833 SwDocInfoFieldType::SwDocInfoFieldType(SwDoc* pDc)
834 : SwValueFieldType( pDc, SwFieldIds::DocInfo )
835 {
836 }
837
Copy() const838 std::unique_ptr<SwFieldType> SwDocInfoFieldType::Copy() const
839 {
840 return std::make_unique<SwDocInfoFieldType>(GetDoc());
841 }
842
lcl_GetLocalDataWrapper(LanguageType nLang,const LocaleDataWrapper ** ppAppLocalData,const LocaleDataWrapper ** ppLocalData)843 static void lcl_GetLocalDataWrapper( LanguageType nLang,
844 const LocaleDataWrapper **ppAppLocalData,
845 const LocaleDataWrapper **ppLocalData )
846 {
847 SvtSysLocale aLocale;
848 *ppAppLocalData = &aLocale.GetLocaleData();
849 *ppLocalData = *ppAppLocalData;
850 if( nLang != (*ppLocalData)->getLanguageTag().getLanguageType() )
851 *ppLocalData = new LocaleDataWrapper(LanguageTag( nLang ));
852 }
853
Expand(sal_uInt16 nSub,sal_uInt32 nFormat,LanguageType nLang,const OUString & rName) const854 OUString SwDocInfoFieldType::Expand( sal_uInt16 nSub, sal_uInt32 nFormat,
855 LanguageType nLang, const OUString& rName ) const
856 {
857 const LocaleDataWrapper *pAppLocalData = nullptr, *pLocalData = nullptr;
858 SwDocShell *pDocShell(GetDoc()->GetDocShell());
859 OSL_ENSURE(pDocShell, "no SwDocShell");
860 if (!pDocShell) { return OUString(); }
861
862 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
863 pDocShell->GetModel(), uno::UNO_QUERY_THROW);
864 uno::Reference<document::XDocumentProperties> xDocProps(
865 xDPS->getDocumentProperties());
866 OSL_ENSURE(xDocProps.is(), "Doc has no DocumentProperties");
867
868 sal_uInt16 nExtSub = nSub & 0xff00;
869 nSub &= 0xff; // do not consider extended SubTypes
870
871 OUString aStr;
872 switch(nSub)
873 {
874 case DI_TITLE: aStr = xDocProps->getTitle(); break;
875 case DI_THEMA: aStr = xDocProps->getSubject(); break;
876 case DI_KEYS: aStr = ::comphelper::string::convertCommaSeparated(
877 xDocProps->getKeywords());
878 break;
879 case DI_COMMENT:aStr = xDocProps->getDescription(); break;
880 case DI_DOCNO: aStr = OUString::number(
881 xDocProps->getEditingCycles() );
882 break;
883 case DI_EDIT:
884 if ( !nFormat )
885 {
886 lcl_GetLocalDataWrapper( nLang, &pAppLocalData, &pLocalData );
887 sal_Int32 dur = xDocProps->getEditingDuration();
888 // If Seconds > 0 then bSec should be TRUE otherwise Seconds
889 // information will be lost if file has EditTime in Seconds format.
890 aStr = pLocalData->getTime( tools::Time(dur/3600, (dur%3600)/60, dur%60),
891 dur%60 > 0);
892 }
893 else
894 {
895 sal_Int32 dur = xDocProps->getEditingDuration();
896 double fVal = tools::Time(dur/3600, (dur%3600)/60, dur%60).GetTimeInDays();
897 aStr = ExpandValue(fVal, nFormat, nLang);
898 }
899 break;
900 case DI_CUSTOM:
901 {
902 OUString sVal;
903 try
904 {
905 uno::Any aAny;
906 uno::Reference < beans::XPropertySet > xSet(
907 xDocProps->getUserDefinedProperties(),
908 uno::UNO_QUERY_THROW);
909 aAny = xSet->getPropertyValue( rName );
910
911 uno::Reference < script::XTypeConverter > xConverter( script::Converter::create(comphelper::getProcessComponentContext()) );
912 uno::Any aNew = xConverter->convertToSimpleType( aAny, uno::TypeClass_STRING );
913 aNew >>= sVal;
914 }
915 catch (uno::Exception&) {}
916 return sVal;
917 }
918
919 default:
920 {
921 OUString aName( xDocProps->getAuthor() );
922 util::DateTime uDT( xDocProps->getCreationDate() );
923 DateTime aDate(uDT);
924 if( nSub == DI_CREATE )
925 ; // that's it !!
926 else if( nSub == DI_CHANGE )
927 {
928 aName = xDocProps->getModifiedBy();
929 uDT = xDocProps->getModificationDate();
930 aDate = DateTime(uDT);
931 }
932 else if( nSub == DI_PRINT )
933 {
934 aName = xDocProps->getPrintedBy();
935 uDT = xDocProps->getPrintDate();
936 aDate = DateTime(uDT);
937 }
938 else
939 break;
940
941 if (aDate.IsValidAndGregorian())
942 {
943 switch (nExtSub & ~DI_SUB_FIXED)
944 {
945 case DI_SUB_AUTHOR:
946 aStr = aName;
947 break;
948
949 case DI_SUB_TIME:
950 if (!nFormat)
951 {
952 lcl_GetLocalDataWrapper( nLang, &pAppLocalData,
953 &pLocalData );
954 aStr = pLocalData->getTime( aDate,
955 false);
956 }
957 else
958 {
959 // start the number formatter
960 double fVal = SwDateTimeField::GetDateTime( GetDoc(),
961 aDate);
962 aStr = ExpandValue(fVal, nFormat, nLang);
963 }
964 break;
965
966 case DI_SUB_DATE:
967 if (!nFormat)
968 {
969 lcl_GetLocalDataWrapper( nLang, &pAppLocalData,
970 &pLocalData );
971 aStr = pLocalData->getDate( aDate );
972 }
973 else
974 {
975 // start the number formatter
976 double fVal = SwDateTimeField::GetDateTime( GetDoc(),
977 aDate);
978 aStr = ExpandValue(fVal, nFormat, nLang);
979 }
980 break;
981 }
982 }
983 }
984 break;
985 }
986
987 if( pAppLocalData != pLocalData )
988 delete pLocalData;
989
990 return aStr;
991 }
992
993 // document info field
994
SwDocInfoField(SwDocInfoFieldType * pTyp,sal_uInt16 nSub,const OUString & rName,sal_uInt32 nFormat)995 SwDocInfoField::SwDocInfoField(SwDocInfoFieldType* pTyp, sal_uInt16 nSub, const OUString& rName, sal_uInt32 nFormat) :
996 SwValueField(pTyp, nFormat), m_nSubType(nSub)
997 {
998 m_aName = rName;
999 m_aContent = static_cast<SwDocInfoFieldType*>(GetTyp())->Expand(m_nSubType, nFormat, GetLanguage(), m_aName);
1000 }
1001
SwDocInfoField(SwDocInfoFieldType * pTyp,sal_uInt16 nSub,const OUString & rName,const OUString & rValue,sal_uInt32 nFormat)1002 SwDocInfoField::SwDocInfoField(SwDocInfoFieldType* pTyp, sal_uInt16 nSub, const OUString& rName, const OUString& rValue, sal_uInt32 nFormat) :
1003 SwValueField(pTyp, nFormat), m_nSubType(nSub)
1004 {
1005 m_aName = rName;
1006 m_aContent = rValue;
1007 }
1008
1009 template<class T>
lcl_TimeToDouble(const T & rTime)1010 static double lcl_TimeToDouble( const T& rTime )
1011 {
1012 const double fNanoSecondsPerDay = 86400000000000.0;
1013 return ( (rTime.Hours * SAL_CONST_INT64(3600000000000))
1014 + (rTime.Minutes * SAL_CONST_INT64( 60000000000))
1015 + (rTime.Seconds * SAL_CONST_INT64( 1000000000))
1016 + (rTime.NanoSeconds))
1017 / fNanoSecondsPerDay;
1018 }
1019
1020 template<class D>
lcl_DateToDouble(const D & rDate,const Date & rNullDate)1021 static double lcl_DateToDouble( const D& rDate, const Date& rNullDate )
1022 {
1023 long nDate = Date::DateToDays( rDate.Day, rDate.Month, rDate.Year );
1024 long nNullDate = Date::DateToDays( rNullDate.GetDay(), rNullDate.GetMonth(), rNullDate.GetYear() );
1025 return double( nDate - nNullDate );
1026 }
1027
ExpandImpl(SwRootFrame const * const) const1028 OUString SwDocInfoField::ExpandImpl(SwRootFrame const*const) const
1029 {
1030 if ( ( m_nSubType & 0xFF ) == DI_CUSTOM )
1031 {
1032 // custom properties currently need special treatment
1033 // We don't have a secure way to detect "real" custom properties in Word import of text
1034 // fields, so we treat *every* unknown property as a custom property, even the "built-in"
1035 // section in Word's document summary information stream as these properties have not been
1036 // inserted when the document summary information was imported, we do it here.
1037 // This approach is still a lot better than the old one to import such fields as
1038 // "user fields" and simple text
1039 SwDocShell* pDocShell = GetDoc()->GetDocShell();
1040 if( !pDocShell )
1041 return m_aContent;
1042 try
1043 {
1044 uno::Reference<document::XDocumentPropertiesSupplier> xDPS( pDocShell->GetModel(), uno::UNO_QUERY_THROW);
1045 uno::Reference<document::XDocumentProperties> xDocProps( xDPS->getDocumentProperties());
1046 uno::Reference < beans::XPropertySet > xSet( xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
1047 uno::Reference < beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo();
1048
1049 uno::Any aAny;
1050 if( xSetInfo->hasPropertyByName( m_aName ) )
1051 aAny = xSet->getPropertyValue( m_aName );
1052 if ( aAny.getValueType() != cppu::UnoType<void>::get() )
1053 {
1054 // "void" type means that the property has not been inserted until now
1055 if ( !IsFixed() )
1056 {
1057 // if the field is "fixed" we don't update it from the property
1058 OUString sVal;
1059 uno::Reference < script::XTypeConverter > xConverter( script::Converter::create(comphelper::getProcessComponentContext()) );
1060 util::Date aDate;
1061 util::DateTime aDateTime;
1062 util::Duration aDuration;
1063 if( aAny >>= aDate)
1064 {
1065 SvNumberFormatter* pFormatter = pDocShell->GetDoc()->GetNumberFormatter();
1066 const Date& rNullDate = pFormatter->GetNullDate();
1067 sVal = ExpandValue( lcl_DateToDouble<util::Date>( aDate, rNullDate ), GetFormat(), GetLanguage());
1068 }
1069 else if( aAny >>= aDateTime )
1070 {
1071 double fDateTime = lcl_TimeToDouble<util::DateTime>( aDateTime );
1072 SvNumberFormatter* pFormatter = pDocShell->GetDoc()->GetNumberFormatter();
1073 const Date& rNullDate = pFormatter->GetNullDate();
1074 fDateTime += lcl_DateToDouble<util::DateTime>( aDateTime, rNullDate );
1075 sVal = ExpandValue( fDateTime, GetFormat(), GetLanguage());
1076 }
1077 else if( aAny >>= aDuration )
1078 {
1079 sVal = OUStringChar(aDuration.Negative ? '-' : '+')
1080 + SwViewShell::GetShellRes()->sDurationFormat;
1081 sVal = sVal.replaceFirst("%1", OUString::number( aDuration.Years ) );
1082 sVal = sVal.replaceFirst("%2", OUString::number( aDuration.Months ) );
1083 sVal = sVal.replaceFirst("%3", OUString::number( aDuration.Days ) );
1084 sVal = sVal.replaceFirst("%4", OUString::number( aDuration.Hours ) );
1085 sVal = sVal.replaceFirst("%5", OUString::number( aDuration.Minutes) );
1086 sVal = sVal.replaceFirst("%6", OUString::number( aDuration.Seconds) );
1087 }
1088 else
1089 {
1090 uno::Any aNew = xConverter->convertToSimpleType( aAny, uno::TypeClass_STRING );
1091 aNew >>= sVal;
1092 }
1093 const_cast<SwDocInfoField*>(this)->m_aContent = sVal;
1094 }
1095 }
1096 }
1097 catch (uno::Exception&) {}
1098 }
1099 else if ( !IsFixed() )
1100 const_cast<SwDocInfoField*>(this)->m_aContent = static_cast<SwDocInfoFieldType*>(GetTyp())->Expand(m_nSubType, GetFormat(), GetLanguage(), m_aName);
1101
1102 return m_aContent;
1103 }
1104
GetFieldName() const1105 OUString SwDocInfoField::GetFieldName() const
1106 {
1107 OUString aStr(SwFieldType::GetTypeStr(GetTypeId()) + ":");
1108
1109 sal_uInt16 const nSub = m_nSubType & 0xff;
1110
1111 switch (nSub)
1112 {
1113 case DI_CUSTOM:
1114 aStr += m_aName;
1115 break;
1116
1117 default:
1118 aStr += SwViewShell::GetShellRes()
1119 ->aDocInfoLst[ nSub - DI_SUBTYPE_BEGIN ];
1120 break;
1121 }
1122 if (IsFixed())
1123 {
1124 aStr += " " + SwViewShell::GetShellRes()->aFixedStr;
1125 }
1126 return aStr;
1127 }
1128
Copy() const1129 std::unique_ptr<SwField> SwDocInfoField::Copy() const
1130 {
1131 std::unique_ptr<SwDocInfoField> pField(new SwDocInfoField(static_cast<SwDocInfoFieldType*>(GetTyp()), m_nSubType, m_aName, GetFormat()));
1132 pField->SetAutomaticLanguage(IsAutomaticLanguage());
1133 pField->m_aContent = m_aContent;
1134
1135 return std::unique_ptr<SwField>(pField.release());
1136 }
1137
GetSubType() const1138 sal_uInt16 SwDocInfoField::GetSubType() const
1139 {
1140 return m_nSubType;
1141 }
1142
SetSubType(sal_uInt16 nSub)1143 void SwDocInfoField::SetSubType(sal_uInt16 nSub)
1144 {
1145 m_nSubType = nSub;
1146 }
1147
SetLanguage(LanguageType nLng)1148 void SwDocInfoField::SetLanguage(LanguageType nLng)
1149 {
1150 if (!GetFormat())
1151 SwField::SetLanguage(nLng);
1152 else
1153 SwValueField::SetLanguage(nLng);
1154 }
1155
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const1156 bool SwDocInfoField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
1157 {
1158 switch( nWhichId )
1159 {
1160 case FIELD_PROP_PAR1:
1161 rAny <<= m_aContent;
1162 break;
1163
1164 case FIELD_PROP_PAR4:
1165 rAny <<= m_aName;
1166 break;
1167
1168 case FIELD_PROP_USHORT1:
1169 rAny <<= static_cast<sal_Int16>(m_aContent.toInt32());
1170 break;
1171
1172 case FIELD_PROP_BOOL1:
1173 rAny <<= 0 != (m_nSubType & DI_SUB_FIXED);
1174 break;
1175
1176 case FIELD_PROP_FORMAT:
1177 rAny <<= static_cast<sal_Int32>(GetFormat());
1178 break;
1179
1180 case FIELD_PROP_DOUBLE:
1181 {
1182 double fVal = GetValue();
1183 rAny <<= fVal;
1184 }
1185 break;
1186 case FIELD_PROP_PAR3:
1187 rAny <<= ExpandImpl(nullptr);
1188 break;
1189 case FIELD_PROP_BOOL2:
1190 {
1191 sal_uInt16 nExtSub = (m_nSubType & 0xff00) & ~DI_SUB_FIXED;
1192 rAny <<= nExtSub == DI_SUB_DATE;
1193 }
1194 break;
1195 default:
1196 return SwField::QueryValue(rAny, nWhichId);
1197 }
1198 return true;
1199 }
1200
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)1201 bool SwDocInfoField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
1202 {
1203 sal_Int32 nValue = 0;
1204 switch( nWhichId )
1205 {
1206 case FIELD_PROP_PAR1:
1207 if( m_nSubType & DI_SUB_FIXED )
1208 rAny >>= m_aContent;
1209 break;
1210
1211 case FIELD_PROP_USHORT1:
1212 if( m_nSubType & DI_SUB_FIXED )
1213 {
1214 rAny >>= nValue;
1215 m_aContent = OUString::number(nValue);
1216 }
1217 break;
1218
1219 case FIELD_PROP_BOOL1:
1220 if(*o3tl::doAccess<bool>(rAny))
1221 m_nSubType |= DI_SUB_FIXED;
1222 else
1223 m_nSubType &= ~DI_SUB_FIXED;
1224 break;
1225 case FIELD_PROP_FORMAT:
1226 {
1227 rAny >>= nValue;
1228 if( nValue >= 0)
1229 SetFormat(nValue);
1230 }
1231 break;
1232
1233 case FIELD_PROP_PAR3:
1234 rAny >>= m_aContent;
1235 break;
1236 case FIELD_PROP_BOOL2:
1237 m_nSubType &= 0xf0ff;
1238 if(*o3tl::doAccess<bool>(rAny))
1239 m_nSubType |= DI_SUB_DATE;
1240 else
1241 m_nSubType |= DI_SUB_TIME;
1242 break;
1243 default:
1244 return SwField::PutValue(rAny, nWhichId);
1245 }
1246 return true;
1247 }
1248
SwHiddenTextFieldType(bool bSetHidden)1249 SwHiddenTextFieldType::SwHiddenTextFieldType( bool bSetHidden )
1250 : SwFieldType( SwFieldIds::HiddenText ), m_bHidden( bSetHidden )
1251 {
1252 }
1253
Copy() const1254 std::unique_ptr<SwFieldType> SwHiddenTextFieldType::Copy() const
1255 {
1256 return std::make_unique<SwHiddenTextFieldType>( m_bHidden );
1257 }
1258
SetHiddenFlag(bool bSetHidden)1259 void SwHiddenTextFieldType::SetHiddenFlag( bool bSetHidden )
1260 {
1261 if( m_bHidden != bSetHidden )
1262 {
1263 m_bHidden = bSetHidden;
1264 UpdateFields(); // notify all HiddenTexts
1265 }
1266 }
1267
SwHiddenTextField(SwHiddenTextFieldType * pFieldType,bool bConditional,const OUString & rCond,const OUString & rStr,bool bHidden,SwFieldTypesEnum nSub)1268 SwHiddenTextField::SwHiddenTextField( SwHiddenTextFieldType* pFieldType,
1269 bool bConditional,
1270 const OUString& rCond,
1271 const OUString& rStr,
1272 bool bHidden,
1273 SwFieldTypesEnum nSub) :
1274 SwField( pFieldType ), m_aCond(rCond), m_nSubType(nSub),
1275 m_bCanToggle(bConditional), m_bIsHidden(bHidden), m_bValid(false)
1276 {
1277 if(m_nSubType == SwFieldTypesEnum::ConditionalText)
1278 {
1279 sal_Int32 nPos = 0;
1280 m_aTRUEText = rStr.getToken(0, '|', nPos);
1281
1282 if(nPos != -1)
1283 {
1284 m_aFALSEText = rStr.getToken(0, '|', nPos);
1285 if(nPos != -1)
1286 {
1287 m_aContent = rStr.getToken(0, '|', nPos);
1288 m_bValid = true;
1289 }
1290 }
1291 }
1292 else
1293 m_aTRUEText = rStr;
1294 }
1295
SwHiddenTextField(SwHiddenTextFieldType * pFieldType,const OUString & rCond,const OUString & rTrue,const OUString & rFalse,SwFieldTypesEnum nSub)1296 SwHiddenTextField::SwHiddenTextField( SwHiddenTextFieldType* pFieldType,
1297 const OUString& rCond,
1298 const OUString& rTrue,
1299 const OUString& rFalse,
1300 SwFieldTypesEnum nSub)
1301 : SwField( pFieldType ), m_aTRUEText(rTrue), m_aFALSEText(rFalse), m_aCond(rCond), m_nSubType(nSub),
1302 m_bIsHidden(true), m_bValid(false)
1303 {
1304 m_bCanToggle = !m_aCond.isEmpty();
1305 }
1306
ExpandImpl(SwRootFrame const * const) const1307 OUString SwHiddenTextField::ExpandImpl(SwRootFrame const*const) const
1308 {
1309 // Type: !Hidden -> show always
1310 // Hide -> evaluate condition
1311
1312 if( SwFieldTypesEnum::ConditionalText == m_nSubType )
1313 {
1314 if( m_bValid )
1315 return m_aContent;
1316
1317 if( m_bCanToggle && !m_bIsHidden )
1318 return m_aTRUEText;
1319 }
1320 else if( !static_cast<SwHiddenTextFieldType*>(GetTyp())->GetHiddenFlag() ||
1321 ( m_bCanToggle && m_bIsHidden ))
1322 return m_aTRUEText;
1323
1324 return m_aFALSEText;
1325 }
1326
1327 /// get current field value and cache it
Evaluate(SwDoc * pDoc)1328 void SwHiddenTextField::Evaluate(SwDoc* pDoc)
1329 {
1330 OSL_ENSURE(pDoc, "got no document");
1331
1332 if( SwFieldTypesEnum::ConditionalText == m_nSubType )
1333 {
1334 #if !HAVE_FEATURE_DBCONNECTIVITY
1335 (void) pDoc;
1336 #else
1337 SwDBManager* pMgr = pDoc->GetDBManager();
1338 #endif
1339 m_bValid = false;
1340 OUString sTmpName = (m_bCanToggle && !m_bIsHidden) ? m_aTRUEText : m_aFALSEText;
1341
1342 // Database expressions need to be different from normal text. Therefore, normal text is set
1343 // in quotes. If the latter exist they will be removed. If not, check if potential DB name.
1344 // Only if there are two or more dots and no quotes, we assume a database.
1345 if (sTmpName.getLength()>1 &&
1346 sTmpName.startsWith("\"") &&
1347 sTmpName.endsWith("\""))
1348 {
1349 m_aContent = sTmpName.copy(1, sTmpName.getLength() - 2);
1350 m_bValid = true;
1351 }
1352 else if(sTmpName.indexOf('\"')<0 &&
1353 comphelper::string::getTokenCount(sTmpName, '.') > 2)
1354 {
1355 sTmpName = ::ReplacePoint(sTmpName);
1356 if(sTmpName.startsWith("[") && sTmpName.endsWith("]"))
1357 { // remove brackets
1358 sTmpName = sTmpName.copy(1, sTmpName.getLength() - 2);
1359 }
1360 #if HAVE_FEATURE_DBCONNECTIVITY
1361 if( pMgr)
1362 {
1363 sal_Int32 nIdx{ 0 };
1364 OUString sDBName( GetDBName( sTmpName, pDoc ));
1365 OUString sDataSource(sDBName.getToken(0, DB_DELIM, nIdx));
1366 OUString sDataTableOrQuery(sDBName.getToken(0, DB_DELIM, nIdx));
1367 if( pMgr->IsInMerge() && !sDBName.isEmpty() &&
1368 pMgr->IsDataSourceOpen( sDataSource,
1369 sDataTableOrQuery, false))
1370 {
1371 double fNumber;
1372 pMgr->GetMergeColumnCnt(GetColumnName( sTmpName ),
1373 GetLanguage(), m_aContent, &fNumber );
1374 m_bValid = true;
1375 }
1376 else if( !sDBName.isEmpty() && !sDataSource.isEmpty() &&
1377 !sDataTableOrQuery.isEmpty() )
1378 m_bValid = true;
1379 }
1380 #endif
1381 }
1382 }
1383 }
1384
GetFieldName() const1385 OUString SwHiddenTextField::GetFieldName() const
1386 {
1387 OUString aStr = SwFieldType::GetTypeStr(m_nSubType) +
1388 " " + m_aCond + " " + m_aTRUEText;
1389
1390 if (m_nSubType == SwFieldTypesEnum::ConditionalText)
1391 {
1392 aStr += " : " + m_aFALSEText;
1393 }
1394 return aStr;
1395 }
1396
Copy() const1397 std::unique_ptr<SwField> SwHiddenTextField::Copy() const
1398 {
1399 std::unique_ptr<SwHiddenTextField> pField(
1400 new SwHiddenTextField(static_cast<SwHiddenTextFieldType*>(GetTyp()), m_aCond,
1401 m_aTRUEText, m_aFALSEText));
1402 pField->m_bIsHidden = m_bIsHidden;
1403 pField->m_bValid = m_bValid;
1404 pField->m_aContent = m_aContent;
1405 pField->SetFormat(GetFormat());
1406 pField->m_nSubType = m_nSubType;
1407 return std::unique_ptr<SwField>(pField.release());
1408 }
1409
1410 /// set condition
SetPar1(const OUString & rStr)1411 void SwHiddenTextField::SetPar1(const OUString& rStr)
1412 {
1413 m_aCond = rStr;
1414 m_bCanToggle = !m_aCond.isEmpty();
1415 }
1416
GetPar1() const1417 OUString SwHiddenTextField::GetPar1() const
1418 {
1419 return m_aCond;
1420 }
1421
1422 /// set True/False text
SetPar2(const OUString & rStr)1423 void SwHiddenTextField::SetPar2(const OUString& rStr)
1424 {
1425 if (m_nSubType == SwFieldTypesEnum::ConditionalText)
1426 {
1427 sal_Int32 nPos = rStr.indexOf('|');
1428 if (nPos == -1)
1429 m_aTRUEText = rStr;
1430 else
1431 {
1432 m_aTRUEText = rStr.copy(0, nPos);
1433 m_aFALSEText = rStr.copy(nPos + 1);
1434 }
1435 }
1436 else
1437 m_aTRUEText = rStr;
1438 }
1439
1440 /// get True/False text
GetPar2() const1441 OUString SwHiddenTextField::GetPar2() const
1442 {
1443 if(m_nSubType != SwFieldTypesEnum::ConditionalText)
1444 {
1445 return m_aTRUEText;
1446 }
1447 return m_aTRUEText + "|" + m_aFALSEText;
1448 }
1449
GetSubType() const1450 sal_uInt16 SwHiddenTextField::GetSubType() const
1451 {
1452 return static_cast<sal_uInt16>(m_nSubType);
1453 }
1454
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const1455 bool SwHiddenTextField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
1456 {
1457 switch( nWhichId )
1458 {
1459 case FIELD_PROP_PAR1:
1460 rAny <<= m_aCond;
1461 break;
1462 case FIELD_PROP_PAR2:
1463 rAny <<= m_aTRUEText;
1464 break;
1465 case FIELD_PROP_PAR3:
1466 rAny <<= m_aFALSEText;
1467 break;
1468 case FIELD_PROP_PAR4 :
1469 rAny <<= m_aContent;
1470 break;
1471 case FIELD_PROP_BOOL1:
1472 rAny <<= m_bIsHidden;
1473 break;
1474 default:
1475 assert(false);
1476 }
1477 return true;
1478 }
1479
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)1480 bool SwHiddenTextField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
1481 {
1482 switch( nWhichId )
1483 {
1484 case FIELD_PROP_PAR1:
1485 {
1486 OUString sVal;
1487 rAny >>= sVal;
1488 SetPar1(sVal);
1489 }
1490 break;
1491 case FIELD_PROP_PAR2:
1492 rAny >>= m_aTRUEText;
1493 break;
1494 case FIELD_PROP_PAR3:
1495 rAny >>= m_aFALSEText;
1496 break;
1497 case FIELD_PROP_BOOL1:
1498 m_bIsHidden = *o3tl::doAccess<bool>(rAny);
1499 break;
1500 case FIELD_PROP_PAR4:
1501 rAny >>= m_aContent;
1502 m_bValid = true;
1503 break;
1504 default:
1505 assert(false);
1506 }
1507 return true;
1508 }
1509
GetColumnName(const OUString & rName)1510 OUString SwHiddenTextField::GetColumnName(const OUString& rName)
1511 {
1512 sal_Int32 nPos = rName.indexOf(DB_DELIM);
1513 if( nPos>=0 )
1514 {
1515 nPos = rName.indexOf(DB_DELIM, nPos + 1);
1516
1517 if( nPos>=0 )
1518 return rName.copy(nPos + 1);
1519 }
1520 return rName;
1521 }
1522
GetDBName(const OUString & rName,SwDoc * pDoc)1523 OUString SwHiddenTextField::GetDBName(const OUString& rName, SwDoc *pDoc)
1524 {
1525 sal_Int32 nPos = rName.indexOf(DB_DELIM);
1526 if( nPos>=0 )
1527 {
1528 nPos = rName.indexOf(DB_DELIM, nPos + 1);
1529
1530 if( nPos>=0 )
1531 return rName.copy(0, nPos);
1532 }
1533
1534 SwDBData aData = pDoc->GetDBData();
1535 return aData.sDataSource + OUStringChar(DB_DELIM) + aData.sCommand;
1536 }
1537
1538 // [aFieldDefinition] value sample : " IF A == B \"TrueText\" \"FalseText\""
ParseIfFieldDefinition(const OUString & aFieldDefinition,OUString & rCondition,OUString & rTrue,OUString & rFalse)1539 void SwHiddenTextField::ParseIfFieldDefinition(const OUString& aFieldDefinition,
1540 OUString& rCondition,
1541 OUString& rTrue,
1542 OUString& rFalse)
1543 {
1544 // get all positions inside the input string where words are started
1545 //
1546 // In: " IF A == B \"TrueText\" \"FalseText\""
1547 // 0 1 2 3
1548 // 01234567890 123456789 01 2345678901 2
1549 //
1550 // result:
1551 // [1, 4, 6, 9, 11, 22]
1552 std::vector<sal_Int32> wordPosition;
1553 {
1554 bool quoted = false;
1555 bool insideWord = false;
1556 for (sal_Int32 i = 0; i < aFieldDefinition.getLength(); i++)
1557 {
1558 if (quoted)
1559 {
1560 if (aFieldDefinition[i] == '\"')
1561 {
1562 quoted = false;
1563 insideWord = false;
1564 }
1565 }
1566 else
1567 {
1568 if (aFieldDefinition[i] == ' ')
1569 {
1570 // word delimiter
1571 insideWord = false;
1572 }
1573 else
1574 {
1575 if (insideWord)
1576 {
1577 quoted = (aFieldDefinition[i] == '\"');
1578 }
1579 else
1580 {
1581 insideWord = true;
1582 wordPosition.push_back(i);
1583 quoted = (aFieldDefinition[i] == '\"');
1584 }
1585 }
1586 }
1587 }
1588 }
1589
1590 // first word is always "IF"
1591 // last two words are: true-case and false-case,
1592 // everything before is treated as condition expression
1593 // => we need at least 4 words to be inside the input string
1594 if (wordPosition.size() < 4)
1595 {
1596 return;
1597 }
1598
1599
1600 const sal_Int32 conditionBegin = wordPosition[1];
1601 const sal_Int32 trueBegin = wordPosition[wordPosition.size() - 2];
1602 const sal_Int32 falseBegin = wordPosition[wordPosition.size() - 1];
1603
1604 const sal_Int32 conditionLength = trueBegin - conditionBegin;
1605 const sal_Int32 trueLength = falseBegin - trueBegin;
1606
1607 // Syntax
1608 // OUString::copy( sal_Int32 beginIndex, sal_Int32 count )
1609 rCondition = aFieldDefinition.copy(conditionBegin, conditionLength);
1610 rTrue = aFieldDefinition.copy(trueBegin, trueLength);
1611 rFalse = aFieldDefinition.copy(falseBegin);
1612
1613 // trim
1614 rCondition = rCondition.trim();
1615 rTrue = rTrue.trim();
1616 rFalse = rFalse.trim();
1617
1618 // remove quotes
1619 if (rCondition.getLength() >= 2)
1620 {
1621 if (rCondition[0] == '\"' && rCondition[rCondition.getLength() - 1] == '\"')
1622 rCondition = rCondition.copy(1, rCondition.getLength() - 2);
1623 }
1624 if (rTrue.getLength() >= 2)
1625 {
1626 if (rTrue[0] == '\"' && rTrue[rTrue.getLength() - 1] == '\"')
1627 rTrue = rTrue.copy(1, rTrue.getLength() - 2);
1628 }
1629 if (rFalse.getLength() >= 2)
1630 {
1631 if (rFalse[0] == '\"' && rFalse[rFalse.getLength() - 1] == '\"')
1632 rFalse = rFalse.copy(1, rFalse.getLength() - 2);
1633 }
1634
1635 // Note: do not make trim once again, while this is a user defined data
1636 }
1637
1638 // field type for line height 0
1639
SwHiddenParaFieldType()1640 SwHiddenParaFieldType::SwHiddenParaFieldType()
1641 : SwFieldType( SwFieldIds::HiddenPara )
1642 {
1643 }
1644
Copy() const1645 std::unique_ptr<SwFieldType> SwHiddenParaFieldType::Copy() const
1646 {
1647 return std::make_unique<SwHiddenParaFieldType>();
1648 }
1649
1650 // field for line height 0
1651
SwHiddenParaField(SwHiddenParaFieldType * pTyp,const OUString & rStr)1652 SwHiddenParaField::SwHiddenParaField(SwHiddenParaFieldType* pTyp, const OUString& rStr)
1653 : SwField(pTyp), m_aCond(rStr)
1654 {
1655 m_bIsHidden = false;
1656 }
1657
ExpandImpl(SwRootFrame const * const) const1658 OUString SwHiddenParaField::ExpandImpl(SwRootFrame const*const) const
1659 {
1660 return OUString();
1661 }
1662
Copy() const1663 std::unique_ptr<SwField> SwHiddenParaField::Copy() const
1664 {
1665 std::unique_ptr<SwHiddenParaField> pField(new SwHiddenParaField(static_cast<SwHiddenParaFieldType*>(GetTyp()), m_aCond));
1666 pField->m_bIsHidden = m_bIsHidden;
1667 return std::unique_ptr<SwField>(pField.release());
1668 }
1669
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const1670 bool SwHiddenParaField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
1671 {
1672 switch ( nWhichId )
1673 {
1674 case FIELD_PROP_PAR1:
1675 rAny <<= m_aCond;
1676 break;
1677 case FIELD_PROP_BOOL1:
1678 rAny <<= m_bIsHidden;
1679 break;
1680
1681 default:
1682 assert(false);
1683 }
1684 return true;
1685 }
1686
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)1687 bool SwHiddenParaField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
1688 {
1689 switch ( nWhichId )
1690 {
1691 case FIELD_PROP_PAR1:
1692 rAny >>= m_aCond;
1693 break;
1694 case FIELD_PROP_BOOL1:
1695 m_bIsHidden = *o3tl::doAccess<bool>(rAny);
1696 break;
1697
1698 default:
1699 assert(false);
1700 }
1701 return true;
1702 }
1703
1704 /// set condition
SetPar1(const OUString & rStr)1705 void SwHiddenParaField::SetPar1(const OUString& rStr)
1706 {
1707 m_aCond = rStr;
1708 }
1709
GetPar1() const1710 OUString SwHiddenParaField::GetPar1() const
1711 {
1712 return m_aCond;
1713 }
1714
1715 // PostIt field type
1716
SwPostItFieldType(SwDoc * pDoc)1717 SwPostItFieldType::SwPostItFieldType(SwDoc *pDoc)
1718 : SwFieldType( SwFieldIds::Postit )
1719 , mpDoc(pDoc)
1720 {}
1721
Copy() const1722 std::unique_ptr<SwFieldType> SwPostItFieldType::Copy() const
1723 {
1724 return std::make_unique<SwPostItFieldType>(mpDoc);
1725 }
1726
1727 // PostIt field
1728
1729 sal_uInt32 SwPostItField::m_nLastPostItId = 1;
1730
SwPostItField(SwPostItFieldType * pT,const OUString & rAuthor,const OUString & rText,const OUString & rInitials,const OUString & rName,const DateTime & rDateTime,const bool bResolved,const sal_uInt32 nPostItId)1731 SwPostItField::SwPostItField( SwPostItFieldType* pT,
1732 const OUString& rAuthor,
1733 const OUString& rText,
1734 const OUString& rInitials,
1735 const OUString& rName,
1736 const DateTime& rDateTime,
1737 const bool bResolved,
1738 const sal_uInt32 nPostItId
1739 )
1740 : SwField( pT )
1741 , m_sText( rText )
1742 , m_sAuthor( rAuthor )
1743 , m_sInitials( rInitials )
1744 , m_sName( rName )
1745 , m_aDateTime( rDateTime )
1746 , m_bResolved( bResolved )
1747 {
1748 m_nPostItId = nPostItId == 0 ? m_nLastPostItId++ : nPostItId;
1749 }
1750
~SwPostItField()1751 SwPostItField::~SwPostItField()
1752 {
1753 if ( m_xTextObject.is() )
1754 {
1755 m_xTextObject->DisposeEditSource();
1756 }
1757
1758 mpText.reset();
1759 }
1760
ExpandImpl(SwRootFrame const * const) const1761 OUString SwPostItField::ExpandImpl(SwRootFrame const*const) const
1762 {
1763 return OUString();
1764 }
1765
GetDescription() const1766 OUString SwPostItField::GetDescription() const
1767 {
1768 return SwResId(STR_NOTE);
1769 }
1770
SetResolved(bool bNewState)1771 void SwPostItField::SetResolved(bool bNewState)
1772 {
1773 m_bResolved = bNewState;
1774 }
1775
ToggleResolved()1776 void SwPostItField::ToggleResolved()
1777 {
1778 m_bResolved = !m_bResolved;
1779 }
1780
GetResolved() const1781 bool SwPostItField::GetResolved() const
1782 {
1783 return m_bResolved;
1784 }
1785
Copy() const1786 std::unique_ptr<SwField> SwPostItField::Copy() const
1787 {
1788 std::unique_ptr<SwPostItField> pRet(new SwPostItField( static_cast<SwPostItFieldType*>(GetTyp()), m_sAuthor, m_sText, m_sInitials, m_sName,
1789 m_aDateTime, m_bResolved, m_nPostItId));
1790 if (mpText)
1791 pRet->SetTextObject( std::make_unique<OutlinerParaObject>(*mpText) );
1792
1793 // Note: member <m_xTextObject> not copied.
1794
1795 return std::unique_ptr<SwField>(pRet.release());
1796 }
1797
1798 /// set author
SetPar1(const OUString & rStr)1799 void SwPostItField::SetPar1(const OUString& rStr)
1800 {
1801 m_sAuthor = rStr;
1802 }
1803
1804 /// get author
GetPar1() const1805 OUString SwPostItField::GetPar1() const
1806 {
1807 return m_sAuthor;
1808 }
1809
1810 /// set the PostIt's text
SetPar2(const OUString & rStr)1811 void SwPostItField::SetPar2(const OUString& rStr)
1812 {
1813 m_sText = rStr;
1814 }
1815
1816 /// get the PostIt's text
GetPar2() const1817 OUString SwPostItField::GetPar2() const
1818 {
1819 return m_sText;
1820 }
1821
1822
SetName(const OUString & rName)1823 void SwPostItField::SetName(const OUString& rName)
1824 {
1825 m_sName = rName;
1826 }
1827
1828
SetTextObject(std::unique_ptr<OutlinerParaObject> pText)1829 void SwPostItField::SetTextObject( std::unique_ptr<OutlinerParaObject> pText )
1830 {
1831 mpText = std::move(pText);
1832 }
1833
GetNumberOfParagraphs() const1834 sal_Int32 SwPostItField::GetNumberOfParagraphs() const
1835 {
1836 return mpText ? mpText->Count() : 1;
1837 }
1838
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const1839 bool SwPostItField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
1840 {
1841 switch( nWhichId )
1842 {
1843 case FIELD_PROP_PAR1:
1844 rAny <<= m_sAuthor;
1845 break;
1846 case FIELD_PROP_PAR2:
1847 {
1848 rAny <<= m_sText;
1849 break;
1850 }
1851 case FIELD_PROP_PAR3:
1852 rAny <<= m_sInitials;
1853 break;
1854 case FIELD_PROP_PAR4:
1855 rAny <<= m_sName;
1856 break;
1857 case FIELD_PROP_BOOL1:
1858 rAny <<= m_bResolved;
1859 break;
1860 case FIELD_PROP_TEXT:
1861 {
1862 if ( !m_xTextObject.is() )
1863 {
1864 SwPostItFieldType* pGetType = static_cast<SwPostItFieldType*>(GetTyp());
1865 SwDoc* pDoc = pGetType->GetDoc();
1866 auto pObj = std::make_unique<SwTextAPIEditSource>( pDoc );
1867 const_cast <SwPostItField*> (this)->m_xTextObject = new SwTextAPIObject( std::move(pObj) );
1868 }
1869
1870 if ( mpText )
1871 m_xTextObject->SetText( *mpText );
1872 else
1873 m_xTextObject->SetString( m_sText );
1874
1875 uno::Reference < text::XText > xText( m_xTextObject.get() );
1876 rAny <<= xText;
1877 break;
1878 }
1879 case FIELD_PROP_DATE:
1880 {
1881 rAny <<= m_aDateTime.GetUNODate();
1882 }
1883 break;
1884 case FIELD_PROP_DATE_TIME:
1885 {
1886 rAny <<= m_aDateTime.GetUNODateTime();
1887 }
1888 break;
1889 default:
1890 assert(false);
1891 }
1892 return true;
1893 }
1894
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)1895 bool SwPostItField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
1896 {
1897 switch( nWhichId )
1898 {
1899 case FIELD_PROP_PAR1:
1900 rAny >>= m_sAuthor;
1901 break;
1902 case FIELD_PROP_PAR2:
1903 rAny >>= m_sText;
1904 //#i100374# new string via api, delete complex text object so SwPostItNote picks up the new string
1905 mpText.reset();
1906 break;
1907 case FIELD_PROP_PAR3:
1908 rAny >>= m_sInitials;
1909 break;
1910 case FIELD_PROP_PAR4:
1911 rAny >>= m_sName;
1912 break;
1913 case FIELD_PROP_BOOL1:
1914 rAny >>= m_bResolved;
1915 break;
1916 case FIELD_PROP_TEXT:
1917 OSL_FAIL("Not implemented!");
1918 break;
1919 case FIELD_PROP_DATE:
1920 if( auto aSetDate = o3tl::tryAccess<util::Date>(rAny) )
1921 {
1922 m_aDateTime = Date(aSetDate->Day, aSetDate->Month, aSetDate->Year);
1923 }
1924 break;
1925 case FIELD_PROP_DATE_TIME:
1926 {
1927 util::DateTime aDateTimeValue;
1928 if(!(rAny >>= aDateTimeValue))
1929 return false;
1930 m_aDateTime = DateTime(aDateTimeValue);
1931 }
1932 break;
1933 default:
1934 assert(false);
1935 }
1936 return true;
1937 }
1938
dumpAsXml(xmlTextWriterPtr pWriter) const1939 void SwPostItField::dumpAsXml(xmlTextWriterPtr pWriter) const
1940 {
1941 xmlTextWriterStartElement(pWriter, BAD_CAST("SwPostItField"));
1942 xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"), BAD_CAST(GetName().toUtf8().getStr()));
1943
1944 SwField::dumpAsXml(pWriter);
1945
1946 xmlTextWriterStartElement(pWriter, BAD_CAST("mpText"));
1947 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", mpText.get());
1948 if (mpText)
1949 mpText->dumpAsXml(pWriter);
1950 xmlTextWriterEndElement(pWriter);
1951
1952 xmlTextWriterEndElement(pWriter);
1953 }
1954
1955 // extended user information field type
1956
SwExtUserFieldType()1957 SwExtUserFieldType::SwExtUserFieldType()
1958 : SwFieldType( SwFieldIds::ExtUser )
1959 {
1960 }
1961
Copy() const1962 std::unique_ptr<SwFieldType> SwExtUserFieldType::Copy() const
1963 {
1964 return std::make_unique<SwExtUserFieldType>();
1965 }
1966
Expand(sal_uInt16 nSub)1967 OUString SwExtUserFieldType::Expand(sal_uInt16 nSub )
1968 {
1969 UserOptToken nRet = static_cast<UserOptToken>(USHRT_MAX);
1970 switch(nSub)
1971 {
1972 case EU_FIRSTNAME: nRet = UserOptToken::FirstName; break;
1973 case EU_NAME: nRet = UserOptToken::LastName; break;
1974 case EU_SHORTCUT: nRet = UserOptToken::ID; break;
1975
1976 case EU_COMPANY: nRet = UserOptToken::Company; break;
1977 case EU_STREET: nRet = UserOptToken::Street; break;
1978 case EU_TITLE: nRet = UserOptToken::Title; break;
1979 case EU_POSITION: nRet = UserOptToken::Position; break;
1980 case EU_PHONE_PRIVATE: nRet = UserOptToken::TelephoneHome; break;
1981 case EU_PHONE_COMPANY: nRet = UserOptToken::TelephoneWork; break;
1982 case EU_FAX: nRet = UserOptToken::Fax; break;
1983 case EU_EMAIL: nRet = UserOptToken::Email; break;
1984 case EU_COUNTRY: nRet = UserOptToken::Country; break;
1985 case EU_ZIP: nRet = UserOptToken::Zip; break;
1986 case EU_CITY: nRet = UserOptToken::City; break;
1987 case EU_STATE: nRet = UserOptToken::State; break;
1988 case EU_FATHERSNAME: nRet = UserOptToken::FathersName; break;
1989 case EU_APARTMENT: nRet = UserOptToken::Apartment; break;
1990 default: OSL_ENSURE( false, "Field unknown");
1991 }
1992 if( static_cast<UserOptToken>(USHRT_MAX) != nRet )
1993 {
1994 SvtUserOptions& rUserOpt = SW_MOD()->GetUserOptions();
1995 return rUserOpt.GetToken( nRet );
1996 }
1997 return OUString();
1998 }
1999
2000 // extended user information field
2001
SwExtUserField(SwExtUserFieldType * pTyp,sal_uInt16 nSubTyp,sal_uInt32 nFormat)2002 SwExtUserField::SwExtUserField(SwExtUserFieldType* pTyp, sal_uInt16 nSubTyp, sal_uInt32 nFormat) :
2003 SwField(pTyp, nFormat), m_nType(nSubTyp)
2004 {
2005 m_aContent = SwExtUserFieldType::Expand(m_nType);
2006 }
2007
ExpandImpl(SwRootFrame const * const) const2008 OUString SwExtUserField::ExpandImpl(SwRootFrame const*const) const
2009 {
2010 if (!IsFixed())
2011 const_cast<SwExtUserField*>(this)->m_aContent = SwExtUserFieldType::Expand(m_nType);
2012
2013 return m_aContent;
2014 }
2015
Copy() const2016 std::unique_ptr<SwField> SwExtUserField::Copy() const
2017 {
2018 std::unique_ptr<SwExtUserField> pField(new SwExtUserField(static_cast<SwExtUserFieldType*>(GetTyp()), m_nType, GetFormat()));
2019 pField->SetExpansion(m_aContent);
2020
2021 return std::unique_ptr<SwField>(pField.release());
2022 }
2023
GetSubType() const2024 sal_uInt16 SwExtUserField::GetSubType() const
2025 {
2026 return m_nType;
2027 }
2028
SetSubType(sal_uInt16 nSub)2029 void SwExtUserField::SetSubType(sal_uInt16 nSub)
2030 {
2031 m_nType = nSub;
2032 }
2033
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const2034 bool SwExtUserField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
2035 {
2036 switch( nWhichId )
2037 {
2038 case FIELD_PROP_PAR1:
2039 rAny <<= m_aContent;
2040 break;
2041
2042 case FIELD_PROP_USHORT1:
2043 {
2044 sal_Int16 nTmp = m_nType;
2045 rAny <<= nTmp;
2046 }
2047 break;
2048 case FIELD_PROP_BOOL1:
2049 rAny <<= IsFixed();
2050 break;
2051 default:
2052 assert(false);
2053 }
2054 return true;
2055 }
2056
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)2057 bool SwExtUserField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
2058 {
2059 switch( nWhichId )
2060 {
2061 case FIELD_PROP_PAR1:
2062 rAny >>= m_aContent;
2063 break;
2064
2065 case FIELD_PROP_USHORT1:
2066 {
2067 sal_Int16 nTmp = 0;
2068 rAny >>= nTmp;
2069 m_nType = nTmp;
2070 }
2071 break;
2072 case FIELD_PROP_BOOL1:
2073 if( *o3tl::doAccess<bool>(rAny) )
2074 SetFormat(GetFormat() | AF_FIXED);
2075 else
2076 SetFormat(GetFormat() & ~AF_FIXED);
2077 break;
2078 default:
2079 assert(false);
2080 }
2081 return true;
2082 }
2083
2084 // field type for relative page numbers
2085
SwRefPageSetFieldType()2086 SwRefPageSetFieldType::SwRefPageSetFieldType()
2087 : SwFieldType( SwFieldIds::RefPageSet )
2088 {
2089 }
2090
Copy() const2091 std::unique_ptr<SwFieldType> SwRefPageSetFieldType::Copy() const
2092 {
2093 return std::make_unique<SwRefPageSetFieldType>();
2094 }
2095
2096 // overridden since there is nothing to update
Modify(const SfxPoolItem *,const SfxPoolItem *)2097 void SwRefPageSetFieldType::Modify( const SfxPoolItem*, const SfxPoolItem * )
2098 {
2099 }
2100
2101 // field for relative page numbers
2102
SwRefPageSetField(SwRefPageSetFieldType * pTyp,short nOff,bool bFlag)2103 SwRefPageSetField::SwRefPageSetField( SwRefPageSetFieldType* pTyp,
2104 short nOff, bool bFlag )
2105 : SwField( pTyp ), m_nOffset( nOff ), m_bOn( bFlag )
2106 {
2107 }
2108
ExpandImpl(SwRootFrame const * const) const2109 OUString SwRefPageSetField::ExpandImpl(SwRootFrame const*const) const
2110 {
2111 return OUString();
2112 }
2113
Copy() const2114 std::unique_ptr<SwField> SwRefPageSetField::Copy() const
2115 {
2116 return std::make_unique<SwRefPageSetField>( static_cast<SwRefPageSetFieldType*>(GetTyp()), m_nOffset, m_bOn );
2117 }
2118
GetPar2() const2119 OUString SwRefPageSetField::GetPar2() const
2120 {
2121 return OUString::number(GetOffset());
2122 }
2123
SetPar2(const OUString & rStr)2124 void SwRefPageSetField::SetPar2(const OUString& rStr)
2125 {
2126 SetOffset( static_cast<short>(rStr.toInt32()) );
2127 }
2128
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const2129 bool SwRefPageSetField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
2130 {
2131 switch( nWhichId )
2132 {
2133 case FIELD_PROP_BOOL1:
2134 rAny <<= m_bOn;
2135 break;
2136 case FIELD_PROP_USHORT1:
2137 rAny <<= static_cast<sal_Int16>(m_nOffset);
2138 break;
2139 default:
2140 assert(false);
2141 }
2142 return true;
2143 }
2144
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)2145 bool SwRefPageSetField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
2146 {
2147 switch( nWhichId )
2148 {
2149 case FIELD_PROP_BOOL1:
2150 m_bOn = *o3tl::doAccess<bool>(rAny);
2151 break;
2152 case FIELD_PROP_USHORT1:
2153 rAny >>=m_nOffset;
2154 break;
2155 default:
2156 assert(false);
2157 }
2158 return true;
2159 }
2160
2161 // relative page numbers - query field
2162
SwRefPageGetFieldType(SwDoc * pDc)2163 SwRefPageGetFieldType::SwRefPageGetFieldType( SwDoc* pDc )
2164 : SwFieldType( SwFieldIds::RefPageGet ), m_pDoc( pDc ), m_nNumberingType( SVX_NUM_ARABIC )
2165 {
2166 }
2167
Copy() const2168 std::unique_ptr<SwFieldType> SwRefPageGetFieldType::Copy() const
2169 {
2170 std::unique_ptr<SwRefPageGetFieldType> pNew(new SwRefPageGetFieldType( m_pDoc ));
2171 pNew->m_nNumberingType = m_nNumberingType;
2172 return pNew;
2173 }
2174
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)2175 void SwRefPageGetFieldType::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
2176 {
2177 auto const ModifyImpl = [this](SwRootFrame const*const pLayout)
2178 {
2179 // first collect all SetPageRefFields
2180 SetGetExpFields aTmpLst;
2181 if (MakeSetList(aTmpLst, pLayout))
2182 {
2183 SwIterator<SwFormatField,SwFieldType> aIter( *this );
2184 for ( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() )
2185 {
2186 // update only the GetRef fields
2187 if( pFormatField->GetTextField() )
2188 UpdateField(pFormatField->GetTextField(), aTmpLst, pLayout);
2189 }
2190 }
2191 };
2192
2193 // update all GetReference fields
2194 if( !pNew && !pOld && HasWriterListeners() )
2195 {
2196 SwRootFrame const* pLayout(nullptr);
2197 SwRootFrame const* pLayoutRLHidden(nullptr);
2198 for (SwRootFrame const*const pLay : m_pDoc->GetAllLayouts())
2199 {
2200 if (pLay->IsHideRedlines())
2201 {
2202 pLayoutRLHidden = pLay;
2203 }
2204 else
2205 {
2206 pLayout = pLay;
2207 }
2208 }
2209 ModifyImpl(pLayout);
2210 if (pLayoutRLHidden)
2211 {
2212 ModifyImpl(pLayoutRLHidden);
2213 }
2214 }
2215
2216 // forward to text fields, they "expand" the text
2217 NotifyClients( pOld, pNew );
2218 }
2219
MakeSetList(SetGetExpFields & rTmpLst,SwRootFrame const * const pLayout)2220 bool SwRefPageGetFieldType::MakeSetList(SetGetExpFields& rTmpLst,
2221 SwRootFrame const*const pLayout)
2222 {
2223 IDocumentRedlineAccess const& rIDRA(m_pDoc->getIDocumentRedlineAccess());
2224 SwIterator<SwFormatField,SwFieldType> aIter(*m_pDoc->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::RefPageSet));
2225 for ( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() )
2226 {
2227 // update only the GetRef fields
2228 const SwTextField* pTField = pFormatField->GetTextField();
2229 if( pTField )
2230 {
2231 if (!pLayout || !pLayout->IsHideRedlines()
2232 || !sw::IsFieldDeletedInModel(rIDRA, *pTField))
2233 {
2234 const SwTextNode& rTextNd = pTField->GetTextNode();
2235
2236 // Always the first! (in Tab-Headline, header/footer )
2237 Point aPt;
2238 std::pair<Point, bool> const tmp(aPt, false);
2239 const SwContentFrame *const pFrame = rTextNd.getLayoutFrame(
2240 pLayout, nullptr, &tmp);
2241
2242 std::unique_ptr<SetGetExpField> pNew;
2243
2244 if( !pFrame ||
2245 pFrame->IsInDocBody() ||
2246 // #i31868#
2247 // Check if pFrame is not yet connected to the layout.
2248 !pFrame->FindPageFrame() )
2249 {
2250 // create index for determination of the TextNode
2251 SwNodeIndex aIdx( rTextNd );
2252 pNew.reset( new SetGetExpField( aIdx, pTField ) );
2253 }
2254 else
2255 {
2256 // create index for determination of the TextNode
2257 SwPosition aPos( m_pDoc->GetNodes().GetEndOfPostIts() );
2258 bool const bResult = GetBodyTextNode( *m_pDoc, aPos, *pFrame );
2259 OSL_ENSURE(bResult, "where is the Field?");
2260 pNew.reset( new SetGetExpField( aPos.nNode, pTField,
2261 &aPos.nContent ) );
2262 }
2263
2264 rTmpLst.insert( std::move(pNew) );
2265 }
2266 }
2267 }
2268
2269 return !rTmpLst.empty();
2270 }
2271
UpdateField(SwTextField const * pTextField,SetGetExpFields const & rSetList,SwRootFrame const * const pLayout)2272 void SwRefPageGetFieldType::UpdateField( SwTextField const * pTextField,
2273 SetGetExpFields const & rSetList,
2274 SwRootFrame const*const pLayout)
2275 {
2276 SwRefPageGetField* pGetField = const_cast<SwRefPageGetField*>(static_cast<const SwRefPageGetField*>(pTextField->GetFormatField().GetField()));
2277 pGetField->SetText( OUString(), pLayout );
2278
2279 // then search the correct RefPageSet field
2280 SwTextNode* pTextNode = &pTextField->GetTextNode();
2281 if( pTextNode->StartOfSectionIndex() >
2282 m_pDoc->GetNodes().GetEndOfExtras().GetIndex() )
2283 {
2284 SwNodeIndex aIdx( *pTextNode );
2285 SetGetExpField aEndField( aIdx, pTextField );
2286
2287 SetGetExpFields::const_iterator itLast = rSetList.lower_bound( &aEndField );
2288
2289 if( itLast != rSetList.begin() )
2290 {
2291 --itLast;
2292 const SwTextField* pRefTextField = (*itLast)->GetTextField();
2293 const SwRefPageSetField* pSetField =
2294 static_cast<const SwRefPageSetField*>(pRefTextField->GetFormatField().GetField());
2295 if( pSetField->IsOn() )
2296 {
2297 // determine the correct offset
2298 Point aPt;
2299 std::pair<Point, bool> const tmp(aPt, false);
2300 const SwContentFrame *const pFrame = pTextNode->getLayoutFrame(
2301 pLayout, nullptr, &tmp);
2302 const SwContentFrame *const pRefFrame = pRefTextField->GetTextNode().getLayoutFrame(
2303 pLayout, nullptr, &tmp);
2304 const SwPageFrame* pPgFrame = nullptr;
2305 short nDiff = 1;
2306 if ( pFrame && pRefFrame )
2307 {
2308 pPgFrame = pFrame->FindPageFrame();
2309 nDiff = pPgFrame->GetPhyPageNum() -
2310 pRefFrame->FindPageFrame()->GetPhyPageNum() + 1;
2311 }
2312
2313 SvxNumType nTmpFormat = SVX_NUM_PAGEDESC == static_cast<SvxNumType>(pGetField->GetFormat())
2314 ? ( !pPgFrame
2315 ? SVX_NUM_ARABIC
2316 : pPgFrame->GetPageDesc()->GetNumType().GetNumberingType() )
2317 : static_cast<SvxNumType>(pGetField->GetFormat());
2318 const short nPageNum = std::max<short>(0, pSetField->GetOffset() + nDiff);
2319 pGetField->SetText(FormatNumber(nPageNum, nTmpFormat), pLayout);
2320 }
2321 }
2322 }
2323 // start formatting
2324 const_cast<SwFormatField&>(pTextField->GetFormatField()).ModifyNotification( nullptr, nullptr );
2325 }
2326
2327 // queries for relative page numbering
2328
SwRefPageGetField(SwRefPageGetFieldType * pTyp,sal_uInt32 nFormat)2329 SwRefPageGetField::SwRefPageGetField( SwRefPageGetFieldType* pTyp,
2330 sal_uInt32 nFormat )
2331 : SwField( pTyp, nFormat )
2332 {
2333 }
2334
SetText(const OUString & rText,SwRootFrame const * const pLayout)2335 void SwRefPageGetField::SetText(const OUString& rText,
2336 SwRootFrame const*const pLayout)
2337 {
2338 if (!pLayout || !pLayout->IsHideRedlines())
2339 {
2340 m_sText = rText;
2341 }
2342 if (!pLayout || pLayout->IsHideRedlines())
2343 {
2344 m_sTextRLHidden = rText;
2345 }
2346 }
2347
ExpandImpl(SwRootFrame const * const pLayout) const2348 OUString SwRefPageGetField::ExpandImpl(SwRootFrame const*const pLayout) const
2349 {
2350 return pLayout && pLayout->IsHideRedlines() ? m_sTextRLHidden : m_sText;
2351 }
2352
Copy() const2353 std::unique_ptr<SwField> SwRefPageGetField::Copy() const
2354 {
2355 std::unique_ptr<SwRefPageGetField> pCpy(new SwRefPageGetField(
2356 static_cast<SwRefPageGetFieldType*>(GetTyp()), GetFormat() ));
2357 pCpy->m_sText = m_sText;
2358 pCpy->m_sTextRLHidden = m_sTextRLHidden;
2359 return std::unique_ptr<SwField>(pCpy.release());
2360 }
2361
ChangeExpansion(const SwFrame & rFrame,const SwTextField * pField)2362 void SwRefPageGetField::ChangeExpansion(const SwFrame& rFrame,
2363 const SwTextField* pField )
2364 {
2365 // only fields in Footer, Header, FootNote, Flys
2366 SwRefPageGetFieldType* pGetType = static_cast<SwRefPageGetFieldType*>(GetTyp());
2367 SwDoc* pDoc = pGetType->GetDoc();
2368 if( pField->GetTextNode().StartOfSectionIndex() >
2369 pDoc->GetNodes().GetEndOfExtras().GetIndex() )
2370 return;
2371
2372 SwRootFrame const& rLayout(*rFrame.getRootFrame());
2373 OUString & rText(rLayout.IsHideRedlines() ? m_sTextRLHidden : m_sText);
2374 rText.clear();
2375
2376 OSL_ENSURE(!rFrame.IsInDocBody(), "Flag incorrect, frame is in DocBody");
2377
2378 // collect all SetPageRefFields
2379 SetGetExpFields aTmpLst;
2380 if (!pGetType->MakeSetList(aTmpLst, &rLayout))
2381 return ;
2382
2383 // create index for determination of the TextNode
2384 SwPosition aPos( SwNodeIndex( pDoc->GetNodes() ) );
2385 SwTextNode* pTextNode = const_cast<SwTextNode*>(GetBodyTextNode(*pDoc, aPos, rFrame));
2386
2387 // If no layout exists, ChangeExpansion is called for header and
2388 // footer lines via layout formatting without existing TextNode.
2389 if(!pTextNode)
2390 return;
2391
2392 SetGetExpField aEndField( aPos.nNode, pField, &aPos.nContent );
2393
2394 SetGetExpFields::const_iterator itLast = aTmpLst.lower_bound( &aEndField );
2395
2396 if( itLast == aTmpLst.begin() )
2397 return; // there is no corresponding set-field in front
2398 --itLast;
2399
2400 const SwTextField* pRefTextField = (*itLast)->GetTextField();
2401 const SwRefPageSetField* pSetField =
2402 static_cast<const SwRefPageSetField*>(pRefTextField->GetFormatField().GetField());
2403 Point aPt;
2404 std::pair<Point, bool> const tmp(aPt, false);
2405 const SwContentFrame *const pRefFrame = pRefTextField->GetTextNode().getLayoutFrame(
2406 &rLayout, nullptr, &tmp);
2407 if( pSetField->IsOn() && pRefFrame )
2408 {
2409 // determine the correct offset
2410 const SwPageFrame* pPgFrame = rFrame.FindPageFrame();
2411 const short nDiff = pPgFrame->GetPhyPageNum() -
2412 pRefFrame->FindPageFrame()->GetPhyPageNum() + 1;
2413
2414 SwRefPageGetField* pGetField = const_cast<SwRefPageGetField*>(static_cast<const SwRefPageGetField*>(pField->GetFormatField().GetField()));
2415 SvxNumType nTmpFormat = SVX_NUM_PAGEDESC == pGetField->GetFormat()
2416 ? pPgFrame->GetPageDesc()->GetNumType().GetNumberingType()
2417 : static_cast<SvxNumType>(pGetField->GetFormat());
2418 const short nPageNum = std::max<short>(0, pSetField->GetOffset() + nDiff);
2419 pGetField->SetText(FormatNumber(nPageNum, nTmpFormat), &rLayout);
2420 }
2421 }
2422
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const2423 bool SwRefPageGetField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
2424 {
2425 switch( nWhichId )
2426 {
2427 case FIELD_PROP_USHORT1:
2428 rAny <<= static_cast<sal_Int16>(GetFormat());
2429 break;
2430 case FIELD_PROP_PAR1:
2431 rAny <<= m_sText;
2432 break;
2433 default:
2434 assert(false);
2435 }
2436 return true;
2437 }
2438
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)2439 bool SwRefPageGetField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
2440 {
2441 switch( nWhichId )
2442 {
2443 case FIELD_PROP_USHORT1:
2444 {
2445 sal_Int16 nSet = 0;
2446 rAny >>= nSet;
2447 if(nSet <= SVX_NUM_PAGEDESC )
2448 SetFormat(nSet);
2449 }
2450 break;
2451 case FIELD_PROP_PAR1:
2452 rAny >>= m_sText;
2453 m_sTextRLHidden = m_sText;
2454 break;
2455 default:
2456 assert(false);
2457 }
2458 return true;
2459 }
2460
2461 // field type to jump to and edit
2462
SwJumpEditFieldType(SwDoc * pD)2463 SwJumpEditFieldType::SwJumpEditFieldType( SwDoc* pD )
2464 : SwFieldType( SwFieldIds::JumpEdit ), m_pDoc( pD ), m_aDep( *this )
2465 {
2466 }
2467
Copy() const2468 std::unique_ptr<SwFieldType> SwJumpEditFieldType::Copy() const
2469 {
2470 return std::make_unique<SwJumpEditFieldType>( m_pDoc );
2471 }
2472
GetCharFormat()2473 SwCharFormat* SwJumpEditFieldType::GetCharFormat()
2474 {
2475 SwCharFormat* pFormat = m_pDoc->getIDocumentStylePoolAccess().GetCharFormatFromPool( RES_POOLCHR_JUMPEDIT );
2476 m_aDep.StartListening(pFormat);
2477 return pFormat;
2478 }
2479
SwJumpEditField(SwJumpEditFieldType * pTyp,sal_uInt32 nForm,const OUString & rText,const OUString & rHelp)2480 SwJumpEditField::SwJumpEditField( SwJumpEditFieldType* pTyp, sal_uInt32 nForm,
2481 const OUString& rText, const OUString& rHelp )
2482 : SwField( pTyp, nForm ), m_sText( rText ), m_sHelp( rHelp )
2483 {
2484 }
2485
ExpandImpl(SwRootFrame const * const) const2486 OUString SwJumpEditField::ExpandImpl(SwRootFrame const*const) const
2487 {
2488 return "<" + m_sText + ">";
2489 }
2490
Copy() const2491 std::unique_ptr<SwField> SwJumpEditField::Copy() const
2492 {
2493 return std::make_unique<SwJumpEditField>( static_cast<SwJumpEditFieldType*>(GetTyp()), GetFormat(),
2494 m_sText, m_sHelp );
2495 }
2496
2497 /// get place holder text
GetPar1() const2498 OUString SwJumpEditField::GetPar1() const
2499 {
2500 return m_sText;
2501 }
2502
2503 /// set place holder text
SetPar1(const OUString & rStr)2504 void SwJumpEditField::SetPar1(const OUString& rStr)
2505 {
2506 m_sText = rStr;
2507 }
2508
2509 /// get hint text
GetPar2() const2510 OUString SwJumpEditField::GetPar2() const
2511 {
2512 return m_sHelp;
2513 }
2514
2515 /// set hint text
SetPar2(const OUString & rStr)2516 void SwJumpEditField::SetPar2(const OUString& rStr)
2517 {
2518 m_sHelp = rStr;
2519 }
2520
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const2521 bool SwJumpEditField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
2522 {
2523 switch( nWhichId )
2524 {
2525 case FIELD_PROP_USHORT1:
2526 {
2527 sal_Int16 nRet;
2528 switch( GetFormat() )
2529 {
2530 case JE_FMT_TABLE: nRet = text::PlaceholderType::TABLE; break;
2531 case JE_FMT_FRAME: nRet = text::PlaceholderType::TEXTFRAME; break;
2532 case JE_FMT_GRAPHIC:nRet = text::PlaceholderType::GRAPHIC; break;
2533 case JE_FMT_OLE: nRet = text::PlaceholderType::OBJECT; break;
2534 default:
2535 nRet = text::PlaceholderType::TEXT; break;
2536 }
2537 rAny <<= nRet;
2538 }
2539 break;
2540 case FIELD_PROP_PAR1 :
2541 rAny <<= m_sHelp;
2542 break;
2543 case FIELD_PROP_PAR2 :
2544 rAny <<= m_sText;
2545 break;
2546 default:
2547 assert(false);
2548 }
2549 return true;
2550 }
2551
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)2552 bool SwJumpEditField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
2553 {
2554 switch( nWhichId )
2555 {
2556 case FIELD_PROP_USHORT1:
2557 {
2558 //JP 24.10.2001: int32 because in UnoField.cxx a putvalue is
2559 // called with a int32 value! But normally we need
2560 // here only a int16
2561 sal_Int32 nSet = 0;
2562 rAny >>= nSet;
2563 switch( nSet )
2564 {
2565 case text::PlaceholderType::TEXT : SetFormat(JE_FMT_TEXT); break;
2566 case text::PlaceholderType::TABLE : SetFormat(JE_FMT_TABLE); break;
2567 case text::PlaceholderType::TEXTFRAME: SetFormat(JE_FMT_FRAME); break;
2568 case text::PlaceholderType::GRAPHIC : SetFormat(JE_FMT_GRAPHIC); break;
2569 case text::PlaceholderType::OBJECT : SetFormat(JE_FMT_OLE); break;
2570 }
2571 }
2572 break;
2573 case FIELD_PROP_PAR1 :
2574 rAny >>= m_sHelp;
2575 break;
2576 case FIELD_PROP_PAR2 :
2577 rAny >>= m_sText;
2578 break;
2579 default:
2580 assert(false);
2581 }
2582 return true;
2583 }
2584
2585 // combined character field type
2586
SwCombinedCharFieldType()2587 SwCombinedCharFieldType::SwCombinedCharFieldType()
2588 : SwFieldType( SwFieldIds::CombinedChars )
2589 {
2590 }
2591
Copy() const2592 std::unique_ptr<SwFieldType> SwCombinedCharFieldType::Copy() const
2593 {
2594 return std::make_unique<SwCombinedCharFieldType>();
2595 }
2596
2597 // combined character field
2598
SwCombinedCharField(SwCombinedCharFieldType * pFTyp,const OUString & rChars)2599 SwCombinedCharField::SwCombinedCharField( SwCombinedCharFieldType* pFTyp,
2600 const OUString& rChars )
2601 : SwField( pFTyp, 0 ),
2602 m_sCharacters( rChars.copy( 0, std::min<sal_Int32>(rChars.getLength(), MAX_COMBINED_CHARACTERS) ))
2603 {
2604 }
2605
ExpandImpl(SwRootFrame const * const) const2606 OUString SwCombinedCharField::ExpandImpl(SwRootFrame const*const) const
2607 {
2608 return m_sCharacters;
2609 }
2610
Copy() const2611 std::unique_ptr<SwField> SwCombinedCharField::Copy() const
2612 {
2613 return std::make_unique<SwCombinedCharField>( static_cast<SwCombinedCharFieldType*>(GetTyp()),
2614 m_sCharacters );
2615 }
2616
GetPar1() const2617 OUString SwCombinedCharField::GetPar1() const
2618 {
2619 return m_sCharacters;
2620 }
2621
SetPar1(const OUString & rStr)2622 void SwCombinedCharField::SetPar1(const OUString& rStr)
2623 {
2624 m_sCharacters = rStr.copy(0, std::min<sal_Int32>(rStr.getLength(), MAX_COMBINED_CHARACTERS));
2625 }
2626
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const2627 bool SwCombinedCharField::QueryValue( uno::Any& rAny,
2628 sal_uInt16 nWhichId ) const
2629 {
2630 switch( nWhichId )
2631 {
2632 case FIELD_PROP_PAR1:
2633 rAny <<= m_sCharacters;
2634 break;
2635 default:
2636 assert(false);
2637 }
2638 return true;
2639 }
2640
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)2641 bool SwCombinedCharField::PutValue( const uno::Any& rAny,
2642 sal_uInt16 nWhichId )
2643 {
2644 switch( nWhichId )
2645 {
2646 case FIELD_PROP_PAR1:
2647 {
2648 OUString sTmp;
2649 rAny >>= sTmp;
2650 SetPar1(sTmp);
2651 }
2652 break;
2653 default:
2654 assert(false);
2655 }
2656 return true;
2657 }
2658
2659 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2660