LibreOffice Module reportdesign (master) 1
xmlControlProperty.cxx
Go to the documentation of this file.
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 <sal/config.h>
21
22#include <cmath>
23#include <map>
24
26
27#include <o3tl/temporary.hxx>
28#include <rtl/strbuf.hxx>
30#include "xmlfilter.hxx"
31#include <xmloff/xmltoken.hxx>
34#include "xmlEnums.hxx"
35#include <tools/date.hxx>
36#include <unotools/datetime.hxx>
37#include <com/sun/star/util/DateTime.hpp>
38#include <rtl/math.hxx>
39#include <osl/diagnose.h>
40
41#define TYPE_DATE 1
42#define TYPE_TIME 2
43#define TYPE_DATETIME 3
44
45namespace rptxml
46{
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::xml::sax;
50
52 ,const Reference< XFastAttributeList > & _xAttrList
53 ,const Reference< XPropertySet >& _xControl
54 ,OXMLControlProperty* _pContainer) :
55 SvXMLImportContext( rImport )
56 ,m_xControl(_xControl)
57 ,m_pContainer(_pContainer)
58 ,m_bIsList(false)
59{
60 m_aPropType = cppu::UnoType<void>::get();
61
62 OSL_ENSURE(m_xControl.is(),"Control is NULL!");
63
64 for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList ))
65 {
66 switch( aIter.getToken() )
67 {
69 m_bIsList = aIter.toView() == "true";
70 break;
71 case XML_ELEMENT(OOO, XML_VALUE_TYPE):
72 {
73 // needs to be translated into a css::uno::Type
74 static std::map< OUString, css::uno::Type > const s_aTypeNameMap
75 {
77 // Not a copy paste error, see comment xmloff/source/forms/propertyimport.cxx lines 244-248
86 };
87
88 const std::map< OUString, css::uno::Type >::const_iterator aTypePos = s_aTypeNameMap.find(aIter.toString());
89 OSL_ENSURE(s_aTypeNameMap.end() != aTypePos, "OXMLControlProperty::OXMLControlProperty: invalid type!");
90 if (s_aTypeNameMap.end() != aTypePos)
91 m_aPropType = aTypePos->second;
92 }
93 break;
95 m_aSetting.Name = aIter.toString();
96 break;
97 default:
98 XMLOFF_WARN_UNKNOWN("reportdesign", aIter);
99 break;
100 }
101 }
102
103}
104
105
107{
108}
109
110css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLControlProperty::createFastChildContext(
111 sal_Int32 nElement,
112 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
113{
114 css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
115 ORptFilter& rImport = GetOwnImport();
116
117 switch( nElement )
118 {
120 rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
121 xContext = new OXMLControlProperty( rImport,xAttrList,m_xControl);
122 break;
123 case XML_ELEMENT(OOO, XML_VALUE):
124 rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
125 xContext = new OXMLControlProperty( rImport,xAttrList,m_xControl,this );
126 break;
127 default:
128 break;
129 }
130
131 return xContext;
132}
133
135{
136 if ( m_pContainer )
137 m_pContainer->addValue(m_aCharBuffer.makeStringAndClear());
138 if ( m_aSetting.Name.isEmpty() || !m_xControl.is() )
139 return;
140
141 if ( m_bIsList && !m_aSequence.hasElements() )
142 m_aSetting.Value <<= m_aSequence;
143 try
144 {
145 m_xControl->setPropertyValue(m_aSetting.Name,m_aSetting.Value);
146 }
147 catch(const Exception&)
148 {
149 OSL_FAIL("Unknown property found!");
150 }
151}
152
153void OXMLControlProperty::characters( const OUString& rChars )
154{
155 m_aCharBuffer.append(rChars);
156}
157
158void OXMLControlProperty::addValue(const OUString& _sValue)
159{
160 Any aValue;
161 if( TypeClass_VOID != m_aPropType.getTypeClass() )
162 aValue = convertString(m_aPropType, _sValue);
163
164 if ( !m_bIsList )
165 m_aSetting.Value = aValue;
166 else
167 {
168 sal_Int32 nPos = m_aSequence.getLength();
169 m_aSequence.realloc(nPos+1);
170 m_aSequence.getArray()[nPos] = aValue;
171 }
172}
173
175{
176 return static_cast<ORptFilter&>(GetImport());
177}
178
179Any OXMLControlProperty::convertString(const css::uno::Type& _rExpectedType, const OUString& _rReadCharacters)
180{
181 Any aReturn;
182 switch (_rExpectedType.getTypeClass())
183 {
184 case TypeClass_BOOLEAN: // sal_Bool
185 {
186 bool bValue(false);
187 bool bSuccess =
188 ::sax::Converter::convertBool(bValue, _rReadCharacters);
189 OSL_ENSURE(bSuccess,
190 OStringBuffer("OXMLControlProperty::convertString: could not convert \"" +
191 OUStringToOString(_rReadCharacters, RTL_TEXTENCODING_ASCII_US) +
192 "\" into a boolean!").getStr());
193 aReturn <<= bValue;
194 }
195 break;
196 case TypeClass_SHORT: // sal_Int16
197 case TypeClass_LONG: // sal_Int32
198 { // it's a real int32/16 property
199 sal_Int32 nValue(0);
200 bool bSuccess =
201 ::sax::Converter::convertNumber(nValue, _rReadCharacters);
202 OSL_ENSURE(bSuccess,
203 OStringBuffer("OXMLControlProperty::convertString: could not convert \"" +
204 OUStringToOString(_rReadCharacters, RTL_TEXTENCODING_ASCII_US) +
205 "\" into an integer!").getStr());
206 if (TypeClass_SHORT == _rExpectedType.getTypeClass())
207 aReturn <<= static_cast<sal_Int16>(nValue);
208 else
209 aReturn <<= nValue;
210 break;
211 }
212 case TypeClass_HYPER:
213 {
214 OSL_FAIL("OXMLControlProperty::convertString: 64-bit integers not implemented yet!");
215 }
216 break;
217 case TypeClass_DOUBLE:
218 {
219 double nValue = 0.0;
220 bool bSuccess =
221 ::sax::Converter::convertDouble(nValue, _rReadCharacters);
222 OSL_ENSURE(bSuccess,
223 OStringBuffer("OXMLControlProperty::convertString: could not convert \"" +
224 OUStringToOString(_rReadCharacters, RTL_TEXTENCODING_ASCII_US) +
225 "\" into a double!").getStr());
226 aReturn <<= nValue;
227 }
228 break;
229 case TypeClass_STRING:
230 aReturn <<= _rReadCharacters;
231 break;
232 case TypeClass_STRUCT:
233 {
234 // recognized structs:
235 static css::uno::Type s_aDateType = ::cppu::UnoType<css::util::Date>::get();
236 static css::uno::Type s_aTimeType = ::cppu::UnoType<css::util::Time>::get();
237 static css::uno::Type s_aDateTimeType = ::cppu::UnoType<css::util::DateTime>::get();
238 sal_Int32 nType = 0;
239 if ( _rExpectedType.equals(s_aDateType) )
241 else if ( _rExpectedType.equals(s_aTimeType) )
243 else if ( _rExpectedType.equals(s_aDateTimeType) )
245 if ( nType )
246 {
247 // first extract the double
248 double nValue = 0;
249 bool bSuccess =
250 ::sax::Converter::convertDouble(nValue, _rReadCharacters);
251 OSL_ENSURE(bSuccess,
252 OStringBuffer("OPropertyImport::convertString: could not convert \"" +
253 OUStringToOString(_rReadCharacters, RTL_TEXTENCODING_ASCII_US) +
254 "\" into a double!").getStr());
255
256 // then convert it into the target type
257 switch (nType)
258 {
259 case TYPE_DATE:
260 {
261 OSL_ENSURE(std::modf(nValue, &o3tl::temporary(double())) == 0,
262 "OPropertyImport::convertString: a Date value with a fractional part?");
263 aReturn <<= implGetDate(nValue);
264 }
265 break;
266 case TYPE_TIME:
267 {
268 OSL_ENSURE((static_cast<sal_uInt32>(nValue)) == 0,
269 "OPropertyImport::convertString: a tools::Time value with more than a fractional part?");
270 aReturn <<= implGetTime(nValue);
271 }
272 break;
273 case TYPE_DATETIME:
274 {
275 css::util::Time aTime = implGetTime(nValue);
276 css::util::Date aDate = implGetDate(nValue);
277
278 css::util::DateTime aDateTime;
279 aDateTime.NanoSeconds = aTime.NanoSeconds;
280 aDateTime.Seconds = aTime.Seconds;
281 aDateTime.Minutes = aTime.Minutes;
282 aDateTime.Hours = aTime.Hours;
283 aDateTime.Day = aDate.Day;
284 aDateTime.Month = aDate.Month;
285 aDateTime.Year = aDate.Year;
286 aReturn <<= aDateTime;
287 }
288 break;
289 default:
290 break;
291 }
292 }
293 else
294 OSL_FAIL("OPropertyImport::convertString: unsupported property type!");
295 }
296 break;
297 default:
298 OSL_FAIL("OXMLControlProperty::convertString: invalid type class!");
299 }
300
301 return aReturn;
302}
303
304css::util::Time OXMLControlProperty::implGetTime(double _nValue)
305{
306 css::util::Time aTime;
307 sal_uInt64 nIntValue = ::rtl::math::round(_nValue * 86400000000000.0);
308 aTime.NanoSeconds = static_cast<sal_uInt16>( nIntValue % 1000000000 );
309 nIntValue /= 1000000000;
310 aTime.Seconds = static_cast<sal_uInt16>( nIntValue % 60 );
311 nIntValue /= 60;
312 aTime.Minutes = static_cast<sal_uInt16>( nIntValue % 60 );
313 nIntValue /= 60;
314 OSL_ENSURE(nIntValue < 24, "OPropertyImport::implGetTime: more than a day?");
315 aTime.Hours = static_cast< sal_uInt16 >( nIntValue );
316
317 return aTime;
318}
319
320
321css::util::Date OXMLControlProperty::implGetDate(double _nValue)
322{
323 Date aToolsDate(static_cast<sal_uInt32>(_nValue));
324 css::util::Date aDate;
325 ::utl::typeConvert(aToolsDate, aDate);
326 return aDate;
327}
328
329} // namespace rptxml
330
331
332/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SvXMLImport & GetImport()
css::uno::Type const & get()
css::uno::Reference< css::beans::XPropertySet > m_xControl
OXMLControlProperty(const OXMLControlProperty &)=delete
OXMLControlProperty * m_pContainer
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
void addValue(const OUString &_sValue)
adds value to property
css::beans::PropertyValue m_aSetting
css::uno::Sequence< css::uno::Any > m_aSequence
static css::util::Time implGetTime(double _nValue)
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
virtual ~OXMLControlProperty() override
virtual void SAL_CALL characters(const OUString &rChars) override
static css::util::Date implGetDate(double _nValue)
static css::uno::Any convertString(const css::uno::Type &_rExpectedType, const OUString &_rReadCharacters)
static void convertDouble(OUStringBuffer &rBuffer, double fNumber, bool bWriteUnits, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
static bool convertNumber(sal_Int32 &rValue, std::u16string_view aString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32)
static bool convertBool(bool &rBool, std::u16string_view rString)
sal_Int32 _nValue
sal_Int16 nValue
sal_uInt16 nPos
@ Exception
FORM
constexpr T & temporary(T &&x)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
XML_LIST_PROPERTY
XML_FLOAT
XML_STRING
XML_VALUE
XML_BOOLEAN
XML_PROPERTY_NAME
XML_TIME
XML_VOID
XML_VALUE_TYPE
XML_DATE
XML_DOUBLE
XML_SHORT
XML_INT
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
QPRO_FUNC_TYPE nType
Reference< XControl > m_xControl
#define TYPE_DATETIME
#define TYPE_TIME
#define TYPE_DATE
#define PROGRESS_BAR_STEP
Definition: xmlEnums.hxx:22
#define XMLOFF_WARN_UNKNOWN(area, rIter)
#define XML_ELEMENT(prefix, name)