simplify writeBitmapObject
[LibreOffice.git] / sw / source / core / fields / usrfld.cxx
blob11f19b03150add04999abf9f0b32275ccfb8d3c3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <libxml/xmlwriter.h>
24 #include <o3tl/any.hxx>
26 #include <svl/numformat.hxx>
27 #include <unotools/charclass.hxx>
29 #include <calbck.hxx>
30 #include <calc.hxx>
31 #include <usrfld.hxx>
32 #include <doc.hxx>
33 #include <IDocumentFieldsAccess.hxx>
34 #include <IDocumentUndoRedo.hxx>
35 #include <IDocumentState.hxx>
36 #include <unofldmid.h>
38 using namespace ::com::sun::star;
40 namespace
42 /**
43 * Returns the language used for float <-> string conversions in
44 * SwUserFieldType.
46 LanguageType GetFieldTypeLanguage()
48 return LANGUAGE_SYSTEM;
52 // Userfields
54 SwUserField::SwUserField(SwUserFieldType* pTyp, sal_uInt16 nSub, sal_uInt32 nFormat)
55 : SwValueField(pTyp, nFormat),
56 m_nSubType(nSub)
60 OUString SwUserField::ExpandImpl(SwRootFrame const*const) const
62 if(!(m_nSubType & nsSwExtendedSubType::SUB_INVISIBLE))
63 return static_cast<SwUserFieldType*>(GetTyp())->Expand(GetFormat(), m_nSubType, GetLanguage());
65 return OUString();
68 std::unique_ptr<SwField> SwUserField::Copy() const
70 std::unique_ptr<SwField> pTmp(new SwUserField(static_cast<SwUserFieldType*>(GetTyp()), m_nSubType, GetFormat()));
71 pTmp->SetAutomaticLanguage(IsAutomaticLanguage());
72 pTmp->SetTitle(GetTitle());
73 return pTmp;
76 OUString SwUserField::GetFieldName() const
78 return SwFieldType::GetTypeStr(SwFieldTypesEnum::User) +
79 " " + GetTyp()->GetName() + " = " +
80 static_cast<SwUserFieldType*>(GetTyp())->GetContent();
83 double SwUserField::GetValue() const
85 return static_cast<SwUserFieldType*>(GetTyp())->GetValue();
88 void SwUserField::SetValue( const double& rVal )
90 static_cast<SwUserFieldType*>(GetTyp())->SetValue(rVal);
93 /// Get name
94 OUString SwUserField::GetPar1() const
96 return static_cast<const SwUserFieldType*>(GetTyp())->GetName();
99 /// Get content
100 OUString SwUserField::GetPar2() const
102 return static_cast<SwUserFieldType*>(GetTyp())->GetContent(GetFormat());
105 void SwUserField::SetPar2(const OUString& rStr)
107 static_cast<SwUserFieldType*>(GetTyp())->SetContent(rStr, GetFormat());
110 sal_uInt16 SwUserField::GetSubType() const
112 return static_cast<SwUserFieldType*>(GetTyp())->GetType() | m_nSubType;
115 void SwUserField::SetSubType(sal_uInt16 nSub)
117 static_cast<SwUserFieldType*>(GetTyp())->SetType(nSub & 0x00ff);
118 m_nSubType = nSub & 0xff00;
121 bool SwUserField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
123 switch( nWhichId )
125 case FIELD_PROP_BOOL2:
126 rAny <<= 0 != (m_nSubType & nsSwExtendedSubType::SUB_CMD);
127 break;
128 case FIELD_PROP_BOOL1:
129 rAny <<= 0 == (m_nSubType & nsSwExtendedSubType::SUB_INVISIBLE);
130 break;
131 case FIELD_PROP_FORMAT:
132 rAny <<= static_cast<sal_Int32>(GetFormat());
133 break;
134 default:
135 return SwField::QueryValue(rAny, nWhichId);
137 return true;
140 bool SwUserField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
142 switch( nWhichId )
144 case FIELD_PROP_BOOL1:
145 if(*o3tl::doAccess<bool>(rAny))
146 m_nSubType &= (~nsSwExtendedSubType::SUB_INVISIBLE);
147 else
148 m_nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
149 break;
150 case FIELD_PROP_BOOL2:
151 if(*o3tl::doAccess<bool>(rAny))
152 m_nSubType |= nsSwExtendedSubType::SUB_CMD;
153 else
154 m_nSubType &= (~nsSwExtendedSubType::SUB_CMD);
155 break;
156 case FIELD_PROP_FORMAT:
158 sal_Int32 nTmp = 0;
159 rAny >>= nTmp;
160 SetFormat(nTmp);
162 break;
163 default:
164 return SwField::PutValue(rAny, nWhichId);
166 return true;
169 void SwUserField::dumpAsXml(xmlTextWriterPtr pWriter) const
171 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwUserField"));
172 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nSubType"), BAD_CAST(OString::number(m_nSubType).getStr()));
173 SwValueField::dumpAsXml(pWriter);
174 (void)xmlTextWriterEndElement(pWriter);
177 SwUserFieldType::SwUserFieldType( SwDoc* pDocPtr, const OUString& aNam )
178 : SwValueFieldType( pDocPtr, SwFieldIds::User ),
179 m_nValue( 0 ),
180 m_nType(nsSwGetSetExpType::GSE_STRING)
182 m_bValidValue = m_bDeleted = false;
183 m_aName = aNam;
185 EnableFormat(false); // Do not use a Numberformatter for nsSwGetSetExpType::GSE_STRING
188 OUString SwUserFieldType::Expand(sal_uInt32 nFormat, sal_uInt16 nSubType, LanguageType nLng)
190 if((m_nType & nsSwGetSetExpType::GSE_EXPR) && !(nSubType & nsSwExtendedSubType::SUB_CMD))
192 EnableFormat();
193 return ExpandValue(m_nValue, nFormat, nLng);
196 EnableFormat(false); // Do not use a Numberformatter
197 return m_aContent;
200 std::unique_ptr<SwFieldType> SwUserFieldType::Copy() const
202 std::unique_ptr<SwUserFieldType> pTmp(new SwUserFieldType( GetDoc(), m_aName ));
203 pTmp->m_aContent = m_aContent;
204 pTmp->m_aContentLang = m_aContentLang;
205 pTmp->m_nType = m_nType;
206 pTmp->m_bValidValue = m_bValidValue;
207 pTmp->m_nValue = m_nValue;
208 pTmp->m_bDeleted = m_bDeleted;
210 return pTmp;
213 OUString SwUserFieldType::GetName() const
215 return m_aName;
218 void SwUserFieldType::SwClientNotify(const SwModify&, const SfxHint& rHint)
220 if (rHint.GetId() == SfxHintId::SwLegacyModify)
222 auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
223 if (!pLegacy->m_pOld && !pLegacy->m_pNew)
224 m_bValidValue = false;
226 else if (rHint.GetId() == SfxHintId::SwUpdateAttr)
228 auto pUpdateHint = static_cast<const sw::UpdateAttrHint*>(&rHint);
229 if (!pUpdateHint->m_pOld && !pUpdateHint->m_pNew)
230 m_bValidValue = false;
232 else if (rHint.GetId() == SfxHintId::SwAttrSetChange)
234 auto pChangeHint = static_cast<const sw::AttrSetChangeHint*>(&rHint);
235 if (!pChangeHint->m_pOld && !pChangeHint->m_pNew)
236 m_bValidValue = false;
239 CallSwClientNotify(rHint);
240 // update input fields that might be connected to the user field
241 if (!IsModifyLocked())
243 LockModify();
244 GetDoc()->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Input)->UpdateFields();
245 UnlockModify();
249 void SwUserFieldType::UpdateFields()
251 m_bValidValue = false;
252 CallSwClientNotify(sw::LegacyModifyHint(nullptr, nullptr));
253 if (!IsModifyLocked())
255 LockModify();
256 GetDoc()->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Input)->UpdateFields();
257 UnlockModify();
261 double SwUserFieldType::GetValue( SwCalc& rCalc )
263 if(m_bValidValue)
264 return m_nValue;
266 if(!rCalc.Push( this ))
268 rCalc.SetCalcError( SwCalcError::Syntax );
269 return 0;
272 // See if we need to temporarily switch rCalc's language: in case it
273 // differs from the field type locale.
274 const CharClass* pCharClass = rCalc.GetCharClass();
275 LanguageTag aCharClassLanguage = pCharClass->getLanguageTag();
276 LanguageTag aContentLang(m_aContentLang);
278 // for the call of calculate we need the language that was used for putting/setting
279 // the m_aContent string, otherwise the aContent could be interpreted wrongly,
281 bool bSwitchLanguage = m_aContentLang != aCharClassLanguage.getBcp47();
283 if (bSwitchLanguage)
284 rCalc.SetCharClass(aContentLang);
286 m_nValue = rCalc.Calculate( m_aContent ).GetDouble();
288 // we than have to set the proper char class languageTag again
290 if (bSwitchLanguage)
291 rCalc.SetCharClass(aCharClassLanguage);
293 rCalc.Pop();
295 if( !rCalc.IsCalcError() )
296 m_bValidValue = true;
297 else
298 m_nValue = 0;
300 return m_nValue;
303 OUString SwUserFieldType::GetInputOrDateTime( sal_uInt32 nFormat ) const
305 return static_cast<const SwValueFieldType*>(this)->GetInputOrDateTime( m_aContent, GetValue(), nFormat);
308 OUString SwUserFieldType::GetContent( sal_uInt32 nFormat ) const
310 if (nFormat && nFormat != SAL_MAX_UINT32)
312 OUString sFormattedValue;
313 const Color* pCol = nullptr;
315 SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
317 pFormatter->GetOutputString(GetValue(), nFormat, sFormattedValue, &pCol);
318 return sFormattedValue;
321 return m_aContent;
324 void SwUserFieldType::SetContent( const OUString& rStr, sal_uInt32 nFormat )
326 if( m_aContent == rStr )
327 return;
329 m_aContent = rStr;
331 if (nFormat && nFormat != SAL_MAX_UINT32)
333 double fValue;
335 if (GetDoc()->IsNumberFormat(rStr, nFormat, fValue))
337 SetValue(fValue);
338 LanguageTag aContentLanguage(GetFieldTypeLanguage());
339 m_aContentLang = aContentLanguage.getBcp47();
340 m_aContent = DoubleToString(fValue, aContentLanguage.getLanguageType());
344 bool bModified = GetDoc()->getIDocumentState().IsModified();
345 GetDoc()->getIDocumentState().SetModified();
346 if( !bModified ) // Bug 57028
348 GetDoc()->GetIDocumentUndoRedo().SetUndoNoResetModified();
352 void SwUserFieldType::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
354 switch( nWhichId )
356 case FIELD_PROP_DOUBLE:
357 rAny <<= m_nValue;
358 break;
359 case FIELD_PROP_PAR2:
360 rAny <<= m_aContent;
361 break;
362 case FIELD_PROP_BOOL1:
363 rAny <<= 0 != (nsSwGetSetExpType::GSE_EXPR&m_nType);
364 break;
365 default:
366 assert(false);
370 void SwUserFieldType::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
372 switch( nWhichId )
374 case FIELD_PROP_DOUBLE:
376 double fVal = 0;
377 rAny >>= fVal;
378 m_nValue = fVal;
379 LanguageTag aContentLanguage(GetFieldTypeLanguage());
380 m_aContentLang = aContentLanguage.getBcp47();
381 m_aContent = DoubleToString(m_nValue, aContentLanguage.getLanguageType());
383 break;
384 case FIELD_PROP_PAR2:
385 rAny >>= m_aContent;
386 break;
387 case FIELD_PROP_BOOL1:
388 if(*o3tl::doAccess<bool>(rAny))
390 m_nType |= nsSwGetSetExpType::GSE_EXPR;
391 m_nType &= ~nsSwGetSetExpType::GSE_STRING;
393 else
395 m_nType &= ~nsSwGetSetExpType::GSE_EXPR;
396 m_nType |= nsSwGetSetExpType::GSE_STRING;
398 break;
399 default:
400 assert(false);
404 void SwUserFieldType::EnsureValid()
406 if(IsValid())
407 return;
408 SwCalc aCalc(*GetDoc());
409 GetValue(aCalc);
412 void SwUserFieldType::dumpAsXml(xmlTextWriterPtr pWriter) const
414 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwUserFieldType"));
415 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nValue"), BAD_CAST(OString::number(m_nValue).getStr()));
416 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aContent"), BAD_CAST(m_aContent.toUtf8().getStr()));
417 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aContentLang"), BAD_CAST(m_aContentLang.toUtf8().getStr()));
418 SwFieldType::dumpAsXml(pWriter);
419 (void)xmlTextWriterEndElement(pWriter);
422 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */