Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <stdio.h>
31 : : #include "propertyexport.hxx"
32 : : #include <xmloff/xmlexp.hxx>
33 : : #include "strings.hxx"
34 : : #include "xmloff/xmlnmspe.hxx"
35 : : #include <xmloff/xmluconv.hxx>
36 : : #include <xmloff/families.hxx>
37 : : #include <sax/tools/converter.hxx>
38 : : #include <osl/diagnose.h>
39 : : #include <rtl/strbuf.hxx>
40 : : #include <com/sun/star/beans/PropertyAttribute.hpp>
41 : : #include <com/sun/star/util/Date.hpp>
42 : : #include <com/sun/star/util/Time.hpp>
43 : : #include <com/sun/star/util/DateTime.hpp>
44 : : #include <comphelper/extract.hxx>
45 : : #include <comphelper/sequence.hxx>
46 : : #include <comphelper/types.hxx>
47 : : #include "callbacks.hxx"
48 : : #include <unotools/datetime.hxx>
49 : : #include <tools/date.hxx>
50 : : #include <tools/datetime.hxx>
51 : :
52 : : //.........................................................................
53 : : namespace xmloff
54 : : {
55 : : //.........................................................................
56 : :
57 : : using namespace ::com::sun::star::uno;
58 : : using namespace ::com::sun::star::lang;
59 : : using namespace ::com::sun::star::beans;
60 : :
61 : : // NO using namespace ...util !!!
62 : : // need a tools Date/Time/DateTime below, which would conflict with the uno types then
63 : :
64 : : using namespace ::comphelper;
65 : :
66 : : //=====================================================================
67 : : //= OPropertyExport
68 : : //=====================================================================
69 : : //---------------------------------------------------------------------
70 : 0 : OPropertyExport::OPropertyExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxProps)
71 : : :m_rContext(_rContext)
72 : : ,m_xProps(_rxProps)
73 [ # # ]: 0 : ,m_xPropertyInfo( m_xProps->getPropertySetInfo() )
74 [ # # ][ # # ]: 0 : ,m_xPropertyState( _rxProps, UNO_QUERY )
75 : : {
76 : : // caching
77 : 0 : ::rtl::OUStringBuffer aBuffer;
78 [ # # ]: 0 : ::sax::Converter::convertBool(aBuffer, true);
79 [ # # ]: 0 : m_sValueTrue = aBuffer.makeStringAndClear();
80 [ # # ]: 0 : ::sax::Converter::convertBool(aBuffer, false);
81 [ # # ]: 0 : m_sValueFalse = aBuffer.makeStringAndClear();
82 : :
83 : : OSL_ENSURE(m_xPropertyInfo.is(), "OPropertyExport::OPropertyExport: need an XPropertySetInfo!");
84 : :
85 : : // collect the properties which need to be exported
86 [ # # ]: 0 : examinePersistence();
87 : 0 : }
88 : :
89 : : //---------------------------------------------------------------------
90 : 0 : bool OPropertyExport::shouldExportProperty( const ::rtl::OUString& i_propertyName ) const
91 : : {
92 : : // if the property state is DEFAULT, it does not need to be written - at least
93 : : // if it's a built-in property, and not a dynamically-added one.
94 : 0 : bool bIsDefaultValue = m_xPropertyState.is()
95 [ # # ][ # # ]: 0 : && ( PropertyState_DEFAULT_VALUE == m_xPropertyState->getPropertyState( i_propertyName ) );
96 : 0 : bool bIsDynamicProperty = m_xPropertyInfo.is()
97 [ # # ][ # # ]: 0 : && ( ( m_xPropertyInfo->getPropertyByName( i_propertyName ).Attributes & PropertyAttribute::REMOVEABLE ) != 0 );
[ # # ][ # # ]
[ # # ][ # # ]
98 [ # # ][ # # ]: 0 : return ( !bIsDefaultValue || bIsDynamicProperty );
99 : : }
100 : :
101 : : template< typename T > void
102 : 0 : OPropertyExport::exportRemainingPropertiesSequence(
103 : : Any const & value, token::XMLTokenEnum eValueAttName)
104 : : {
105 [ # # ][ # # ]: 0 : OSequenceIterator< T > i(value);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
106 [ # # ][ # # ]: 0 : while (i.hasMoreElements())
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
107 : : {
108 [ # # ][ # # ]: 0 : ::rtl::OUString sValue(implConvertAny(i.nextElement()));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
109 [ # # # # : 0 : AddAttribute(XML_NAMESPACE_OFFICE, eValueAttName, sValue );
# # # # #
# # # #
# ]
110 : : SvXMLElementExport aValueTag(
111 : : m_rContext.getGlobalContext(), XML_NAMESPACE_FORM,
112 [ # # ][ # # ]: 0 : token::XML_LIST_VALUE, sal_True, sal_False);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
113 : : }
114 : 0 : }
115 : :
116 : 0 : void OPropertyExport::exportRemainingProperties()
117 : : {
118 : : // the properties tag (will be created if we have at least one no-default property)
119 : 0 : SvXMLElementExport* pPropertiesTag = NULL;
120 : :
121 : : try
122 : : {
123 : 0 : Any aValue;
124 : 0 : ::rtl::OUString sValue;
125 : :
126 : : // loop through all the properties which are yet to be exported
127 [ # # ]: 0 : for ( ConstStringSetIterator aProperty = m_aRemainingProps.begin();
128 : 0 : aProperty != m_aRemainingProps.end();
129 : : ++aProperty
130 : : )
131 : : {
132 : : DBG_CHECK_PROPERTY_NO_TYPE(*aProperty);
133 : :
134 : : #if OSL_DEBUG_LEVEL > 0
135 : : const ::rtl::OUString sPropertyName = *aProperty; (void)sPropertyName;
136 : : #endif
137 [ # # ][ # # ]: 0 : if ( !shouldExportProperty( *aProperty ) )
138 : 0 : continue;
139 : :
140 : : // now that we have the first sub-tag we need the form:properties element
141 [ # # ]: 0 : if (!pPropertiesTag)
142 [ # # ][ # # ]: 0 : pPropertiesTag = new SvXMLElementExport(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, token::XML_PROPERTIES, sal_True, sal_True);
[ # # ]
143 : :
144 : : // add the name attribute
145 [ # # ]: 0 : AddAttribute(XML_NAMESPACE_FORM, token::XML_PROPERTY_NAME, *aProperty);
146 : :
147 : : // get the value
148 [ # # ][ # # ]: 0 : aValue = m_xProps->getPropertyValue(*aProperty);
149 : :
150 : : // the type to export
151 : 0 : Type aExportType;
152 : :
153 : : // is it a sequence
154 : 0 : sal_Bool bIsSequence = TypeClass_SEQUENCE == aValue.getValueTypeClass();
155 : : // the type of the property, maybe reduced to the element type of a sequence
156 [ # # ]: 0 : if (bIsSequence)
157 [ # # ]: 0 : aExportType = getSequenceElementType( aValue.getValueType() );
158 : : else
159 : 0 : aExportType = aValue.getValueType();
160 : :
161 : : // the type attribute
162 : :
163 : 0 : bool bIsEmptyValue = TypeClass_VOID == aValue.getValueType().getTypeClass();
164 [ # # ]: 0 : if ( bIsEmptyValue )
165 : : {
166 : 0 : com::sun::star::beans::Property aPropDesc;
167 [ # # ][ # # ]: 0 : aPropDesc = m_xPropertyInfo->getPropertyByName( *aProperty );
168 : 0 : aExportType = aPropDesc.Type;
169 : : }
170 : 0 : token::XMLTokenEnum eValueType = implGetPropertyXMLType( aExportType );
171 : :
172 [ # # ]: 0 : if ( bIsEmptyValue )
173 [ # # ]: 0 : AddAttribute( XML_NAMESPACE_OFFICE, token::XML_VALUE_TYPE, token::XML_VOID );
174 : : else
175 [ # # ]: 0 : AddAttribute( XML_NAMESPACE_OFFICE, token::XML_VALUE_TYPE, eValueType );
176 : :
177 : 0 : token::XMLTokenEnum eValueAttName( token::XML_VALUE );
178 [ # # # ]: 0 : switch ( eValueType )
179 : : {
180 : 0 : case token::XML_BOOLEAN: eValueAttName = token::XML_BOOLEAN_VALUE; break;
181 : 0 : case token::XML_STRING: eValueAttName = token::XML_STRING_VALUE; break;
182 : 0 : default: break;
183 : : }
184 : :
185 [ # # ][ # # ]: 0 : if( !bIsSequence && !bIsEmptyValue )
186 : : { // the simple case
187 : :
188 [ # # ]: 0 : sValue = implConvertAny(aValue);
189 [ # # ]: 0 : AddAttribute(XML_NAMESPACE_OFFICE, eValueAttName, sValue );
190 : : }
191 : :
192 : :
193 : : // start the property tag
194 [ # # ]: 0 : SvXMLElementExport aValueTag1(m_rContext.getGlobalContext(),
195 : : XML_NAMESPACE_FORM,
196 : : bIsSequence ? token::XML_LIST_PROPERTY
197 [ # # ][ # # ]: 0 : : token::XML_PROPERTY, sal_True, sal_True);
198 : :
199 [ # # ]: 0 : if (!bIsSequence)
200 : 0 : continue;
201 : :
202 : : // the not-that-simple case, we need to iterate through the sequence elements
203 [ # # # # : 0 : switch ( aExportType.getTypeClass() )
# # # # ]
204 : : {
205 : : case TypeClass_STRING:
206 : : exportRemainingPropertiesSequence< ::rtl::OUString >(
207 [ # # ]: 0 : aValue, eValueAttName);
208 : 0 : break;
209 : : case TypeClass_DOUBLE:
210 : : exportRemainingPropertiesSequence< double >(
211 [ # # ]: 0 : aValue, eValueAttName);
212 : 0 : break;
213 : : case TypeClass_BOOLEAN:
214 : : exportRemainingPropertiesSequence< sal_Bool >(
215 [ # # ]: 0 : aValue, eValueAttName);
216 : 0 : break;
217 : : case TypeClass_BYTE:
218 : : exportRemainingPropertiesSequence< sal_Int8 >(
219 [ # # ]: 0 : aValue, eValueAttName);
220 : 0 : break;
221 : : case TypeClass_SHORT:
222 : : exportRemainingPropertiesSequence< sal_Int16 >(
223 [ # # ]: 0 : aValue, eValueAttName);
224 : 0 : break;
225 : : case TypeClass_LONG:
226 : : exportRemainingPropertiesSequence< sal_Int32 >(
227 [ # # ]: 0 : aValue, eValueAttName);
228 : 0 : break;
229 : : case TypeClass_HYPER:
230 : : exportRemainingPropertiesSequence< sal_Int64 >(
231 [ # # ]: 0 : aValue, eValueAttName);
232 : 0 : break;
233 : : default:
234 : : OSL_FAIL("OPropertyExport::exportRemainingProperties: unsupported sequence tyoe !");
235 : 0 : break;
236 : : }
237 [ # # ][ # # ]: 0 : }
[ # # ]
238 : : }
239 : 0 : catch(...)
240 : : {
241 [ # # # # ]: 0 : delete pPropertiesTag;
242 : 0 : throw;
243 : : }
244 [ # # ]: 0 : delete pPropertiesTag;
245 : 0 : }
246 : :
247 : : //---------------------------------------------------------------------
248 : 0 : void OPropertyExport::examinePersistence()
249 : : {
250 : 0 : m_aRemainingProps.clear();
251 [ # # ][ # # ]: 0 : Sequence< Property > aProperties = m_xPropertyInfo->getProperties();
252 : 0 : const Property* pProperties = aProperties.getConstArray();
253 [ # # ]: 0 : for (sal_Int32 i=0; i<aProperties.getLength(); ++i, ++pProperties)
254 : : {
255 : : // no transient props
256 [ # # ]: 0 : if ( pProperties->Attributes & PropertyAttribute::TRANSIENT )
257 : 0 : continue;
258 : : // no read-only props
259 [ # # ]: 0 : if ( ( pProperties->Attributes & PropertyAttribute::READONLY ) != 0 )
260 : : // except they're dynamically added
261 [ # # ]: 0 : if ( ( pProperties->Attributes & PropertyAttribute::REMOVEABLE ) == 0 )
262 : 0 : continue;
263 [ # # ]: 0 : m_aRemainingProps.insert(pProperties->Name);
264 [ # # ]: 0 : }
265 : 0 : }
266 : :
267 : : //---------------------------------------------------------------------
268 : 0 : void OPropertyExport::exportStringPropertyAttribute( const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName,
269 : : const ::rtl::OUString& _rPropertyName )
270 : : {
271 : : DBG_CHECK_PROPERTY( _rPropertyName, ::rtl::OUString );
272 : :
273 : : // no try-catch here, this would be to expensive. The outer scope has to handle exceptions (which should not
274 : : // happen if we're used correctly :)
275 : :
276 : : // this is way simple, as we don't need to convert anything (the property already is a string)
277 : :
278 : : // get the string
279 : 0 : ::rtl::OUString sPropValue;
280 [ # # ][ # # ]: 0 : m_xProps->getPropertyValue( _rPropertyName ) >>= sPropValue;
281 : :
282 : : // add the attribute
283 [ # # ]: 0 : if ( !sPropValue.isEmpty() )
284 [ # # ]: 0 : AddAttribute( _nNamespaceKey, _pAttributeName, sPropValue );
285 : :
286 : : // the property does not need to be handled anymore
287 [ # # ]: 0 : exportedProperty( _rPropertyName );
288 : 0 : }
289 : :
290 : : //---------------------------------------------------------------------
291 : 0 : void OPropertyExport::exportBooleanPropertyAttribute(const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName,
292 : : const ::rtl::OUString& _rPropertyName, const sal_Int8 _nBooleanAttributeFlags)
293 : : {
294 : : DBG_CHECK_PROPERTY_NO_TYPE( _rPropertyName );
295 : : // no check of the property value type: this method is allowed to be called with any interger properties
296 : : // (e.g. sal_Int32, sal_uInt16 etc)
297 : :
298 : 0 : sal_Bool bDefault = (BOOLATTR_DEFAULT_TRUE == (BOOLATTR_DEFAULT_MASK & _nBooleanAttributeFlags));
299 : 0 : sal_Bool bDefaultVoid = (BOOLATTR_DEFAULT_VOID == (BOOLATTR_DEFAULT_MASK & _nBooleanAttributeFlags));
300 : :
301 : : // get the value
302 : 0 : sal_Bool bCurrentValue = bDefault;
303 [ # # ][ # # ]: 0 : Any aCurrentValue = m_xProps->getPropertyValue( _rPropertyName );
304 [ # # ]: 0 : if (aCurrentValue.hasValue())
305 : : {
306 [ # # ]: 0 : bCurrentValue = ::cppu::any2bool(aCurrentValue);
307 : : // this will extract a boolean value even if the Any contains a int or short or something like that ...
308 : :
309 [ # # ]: 0 : if (_nBooleanAttributeFlags & BOOLATTR_INVERSE_SEMANTICS)
310 : 0 : bCurrentValue = !bCurrentValue;
311 : :
312 : : // we have a non-void current value
313 [ # # ][ # # ]: 0 : if (bDefaultVoid || (bDefault != bCurrentValue))
314 : : // and (the default is void, or the non-void default does not equal the current value)
315 : : // -> write the attribute
316 [ # # ][ # # ]: 0 : AddAttribute(_nNamespaceKey, _pAttributeName, bCurrentValue ? m_sValueTrue : m_sValueFalse);
317 : : }
318 : : else
319 : : // we have a void current value
320 [ # # ]: 0 : if (!bDefaultVoid)
321 : : // and we have a non-void default
322 : : // -> write the attribute
323 [ # # ][ # # ]: 0 : AddAttribute(_nNamespaceKey, _pAttributeName, bCurrentValue ? m_sValueTrue : m_sValueFalse);
324 : :
325 : : // the property does not need to be handled anymore
326 [ # # ]: 0 : exportedProperty( _rPropertyName );
327 : 0 : }
328 : :
329 : : //---------------------------------------------------------------------
330 : 0 : void OPropertyExport::exportInt16PropertyAttribute(const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName,
331 : : const ::rtl::OUString& _rPropertyName, const sal_Int16 _nDefault)
332 : : {
333 : : DBG_CHECK_PROPERTY( _rPropertyName, sal_Int16 );
334 : :
335 : : // get the value
336 : 0 : sal_Int16 nCurrentValue(_nDefault);
337 [ # # ][ # # ]: 0 : m_xProps->getPropertyValue( _rPropertyName ) >>= nCurrentValue;
338 : :
339 : : // add the attribute
340 [ # # ]: 0 : if (_nDefault != nCurrentValue)
341 : : {
342 : : // let the formatter of the export context build a string
343 : 0 : ::rtl::OUStringBuffer sBuffer;
344 [ # # ]: 0 : ::sax::Converter::convertNumber(sBuffer, (sal_Int32)nCurrentValue);
345 : :
346 [ # # ][ # # ]: 0 : AddAttribute(_nNamespaceKey, _pAttributeName, sBuffer.makeStringAndClear());
347 : : }
348 : :
349 : : // the property does not need to be handled anymore
350 [ # # ]: 0 : exportedProperty( _rPropertyName );
351 : 0 : }
352 : :
353 : : //---------------------------------------------------------------------
354 : 0 : void OPropertyExport::exportInt32PropertyAttribute( const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName,
355 : : const ::rtl::OUString& _rPropertyName, const sal_Int32 _nDefault )
356 : : {
357 : : DBG_CHECK_PROPERTY( _rPropertyName, sal_Int32 );
358 : :
359 : : // get the value
360 : 0 : sal_Int32 nCurrentValue( _nDefault );
361 [ # # ][ # # ]: 0 : m_xProps->getPropertyValue( _rPropertyName ) >>= nCurrentValue;
362 : :
363 : : // add the attribute
364 [ # # ]: 0 : if ( _nDefault != nCurrentValue )
365 : : {
366 : : // let the formatter of the export context build a string
367 : 0 : ::rtl::OUStringBuffer sBuffer;
368 [ # # ]: 0 : ::sax::Converter::convertNumber( sBuffer, nCurrentValue );
369 : :
370 [ # # ][ # # ]: 0 : AddAttribute( _nNamespaceKey, _pAttributeName, sBuffer.makeStringAndClear() );
371 : : }
372 : :
373 : : // the property does not need to be handled anymore
374 [ # # ]: 0 : exportedProperty( _rPropertyName );
375 : 0 : }
376 : :
377 : : //---------------------------------------------------------------------
378 : 0 : void OPropertyExport::exportEnumPropertyAttribute(
379 : : const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName,
380 : : const rtl::OUString &rPropertyName, const SvXMLEnumMapEntry* _pValueMap,
381 : : const sal_Int32 _nDefault, const sal_Bool _bVoidDefault)
382 : : {
383 : : // get the value
384 : 0 : sal_Int32 nCurrentValue(_nDefault);
385 [ # # ][ # # ]: 0 : Any aValue = m_xProps->getPropertyValue(rPropertyName);
386 : :
387 [ # # ]: 0 : if (aValue.hasValue())
388 : : { // we have a non-void current value
389 : 0 : ::cppu::enum2int(nCurrentValue, aValue);
390 : :
391 : : // add the attribute
392 [ # # ][ # # ]: 0 : if ((_nDefault != nCurrentValue) || _bVoidDefault)
393 : : { // the default does not equal the value, or the default is void and the value isn't
394 : :
395 : : // let the formatter of the export context build a string
396 : 0 : ::rtl::OUStringBuffer sBuffer;
397 [ # # ][ # # ]: 0 : m_rContext.getGlobalContext().GetMM100UnitConverter().convertEnum(sBuffer, (sal_uInt16)nCurrentValue, _pValueMap);
398 : :
399 [ # # ][ # # ]: 0 : AddAttribute(_nNamespaceKey, _pAttributeName, sBuffer.makeStringAndClear());
400 : : }
401 : : }
402 : : else
403 : : {
404 [ # # ]: 0 : if (!_bVoidDefault)
405 [ # # ]: 0 : AddAttributeASCII(_nNamespaceKey, _pAttributeName, "");
406 : : }
407 : :
408 : : // the property does not need to be handled anymore
409 [ # # ]: 0 : exportedProperty(rPropertyName);
410 : 0 : }
411 : :
412 : : //---------------------------------------------------------------------
413 : 0 : void OPropertyExport::exportTargetFrameAttribute()
414 : : {
415 : : DBG_CHECK_PROPERTY( PROPERTY_TARGETFRAME, ::rtl::OUString );
416 : :
417 [ # # ][ # # ]: 0 : ::rtl::OUString sTargetFrame = comphelper::getString(m_xProps->getPropertyValue(PROPERTY_TARGETFRAME));
[ # # ][ # # ]
418 [ # # ]: 0 : if (0 != sTargetFrame.compareToAscii("_blank"))
419 : : { // an empty string and "_blank" have the same meaning and don't have to be written
420 [ # # ]: 0 : AddAttribute(OAttributeMetaData::getCommonControlAttributeNamespace(CCA_TARGET_FRAME)
421 : : ,OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_FRAME)
422 [ # # ][ # # ]: 0 : ,sTargetFrame);
423 : : }
424 : :
425 [ # # ][ # # ]: 0 : exportedProperty(PROPERTY_TARGETFRAME);
426 : 0 : }
427 : :
428 : : //---------------------------------------------------------------------
429 : 0 : void OPropertyExport::exportRelativeTargetLocation(const ConstAsciiString& _sPropertyName,sal_Int32 _nProperty,bool _bAddType)
430 : : {
431 : : DBG_CHECK_PROPERTY( _sPropertyName, ::rtl::OUString );
432 : :
433 [ # # ][ # # ]: 0 : ::rtl::OUString sTargetLocation = comphelper::getString(m_xProps->getPropertyValue(_sPropertyName));
[ # # ][ # # ]
434 [ # # ]: 0 : if ( !sTargetLocation.isEmpty() )
435 : : // If this isn't a GraphicObject then GetRelativeReference
436 : : // will be called anyway ( in AddEmbeddedGraphic )
437 [ # # ][ # # ]: 0 : sTargetLocation = m_rContext.getGlobalContext().AddEmbeddedGraphicObject(sTargetLocation);
438 [ # # ]: 0 : AddAttribute(OAttributeMetaData::getCommonControlAttributeNamespace(_nProperty)
439 : : ,OAttributeMetaData::getCommonControlAttributeName(_nProperty)
440 [ # # ][ # # ]: 0 : , sTargetLocation);
441 : :
442 : : // #i110911# add xlink:type="simple" if required
443 [ # # ]: 0 : if (_bAddType)
444 [ # # ]: 0 : AddAttribute(XML_NAMESPACE_XLINK, token::XML_TYPE, token::XML_SIMPLE);
445 : :
446 [ # # ][ # # ]: 0 : exportedProperty(_sPropertyName);
447 : 0 : }
448 : : //---------------------------------------------------------------------
449 : 0 : void OPropertyExport::flagStyleProperties()
450 : : {
451 : : // flag all the properties which are part of the style as "handled"
452 [ # # ][ # # ]: 0 : UniReference< XMLPropertySetMapper > xStylePropertiesSupplier = m_rContext.getStylePropertyMapper()->getPropertySetMapper();
[ # # ]
453 [ # # ][ # # ]: 0 : for (sal_Int32 i=0; i<xStylePropertiesSupplier->GetEntryCount(); ++i)
454 [ # # ][ # # ]: 0 : exportedProperty(xStylePropertiesSupplier->GetEntryAPIName(i));
[ # # ]
455 : :
456 : : // the font properties are exported as single properties, but there is a FontDescriptor property which
457 : : // collects them all-in-one, this has been exported implicitly
458 [ # # ][ # # ]: 0 : exportedProperty(PROPERTY_FONT);
459 : :
460 : : // for the DateFormat and TimeFormat, there exist wrapper properties which has been exported as
461 : : // style, too
462 [ # # ][ # # ]: 0 : exportedProperty(PROPERTY_DATEFORMAT);
463 [ # # ][ # # ]: 0 : exportedProperty(PROPERTY_TIMEFORMAT);
464 : :
465 : : // the following properties should have been exported at the shape already:
466 [ # # ][ # # ]: 0 : exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VerticalAlign" ) ) );
467 [ # # ][ # # ]: 0 : exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WritingMode" ) ) );
468 [ # # ][ # # ]: 0 : exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScaleMode" ) ) );
469 : : // ditto the TextWritingMode
470 [ # # ][ # # ]: 0 : exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WritingMode" ) ) );
[ # # ]
471 : 0 : }
472 : :
473 : : //---------------------------------------------------------------------
474 : 0 : void OPropertyExport::exportGenericPropertyAttribute(
475 : : const sal_uInt16 _nAttributeNamespaceKey, const sal_Char* _pAttributeName, const sal_Char* _pPropertyName)
476 : : {
477 : : DBG_CHECK_PROPERTY_ASCII_NO_TYPE( _pPropertyName );
478 : :
479 : 0 : ::rtl::OUString sPropertyName = ::rtl::OUString::createFromAscii(_pPropertyName);
480 [ # # ]: 0 : exportedProperty(sPropertyName);
481 : :
482 [ # # ][ # # ]: 0 : Any aCurrentValue = m_xProps->getPropertyValue(sPropertyName);
483 [ # # ]: 0 : if (!aCurrentValue.hasValue())
484 : : // nothing to do without a concrete value
485 : : return;
486 : :
487 [ # # ]: 0 : ::rtl::OUString sValue = implConvertAny(aCurrentValue);
488 [ # # ][ # # ]: 0 : if (sValue.isEmpty() && (TypeClass_STRING == aCurrentValue.getValueTypeClass()))
[ # # ]
489 : : {
490 : : // check whether or not the property is allowed to be VOID
491 [ # # ][ # # ]: 0 : Property aProperty = m_xPropertyInfo->getPropertyByName(sPropertyName);
492 [ # # ]: 0 : if ((aProperty.Attributes & PropertyAttribute::MAYBEVOID) == 0)
493 : : // the string is empty, and the property is not allowed to be void
494 : : // -> don't need to write the attibute, 'cause missing it is unambiguous
495 [ # # ]: 0 : return;
496 : : }
497 : :
498 : : // finally add the attribuite to the context
499 [ # # ][ # # ]: 0 : AddAttribute(_nAttributeNamespaceKey, _pAttributeName, sValue);
[ # # ][ # # ]
500 : : }
501 : :
502 : : //---------------------------------------------------------------------
503 : 0 : void OPropertyExport::exportStringSequenceAttribute(const sal_uInt16 _nAttributeNamespaceKey, const sal_Char* _pAttributeName,
504 : : const ::rtl::OUString& _rPropertyName,
505 : : const sal_Unicode _aQuoteCharacter, const sal_Unicode _aListSeparator)
506 : : {
507 : : DBG_CHECK_PROPERTY( _rPropertyName, Sequence< ::rtl::OUString > );
508 : : OSL_ENSURE(_aListSeparator != 0, "OPropertyExport::exportStringSequenceAttribute: invalid separator character!");
509 : :
510 [ # # ]: 0 : Sequence< ::rtl::OUString > aItems;
511 [ # # ][ # # ]: 0 : m_xProps->getPropertyValue( _rPropertyName ) >>= aItems;
[ # # ]
512 : :
513 : 0 : ::rtl::OUString sFinalList;
514 : :
515 : : // unfortunately the OUString can't append single sal_Unicode characters ...
516 : 0 : const ::rtl::OUString sQuote(&_aQuoteCharacter, 1);
517 : 0 : const ::rtl::OUString sSeparator(&_aListSeparator, 1);
518 : 0 : const sal_Bool bQuote = !sQuote.isEmpty();
519 : :
520 : : // concatenate the string items
521 : 0 : const ::rtl::OUString* pItems = aItems.getConstArray();
522 : 0 : const ::rtl::OUString* pEnd = pItems + aItems.getLength();
523 : 0 : const ::rtl::OUString* pLastElement = pEnd - 1;
524 [ # # ]: 0 : for ( ;
525 : : pItems != pEnd;
526 : : ++pItems
527 : : )
528 : : {
529 : : OSL_ENSURE(!_aQuoteCharacter || (-1 == pItems->indexOf(_aQuoteCharacter)),
530 : : "OPropertyExport::exportStringSequenceAttribute: there is an item which contains the quote character!");
531 : : OSL_ENSURE(_aQuoteCharacter || (-1 == pItems->indexOf(_aListSeparator)),
532 : : "OPropertyExport::exportStringSequenceAttribute: no quote character, but there is an item containing the separator character!");
533 : :
534 [ # # ]: 0 : if (bQuote)
535 : 0 : sFinalList += sQuote;
536 : 0 : sFinalList += *pItems;
537 [ # # ]: 0 : if (bQuote)
538 : 0 : sFinalList += sQuote;
539 : :
540 [ # # ]: 0 : if (pItems != pLastElement)
541 : 0 : sFinalList += sSeparator;
542 : : }
543 : :
544 [ # # ]: 0 : if (!sFinalList.isEmpty())
545 [ # # ]: 0 : AddAttribute(_nAttributeNamespaceKey, _pAttributeName, sFinalList);
546 : :
547 [ # # ][ # # ]: 0 : exportedProperty( _rPropertyName );
548 : 0 : }
549 : :
550 : : //---------------------------------------------------------------------
551 : 0 : ::rtl::OUString OPropertyExport::implConvertAny(const Any& _rValue)
552 : : {
553 : 0 : ::rtl::OUStringBuffer aBuffer;
554 [ # # # # : 0 : switch (_rValue.getValueTypeClass())
# # # ]
555 : : {
556 : : case TypeClass_STRING:
557 : : { // extract the string
558 : 0 : ::rtl::OUString sCurrentValue;
559 : 0 : _rValue >>= sCurrentValue;
560 [ # # ]: 0 : aBuffer.append(sCurrentValue);
561 : : }
562 : 0 : break;
563 : : case TypeClass_DOUBLE:
564 : : // let the unit converter format is as string
565 [ # # ][ # # ]: 0 : ::sax::Converter::convertDouble(aBuffer, getDouble(_rValue));
566 : 0 : break;
567 : : case TypeClass_BOOLEAN:
568 [ # # ][ # # ]: 0 : aBuffer = getBOOL(_rValue) ? m_sValueTrue : m_sValueFalse;
[ # # ][ # # ]
569 : 0 : break;
570 : : case TypeClass_BYTE:
571 : : case TypeClass_SHORT:
572 : : case TypeClass_LONG:
573 : : // let the unit converter format is as string
574 [ # # ][ # # ]: 0 : ::sax::Converter::convertNumber(aBuffer, getINT32(_rValue));
575 : 0 : break;
576 : : case TypeClass_HYPER:
577 : : // TODO
578 : : OSL_FAIL("OPropertyExport::implConvertAny: missing implementation for sal_Int64!");
579 : 0 : break;
580 : : case TypeClass_ENUM:
581 : : {
582 : : // convert it into an int32
583 : 0 : sal_Int32 nValue = 0;
584 : 0 : ::cppu::enum2int(nValue, _rValue);
585 [ # # ]: 0 : ::sax::Converter::convertNumber(aBuffer, nValue);
586 : : }
587 : 0 : break;
588 : : default:
589 : : { // hmmm .... what else do we know?
590 : 0 : double fValue = 0;
591 : 0 : ::com::sun::star::util::Date aDate;
592 : 0 : ::com::sun::star::util::Time aTime;
593 : 0 : ::com::sun::star::util::DateTime aDateTime;
594 [ # # ][ # # ]: 0 : if (_rValue >>= aDate)
595 : : {
596 : 0 : Date aToolsDate( Date::EMPTY );
597 [ # # ]: 0 : ::utl::typeConvert(aDate, aToolsDate);
598 : 0 : fValue = aToolsDate.GetDate();
599 : : }
600 [ # # ][ # # ]: 0 : else if (_rValue >>= aTime)
601 : : {
602 : 0 : fValue = ((aTime.Hours * 60 + aTime.Minutes) * 60 + aTime.Seconds) * 100 + aTime.HundredthSeconds;
603 : 0 : fValue = fValue / 8640000.0;
604 : : }
605 [ # # ][ # # ]: 0 : else if (_rValue >>= aDateTime)
606 : : {
607 : 0 : DateTime aToolsDateTime( DateTime::EMPTY );
608 [ # # ]: 0 : ::utl::typeConvert(aDateTime, aToolsDateTime);
609 : : // the time part (the digits behind the comma)
610 : 0 : fValue = ((aDateTime.Hours * 60 + aDateTime.Minutes) * 60 + aDateTime.Seconds) * 100 + aDateTime.HundredthSeconds;
611 : 0 : fValue = fValue / 8640000.0;
612 : : // plus the data part (the digits in front of the comma)
613 : 0 : fValue += aToolsDateTime.GetDate();
614 : : }
615 : : else
616 : : {
617 : : // if any other types are added here, please remember to adjust implGetPropertyXMLType accordingly
618 : :
619 : : // no more options ...
620 : : OSL_FAIL("OPropertyExport::implConvertAny: unsupported value type!");
621 : : break;
622 : : }
623 : : // let the unit converter format is as string
624 [ # # ]: 0 : ::sax::Converter::convertDouble(aBuffer, fValue);
625 : : }
626 : 0 : break;
627 : : }
628 : :
629 [ # # ]: 0 : return aBuffer.makeStringAndClear();
630 : : }
631 : :
632 : :
633 : : //---------------------------------------------------------------------
634 : 0 : token::XMLTokenEnum OPropertyExport::implGetPropertyXMLType(const ::com::sun::star::uno::Type& _rType)
635 : : {
636 : : // handle the type description
637 [ # # # # ]: 0 : switch (_rType.getTypeClass())
638 : : {
639 : : case TypeClass_STRING:
640 : 0 : return token::XML_STRING;
641 : : case TypeClass_DOUBLE:
642 : : case TypeClass_BYTE:
643 : : case TypeClass_SHORT:
644 : : case TypeClass_LONG:
645 : : case TypeClass_HYPER:
646 : : case TypeClass_ENUM:
647 : 0 : return token::XML_FLOAT;
648 : : case TypeClass_BOOLEAN:
649 : 0 : return token::XML_BOOLEAN;
650 : :
651 : : default:
652 : 0 : return token::XML_FLOAT;
653 : : }
654 : : }
655 : :
656 : : #ifdef DBG_UTIL
657 : : //---------------------------------------------------------------------
658 : : void OPropertyExport::AddAttribute(sal_uInt16 _nPrefix, const sal_Char* _pName, const ::rtl::OUString& _rValue)
659 : : {
660 : : OSL_ENSURE(m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::rtl::OUString::createFromAscii(_pName)).isEmpty(),
661 : : "OPropertyExport::AddAttribute: already have such an attribute");
662 : :
663 : : m_rContext.getGlobalContext().AddAttribute(_nPrefix, _pName, _rValue);
664 : : }
665 : :
666 : : //---------------------------------------------------------------------
667 : : void OPropertyExport::AddAttribute( sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, const ::rtl::OUString& _rValue )
668 : : {
669 : : OSL_ENSURE(m_rContext.getGlobalContext().GetXAttrList()->getValueByName( _rName ).isEmpty(),
670 : : "OPropertyExport::AddAttribute: already have such an attribute");
671 : :
672 : : m_rContext.getGlobalContext().AddAttribute( _nPrefix, _rName, _rValue );
673 : : }
674 : :
675 : : //---------------------------------------------------------------------
676 : : void OPropertyExport::AddAttributeASCII(sal_uInt16 _nPrefix, const sal_Char* _pName, const sal_Char *pValue)
677 : : {
678 : : OSL_ENSURE(m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::rtl::OUString::createFromAscii(_pName)).isEmpty(),
679 : : "OPropertyExport::AddAttributeASCII: already have such an attribute");
680 : :
681 : : m_rContext.getGlobalContext().AddAttributeASCII(_nPrefix, _pName, pValue);
682 : : }
683 : :
684 : : //---------------------------------------------------------------------
685 : : void OPropertyExport::AddAttribute(sal_uInt16 _nPrefix, ::xmloff::token::XMLTokenEnum _eName, const ::rtl::OUString& _rValue)
686 : : {
687 : : OSL_ENSURE(m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::xmloff::token::GetXMLToken(_eName)).isEmpty(),
688 : : "OPropertyExport::AddAttribute: already have such an attribute");
689 : :
690 : : m_rContext.getGlobalContext().AddAttribute(_nPrefix, _eName, _rValue);
691 : : }
692 : :
693 : : //---------------------------------------------------------------------
694 : : void OPropertyExport::AddAttribute(sal_uInt16 _nPrefix, ::xmloff::token::XMLTokenEnum _eName, ::xmloff::token::XMLTokenEnum _eValue )
695 : : {
696 : : OSL_ENSURE(m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::xmloff::token::GetXMLToken(_eName)).isEmpty(),
697 : : "OPropertyExport::AddAttribute: already have such an attribute");
698 : :
699 : : m_rContext.getGlobalContext().AddAttribute(_nPrefix, _eName, _eValue);
700 : : }
701 : :
702 : : //---------------------------------------------------------------------
703 : : void OPropertyExport::dbg_implCheckProperty(const ::rtl::OUString& _rPropertyName, const Type* _pType)
704 : : {
705 : : try
706 : : {
707 : : // the property must exist
708 : : if (!m_xPropertyInfo->hasPropertyByName(_rPropertyName))
709 : : {
710 : : rtl::OStringBuffer aBuf(RTL_CONSTASCII_STRINGPARAM(
711 : : "OPropertyExport::dbg_implCheckProperty: no property with the name "));
712 : : aBuf.append(rtl::OUStringToOString(_rPropertyName, RTL_TEXTENCODING_ASCII_US)).append('!');
713 : : OSL_FAIL(aBuf.getStr());
714 : : return;
715 : : }
716 : :
717 : : if (_pType)
718 : : {
719 : : // and it must have the correct type
720 : : Property aPropertyDescription = m_xPropertyInfo->getPropertyByName(_rPropertyName);
721 : : OSL_ENSURE(aPropertyDescription.Type.equals(*_pType), "OPropertyExport::dbg_implCheckProperty: invalid property type!");
722 : : }
723 : : }
724 : : catch(Exception&)
725 : : {
726 : : OSL_FAIL("OPropertyExport::dbg_implCheckProperty: caught an exception, could not check the property!");
727 : : }
728 : : }
729 : : #endif // DBG_UTIL - dbg_implCheckProperty
730 : :
731 : : //.........................................................................
732 : : } // namespace xmloff
733 : : //.........................................................................
734 : :
735 : :
736 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|