Line data Source code
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 <fldbas.hxx>
21 :
22 : #include <float.h>
23 : #include <math.h>
24 :
25 : #include <libxml/xmlwriter.h>
26 :
27 : #include <rtl/math.hxx>
28 : #include <svl/zforlist.hxx>
29 : #include <svl/zformat.hxx>
30 : #include <editeng/unolingu.hxx>
31 : #include <unofldmid.h>
32 : #include <doc.hxx>
33 : #include <editsh.hxx>
34 : #include <frame.hxx>
35 : #include <flddat.hxx>
36 : #include <ndtxt.hxx>
37 : #include <fmtfld.hxx>
38 : #include <txtfld.hxx>
39 : #include <pam.hxx>
40 : #include <docfld.hxx>
41 : #include <swtable.hxx>
42 : #include <docufld.hxx>
43 : #include <expfld.hxx>
44 : #include <shellres.hxx>
45 : #include <calc.hxx>
46 : #include <comcore.hrc>
47 : #include <docary.hxx>
48 : #include <authfld.hxx>
49 : #include <calbck.hxx>
50 :
51 : using namespace ::com::sun::star;
52 : using namespace nsSwDocInfoSubType;
53 :
54 247 : static sal_uInt16 lcl_GetLanguageOfFormat( sal_uInt16 nLng, sal_uLong nFormat,
55 : const SvNumberFormatter& rFormatter )
56 : {
57 247 : if( nLng == LANGUAGE_NONE ) // Bug #60010
58 12 : nLng = LANGUAGE_SYSTEM;
59 235 : else if( nLng == ::GetAppLanguage() )
60 26 : switch( rFormatter.GetIndexTableOffset( nFormat ))
61 : {
62 : case NF_NUMBER_SYSTEM:
63 : case NF_DATE_SYSTEM_SHORT:
64 : case NF_DATE_SYSTEM_LONG:
65 : case NF_DATETIME_SYSTEM_SHORT_HHMM:
66 0 : nLng = LANGUAGE_SYSTEM;
67 0 : break;
68 26 : default: break;
69 : }
70 247 : return nLng;
71 : }
72 :
73 : // Globals
74 :
75 : /// field names
76 : std::vector<OUString>* SwFieldType::s_pFieldNames = nullptr;
77 :
78 : namespace
79 : {
80 :
81 : const sal_uInt16 aTypeTab[] = {
82 : /* RES_DBFLD */ TYP_DBFLD,
83 : /* RES_USERFLD */ TYP_USERFLD,
84 : /* RES_FILENAMEFLD */ TYP_FILENAMEFLD,
85 : /* RES_DBNAMEFLD */ TYP_DBNAMEFLD,
86 : /* RES_DATEFLD */ TYP_DATEFLD,
87 : /* RES_TIMEFLD */ TYP_TIMEFLD,
88 : /* RES_PAGENUMBERFLD */ TYP_PAGENUMBERFLD, // dynamic
89 : /* RES_AUTHORFLD */ TYP_AUTHORFLD,
90 : /* RES_CHAPTERFLD */ TYP_CHAPTERFLD,
91 : /* RES_DOCSTATFLD */ TYP_DOCSTATFLD,
92 : /* RES_GETEXPFLD */ TYP_GETFLD, // dynamic
93 : /* RES_SETEXPFLD */ TYP_SETFLD, // dynamic
94 : /* RES_GETREFFLD */ TYP_GETREFFLD,
95 : /* RES_HIDDENTXTFLD */ TYP_HIDDENTXTFLD,
96 : /* RES_POSTITFLD */ TYP_POSTITFLD,
97 : /* RES_FIXDATEFLD */ TYP_FIXDATEFLD,
98 : /* RES_FIXTIMEFLD */ TYP_FIXTIMEFLD,
99 : /* RES_REGFLD */ 0, // old (no change since 2000)
100 : /* RES_VARREGFLD */ 0, // old (no change since 2000)
101 : /* RES_SETREFFLD */ TYP_SETREFFLD,
102 : /* RES_INPUTFLD */ TYP_INPUTFLD,
103 : /* RES_MACROFLD */ TYP_MACROFLD,
104 : /* RES_DDEFLD */ TYP_DDEFLD,
105 : /* RES_TABLEFLD */ TYP_FORMELFLD,
106 : /* RES_HIDDENPARAFLD */ TYP_HIDDENPARAFLD,
107 : /* RES_DOCINFOFLD */ TYP_DOCINFOFLD,
108 : /* RES_TEMPLNAMEFLD */ TYP_TEMPLNAMEFLD,
109 : /* RES_DBNEXTSETFLD */ TYP_DBNEXTSETFLD,
110 : /* RES_DBNUMSETFLD */ TYP_DBNUMSETFLD,
111 : /* RES_DBSETNUMBERFLD */ TYP_DBSETNUMBERFLD,
112 : /* RES_EXTUSERFLD */ TYP_EXTUSERFLD,
113 : /* RES_REFPAGESETFLD */ TYP_SETREFPAGEFLD,
114 : /* RES_REFPAGEGETFLD */ TYP_GETREFPAGEFLD,
115 : /* RES_INTERNETFLD */ TYP_INTERNETFLD,
116 : /* RES_JUMPEDITFLD */ TYP_JUMPEDITFLD,
117 : /* RES_SCRIPTFLD */ TYP_SCRIPTFLD,
118 : /* RES_DATETIMEFLD */ 0, // dynamic
119 : /* RES_AUTHORITY */ TYP_AUTHORITY,
120 : /* RES_COMBINED_CHARS */ TYP_COMBINED_CHARS,
121 : /* RES_DROPDOWN */ TYP_DROPDOWN
122 : };
123 :
124 : }
125 :
126 79 : OUString SwFieldType::GetTypeStr(sal_uInt16 nTypeId)
127 : {
128 79 : if (!s_pFieldNames)
129 5 : _GetFieldName();
130 :
131 79 : if (nTypeId < SwFieldType::s_pFieldNames->size())
132 79 : return (*SwFieldType::s_pFieldNames)[nTypeId];
133 0 : return OUString();
134 : }
135 :
136 : // each field refences a field type that is unique for each document
137 95039 : SwFieldType::SwFieldType( sal_uInt16 nWhichId )
138 : : SwModify(nullptr)
139 95039 : , m_nWhich(nWhichId)
140 : {
141 95039 : }
142 :
143 29213 : OUString SwFieldType::GetName() const
144 : {
145 29213 : return OUString();
146 : }
147 :
148 0 : bool SwFieldType::QueryValue( uno::Any&, sal_uInt16 ) const
149 : {
150 0 : return false;
151 : }
152 0 : bool SwFieldType::PutValue( const uno::Any& , sal_uInt16 )
153 : {
154 0 : return false;
155 : }
156 :
157 0 : void SwFieldTypes::dumpAsXml(xmlTextWriterPtr pWriter) const
158 : {
159 0 : xmlTextWriterStartElement(pWriter, BAD_CAST("swFieldTypes"));
160 0 : sal_uInt16 nCount = size();
161 0 : for (sal_uInt16 nType = 0; nType < nCount; ++nType)
162 : {
163 0 : const SwFieldType *pCurType = (*this)[nType];
164 0 : SwIterator<SwFormatField, SwFieldType> aIter(*pCurType);
165 0 : for (const SwFormatField* pCurFieldFormat = aIter.First(); pCurFieldFormat; pCurFieldFormat = aIter.Next())
166 : {
167 0 : xmlTextWriterStartElement(pWriter, BAD_CAST("swFormatField"));
168 0 : xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", pCurFieldFormat);
169 0 : xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("txtField"), "%p", pCurFieldFormat->GetTextField());
170 :
171 0 : xmlTextWriterStartElement(pWriter, BAD_CAST("swField"));
172 0 : xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("symbol"), "%s", BAD_CAST(typeid(*pCurFieldFormat->GetField()).name()));
173 0 : xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", pCurFieldFormat->GetField());
174 0 : if (pCurFieldFormat->GetField()->GetTyp()->Which() == RES_POSTITFLD)
175 : {
176 0 : const SwPostItField* pField = static_cast<const SwPostItField*>(pCurFieldFormat->GetField());
177 0 : xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"), BAD_CAST(pField->GetName().toUtf8().getStr()));
178 : }
179 0 : xmlTextWriterEndElement(pWriter);
180 :
181 0 : xmlTextWriterEndElement(pWriter);
182 : }
183 0 : }
184 0 : xmlTextWriterEndElement(pWriter);
185 0 : }
186 :
187 : // Base class for all fields.
188 : // A field (multiple can exist) references a field type (can exists only once)
189 7840 : SwField::SwField(
190 : SwFieldType* pType,
191 : sal_uInt32 nFormat,
192 : sal_uInt16 nLang,
193 : bool bUseFieldValueCache)
194 : : m_Cache()
195 : , m_bUseFieldValueCache( bUseFieldValueCache )
196 : , m_nLang( nLang )
197 : , m_bIsAutomaticLanguage( true )
198 : , m_nFormat( nFormat )
199 7840 : , m_pType( pType )
200 : {
201 : assert(m_pType);
202 7840 : }
203 :
204 7833 : SwField::~SwField()
205 : {
206 7833 : }
207 :
208 : // instead of indirectly via the type
209 :
210 : #ifdef DBG_UTIL
211 : sal_uInt16 SwField::Which() const
212 : {
213 : assert(m_pType);
214 : return m_pType->Which();
215 : }
216 : #endif
217 :
218 7760 : sal_uInt16 SwField::GetTypeId() const
219 : {
220 :
221 : sal_uInt16 nRet;
222 7760 : switch (m_pType->Which())
223 : {
224 : case RES_DATETIMEFLD:
225 47 : if (GetSubType() & FIXEDFLD)
226 19 : nRet = static_cast<sal_uInt16>(GetSubType() & DATEFLD ? TYP_FIXDATEFLD : TYP_FIXTIMEFLD);
227 : else
228 28 : nRet = static_cast<sal_uInt16>(GetSubType() & DATEFLD ? TYP_DATEFLD : TYP_TIMEFLD);
229 47 : break;
230 : case RES_GETEXPFLD:
231 2 : nRet = static_cast<sal_uInt16>(nsSwGetSetExpType::GSE_FORMULA & GetSubType() ? TYP_FORMELFLD : TYP_GETFLD);
232 2 : break;
233 :
234 : case RES_HIDDENTXTFLD:
235 0 : nRet = GetSubType();
236 0 : break;
237 :
238 : case RES_SETEXPFLD:
239 191 : if( nsSwGetSetExpType::GSE_SEQ & GetSubType() )
240 146 : nRet = TYP_SEQFLD;
241 45 : else if( static_cast<const SwSetExpField*>(this)->GetInputFlag() )
242 8 : nRet = TYP_SETINPFLD;
243 : else
244 37 : nRet = TYP_SETFLD;
245 191 : break;
246 :
247 : case RES_PAGENUMBERFLD:
248 3189 : nRet = GetSubType();
249 3189 : if( PG_NEXT == nRet )
250 0 : nRet = TYP_NEXTPAGEFLD;
251 3189 : else if( PG_PREV == nRet )
252 0 : nRet = TYP_PREVPAGEFLD;
253 : else
254 3189 : nRet = TYP_PAGENUMBERFLD;
255 3189 : break;
256 :
257 : default:
258 4331 : nRet = aTypeTab[ m_pType->Which() ];
259 : }
260 7760 : return nRet;
261 : }
262 :
263 : /// get name or content
264 3 : OUString SwField::GetFieldName() const
265 : {
266 3 : sal_uInt16 nTypeId = GetTypeId();
267 3 : if (RES_DATETIMEFLD == GetTyp()->Which())
268 : {
269 : nTypeId = static_cast<sal_uInt16>(
270 0 : ((GetSubType() & DATEFLD) != 0) ? TYP_DATEFLD : TYP_TIMEFLD);
271 : }
272 3 : OUString sRet = SwFieldType::GetTypeStr( nTypeId );
273 3 : if (IsFixed())
274 : {
275 0 : sRet += " " + OUString(SwViewShell::GetShellRes()->aFixedStr);
276 : }
277 3 : return sRet;
278 : }
279 :
280 0 : OUString SwField::GetPar1() const
281 : {
282 0 : return OUString();
283 : }
284 :
285 0 : OUString SwField::GetPar2() const
286 : {
287 0 : return OUString();
288 : }
289 :
290 0 : OUString SwField::GetFormula() const
291 : {
292 0 : return GetPar2();
293 : }
294 :
295 0 : void SwField::SetPar1(const OUString& )
296 0 : {}
297 :
298 0 : void SwField::SetPar2(const OUString& )
299 0 : {}
300 :
301 103 : sal_uInt16 SwField::GetSubType() const
302 : {
303 103 : return 0;
304 : }
305 :
306 0 : void SwField::SetSubType(sal_uInt16 )
307 : {
308 0 : }
309 :
310 8 : bool SwField::QueryValue( uno::Any& rVal, sal_uInt16 nWhichId ) const
311 : {
312 8 : switch( nWhichId )
313 : {
314 : case FIELD_PROP_BOOL4:
315 8 : rVal <<= !m_bIsAutomaticLanguage;
316 8 : break;
317 : default:
318 : OSL_FAIL("illegal property");
319 : }
320 8 : return true;
321 : }
322 :
323 2 : bool SwField::PutValue( const uno::Any& rVal, sal_uInt16 nWhichId )
324 : {
325 2 : switch( nWhichId )
326 : {
327 : case FIELD_PROP_BOOL4:
328 : {
329 2 : bool bFixed = false;
330 2 : if(rVal >>= bFixed)
331 2 : m_bIsAutomaticLanguage = !bFixed;
332 : }
333 2 : break;
334 : default:
335 : OSL_FAIL("illegal property");
336 : }
337 2 : return true;
338 : }
339 :
340 : /** Set a new type
341 : *
342 : * This is needed/used for copying between documents.
343 : * Needs to be always of the same type.
344 : * @param pNewType The new type.
345 : * @return The old type.
346 : */
347 83 : SwFieldType* SwField::ChgTyp( SwFieldType* pNewType )
348 : {
349 : assert(pNewType && pNewType->Which() == m_pType->Which());
350 :
351 83 : SwFieldType* pOld = m_pType;
352 83 : m_pType = pNewType;
353 83 : return pOld;
354 : }
355 :
356 : /// Does the field have an action on a ClickHandler? (E.g. INetFields,...)
357 0 : bool SwField::HasClickHdl() const
358 : {
359 0 : bool bRet = false;
360 0 : switch (m_pType->Which())
361 : {
362 : case RES_INTERNETFLD:
363 : case RES_JUMPEDITFLD:
364 : case RES_GETREFFLD:
365 : case RES_MACROFLD:
366 : case RES_INPUTFLD:
367 : case RES_DROPDOWN :
368 0 : bRet = true;
369 0 : break;
370 :
371 : case RES_SETEXPFLD:
372 0 : bRet = static_cast<const SwSetExpField*>(this)->GetInputFlag();
373 0 : break;
374 : }
375 0 : return bRet;
376 : }
377 :
378 4532 : void SwField::SetLanguage(sal_uInt16 const nLang)
379 : {
380 4532 : m_nLang = nLang;
381 4532 : }
382 :
383 1 : void SwField::ChangeFormat(sal_uInt32 const nFormat)
384 : {
385 1 : m_nFormat = nFormat;
386 1 : }
387 :
388 672 : bool SwField::IsFixed() const
389 : {
390 672 : bool bRet = false;
391 672 : switch (m_pType->Which())
392 : {
393 : case RES_FIXDATEFLD:
394 : case RES_FIXTIMEFLD:
395 0 : bRet = true;
396 0 : break;
397 :
398 : case RES_DATETIMEFLD:
399 313 : bRet = 0 != (GetSubType() & FIXEDFLD);
400 313 : break;
401 :
402 : case RES_EXTUSERFLD:
403 : case RES_AUTHORFLD:
404 97 : bRet = 0 != (GetFormat() & AF_FIXED);
405 97 : break;
406 :
407 : case RES_FILENAMEFLD:
408 85 : bRet = 0 != (GetFormat() & FF_FIXED);
409 85 : break;
410 :
411 : case RES_DOCINFOFLD:
412 177 : bRet = 0 != (GetSubType() & DI_SUB_FIXED);
413 177 : break;
414 : }
415 672 : return bRet;
416 : }
417 :
418 8637 : OUString SwField::ExpandField(bool const bCached, ToxAuthorityField eField) const
419 : {
420 8637 : if ( m_bUseFieldValueCache )
421 : {
422 8563 : if (!bCached) // #i85766# do not expand fields in clipboard documents
423 : {
424 7757 : if (GetTypeId() == TYP_AUTHORITY)
425 : {
426 63 : const SwAuthorityField* pAuthorityField = static_cast<const SwAuthorityField*>(this);
427 63 : m_Cache = pAuthorityField->ConditionalExpand(eField);
428 : }
429 : else
430 7694 : m_Cache = Expand();
431 : }
432 8563 : return m_Cache;
433 : }
434 :
435 74 : return Expand();
436 : }
437 :
438 14 : OUString SwField::ExpandCitation(ToxAuthorityField eField) const
439 : {
440 14 : const SwAuthorityField* pAuthorityField = static_cast<const SwAuthorityField*>(this);
441 14 : return (pAuthorityField ? pAuthorityField->ExpandCitation(eField) : OUString());
442 : }
443 :
444 6582 : SwField * SwField::CopyField() const
445 : {
446 6582 : SwField *const pNew = Copy();
447 : // #i85766# cache expansion of source (for clipboard)
448 : // use this->cache, not this->Expand(): only text formatting calls Expand()
449 6582 : pNew->m_Cache = m_Cache;
450 6582 : pNew->m_bUseFieldValueCache = m_bUseFieldValueCache;
451 :
452 6582 : return pNew;
453 : }
454 :
455 : /// expand numbering
456 3686 : OUString FormatNumber(sal_uInt32 nNum, sal_uInt32 nFormat)
457 : {
458 3686 : if(SVX_NUM_PAGEDESC == nFormat)
459 0 : return OUString::number( nNum );
460 3686 : SvxNumberType aNumber;
461 :
462 : OSL_ENSURE(nFormat != SVX_NUM_NUMBER_NONE, "wrong number format" );
463 :
464 3686 : aNumber.SetNumberingType((sal_Int16)nFormat);
465 3686 : return aNumber.GetNumStr(nNum);
466 : }
467 :
468 23991 : SwValueFieldType::SwValueFieldType(SwDoc *const pDoc, sal_uInt16 const nWhichId)
469 : : SwFieldType(nWhichId)
470 : , m_pDoc(pDoc)
471 23991 : , m_bUseFormat(true)
472 : {
473 23991 : }
474 :
475 0 : SwValueFieldType::SwValueFieldType( const SwValueFieldType& rTyp )
476 0 : : SwFieldType(rTyp.Which())
477 0 : , m_pDoc(rTyp.GetDoc())
478 0 : , m_bUseFormat(rTyp.UseFormat())
479 : {
480 0 : }
481 :
482 : /// return value formatted as string
483 118 : OUString SwValueFieldType::ExpandValue( const double& rVal,
484 : sal_uInt32 nFormat, sal_uInt16 nLng) const
485 : {
486 118 : if (rVal >= DBL_MAX) // error string for calculator
487 0 : return SwViewShell::GetShellRes()->aCalc_Error;
488 :
489 118 : OUString sExpand;
490 118 : SvNumberFormatter* pFormatter = m_pDoc->GetNumberFormatter();
491 118 : Color* pCol = 0;
492 :
493 : // Bug #60010
494 118 : sal_uInt16 nFormatLng = ::lcl_GetLanguageOfFormat( nLng, nFormat, *pFormatter );
495 :
496 118 : if( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && LANGUAGE_SYSTEM != nFormatLng )
497 : {
498 5 : short nType = css::util::NumberFormat::DEFINED;
499 : sal_Int32 nDummy;
500 :
501 5 : const SvNumberformat* pEntry = pFormatter->GetEntry(nFormat);
502 :
503 5 : if (pEntry && nLng != pEntry->GetLanguage())
504 : {
505 : sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nFormat,
506 5 : (LanguageType)nFormatLng);
507 :
508 5 : if (nNewFormat == nFormat)
509 : {
510 : // probably user-defined format
511 0 : OUString sFormat(pEntry->GetFormatstring());
512 :
513 : pFormatter->PutandConvertEntry(sFormat, nDummy, nType, nFormat,
514 0 : pEntry->GetLanguage(), nFormatLng );
515 : }
516 : else
517 5 : nFormat = nNewFormat;
518 : }
519 : OSL_ENSURE(pEntry, "unknown number format!");
520 : }
521 :
522 118 : if( pFormatter->IsTextFormat( nFormat ) )
523 : {
524 : pFormatter->GetOutputString(DoubleToString(rVal, nFormatLng), nFormat,
525 0 : sExpand, &pCol);
526 : }
527 : else
528 : {
529 118 : pFormatter->GetOutputString(rVal, nFormat, sExpand, &pCol);
530 : }
531 118 : return sExpand;
532 : }
533 :
534 0 : OUString SwValueFieldType::DoubleToString(const double &rVal,
535 : sal_uInt32 nFormat) const
536 : {
537 0 : SvNumberFormatter* pFormatter = m_pDoc->GetNumberFormatter();
538 0 : const SvNumberformat* pEntry = pFormatter->GetEntry(nFormat);
539 :
540 0 : if (!pEntry)
541 0 : return OUString();
542 :
543 0 : return DoubleToString(rVal, pEntry->GetLanguage());
544 : }
545 :
546 0 : OUString SwValueFieldType::DoubleToString( const double &rVal,
547 : sal_uInt16 nLng ) const
548 : {
549 0 : SvNumberFormatter* pFormatter = m_pDoc->GetNumberFormatter();
550 :
551 : // Bug #60010
552 0 : if( nLng == LANGUAGE_NONE )
553 0 : nLng = LANGUAGE_SYSTEM;
554 :
555 0 : pFormatter->ChangeIntl( nLng ); // get separator in the correct language
556 : return ::rtl::math::doubleToUString( rVal, rtl_math_StringFormat_F, 12,
557 0 : pFormatter->GetDecSep(), true );
558 : }
559 :
560 1281 : SwValueField::SwValueField( SwValueFieldType* pFieldType, sal_uInt32 nFormat,
561 : sal_uInt16 nLng, const double fVal )
562 : : SwField(pFieldType, nFormat, nLng)
563 1281 : , m_fValue(fVal)
564 : {
565 1281 : }
566 :
567 0 : SwValueField::SwValueField( const SwValueField& rField )
568 : : SwField(rField)
569 0 : , m_fValue(rField.GetValue())
570 : {
571 0 : }
572 :
573 1277 : SwValueField::~SwValueField()
574 : {
575 1277 : }
576 :
577 : /** Set a new type
578 : *
579 : * This is needed/used for copying between documents.
580 : * Needs to be always of the same type.
581 : * @param pNewType The new type.
582 : * @return The old type.
583 : */
584 72 : SwFieldType* SwValueField::ChgTyp( SwFieldType* pNewType )
585 : {
586 72 : SwDoc* pNewDoc = static_cast<SwValueFieldType *>(pNewType)->GetDoc();
587 72 : SwDoc* pDoc = GetDoc();
588 :
589 72 : if( pNewDoc && pDoc && pDoc != pNewDoc)
590 : {
591 42 : SvNumberFormatter* pFormatter = pNewDoc->GetNumberFormatter();
592 :
593 42 : if( pFormatter && pFormatter->HasMergeFormatTable() &&
594 0 : static_cast<SwValueFieldType *>(GetTyp())->UseFormat() )
595 0 : SetFormat(pFormatter->GetMergeFormatIndex( GetFormat() ));
596 : }
597 :
598 72 : return SwField::ChgTyp(pNewType);
599 : }
600 :
601 : /// get format in office language
602 0 : sal_uInt32 SwValueField::GetSystemFormat(SvNumberFormatter* pFormatter, sal_uInt32 nFormat)
603 : {
604 0 : const SvNumberformat* pEntry = pFormatter->GetEntry(nFormat);
605 0 : sal_uInt16 nLng = SvtSysLocale().GetLanguageTag().getLanguageType();
606 :
607 0 : if (pEntry && nLng != pEntry->GetLanguage())
608 : {
609 : sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nFormat,
610 0 : (LanguageType)nLng);
611 :
612 0 : if (nNewFormat == nFormat)
613 : {
614 : // probably user-defined format
615 0 : short nType = css::util::NumberFormat::DEFINED;
616 : sal_Int32 nDummy;
617 :
618 0 : OUString sFormat(pEntry->GetFormatstring());
619 :
620 0 : sal_uInt32 nTempFormat = nFormat;
621 : pFormatter->PutandConvertEntry(sFormat, nDummy, nType,
622 0 : nTempFormat, pEntry->GetLanguage(), nLng);
623 0 : nFormat = nTempFormat;
624 : }
625 : else
626 0 : nFormat = nNewFormat;
627 : }
628 :
629 0 : return nFormat;
630 : }
631 :
632 : /// set language of the format
633 457 : void SwValueField::SetLanguage( sal_uInt16 nLng )
634 : {
635 1043 : if( IsAutomaticLanguage() &&
636 586 : static_cast<SwValueFieldType *>(GetTyp())->UseFormat() &&
637 129 : GetFormat() != SAL_MAX_UINT32 )
638 : {
639 : // Bug #60010
640 129 : SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
641 129 : sal_uInt16 nFormatLng = ::lcl_GetLanguageOfFormat( nLng, GetFormat(),
642 129 : *pFormatter );
643 :
644 342 : if( (GetFormat() >= SV_COUNTRY_LANGUAGE_OFFSET ||
645 379 : LANGUAGE_SYSTEM != nFormatLng ) &&
646 125 : !(Which() == RES_USERFLD && (GetSubType()&nsSwExtendedSubType::SUB_CMD) ) )
647 : {
648 125 : const SvNumberformat* pEntry = pFormatter->GetEntry(GetFormat());
649 :
650 125 : if( pEntry && nFormatLng != pEntry->GetLanguage() )
651 : {
652 : sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(
653 83 : GetFormat(), (LanguageType)nFormatLng );
654 :
655 83 : if( nNewFormat == GetFormat() )
656 : {
657 : // probably user-defined format
658 1 : short nType = css::util::NumberFormat::DEFINED;
659 : sal_Int32 nDummy;
660 1 : OUString sFormat( pEntry->GetFormatstring() );
661 : pFormatter->PutandConvertEntry( sFormat, nDummy, nType,
662 : nNewFormat,
663 1 : pEntry->GetLanguage(),
664 2 : nFormatLng );
665 : }
666 83 : SetFormat( nNewFormat );
667 : }
668 : OSL_ENSURE(pEntry, "unknown number format!");
669 : }
670 : }
671 :
672 457 : SwField::SetLanguage(nLng);
673 457 : }
674 :
675 780 : double SwValueField::GetValue() const
676 : {
677 780 : return m_fValue;
678 : }
679 :
680 1231 : void SwValueField::SetValue( const double& rVal )
681 : {
682 1231 : m_fValue = rVal;
683 1231 : }
684 :
685 339 : SwFormulaField::SwFormulaField( SwValueFieldType* pFieldType, sal_uInt32 nFormat, const double fVal)
686 339 : : SwValueField(pFieldType, nFormat, LANGUAGE_SYSTEM, fVal)
687 : {
688 339 : }
689 :
690 0 : SwFormulaField::SwFormulaField( const SwFormulaField& rField )
691 0 : : SwValueField(static_cast<SwValueFieldType *>(rField.GetTyp()), rField.GetFormat(),
692 0 : rField.GetLanguage(), rField.GetValue())
693 : {
694 0 : }
695 :
696 299 : OUString SwFormulaField::GetFormula() const
697 : {
698 299 : return m_sFormula;
699 : }
700 :
701 359 : void SwFormulaField::SetFormula(const OUString& rStr)
702 : {
703 359 : m_sFormula = rStr;
704 :
705 359 : sal_uLong nFormat(GetFormat());
706 :
707 359 : if( nFormat && SAL_MAX_UINT32 != nFormat )
708 : {
709 256 : sal_Int32 nPos = 0;
710 : double fTmpValue;
711 256 : if( SwCalc::Str2Double( rStr, nPos, fTmpValue, GetDoc() ) )
712 0 : SwValueField::SetValue( fTmpValue );
713 : }
714 359 : }
715 :
716 0 : void SwFormulaField::SetExpandedFormula( const OUString& rStr )
717 : {
718 0 : sal_uInt32 nFormat(GetFormat());
719 :
720 0 : if (nFormat && nFormat != SAL_MAX_UINT32 && static_cast<SwValueFieldType *>(GetTyp())->UseFormat())
721 : {
722 : double fTmpValue;
723 :
724 0 : SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
725 :
726 0 : if (pFormatter->IsNumberFormat(rStr, nFormat, fTmpValue))
727 : {
728 0 : SwValueField::SetValue(fTmpValue);
729 :
730 0 : m_sFormula = static_cast<SwValueFieldType *>(GetTyp())->DoubleToString(fTmpValue, nFormat);
731 0 : return;
732 : }
733 : }
734 0 : m_sFormula = rStr;
735 : }
736 :
737 0 : OUString SwFormulaField::GetExpandedFormula() const
738 : {
739 0 : sal_uInt32 nFormat(GetFormat());
740 :
741 0 : if (nFormat && nFormat != SAL_MAX_UINT32 && static_cast<SwValueFieldType *>(GetTyp())->UseFormat())
742 : {
743 0 : OUString sFormattedValue;
744 0 : Color* pCol = 0;
745 :
746 0 : SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
747 :
748 0 : if (pFormatter->IsTextFormat(nFormat))
749 : {
750 0 : OUString sTempIn(static_cast<SwValueFieldType *>(GetTyp())->DoubleToString(GetValue(), nFormat));
751 0 : pFormatter->GetOutputString(sTempIn, nFormat, sFormattedValue, &pCol);
752 : }
753 : else
754 : {
755 0 : pFormatter->GetOutputString(GetValue(), nFormat, sFormattedValue, &pCol);
756 : }
757 0 : return sFormattedValue;
758 : }
759 : else
760 0 : return GetFormula();
761 : }
762 :
763 42 : OUString SwField::GetDescription() const
764 : {
765 42 : return SW_RES(STR_FIELD);
766 : }
767 :
768 0 : bool SwField::IsClickable() const
769 : {
770 0 : switch (Which())
771 : {
772 : case RES_JUMPEDITFLD:
773 : case RES_MACROFLD:
774 : case RES_GETREFFLD:
775 : case RES_INPUTFLD:
776 : case RES_SETEXPFLD:
777 : case RES_DROPDOWN:
778 0 : return true;
779 : }
780 0 : return false;
781 177 : }
782 :
783 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|