1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_xmloff.hxx" 26 27 #include "elementimport.hxx" 28 #include "xmloff/xmlimp.hxx" 29 #include "xmloff/nmspmap.hxx" 30 #include "xmloff/xmluconv.hxx" 31 #include "strings.hxx" 32 #include "callbacks.hxx" 33 #include "attriblistmerge.hxx" 34 #include "xmloff/xmlnmspe.hxx" 35 #include "eventimport.hxx" 36 #include "xmloff/txtstyli.hxx" 37 #include "formenums.hxx" 38 #include "xmloff/xmltoken.hxx" 39 #include "gridcolumnproptranslator.hxx" 40 #include "property_description.hxx" 41 #include "property_meta_data.hxx" 42 43 /** === begin UNO includes === **/ 44 #include <com/sun/star/text/XText.hpp> 45 #include <com/sun/star/util/XCloneable.hpp> 46 #include <com/sun/star/form/FormComponentType.hpp> 47 #include <com/sun/star/awt/ImagePosition.hpp> 48 #include <com/sun/star/beans/XMultiPropertySet.hpp> 49 #include <com/sun/star/beans/XPropertyContainer.hpp> 50 #include <com/sun/star/beans/PropertyAttribute.hpp> 51 /** === end UNO includes === **/ 52 53 #include <tools/urlobj.hxx> 54 #include <tools/diagnose_ex.h> 55 #include <tools/time.hxx> 56 #include <rtl/logfile.hxx> 57 #include <comphelper/extract.hxx> 58 #include <comphelper/types.hxx> 59 60 #include <algorithm> 61 #include <functional> 62 63 //......................................................................... 64 namespace xmloff 65 { 66 //......................................................................... 67 68 using namespace ::xmloff::token; 69 using namespace ::com::sun::star; 70 using namespace ::com::sun::star::uno; 71 using namespace ::com::sun::star::awt; 72 using namespace ::com::sun::star::container; 73 using namespace ::com::sun::star::beans; 74 using namespace ::com::sun::star::script; 75 using namespace ::com::sun::star::lang; 76 using namespace ::com::sun::star::form; 77 using namespace ::com::sun::star::xml; 78 using namespace ::com::sun::star::util; 79 using namespace ::com::sun::star::text; 80 using namespace ::comphelper; 81 82 #define PROPID_VALUE 1 83 #define PROPID_CURRENT_VALUE 2 84 #define PROPID_MIN_VALUE 3 85 #define PROPID_MAX_VALUE 4 86 87 //===================================================================== 88 struct PropertyValueLess 89 { operator ()xmloff::PropertyValueLess90 sal_Bool operator()(const PropertyValue& _rLeft, const PropertyValue& _rRight) 91 { 92 return _rLeft.Name < _rRight.Name; 93 } 94 }; 95 96 //===================================================================== 97 struct PropertyValueCompare : public ::std::binary_function< PropertyValue, ::rtl::OUString, bool> 98 { operator ()xmloff::PropertyValueCompare99 bool operator() (const PropertyValue& lhs, const ::rtl::OUString& rhs) const 100 { 101 return lhs.Name == rhs; 102 } operator ()xmloff::PropertyValueCompare103 bool operator() (const ::rtl::OUString& lhs, const PropertyValue& rhs) const 104 { 105 return lhs == rhs.Name; 106 } 107 }; 108 109 //===================================================================== 110 template <class ELEMENT> pushBackSequenceElement(Sequence<ELEMENT> & _rContainer,const ELEMENT & _rElement)111 void pushBackSequenceElement(Sequence< ELEMENT >& _rContainer, const ELEMENT& _rElement) 112 { 113 sal_Int32 nLen = _rContainer.getLength(); 114 _rContainer.realloc(nLen + 1); 115 _rContainer[nLen] = _rElement; 116 } 117 118 //===================================================================== 119 //= OElementNameMap 120 //===================================================================== 121 //--------------------------------------------------------------------- 122 OElementNameMap::MapString2Element OElementNameMap::s_sElementTranslations; 123 124 //--------------------------------------------------------------------- operator ++(OControlElement::ElementType & _e)125 const OControlElement::ElementType& operator ++(OControlElement::ElementType& _e) 126 { 127 OControlElement::ElementType e = _e; 128 sal_Int32 nAsInt = static_cast<sal_Int32>(e); 129 _e = static_cast<OControlElement::ElementType>( ++nAsInt ); 130 return _e; 131 } 132 133 //--------------------------------------------------------------------- getElementType(const::rtl::OUString & _rName)134 OControlElement::ElementType OElementNameMap::getElementType(const ::rtl::OUString& _rName) 135 { 136 if ( s_sElementTranslations.empty() ) 137 { // initialize 138 for (ElementType eType=(ElementType)0; eType<UNKNOWN; ++eType) 139 s_sElementTranslations[::rtl::OUString::createFromAscii(getElementName(eType))] = eType; 140 } 141 ConstMapString2ElementIterator aPos = s_sElementTranslations.find(_rName); 142 if (s_sElementTranslations.end() != aPos) 143 return aPos->second; 144 145 return UNKNOWN; 146 } 147 148 //===================================================================== 149 //= OElementImport 150 //===================================================================== 151 //--------------------------------------------------------------------- OElementImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer)152 OElementImport::OElementImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 153 const Reference< XNameContainer >& _rxParentContainer) 154 :OPropertyImport(_rImport, _nPrefix, _rName) 155 ,m_rFormImport(_rImport) 156 ,m_rEventManager(_rEventManager) 157 ,m_pStyleElement( NULL ) 158 ,m_xParentContainer(_rxParentContainer) 159 ,m_bImplicitGenericAttributeHandling( true ) 160 { 161 OSL_ENSURE(m_xParentContainer.is(), "OElementImport::OElementImport: invalid parent container!"); 162 } 163 164 //--------------------------------------------------------------------- ~OElementImport()165 OElementImport::~OElementImport() 166 { 167 } 168 169 //--------------------------------------------------------------------- determineDefaultServiceName() const170 ::rtl::OUString OElementImport::determineDefaultServiceName() const 171 { 172 return ::rtl::OUString(); 173 } 174 175 //--------------------------------------------------------------------- StartElement(const Reference<sax::XAttributeList> & _rxAttrList)176 void OElementImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 177 { 178 ENTER_LOG_CONTEXT( "xmloff::OElementImport - importing one element" ); 179 180 const SvXMLNamespaceMap& rMap = m_rContext.getGlobalContext().GetNamespaceMap(); 181 const ::rtl::OUString sImplNameAttribute = rMap.GetQNameByKey( XML_NAMESPACE_FORM, GetXMLToken( XML_CONTROL_IMPLEMENTATION ) ); 182 const ::rtl::OUString sControlImplementation = _rxAttrList->getValueByName( sImplNameAttribute ); 183 184 // retrieve the service name 185 if ( sControlImplementation.getLength() > 0 ) 186 { 187 ::rtl::OUString sOOoImplementationName; 188 const sal_uInt16 nImplPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sControlImplementation, &sOOoImplementationName ); 189 m_sServiceName = ( nImplPrefix == XML_NAMESPACE_OOO ) ? sOOoImplementationName : sControlImplementation; 190 } 191 192 if ( !m_sServiceName.getLength() ) 193 determineDefaultServiceName(); 194 195 // create the object *now*. This allows setting properties in the various handleAttribute methods. 196 // (Though currently not all code is migrated to this pattern, most attributes are still handled 197 // by remembering the value (via implPushBackPropertyValue), and setting the correct property value 198 // later (in OControlImport::StartElement).) 199 m_xElement = createElement(); 200 if ( m_xElement.is() ) 201 m_xInfo = m_xElement->getPropertySetInfo(); 202 203 // call the base class 204 OPropertyImport::StartElement( _rxAttrList ); 205 } 206 207 //--------------------------------------------------------------------- CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> & _rxAttrList)208 SvXMLImportContext* OElementImport::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 209 const Reference< sax::XAttributeList >& _rxAttrList) 210 { 211 if( token::IsXMLToken(_rLocalName, token::XML_EVENT_LISTENERS) && (XML_NAMESPACE_OFFICE == _nPrefix)) 212 return new OFormEventsImportContext(m_rFormImport.getGlobalContext(), _nPrefix, _rLocalName, *this); 213 214 return OPropertyImport::CreateChildContext(_nPrefix, _rLocalName, _rxAttrList); 215 } 216 217 //--------------------------------------------------------------------- EndElement()218 void OElementImport::EndElement() 219 { 220 OSL_ENSURE(m_xElement.is(), "OElementImport::EndElement: invalid element created!"); 221 if (!m_xElement.is()) 222 return; 223 224 // apply the non-generic properties 225 implApplySpecificProperties(); 226 227 // set the generic properties 228 implApplyGenericProperties(); 229 230 // set the style properties 231 if ( m_pStyleElement && m_xElement.is() ) 232 { 233 Reference< XPropertySet > xPropTranslation = 234 new OGridColumnPropertyTranslator( Reference< XMultiPropertySet >( m_xElement, UNO_QUERY ) ); 235 const_cast< XMLTextStyleContext* >( m_pStyleElement )->FillPropertySet( xPropTranslation ); 236 237 const ::rtl::OUString sNumberStyleName = const_cast< XMLTextStyleContext* >( m_pStyleElement )->GetDataStyleName( ); 238 if ( sNumberStyleName.getLength() ) 239 // the style also has a number (sub) style 240 m_rContext.applyControlNumberStyle( m_xElement, sNumberStyleName ); 241 } 242 243 // insert the element into the parent container 244 if (!m_sName.getLength()) 245 { 246 OSL_ENSURE(sal_False, "OElementImport::EndElement: did not find a name attribute!"); 247 m_sName = implGetDefaultName(); 248 } 249 250 m_xParentContainer->insertByName(m_sName, makeAny(m_xElement)); 251 LEAVE_LOG_CONTEXT( ); 252 } 253 254 //--------------------------------------------------------------------- implApplySpecificProperties()255 void OElementImport::implApplySpecificProperties() 256 { 257 if ( m_aValues.empty() ) 258 return; 259 260 // set all the properties we collected 261 #if OSL_DEBUG_LEVEL > 0 262 // check if the object has all the properties 263 // (We do this in the non-pro version only. Doing it all the time would be much to expensive) 264 if ( m_xInfo.is() ) 265 { 266 PropertyValueArray::const_iterator aEnd = m_aValues.end(); 267 for ( PropertyValueArray::iterator aCheck = m_aValues.begin(); 268 aCheck != aEnd; 269 ++aCheck 270 ) 271 { 272 OSL_ENSURE(m_xInfo->hasPropertyByName(aCheck->Name), 273 ::rtl::OString("OElementImport::implApplySpecificProperties: read a property (") 274 += ::rtl::OString(aCheck->Name.getStr(), aCheck->Name.getLength(), RTL_TEXTENCODING_ASCII_US) 275 += ::rtl::OString(") which does not exist on the element!")); 276 } 277 } 278 #endif 279 280 // set the properties 281 const Reference< XMultiPropertySet > xMultiProps(m_xElement, UNO_QUERY); 282 sal_Bool bSuccess = sal_False; 283 if (xMultiProps.is()) 284 { 285 // translate our properties so that the XMultiPropertySet can handle them 286 287 // sort our property value array so that we can use it in a setPropertyValues 288 ::std::sort( m_aValues.begin(), m_aValues.end(), PropertyValueLess()); 289 290 // the names 291 Sequence< ::rtl::OUString > aNames(m_aValues.size()); 292 ::rtl::OUString* pNames = aNames.getArray(); 293 // the values 294 Sequence< Any > aValues(m_aValues.size()); 295 Any* pValues = aValues.getArray(); 296 // copy 297 298 PropertyValueArray::iterator aEnd = m_aValues.end(); 299 for ( PropertyValueArray::iterator aPropValues = m_aValues.begin(); 300 aPropValues != aEnd; 301 ++aPropValues, ++pNames, ++pValues 302 ) 303 { 304 *pNames = aPropValues->Name; 305 *pValues = aPropValues->Value; 306 } 307 308 try 309 { 310 xMultiProps->setPropertyValues(aNames, aValues); 311 bSuccess = sal_True; 312 } 313 catch(Exception&) 314 { 315 OSL_ENSURE(sal_False, "OElementImport::implApplySpecificProperties: could not set the properties (using the XMultiPropertySet)!"); 316 } 317 } 318 319 if (!bSuccess) 320 { // no XMultiPropertySet or setting all properties at once failed 321 PropertyValueArray::iterator aEnd = m_aValues.end(); 322 for ( PropertyValueArray::iterator aPropValues = m_aValues.begin(); 323 aPropValues != aEnd; 324 ++aPropValues 325 ) 326 { 327 // this try/catch here is expensive, but because this is just a fallback which should normally not be 328 // used it's acceptable this way ... 329 try 330 { 331 m_xElement->setPropertyValue(aPropValues->Name, aPropValues->Value); 332 } 333 catch(Exception&) 334 { 335 OSL_ENSURE(sal_False, 336 ::rtl::OString("OElementImport::implApplySpecificProperties: could not set the property \"") 337 += ::rtl::OString(aPropValues->Name.getStr(), aPropValues->Name.getLength(), RTL_TEXTENCODING_ASCII_US) 338 += ::rtl::OString("\"!")); 339 } 340 } 341 } 342 } 343 344 //--------------------------------------------------------------------- implApplyGenericProperties()345 void OElementImport::implApplyGenericProperties() 346 { 347 if ( m_aGenericValues.empty() ) 348 return; 349 350 Reference< XPropertyContainer > xDynamicProperties( m_xElement, UNO_QUERY ); 351 352 PropertyValueArray::iterator aEnd = m_aGenericValues.end(); 353 for ( PropertyValueArray::iterator aPropValues = 354 m_aGenericValues.begin(); 355 aPropValues != aEnd; 356 ++aPropValues 357 ) 358 { 359 // check property type for numeric types before setting 360 // the property 361 try 362 { 363 // if such a property does not yet exist at the element, create it if necessary 364 const bool bExistentProperty = m_xInfo->hasPropertyByName( aPropValues->Name ); 365 if ( !bExistentProperty ) 366 { 367 if ( !xDynamicProperties.is() ) 368 { 369 #if OSL_DEBUG_LEVEL > 0 370 ::rtl::OString aMessage( "OElementImport::implApplyGenericProperties: encountered an unknown property (" ); 371 aMessage += ::rtl::OUStringToOString( aPropValues->Name, RTL_TEXTENCODING_ASCII_US ); 372 aMessage += "), but component is no PropertyBag!"; 373 OSL_ENSURE( false, aMessage.getStr() ); 374 #endif 375 continue; 376 } 377 378 xDynamicProperties->addProperty( 379 aPropValues->Name, 380 PropertyAttribute::BOUND | PropertyAttribute::REMOVEABLE, 381 aPropValues->Value 382 ); 383 384 // re-fetch the PropertySetInfo 385 m_xInfo = m_xElement->getPropertySetInfo(); 386 } 387 388 // determine the type of the value (source for the following conversion) 389 TypeClass eValueTypeClass = aPropValues->Value.getValueTypeClass(); 390 const sal_Bool bValueIsSequence = TypeClass_SEQUENCE == eValueTypeClass; 391 if ( bValueIsSequence ) 392 { 393 uno::Type aSimpleType( getSequenceElementType( aPropValues->Value.getValueType() ) ); 394 eValueTypeClass = aSimpleType.getTypeClass(); 395 } 396 397 // determine the type of the property (target for the following conversion) 398 const Property aProperty( m_xInfo->getPropertyByName( aPropValues->Name ) ); 399 TypeClass ePropTypeClass = aProperty.Type.getTypeClass(); 400 const sal_Bool bPropIsSequence = TypeClass_SEQUENCE == ePropTypeClass; 401 if( bPropIsSequence ) 402 { 403 uno::Type aSimpleType( ::comphelper::getSequenceElementType( aProperty.Type ) ); 404 ePropTypeClass = aSimpleType.getTypeClass(); 405 } 406 407 if ( bPropIsSequence != bValueIsSequence ) 408 { 409 OSL_ENSURE( false, "OElementImport::implApplyGenericProperties: either both value and property should be a sequence, or none of them!" ); 410 continue; 411 } 412 413 if ( bValueIsSequence ) 414 { 415 OSL_ENSURE( eValueTypeClass == TypeClass_ANY, 416 "OElementImport::implApplyGenericProperties: only ANYs should have been imported as generic list property!" ); 417 // (OPropertyImport should produce only Sequencer< Any >, since it cannot know the real type 418 419 OSL_ENSURE( ePropTypeClass == TypeClass_SHORT, 420 "OElementImport::implApplyGenericProperties: conversion to sequences other than 'sequence< short >' not implemented, yet!" ); 421 422 Sequence< Any > aXMLValueList; 423 aPropValues->Value >>= aXMLValueList; 424 Sequence< sal_Int16 > aPropertyValueList( aXMLValueList.getLength() ); 425 426 const Any* pXMLValue = aXMLValueList.getConstArray(); 427 sal_Int16* pPropValue = aPropertyValueList.getArray(); 428 429 for ( sal_Int32 i=0; i<aXMLValueList.getLength(); ++i, ++pXMLValue, ++pPropValue ) 430 { 431 // only value sequences of numeric types implemented so far. 432 double nVal( 0 ); 433 OSL_VERIFY( *pXMLValue >>= nVal ); 434 *pPropValue = static_cast< sal_Int16 >( nVal ); 435 } 436 437 aPropValues->Value <<= aPropertyValueList; 438 } 439 else if ( ePropTypeClass != eValueTypeClass ) 440 { 441 switch ( eValueTypeClass ) 442 { 443 case TypeClass_DOUBLE: 444 { 445 double nVal = 0; 446 aPropValues->Value >>= nVal; 447 switch( ePropTypeClass ) 448 { 449 case TypeClass_BYTE: 450 aPropValues->Value <<= static_cast< sal_Int8 >( nVal ); 451 break; 452 case TypeClass_SHORT: 453 aPropValues->Value <<= static_cast< sal_Int16 >( nVal ); 454 break; 455 case TypeClass_LONG: 456 case TypeClass_ENUM: 457 aPropValues->Value <<= static_cast< sal_Int32 >( nVal ); 458 break; 459 case TypeClass_HYPER: 460 aPropValues->Value <<= static_cast< sal_Int64 >( nVal ); 461 break; 462 default: 463 OSL_ENSURE( false, "OElementImport::implApplyGenericProperties: unsupported value type!" ); 464 break; 465 } 466 } 467 break; 468 default: 469 OSL_ENSURE( false, "OElementImport::implApplyGenericProperties: non-double values not supported!" ); 470 break; 471 } 472 } 473 474 m_xElement->setPropertyValue( aPropValues->Name, aPropValues->Value ); 475 } 476 catch(Exception&) 477 { 478 OSL_ENSURE(sal_False, 479 ::rtl::OString("OElementImport::EndElement: could not set the property \"") 480 += ::rtl::OString(aPropValues->Name.getStr(), aPropValues->Name.getLength(), RTL_TEXTENCODING_ASCII_US) 481 += ::rtl::OString("\"!")); 482 } 483 } 484 } 485 486 //--------------------------------------------------------------------- implGetDefaultName() const487 ::rtl::OUString OElementImport::implGetDefaultName() const 488 { 489 // no optimization here. If this method gets called, the XML stream did not contain a name for the 490 // element, which is a heavy error. So in this case we don't care for performance 491 Sequence< ::rtl::OUString > aNames = m_xParentContainer->getElementNames(); 492 static const ::rtl::OUString sUnnamedName = ::rtl::OUString::createFromAscii("unnamed"); 493 494 ::rtl::OUString sReturn; 495 const ::rtl::OUString* pNames = NULL; 496 const ::rtl::OUString* pNamesEnd = aNames.getConstArray() + aNames.getLength(); 497 for (sal_Int32 i=0; i<32768; ++i) // the limit is nearly arbitrary ... 498 { 499 // assemble the new name (suggestion) 500 sReturn = sUnnamedName; 501 sReturn += ::rtl::OUString::valueOf(i); 502 // check the existence (this is the bad performance part ....) 503 for (pNames = aNames.getConstArray(); pNames<pNamesEnd; ++pNames) 504 { 505 if (*pNames == sReturn) 506 { 507 break; 508 } 509 } 510 if (pNames<pNamesEnd) 511 // found the name 512 continue; 513 return sReturn; 514 } 515 OSL_ENSURE(sal_False, "OElementImport::implGetDefaultName: did not find a free name!"); 516 return sUnnamedName; 517 } 518 519 //--------------------------------------------------------------------- impl_matchPropertyGroup(const PropertyGroups & i_propertyGroups) const520 PropertyGroups::const_iterator OElementImport::impl_matchPropertyGroup( const PropertyGroups& i_propertyGroups ) const 521 { 522 ENSURE_OR_RETURN( m_xInfo.is(), "OElementImport::impl_matchPropertyGroup: no property set info!", i_propertyGroups.end() ); 523 524 for ( PropertyGroups::const_iterator group = i_propertyGroups.begin(); 525 group != i_propertyGroups.end(); 526 ++group 527 ) 528 { 529 bool missingProp = false; 530 for ( PropertyDescriptionList::const_iterator prop = group->begin(); 531 prop != group->end(); 532 ++prop 533 ) 534 { 535 if ( !m_xInfo->hasPropertyByName( (*prop)->propertyName ) ) 536 { 537 missingProp = true; 538 break; 539 } 540 } 541 542 if ( missingProp ) 543 // try next group 544 continue; 545 546 return group; 547 } 548 549 return i_propertyGroups.end(); 550 } 551 552 //--------------------------------------------------------------------- tryGenericAttribute(sal_uInt16 _nNamespaceKey,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)553 bool OElementImport::tryGenericAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue ) 554 { 555 // the generic approach (which I hope all props will be migrated to, on the medium term): property handlers 556 const AttributeDescription attribute( metadata::getAttributeDescription( _nNamespaceKey, _rLocalName ) ); 557 if ( attribute.attributeToken != XML_TOKEN_INVALID ) 558 { 559 PropertyGroups propertyGroups; 560 metadata::getPropertyGroupList( attribute, propertyGroups ); 561 const PropertyGroups::const_iterator pos = impl_matchPropertyGroup( propertyGroups ); 562 if ( pos == propertyGroups.end() ) 563 return false; 564 565 do 566 { 567 const PropertyDescriptionList& rProperties( *pos ); 568 const PropertyDescription* first = *rProperties.begin(); 569 ENSURE_OR_BREAK( first != NULL, "OElementImport::handleAttribute: invalid property description!" ); 570 const PPropertyHandler handler = (*first->factory)( first->propertyId ); 571 ENSURE_OR_BREAK( handler.get() != NULL, "OElementImport::handleAttribute: invalid property handler!" ); 572 573 PropertyValues aValues; 574 for ( PropertyDescriptionList::const_iterator propDesc = rProperties.begin(); 575 propDesc != rProperties.end(); 576 ++propDesc 577 ) 578 { 579 aValues[ (*propDesc)->propertyId ] = Any(); 580 } 581 if ( handler->getPropertyValues( _rValue, aValues ) ) 582 { 583 for ( PropertyDescriptionList::const_iterator propDesc = rProperties.begin(); 584 propDesc != rProperties.end(); 585 ++propDesc 586 ) 587 { 588 implPushBackPropertyValue( (*propDesc)->propertyName, aValues[ (*propDesc)->propertyId ] ); 589 } 590 } 591 } 592 while ( false ); 593 594 // handled 595 return true; 596 } 597 return false; 598 } 599 600 //--------------------------------------------------------------------- handleAttribute(sal_uInt16 _nNamespaceKey,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)601 bool OElementImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 602 { 603 if ( token::IsXMLToken( _rLocalName, token::XML_CONTROL_IMPLEMENTATION ) ) 604 // ignore this, it has already been handled in OElementImport::StartElement 605 return true; 606 607 if ( token::IsXMLToken( _rLocalName, token::XML_NAME ) ) 608 { 609 if ( !m_sName.getLength() ) 610 // remember the name for later use in EndElement 611 m_sName = _rValue; 612 return true; 613 } 614 615 // maybe it's the style attribute? 616 if ( token::IsXMLToken( _rLocalName, token::XML_TEXT_STYLE_NAME ) ) 617 { 618 const SvXMLStyleContext* pStyleContext = m_rContext.getStyleElement( _rValue ); 619 OSL_ENSURE( pStyleContext, "OElementImport::handleAttribute: do not know the style!" ); 620 // remember the element for later usage. 621 m_pStyleElement = PTR_CAST( XMLTextStyleContext, pStyleContext ); 622 return true; 623 } 624 625 if ( m_bImplicitGenericAttributeHandling ) 626 if ( tryGenericAttribute( _nNamespaceKey, _rLocalName, _rValue ) ) 627 return true; 628 629 // let the base class handle it 630 return OPropertyImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); 631 } 632 633 //--------------------------------------------------------------------- createElement()634 Reference< XPropertySet > OElementImport::createElement() 635 { 636 Reference< XPropertySet > xReturn; 637 if (m_sServiceName.getLength()) 638 { 639 Reference< XInterface > xPure = m_rFormImport.getGlobalContext().getServiceFactory()->createInstance(m_sServiceName); 640 OSL_ENSURE(xPure.is(), 641 ::rtl::OString("OElementImport::createElement: service factory gave me no object (service name: ") 642 += ::rtl::OString(m_sServiceName.getStr(), m_sServiceName.getLength(), RTL_TEXTENCODING_ASCII_US) 643 += ::rtl::OString(")!")); 644 xReturn = Reference< XPropertySet >(xPure, UNO_QUERY); 645 } 646 else 647 OSL_ENSURE(sal_False, "OElementImport::createElement: no service name to create an element!"); 648 649 return xReturn; 650 } 651 652 //--------------------------------------------------------------------- registerEvents(const Sequence<ScriptEventDescriptor> & _rEvents)653 void OElementImport::registerEvents(const Sequence< ScriptEventDescriptor >& _rEvents) 654 { 655 OSL_ENSURE(m_xElement.is(), "OElementImport::registerEvents: no element to register events for!"); 656 m_rEventManager.registerEvents(m_xElement, _rEvents); 657 } 658 659 //--------------------------------------------------------------------- simulateDefaultedAttribute(const sal_Char * _pAttributeName,const::rtl::OUString & _rPropertyName,const sal_Char * _pAttributeDefault)660 void OElementImport::simulateDefaultedAttribute(const sal_Char* _pAttributeName, const ::rtl::OUString& _rPropertyName, const sal_Char* _pAttributeDefault) 661 { 662 OSL_ENSURE( m_xInfo.is(), "OPropertyImport::simulateDefaultedAttribute: the component should be more gossipy about it's properties!" ); 663 664 if ( !m_xInfo.is() || m_xInfo->hasPropertyByName( _rPropertyName ) ) 665 { 666 ::rtl::OUString sLocalAttrName = ::rtl::OUString::createFromAscii(_pAttributeName); 667 if ( !encounteredAttribute( sLocalAttrName ) ) 668 OSL_VERIFY( handleAttribute( XML_NAMESPACE_FORM, sLocalAttrName, ::rtl::OUString::createFromAscii( _pAttributeDefault ) ) ); 669 } 670 } 671 672 //===================================================================== 673 //= OControlImport 674 //===================================================================== 675 //--------------------------------------------------------------------- OControlImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer)676 OControlImport::OControlImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 677 const Reference< XNameContainer >& _rxParentContainer) 678 :OElementImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer) 679 ,m_eElementType(OControlElement::UNKNOWN) 680 { 681 disableImplicitGenericAttributeHandling(); 682 } 683 684 //--------------------------------------------------------------------- OControlImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer,OControlElement::ElementType _eType)685 OControlImport::OControlImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 686 const Reference< XNameContainer >& _rxParentContainer, OControlElement::ElementType _eType) 687 :OElementImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer) 688 ,m_eElementType(_eType) 689 { 690 disableImplicitGenericAttributeHandling(); 691 } 692 693 //--------------------------------------------------------------------- determineDefaultServiceName() const694 ::rtl::OUString OControlImport::determineDefaultServiceName() const 695 { 696 const sal_Char* pServiceName = NULL; 697 switch ( m_eElementType ) 698 { 699 case OControlElement::TEXT: 700 case OControlElement::TEXT_AREA: 701 case OControlElement::PASSWORD: pServiceName = "com.sun.star.form.component.TextField"; break; 702 case OControlElement::FILE: pServiceName = "com.sun.star.form.component.FileControl"; break; 703 case OControlElement::FORMATTED_TEXT: pServiceName = "com.sun.star.form.component.FormattedField"; break; 704 case OControlElement::FIXED_TEXT: pServiceName = "com.sun.star.form.component.FixedText"; break; 705 case OControlElement::COMBOBOX: pServiceName = "com.sun.star.form.component.ComboBox"; break; 706 case OControlElement::LISTBOX: pServiceName = "com.sun.star.form.component.ListBox"; break; 707 case OControlElement::BUTTON: pServiceName = "com.sun.star.form.component.CommandButton"; break; 708 case OControlElement::IMAGE: pServiceName = "com.sun.star.form.component.ImageButton"; break; 709 case OControlElement::CHECKBOX: pServiceName = "com.sun.star.form.component.CheckBox"; break; 710 case OControlElement::RADIO: pServiceName = "com.sun.star.form.component.RadioButton"; break; 711 case OControlElement::FRAME: pServiceName = "com.sun.star.form.component.GroupBox"; break; 712 case OControlElement::IMAGE_FRAME: pServiceName = "com.sun.star.form.component.DatabaseImageControl"; break; 713 case OControlElement::HIDDEN: pServiceName = "com.sun.star.form.component.HiddenControl"; break; 714 case OControlElement::GRID: pServiceName = "com.sun.star.form.component.GridControl"; break; 715 case OControlElement::TIME: pServiceName = "com.sun.star.form.component.DateField"; break; 716 case OControlElement::DATE: pServiceName = "com.sun.star.form.component.TimeField"; break; 717 default: break; 718 } 719 if ( pServiceName != NULL ) 720 return ::rtl::OUString::createFromAscii( pServiceName ); 721 return ::rtl::OUString(); 722 } 723 724 //--------------------------------------------------------------------- addOuterAttributes(const Reference<sax::XAttributeList> & _rxOuterAttribs)725 void OControlImport::addOuterAttributes(const Reference< sax::XAttributeList >& _rxOuterAttribs) 726 { 727 OSL_ENSURE(!m_xOuterAttributes.is(), "OControlImport::addOuterAttributes: already have these attributes!"); 728 m_xOuterAttributes = _rxOuterAttribs; 729 } 730 731 //--------------------------------------------------------------------- handleAttribute(sal_uInt16 _nNamespaceKey,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)732 bool OControlImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 733 { 734 static const sal_Char* pLinkedCellAttributeName = OAttributeMetaData::getBindingAttributeName(BA_LINKED_CELL); 735 736 if (IsXMLToken(_rLocalName, XML_ID)) 737 { // it's the control id 738 if (XML_NAMESPACE_XML == _nNamespaceKey) 739 { 740 m_sControlId = _rValue; 741 } 742 else if (XML_NAMESPACE_FORM == _nNamespaceKey) 743 { 744 if (!m_sControlId.getLength()) 745 { 746 m_sControlId = _rValue; 747 } 748 } 749 return true; 750 } 751 752 if ( _rLocalName.equalsAscii( pLinkedCellAttributeName ) ) 753 { // it's the address of a spreadsheet cell 754 m_sBoundCellAddress = _rValue; 755 return true; 756 } 757 758 if ( _nNamespaceKey == XML_NAMESPACE_XFORMS && IsXMLToken( _rLocalName, XML_BIND ) ) 759 { 760 m_sBindingID = _rValue; 761 return true; 762 } 763 764 if ( _nNamespaceKey == XML_NAMESPACE_FORM && IsXMLToken( _rLocalName, XML_XFORMS_LIST_SOURCE ) ) 765 { 766 m_sListBindingID = _rValue; 767 return true; 768 } 769 770 if ( ( ( _nNamespaceKey == XML_NAMESPACE_FORM ) 771 && IsXMLToken( _rLocalName, XML_XFORMS_SUBMISSION ) 772 ) 773 || ( ( _nNamespaceKey == XML_NAMESPACE_XFORMS ) 774 && IsXMLToken( _rLocalName, XML_SUBMISSION ) 775 ) 776 ) 777 { 778 m_sSubmissionID = _rValue; 779 return true; 780 } 781 782 if ( OElementImport::tryGenericAttribute( _nNamespaceKey, _rLocalName, _rValue ) ) 783 return true; 784 785 static const sal_Char* pValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_VALUE); 786 static const sal_Char* pCurrentValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_VALUE); 787 static const sal_Char* pMinValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MIN_VALUE); 788 static const sal_Char* pMaxValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MAX_VALUE); 789 static const sal_Char* pRepeatDelayAttributeName = OAttributeMetaData::getSpecialAttributeName( SCA_REPEAT_DELAY ); 790 791 sal_Int32 nHandle = -1; 792 if ( _rLocalName.equalsAscii( pValueAttributeName ) ) 793 nHandle = PROPID_VALUE; 794 else if ( _rLocalName.equalsAscii( pCurrentValueAttributeName ) ) 795 nHandle = PROPID_CURRENT_VALUE; 796 else if ( _rLocalName.equalsAscii( pMinValueAttributeName ) ) 797 nHandle = PROPID_MIN_VALUE; 798 else if ( _rLocalName.equalsAscii( pMaxValueAttributeName ) ) 799 nHandle = PROPID_MAX_VALUE; 800 if ( nHandle != -1 ) 801 { 802 // for the moment, simply remember the name and the value 803 PropertyValue aProp; 804 aProp.Name = _rLocalName; 805 aProp.Handle = nHandle; 806 aProp.Value <<= _rValue; 807 m_aValueProperties.push_back(aProp); 808 return true; 809 } 810 811 if ( _rLocalName.equalsAscii( pRepeatDelayAttributeName ) ) 812 { 813 ::Time aTime; 814 sal_Int32 nFractions = 0; 815 if ( SvXMLUnitConverter::convertTimeDuration( _rValue, aTime, &nFractions ) ) 816 { 817 PropertyValue aProp; 818 aProp.Name = PROPERTY_REPEAT_DELAY; 819 aProp.Value <<= (sal_Int32)( ( ( aTime.GetMSFromTime() / 1000 ) * 1000 ) + nFractions ); 820 821 implPushBackPropertyValue(aProp); 822 } 823 return true; 824 } 825 826 return OElementImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); 827 } 828 829 //--------------------------------------------------------------------- StartElement(const Reference<sax::XAttributeList> & _rxAttrList)830 void OControlImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 831 { 832 ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > xAttributes; 833 if( m_xOuterAttributes.is() ) 834 { 835 // merge the attribute lists 836 OAttribListMerger* pMerger = new OAttribListMerger; 837 // our own one 838 pMerger->addList(_rxAttrList); 839 // and the ones of our enclosing element 840 pMerger->addList(m_xOuterAttributes); 841 xAttributes = pMerger; 842 } 843 else 844 { 845 xAttributes = _rxAttrList; 846 } 847 848 // let the base class handle all the attributes 849 OElementImport::StartElement(xAttributes); 850 851 if ( !m_aValueProperties.empty() && m_xElement.is()) 852 { 853 // get the property set info 854 if (!m_xInfo.is()) 855 { 856 OSL_ENSURE(sal_False, "OControlImport::StartElement: no PropertySetInfo!"); 857 return; 858 } 859 860 const sal_Char* pValueProperty = NULL; 861 const sal_Char* pCurrentValueProperty = NULL; 862 const sal_Char* pMinValueProperty = NULL; 863 const sal_Char* pMaxValueProperty = NULL; 864 865 sal_Bool bRetrievedValues = sal_False; 866 sal_Bool bRetrievedValueLimits = sal_False; 867 868 // get the class id of our element 869 sal_Int16 nClassId = FormComponentType::CONTROL; 870 m_xElement->getPropertyValue(PROPERTY_CLASSID) >>= nClassId; 871 872 // translate the value properties we collected in handleAttributes 873 PropertyValueArray::iterator aEnd = m_aValueProperties.end(); 874 for ( PropertyValueArray::iterator aValueProps = m_aValueProperties.begin(); 875 aValueProps != aEnd; 876 ++aValueProps 877 ) 878 { 879 bool bSuccess = false; 880 switch (aValueProps->Handle) 881 { 882 case PROPID_VALUE: 883 case PROPID_CURRENT_VALUE: 884 { 885 // get the property names 886 if (!bRetrievedValues) 887 { 888 getValuePropertyNames(m_eElementType, nClassId, pCurrentValueProperty, pValueProperty); 889 ENSURE_OR_BREAK( pValueProperty, "OControlImport::StartElement: illegal value property names!" ); 890 bRetrievedValues = sal_True; 891 } 892 ENSURE_OR_BREAK((PROPID_VALUE != aValueProps->Handle) || pValueProperty, 893 "OControlImport::StartElement: the control does not have a value property!"); 894 ENSURE_OR_BREAK((PROPID_CURRENT_VALUE != aValueProps->Handle) || pCurrentValueProperty, 895 "OControlImport::StartElement: the control does not have a current-value property!"); 896 897 // transfer the name 898 if (PROPID_VALUE == aValueProps->Handle) 899 aValueProps->Name = ::rtl::OUString::createFromAscii(pValueProperty); 900 else 901 aValueProps->Name = ::rtl::OUString::createFromAscii(pCurrentValueProperty); 902 bSuccess = true; 903 } 904 break; 905 case PROPID_MIN_VALUE: 906 case PROPID_MAX_VALUE: 907 { 908 // get the property names 909 if (!bRetrievedValueLimits) 910 { 911 getValueLimitPropertyNames(nClassId, pMinValueProperty, pMaxValueProperty); 912 ENSURE_OR_BREAK( pMinValueProperty && pMaxValueProperty, "OControlImport::StartElement: illegal value limit property names!" ); 913 bRetrievedValueLimits = sal_True; 914 } 915 OSL_ENSURE((PROPID_MIN_VALUE != aValueProps->Handle) || pMinValueProperty, 916 "OControlImport::StartElement: the control does not have a value property!"); 917 OSL_ENSURE((PROPID_MAX_VALUE != aValueProps->Handle) || pMaxValueProperty, 918 "OControlImport::StartElement: the control does not have a current-value property!"); 919 920 // transfer the name 921 if (PROPID_MIN_VALUE == aValueProps->Handle) 922 aValueProps->Name = ::rtl::OUString::createFromAscii(pMinValueProperty); 923 else 924 aValueProps->Name = ::rtl::OUString::createFromAscii(pMaxValueProperty); 925 bSuccess = true; 926 } 927 break; 928 } 929 930 if ( !bSuccess ) 931 continue; 932 933 // translate the value 934 implTranslateValueProperty(m_xInfo, *aValueProps); 935 // add the property to the base class' array 936 implPushBackPropertyValue(*aValueProps); 937 } 938 } 939 } 940 941 //--------------------------------------------------------------------- implTranslateValueProperty(const Reference<XPropertySetInfo> & _rxPropInfo,PropertyValue & _rPropValue)942 void OControlImport::implTranslateValueProperty(const Reference< XPropertySetInfo >& _rxPropInfo, 943 PropertyValue& _rPropValue) 944 { 945 OSL_ENSURE(_rxPropInfo->hasPropertyByName(_rPropValue.Name), 946 "OControlImport::implTranslateValueProperty: invalid property name!"); 947 948 // retrieve the type of the property 949 Property aProp = _rxPropInfo->getPropertyByName(_rPropValue.Name); 950 // the untranslated string value as read in handleAttribute 951 ::rtl::OUString sValue; 952 #if OSL_DEBUG_LEVEL > 0 953 sal_Bool bSuccess = 954 #endif 955 _rPropValue.Value >>= sValue; 956 OSL_ENSURE(bSuccess, "OControlImport::implTranslateValueProperty: supposed to be called with non-translated string values!"); 957 958 if (TypeClass_ANY == aProp.Type.getTypeClass()) 959 { 960 // we have exactly 2 properties where this type class is allowed: 961 OSL_ENSURE( 962 (0 == _rPropValue.Name.compareToAscii(PROPERTY_EFFECTIVE_VALUE)) 963 || (0 == _rPropValue.Name.compareToAscii(PROPERTY_EFFECTIVE_DEFAULT)), 964 "OControlImport::implTranslateValueProperty: invalid property type/name combination!"); 965 966 // Both properties are allowed to have a double or a string value, 967 // so first try to convert the string into a number 968 double nValue; 969 if (GetImport().GetMM100UnitConverter().convertDouble(nValue, sValue)) 970 _rPropValue.Value <<= nValue; 971 else 972 _rPropValue.Value <<= sValue; 973 } 974 else 975 _rPropValue.Value = PropertyConversion::convertString(GetImport(), aProp.Type, sValue); 976 } 977 978 //--------------------------------------------------------------------- EndElement()979 void OControlImport::EndElement() 980 { 981 OSL_ENSURE(m_xElement.is(), "OControlImport::EndElement: invalid control!"); 982 if ( !m_xElement.is() ) 983 return; 984 985 // register our control with it's id 986 if (m_sControlId.getLength()) 987 m_rFormImport.registerControlId(m_xElement, m_sControlId); 988 // it's allowed to have no control id. In this case we're importing a column 989 990 // one more pre-work to do: 991 // when we set default values, then by definition the respective value is set 992 // to this default value, too. This means if the sequence contains for example 993 // a DefaultText value, then the Text will be affected by this, too. 994 // In case the Text is not part of the property sequence (or occurs _before_ 995 // the DefaultText, which can happen for other value/default-value property names), 996 // this means that the Text (the value property) is incorrectly imported. 997 // #102475# - 04.09.2002 - fs@openoffice.org 998 999 sal_Bool bRestoreValuePropertyValue = sal_False; 1000 Any aValuePropertyValue; 1001 1002 sal_Int16 nClassId = FormComponentType::CONTROL; 1003 try 1004 { 1005 // get the class id of our element 1006 m_xElement->getPropertyValue(PROPERTY_CLASSID) >>= nClassId; 1007 } 1008 catch( const Exception& ) 1009 { 1010 OSL_ENSURE( sal_False, "OControlImport::EndElement: caught an exception while retrieving the class id!" ); 1011 } 1012 1013 const sal_Char* pValueProperty = NULL; 1014 const sal_Char* pDefaultValueProperty = NULL; 1015 getRuntimeValuePropertyNames(m_eElementType, nClassId, pValueProperty, pDefaultValueProperty); 1016 if ( pDefaultValueProperty && pValueProperty ) 1017 { 1018 sal_Bool bNonDefaultValuePropertyValue = sal_False; 1019 // is the "value property" part of the sequence? 1020 1021 // look up this property in our sequence 1022 PropertyValueArray::iterator aEnd = m_aValues.end(); 1023 for ( PropertyValueArray::iterator aCheck = m_aValues.begin(); 1024 ( aCheck != aEnd ); 1025 ++aCheck 1026 ) 1027 { 1028 if ( aCheck->Name.equalsAscii( pDefaultValueProperty ) ) 1029 bRestoreValuePropertyValue = sal_True; 1030 else if ( aCheck->Name.equalsAscii( pValueProperty ) ) 1031 { 1032 bNonDefaultValuePropertyValue = sal_True; 1033 // we need to restore the value property we found here, nothing else 1034 aValuePropertyValue = aCheck->Value; 1035 } 1036 } 1037 1038 if ( bRestoreValuePropertyValue && !bNonDefaultValuePropertyValue ) 1039 { 1040 // found it -> need to remember (and restore) the "value property value", which is not set explicitly 1041 try 1042 { 1043 aValuePropertyValue = m_xElement->getPropertyValue( ::rtl::OUString::createFromAscii( pValueProperty ) ); 1044 } 1045 catch( const Exception& ) 1046 { 1047 OSL_ENSURE( sal_False, "OControlImport::EndElement: caught an exception while retrieving the current value property!" ); 1048 } 1049 } 1050 } 1051 1052 // let the base class set all the values 1053 OElementImport::EndElement(); 1054 1055 // restore the "value property value", if necessary 1056 if ( bRestoreValuePropertyValue && pValueProperty ) 1057 { 1058 try 1059 { 1060 m_xElement->setPropertyValue( ::rtl::OUString::createFromAscii( pValueProperty ), aValuePropertyValue ); 1061 } 1062 catch( const Exception& ) 1063 { 1064 OSL_ENSURE( sal_False, "OControlImport::EndElement: caught an exception while restoring the value property!" ); 1065 } 1066 } 1067 1068 // the external cell binding, if applicable 1069 if ( m_xElement.is() && m_sBoundCellAddress.getLength() ) 1070 doRegisterCellValueBinding( m_sBoundCellAddress ); 1071 1072 // XForms binding, if applicable 1073 if ( m_xElement.is() && m_sBindingID.getLength() ) 1074 doRegisterXFormsValueBinding( m_sBindingID ); 1075 1076 // XForms list binding, if applicable 1077 if ( m_xElement.is() && m_sListBindingID.getLength() ) 1078 doRegisterXFormsListBinding( m_sListBindingID ); 1079 1080 // XForms submission, if applicable 1081 if ( m_xElement.is() && m_sSubmissionID.getLength() ) 1082 doRegisterXFormsSubmission( m_sSubmissionID ); 1083 } 1084 1085 //--------------------------------------------------------------------- doRegisterCellValueBinding(const::rtl::OUString & _rBoundCellAddress)1086 void OControlImport::doRegisterCellValueBinding( const ::rtl::OUString& _rBoundCellAddress ) 1087 { 1088 OSL_PRECOND( m_xElement.is(), "OControlImport::doRegisterCellValueBinding: invalid element!" ); 1089 OSL_PRECOND( _rBoundCellAddress.getLength(), 1090 "OControlImport::doRegisterCellValueBinding: invalid address!" ); 1091 1092 m_rContext.registerCellValueBinding( m_xElement, _rBoundCellAddress ); 1093 } 1094 1095 //--------------------------------------------------------------------- doRegisterXFormsValueBinding(const::rtl::OUString & _rBindingID)1096 void OControlImport::doRegisterXFormsValueBinding( const ::rtl::OUString& _rBindingID ) 1097 { 1098 OSL_PRECOND( m_xElement.is(), "need element" ); 1099 OSL_PRECOND( _rBindingID.getLength() > 0, "binding ID is not valid" ); 1100 1101 m_rContext.registerXFormsValueBinding( m_xElement, _rBindingID ); 1102 } 1103 1104 //--------------------------------------------------------------------- doRegisterXFormsListBinding(const::rtl::OUString & _rBindingID)1105 void OControlImport::doRegisterXFormsListBinding( const ::rtl::OUString& _rBindingID ) 1106 { 1107 OSL_PRECOND( m_xElement.is(), "need element" ); 1108 OSL_PRECOND( _rBindingID.getLength() > 0, "binding ID is not valid" ); 1109 1110 m_rContext.registerXFormsListBinding( m_xElement, _rBindingID ); 1111 } 1112 1113 //--------------------------------------------------------------------- doRegisterXFormsSubmission(const::rtl::OUString & _rSubmissionID)1114 void OControlImport::doRegisterXFormsSubmission( const ::rtl::OUString& _rSubmissionID ) 1115 { 1116 OSL_PRECOND( m_xElement.is(), "need element" ); 1117 OSL_PRECOND( _rSubmissionID.getLength() > 0, "binding ID is not valid" ); 1118 1119 m_rContext.registerXFormsSubmission( m_xElement, _rSubmissionID ); 1120 } 1121 1122 //--------------------------------------------------------------------- 1123 //added by BerryJia for fixing bug102407 2002-11-5 createElement()1124 Reference< XPropertySet > OControlImport::createElement() 1125 { 1126 const Reference<XPropertySet> xPropSet = OElementImport::createElement(); 1127 if ( xPropSet.is() ) 1128 { 1129 m_xInfo = xPropSet->getPropertySetInfo(); 1130 if ( m_xInfo.is() && m_xInfo->hasPropertyByName(PROPERTY_ALIGN) ) 1131 { 1132 Any aValue; 1133 xPropSet->setPropertyValue(PROPERTY_ALIGN,aValue); 1134 } 1135 } 1136 return xPropSet; 1137 } 1138 1139 //===================================================================== 1140 //= OImagePositionImport 1141 //===================================================================== 1142 //--------------------------------------------------------------------- OImagePositionImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer,OControlElement::ElementType _eType)1143 OImagePositionImport::OImagePositionImport( OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, 1144 sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, const Reference< XNameContainer >& _rxParentContainer, 1145 OControlElement::ElementType _eType ) 1146 :OControlImport( _rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType ) 1147 ,m_nImagePosition( -1 ) 1148 ,m_nImageAlign( 0 ) 1149 ,m_bHaveImagePosition( sal_False ) 1150 { 1151 } 1152 1153 //--------------------------------------------------------------------- handleAttribute(sal_uInt16 _nNamespaceKey,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)1154 bool OImagePositionImport::handleAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, 1155 const ::rtl::OUString& _rValue ) 1156 { 1157 if ( _rLocalName == GetXMLToken( XML_IMAGE_POSITION ) ) 1158 { 1159 OSL_VERIFY( PropertyConversion::convertString( 1160 m_rContext.getGlobalContext(), ::getCppuType( &m_nImagePosition ), 1161 _rValue, OEnumMapper::getEnumMap( OEnumMapper::epImagePosition ) 1162 ) >>= m_nImagePosition ); 1163 m_bHaveImagePosition = sal_True; 1164 return true; 1165 } 1166 1167 if ( _rLocalName == GetXMLToken( XML_IMAGE_ALIGN ) ) 1168 { 1169 OSL_VERIFY( PropertyConversion::convertString( 1170 m_rContext.getGlobalContext(), ::getCppuType( &m_nImageAlign ), 1171 _rValue, OEnumMapper::getEnumMap( OEnumMapper::epImageAlign ) 1172 ) >>= m_nImageAlign ); 1173 return true; 1174 } 1175 1176 return OControlImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); 1177 } 1178 1179 //--------------------------------------------------------------------- StartElement(const Reference<sax::XAttributeList> & _rxAttrList)1180 void OImagePositionImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1181 { 1182 OControlImport::StartElement( _rxAttrList ); 1183 1184 if ( m_bHaveImagePosition ) 1185 { 1186 sal_Int16 nUnoImagePosition = ImagePosition::Centered; 1187 if ( m_nImagePosition >= 0 ) 1188 { 1189 OSL_ENSURE( ( m_nImagePosition <= 3 ) && ( m_nImageAlign >= 0 ) && ( m_nImageAlign < 3 ), 1190 "OImagePositionImport::StartElement: unknown image align and/or position!" ); 1191 nUnoImagePosition = m_nImagePosition * 3 + m_nImageAlign; 1192 } 1193 1194 PropertyValue aImagePosition; 1195 aImagePosition.Name = PROPERTY_IMAGE_POSITION; 1196 aImagePosition.Value <<= nUnoImagePosition; 1197 implPushBackPropertyValue( aImagePosition ); 1198 } 1199 } 1200 1201 //===================================================================== 1202 //= OReferredControlImport 1203 //===================================================================== 1204 //--------------------------------------------------------------------- OReferredControlImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer,OControlElement::ElementType)1205 OReferredControlImport::OReferredControlImport( 1206 OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1207 const Reference< XNameContainer >& _rxParentContainer, 1208 OControlElement::ElementType ) 1209 :OControlImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer) 1210 { 1211 } 1212 1213 //--------------------------------------------------------------------- StartElement(const Reference<sax::XAttributeList> & _rxAttrList)1214 void OReferredControlImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1215 { 1216 OControlImport::StartElement(_rxAttrList); 1217 1218 // the base class should have created the control, so we can register it 1219 if ( m_sReferringControls.getLength() ) 1220 m_rFormImport.registerControlReferences(m_xElement, m_sReferringControls); 1221 } 1222 1223 //--------------------------------------------------------------------- handleAttribute(sal_uInt16 _nNamespaceKey,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)1224 bool OReferredControlImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, 1225 const ::rtl::OUString& _rValue) 1226 { 1227 static const ::rtl::OUString s_sReferenceAttributeName = ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_FOR)); 1228 if (_rLocalName == s_sReferenceAttributeName) 1229 { 1230 m_sReferringControls = _rValue; 1231 return true; 1232 } 1233 return OControlImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); 1234 } 1235 1236 //===================================================================== 1237 //= OPasswordImport 1238 //===================================================================== 1239 //--------------------------------------------------------------------- OPasswordImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer,OControlElement::ElementType _eType)1240 OPasswordImport::OPasswordImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1241 const Reference< XNameContainer >& _rxParentContainer, OControlElement::ElementType _eType) 1242 :OControlImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType) 1243 { 1244 } 1245 1246 //--------------------------------------------------------------------- handleAttribute(sal_uInt16 _nNamespaceKey,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)1247 bool OPasswordImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 1248 { 1249 static const ::rtl::OUString s_sEchoCharAttributeName = ::rtl::OUString::createFromAscii(OAttributeMetaData::getSpecialAttributeName(SCA_ECHO_CHAR)); 1250 if (_rLocalName == s_sEchoCharAttributeName) 1251 { 1252 // need a special handling for the EchoChar property 1253 PropertyValue aEchoChar; 1254 aEchoChar.Name = PROPERTY_ECHOCHAR; 1255 OSL_ENSURE(_rValue.getLength() == 1, "OPasswordImport::handleAttribute: invalid echo char attribute!"); 1256 // we ourself should not have written values other than of length 1 1257 if (_rValue.getLength() >= 1) 1258 aEchoChar.Value <<= (sal_Int16)_rValue.getStr()[0]; 1259 else 1260 aEchoChar.Value <<= (sal_Int16)0; 1261 implPushBackPropertyValue(aEchoChar); 1262 return true; 1263 } 1264 return OControlImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); 1265 } 1266 1267 //===================================================================== 1268 //= ORadioImport 1269 //===================================================================== 1270 //--------------------------------------------------------------------- ORadioImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer,OControlElement::ElementType _eType)1271 ORadioImport::ORadioImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1272 const Reference< XNameContainer >& _rxParentContainer, OControlElement::ElementType _eType) 1273 :OImagePositionImport( _rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType ) 1274 { 1275 } 1276 1277 //--------------------------------------------------------------------- handleAttribute(sal_uInt16 _nNamespaceKey,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)1278 bool ORadioImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 1279 { 1280 // need special handling for the State & CurrentState properties: 1281 // they're stored as booleans, but expected to be int16 properties 1282 static const sal_Char* pCurrentSelectedAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_SELECTED); 1283 static const sal_Char* pSelectedAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_SELECTED); 1284 if ( _rLocalName.equalsAscii( pCurrentSelectedAttributeName ) 1285 || _rLocalName.equalsAscii( pSelectedAttributeName ) 1286 ) 1287 { 1288 const OAttribute2Property::AttributeAssignment* pProperty = m_rContext.getAttributeMap().getAttributeTranslation(_rLocalName); 1289 OSL_ENSURE(pProperty, "ORadioImport::handleAttribute: invalid property map!"); 1290 if (pProperty) 1291 { 1292 const Any aBooleanValue( PropertyConversion::convertString(m_rContext.getGlobalContext(), pProperty->aPropertyType, _rValue, pProperty->pEnumMap) ); 1293 1294 // create and store a new PropertyValue 1295 PropertyValue aNewValue; 1296 aNewValue.Name = pProperty->sPropertyName; 1297 aNewValue.Value <<= (sal_Int16)::cppu::any2bool(aBooleanValue); 1298 1299 implPushBackPropertyValue(aNewValue); 1300 } 1301 return true; 1302 } 1303 return OImagePositionImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); 1304 } 1305 1306 //===================================================================== 1307 //= OURLReferenceImport 1308 //===================================================================== OURLReferenceImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer,OControlElement::ElementType _eType)1309 OURLReferenceImport::OURLReferenceImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1310 const Reference< XNameContainer >& _rxParentContainer, 1311 OControlElement::ElementType _eType) 1312 :OImagePositionImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType) 1313 { 1314 } 1315 1316 //--------------------------------------------------------------------- handleAttribute(sal_uInt16 _nNamespaceKey,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)1317 bool OURLReferenceImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 1318 { 1319 static const sal_Char* s_pTargetLocationAttributeName = OAttributeMetaData::getCommonControlAttributeName( CCA_TARGET_LOCATION ); 1320 static const sal_Char* s_pImageDataAttributeName = OAttributeMetaData::getCommonControlAttributeName( CCA_IMAGE_DATA ); 1321 1322 // need to make the URL absolute if 1323 // * it's the image-data attribute 1324 // * it's the target-location attribute, and we're dealign with an object which has the respective property 1325 sal_Bool bMakeAbsolute = 1326 ( 0 == _rLocalName.compareToAscii( s_pImageDataAttributeName ) ) 1327 || ( ( 0 == _rLocalName.compareToAscii( s_pTargetLocationAttributeName ) ) 1328 && ( ( OControlElement::BUTTON == m_eElementType ) 1329 || ( OControlElement::IMAGE == m_eElementType ) 1330 ) 1331 ); 1332 1333 if ( bMakeAbsolute && ( _rValue.getLength() > 0 ) ) 1334 { 1335 // make a global URL out of the local one 1336 ::rtl::OUString sAdjustedValue; 1337 // only resolve image related url 1338 // we don't want say form url targets to be resolved 1339 // using ResolveGraphicObjectURL 1340 if ( 0 == _rLocalName.compareToAscii( s_pImageDataAttributeName ) ) 1341 sAdjustedValue = m_rContext.getGlobalContext().ResolveGraphicObjectURL( _rValue, sal_False ); 1342 else 1343 sAdjustedValue = m_rContext.getGlobalContext().GetAbsoluteReference( _rValue ); 1344 return OImagePositionImport::handleAttribute( _nNamespaceKey, _rLocalName, sAdjustedValue ); 1345 } 1346 1347 return OImagePositionImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); 1348 } 1349 1350 //===================================================================== 1351 //= OButtonImport 1352 //===================================================================== 1353 //--------------------------------------------------------------------- OButtonImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer,OControlElement::ElementType _eType)1354 OButtonImport::OButtonImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1355 const Reference< XNameContainer >& _rxParentContainer, 1356 OControlElement::ElementType _eType) 1357 :OURLReferenceImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType) 1358 { 1359 enableTrackAttributes(); 1360 } 1361 1362 //--------------------------------------------------------------------- StartElement(const Reference<sax::XAttributeList> & _rxAttrList)1363 void OButtonImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1364 { 1365 OURLReferenceImport::StartElement(_rxAttrList); 1366 1367 // handle the target-frame attribute 1368 simulateDefaultedAttribute(OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_FRAME), PROPERTY_TARGETFRAME, "_blank"); 1369 } 1370 1371 //===================================================================== 1372 //= OValueRangeImport 1373 //===================================================================== 1374 //--------------------------------------------------------------------- OValueRangeImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer,OControlElement::ElementType _eType)1375 OValueRangeImport::OValueRangeImport( OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1376 const Reference< XNameContainer >& _rxParentContainer, OControlElement::ElementType _eType ) 1377 :OControlImport( _rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType ) 1378 ,m_nStepSizeValue( 1 ) 1379 { 1380 1381 } 1382 1383 //--------------------------------------------------------------------- handleAttribute(sal_uInt16 _nNamespaceKey,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)1384 bool OValueRangeImport::handleAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue ) 1385 { 1386 if ( _rLocalName.equalsAscii( OAttributeMetaData::getSpecialAttributeName( SCA_STEP_SIZE ) ) ) 1387 { 1388 GetImport().GetMM100UnitConverter().convertNumber( m_nStepSizeValue, _rValue ); 1389 return true; 1390 } 1391 return OControlImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); 1392 } 1393 1394 //--------------------------------------------------------------------- StartElement(const Reference<sax::XAttributeList> & _rxAttrList)1395 void OValueRangeImport::StartElement( const Reference< sax::XAttributeList >& _rxAttrList ) 1396 { 1397 OControlImport::StartElement( _rxAttrList ); 1398 1399 if ( m_xInfo.is() ) 1400 { 1401 if ( m_xInfo->hasPropertyByName( PROPERTY_SPIN_INCREMENT ) ) 1402 m_xElement->setPropertyValue( PROPERTY_SPIN_INCREMENT, makeAny( m_nStepSizeValue ) ); 1403 else if ( m_xInfo->hasPropertyByName( PROPERTY_LINE_INCREMENT ) ) 1404 m_xElement->setPropertyValue( PROPERTY_LINE_INCREMENT, makeAny( m_nStepSizeValue ) ); 1405 } 1406 } 1407 1408 //===================================================================== 1409 //= OTextLikeImport 1410 //===================================================================== 1411 //--------------------------------------------------------------------- OTextLikeImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer,OControlElement::ElementType _eType)1412 OTextLikeImport::OTextLikeImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1413 const Reference< XNameContainer >& _rxParentContainer, 1414 OControlElement::ElementType _eType) 1415 :OControlImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType) 1416 ,m_bEncounteredTextPara( false ) 1417 { 1418 enableTrackAttributes(); 1419 } 1420 1421 //--------------------------------------------------------------------- CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> & _rxAttrList)1422 SvXMLImportContext* OTextLikeImport::CreateChildContext( sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 1423 const Reference< sax::XAttributeList >& _rxAttrList ) 1424 { 1425 if ( ( XML_NAMESPACE_TEXT == _nPrefix ) && _rLocalName.equalsIgnoreAsciiCaseAscii( "p" ) ) 1426 { 1427 OSL_ENSURE( m_eElementType == OControlElement::TEXT_AREA, 1428 "OTextLikeImport::CreateChildContext: text paragraphs in a non-text-area?" ); 1429 1430 if ( m_eElementType == OControlElement::TEXT_AREA ) 1431 { 1432 Reference< XText > xTextElement( m_xElement, UNO_QUERY ); 1433 if ( xTextElement.is() ) 1434 { 1435 UniReference < XMLTextImportHelper > xTextImportHelper( m_rContext.getGlobalContext().GetTextImport() ); 1436 1437 if ( !m_xCursor.is() ) 1438 { 1439 m_xOldCursor = xTextImportHelper->GetCursor(); 1440 m_xCursor = xTextElement->createTextCursor(); 1441 1442 if ( m_xCursor.is() ) 1443 xTextImportHelper->SetCursor( m_xCursor ); 1444 } 1445 if ( m_xCursor.is() ) 1446 { 1447 m_bEncounteredTextPara = true; 1448 return xTextImportHelper->CreateTextChildContext( m_rContext.getGlobalContext(), _nPrefix, _rLocalName, _rxAttrList ); 1449 } 1450 } 1451 else 1452 { 1453 // in theory, we could accumulate all the text portions (without formatting), 1454 // and set it as Text property at the model ... 1455 } 1456 } 1457 } 1458 1459 return OControlImport::CreateChildContext( _nPrefix, _rLocalName, _rxAttrList ); 1460 } 1461 1462 //--------------------------------------------------------------------- StartElement(const Reference<sax::XAttributeList> & _rxAttrList)1463 void OTextLikeImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1464 { 1465 OControlImport::StartElement(_rxAttrList); 1466 1467 // handle the convert-empty-to-null attribute, whose default is different from the property default 1468 // unfortunately, different classes are imported by this class ('cause they're represented by the 1469 // same XML element), though not all of them know this property. 1470 // So we have to do a check ... 1471 if (m_xElement.is() && m_xInfo.is() && m_xInfo->hasPropertyByName(PROPERTY_EMPTY_IS_NULL) ) 1472 simulateDefaultedAttribute(OAttributeMetaData::getDatabaseAttributeName(DA_CONVERT_EMPTY), PROPERTY_EMPTY_IS_NULL, "false"); 1473 } 1474 1475 //--------------------------------------------------------------------- 1476 struct EqualHandle : public ::std::unary_function< PropertyValue, bool > 1477 { 1478 const sal_Int32 m_nHandle; EqualHandlexmloff::EqualHandle1479 EqualHandle( sal_Int32 _nHandle ) : m_nHandle( _nHandle ) { } 1480 operator ()xmloff::EqualHandle1481 inline bool operator()( const PropertyValue& _rProp ) 1482 { 1483 return _rProp.Handle == m_nHandle; 1484 } 1485 }; 1486 1487 //--------------------------------------------------------------------- removeRedundantCurrentValue()1488 void OTextLikeImport::removeRedundantCurrentValue() 1489 { 1490 if ( m_bEncounteredTextPara ) 1491 { 1492 // In case the text is written in the text:p elements, we need to ignore what we read as 1493 // current-value attribute, since it's redundant. 1494 // fortunately, OElementImport tagged the value property with the PROPID_CURRENT_VALUE 1495 // handle, so we do not need to determine the name of our value property here 1496 // (normally, it should be "Text", since no other controls than the edit field should 1497 // have the text:p elements) 1498 PropertyValueArray::iterator aValuePropertyPos = ::std::find_if( 1499 m_aValues.begin(), 1500 m_aValues.end(), 1501 EqualHandle( PROPID_CURRENT_VALUE ) 1502 ); 1503 if ( aValuePropertyPos != m_aValues.end() ) 1504 { 1505 OSL_ENSURE( aValuePropertyPos->Name == PROPERTY_TEXT, "OTextLikeImport::EndElement: text:p was present, but our value property is *not* 'Text'!" ); 1506 if ( aValuePropertyPos->Name == PROPERTY_TEXT ) 1507 { 1508 ::std::copy( 1509 aValuePropertyPos + 1, 1510 m_aValues.end(), 1511 aValuePropertyPos 1512 ); 1513 m_aValues.resize( m_aValues.size() - 1 ); 1514 } 1515 } 1516 1517 // additionally, we need to set the "RichText" property of our element to sal_True 1518 // (the presence of the text:p is used as indicator for the value of the RichText property) 1519 sal_Bool bHasRichTextProperty = sal_False; 1520 if ( m_xInfo.is() ) 1521 bHasRichTextProperty = m_xInfo->hasPropertyByName( PROPERTY_RICH_TEXT ); 1522 OSL_ENSURE( bHasRichTextProperty, "OTextLikeImport::EndElement: text:p, but no rich text control?" ); 1523 if ( bHasRichTextProperty ) 1524 m_xElement->setPropertyValue( PROPERTY_RICH_TEXT, makeAny( (sal_Bool)sal_True ) ); 1525 } 1526 // Note that we do *not* set the RichText property (in case our element has one) to sal_False here 1527 // since this is the default of this property, anyway. 1528 } 1529 1530 //--------------------------------------------------------------------- 1531 struct EqualName : public ::std::unary_function< PropertyValue, bool > 1532 { 1533 const ::rtl::OUString m_sName; EqualNamexmloff::EqualName1534 EqualName( const ::rtl::OUString& _rName ) : m_sName( _rName ) { } 1535 operator ()xmloff::EqualName1536 inline bool operator()( const PropertyValue& _rProp ) 1537 { 1538 return _rProp.Name == m_sName; 1539 } 1540 }; 1541 1542 //--------------------------------------------------------------------- adjustDefaultControlProperty()1543 void OTextLikeImport::adjustDefaultControlProperty() 1544 { 1545 // In OpenOffice.org 2.0, we changed the implementation of the css.form.component.TextField (the model of a text field control), 1546 // so that it now uses another default control. So if we encounter a text field where the *old* default 1547 // control property is writting, we are not allowed to use it 1548 PropertyValueArray::iterator aDefaultControlPropertyPos = ::std::find_if( 1549 m_aValues.begin(), 1550 m_aValues.end(), 1551 EqualName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultControl" ) ) ) 1552 ); 1553 if ( aDefaultControlPropertyPos != m_aValues.end() ) 1554 { 1555 ::rtl::OUString sDefaultControl; 1556 OSL_VERIFY( aDefaultControlPropertyPos->Value >>= sDefaultControl ); 1557 if ( sDefaultControl.equalsAscii( "stardiv.one.form.control.Edit" ) ) 1558 { 1559 // complete remove this property value from the array. Today's "default value" of the "DefaultControl" 1560 // property is sufficient 1561 ::std::copy( 1562 aDefaultControlPropertyPos + 1, 1563 m_aValues.end(), 1564 aDefaultControlPropertyPos 1565 ); 1566 m_aValues.resize( m_aValues.size() - 1 ); 1567 } 1568 } 1569 } 1570 1571 //--------------------------------------------------------------------- EndElement()1572 void OTextLikeImport::EndElement() 1573 { 1574 removeRedundantCurrentValue(); 1575 adjustDefaultControlProperty(); 1576 1577 // let the base class do the stuff 1578 OControlImport::EndElement(); 1579 1580 // some cleanups 1581 UniReference < XMLTextImportHelper > xTextImportHelper( m_rContext.getGlobalContext().GetTextImport() ); 1582 if ( m_xCursor.is() ) 1583 { 1584 // delete the newline which has been imported errornously 1585 // TODO (fs): stole this code somewhere - why don't we fix the text import?? 1586 m_xCursor->gotoEnd( sal_False ); 1587 m_xCursor->goLeft( 1, sal_True ); 1588 m_xCursor->setString( ::rtl::OUString() ); 1589 1590 // reset cursor 1591 xTextImportHelper->ResetCursor(); 1592 } 1593 1594 if ( m_xOldCursor.is() ) 1595 xTextImportHelper->SetCursor( m_xOldCursor ); 1596 1597 } 1598 1599 //===================================================================== 1600 //= OListAndComboImport 1601 //===================================================================== 1602 //--------------------------------------------------------------------- OListAndComboImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer,OControlElement::ElementType _eType)1603 OListAndComboImport::OListAndComboImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1604 const Reference< XNameContainer >& _rxParentContainer, 1605 OControlElement::ElementType _eType) 1606 :OControlImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType) 1607 ,m_nEmptyListItems( 0 ) 1608 ,m_nEmptyValueItems( 0 ) 1609 ,m_bEncounteredLSAttrib( sal_False ) 1610 ,m_bLinkWithIndexes( sal_False ) 1611 { 1612 if (OControlElement::COMBOBOX == m_eElementType) 1613 enableTrackAttributes(); 1614 } 1615 1616 //--------------------------------------------------------------------- CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> & _rxAttrList)1617 SvXMLImportContext* OListAndComboImport::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 1618 const Reference< sax::XAttributeList >& _rxAttrList) 1619 { 1620 // is it the "option" sub tag of a listbox ? 1621 static const ::rtl::OUString s_sOptionElementName = ::rtl::OUString::createFromAscii("option"); 1622 if (s_sOptionElementName == _rLocalName) 1623 return new OListOptionImport(GetImport(), _nPrefix, _rLocalName, this); 1624 1625 // is it the "item" sub tag of a combobox ? 1626 static const ::rtl::OUString s_sItemElementName = ::rtl::OUString::createFromAscii("item"); 1627 if (s_sItemElementName == _rLocalName) 1628 return new OComboItemImport(GetImport(), _nPrefix, _rLocalName, this); 1629 1630 // everything else 1631 return OControlImport::CreateChildContext(_nPrefix, _rLocalName, _rxAttrList); 1632 } 1633 1634 //--------------------------------------------------------------------- StartElement(const Reference<sax::XAttributeList> & _rxAttrList)1635 void OListAndComboImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1636 { 1637 m_bLinkWithIndexes = sal_False; 1638 1639 OControlImport::StartElement(_rxAttrList); 1640 1641 if (OControlElement::COMBOBOX == m_eElementType) 1642 { 1643 // for the auto-completion 1644 // the attribute default does not equal the property default, so in case we did not read this attribute, 1645 // we have to simulate it 1646 simulateDefaultedAttribute( OAttributeMetaData::getSpecialAttributeName( SCA_AUTOMATIC_COMPLETION ), PROPERTY_AUTOCOMPLETE, "false"); 1647 1648 // same for the convert-empty-to-null attribute, which's default is different from the property default 1649 simulateDefaultedAttribute( OAttributeMetaData::getDatabaseAttributeName( DA_CONVERT_EMPTY ), PROPERTY_EMPTY_IS_NULL, "false"); 1650 } 1651 } 1652 1653 //--------------------------------------------------------------------- EndElement()1654 void OListAndComboImport::EndElement() 1655 { 1656 // append the list source property the the properties sequence of our importer 1657 // the string item list 1658 PropertyValue aItemList; 1659 aItemList.Name = PROPERTY_STRING_ITEM_LIST; 1660 aItemList.Value <<= m_aListSource; 1661 implPushBackPropertyValue(aItemList); 1662 1663 if (OControlElement::LISTBOX == m_eElementType) 1664 { 1665 OSL_ENSURE((m_aListSource.getLength() + m_nEmptyListItems) == (m_aValueList.getLength() + m_nEmptyValueItems), 1666 "OListAndComboImport::EndElement: inconsistence between labels and values!"); 1667 1668 if ( !m_bEncounteredLSAttrib ) 1669 { 1670 // the value sequence 1671 PropertyValue aValueList; 1672 aValueList.Name = PROPERTY_LISTSOURCE; 1673 aValueList.Value <<= m_aValueList; 1674 implPushBackPropertyValue(aValueList); 1675 } 1676 1677 // the select sequence 1678 PropertyValue aSelected; 1679 aSelected.Name = PROPERTY_SELECT_SEQ; 1680 aSelected.Value <<= m_aSelectedSeq; 1681 implPushBackPropertyValue(aSelected); 1682 1683 // the default select sequence 1684 PropertyValue aDefaultSelected; 1685 aDefaultSelected.Name = PROPERTY_DEFAULT_SELECT_SEQ; 1686 aDefaultSelected.Value <<= m_aDefaultSelectedSeq; 1687 implPushBackPropertyValue(aDefaultSelected); 1688 } 1689 1690 OControlImport::EndElement(); 1691 1692 // the external list source, if applicable 1693 if ( m_xElement.is() && m_sCellListSource.getLength() ) 1694 m_rContext.registerCellRangeListSource( m_xElement, m_sCellListSource ); 1695 } 1696 1697 //--------------------------------------------------------------------- doRegisterCellValueBinding(const::rtl::OUString & _rBoundCellAddress)1698 void OListAndComboImport::doRegisterCellValueBinding( const ::rtl::OUString& _rBoundCellAddress ) 1699 { 1700 ::rtl::OUString sBoundCellAddress( _rBoundCellAddress ); 1701 if ( m_bLinkWithIndexes ) 1702 { 1703 // This is a HACK. We register a string which is no valid address, but allows 1704 // (somewhere else) to determine that a non-standard binding should be created. 1705 // This hack is acceptable for OOo 1.1.1, since the file format for value 1706 // bindings of form controls is to be changed afterwards, anyway. 1707 sBoundCellAddress += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":index" ) ); 1708 } 1709 1710 OControlImport::doRegisterCellValueBinding( sBoundCellAddress ); 1711 } 1712 1713 //--------------------------------------------------------------------- handleAttribute(sal_uInt16 _nNamespaceKey,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)1714 bool OListAndComboImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 1715 { 1716 static const sal_Char* pListSourceAttributeName = OAttributeMetaData::getDatabaseAttributeName(DA_LIST_SOURCE); 1717 if ( _rLocalName.equalsAscii(pListSourceAttributeName) ) 1718 { 1719 PropertyValue aListSource; 1720 aListSource.Name = PROPERTY_LISTSOURCE; 1721 1722 // it's the ListSource attribute 1723 m_bEncounteredLSAttrib = sal_True; 1724 if ( OControlElement::COMBOBOX == m_eElementType ) 1725 { 1726 aListSource.Value <<= _rValue; 1727 } 1728 else 1729 { 1730 // a listbox which has a list-source attribute must have a list-source-type of something 1731 // not equal to ValueList. 1732 // In this case, the list-source value is simply the one and only element of the ListSource property. 1733 Sequence< ::rtl::OUString > aListSourcePropValue( 1 ); 1734 aListSourcePropValue[0] = _rValue; 1735 aListSource.Value <<= aListSourcePropValue; 1736 } 1737 1738 implPushBackPropertyValue( aListSource ); 1739 return true; 1740 } 1741 1742 if ( _rLocalName.equalsAscii( OAttributeMetaData::getBindingAttributeName( BA_LIST_CELL_RANGE ) ) ) 1743 { 1744 m_sCellListSource = _rValue; 1745 return true; 1746 } 1747 1748 if ( _rLocalName.equalsAscii( OAttributeMetaData::getBindingAttributeName( BA_LIST_LINKING_TYPE ) ) ) 1749 { 1750 sal_Int16 nLinkageType = 0; 1751 PropertyConversion::convertString( 1752 m_rContext.getGlobalContext(), 1753 ::getCppuType( static_cast< sal_Int16* >( NULL ) ), 1754 _rValue, 1755 OEnumMapper::getEnumMap( OEnumMapper::epListLinkageType ) 1756 ) >>= nLinkageType; 1757 1758 m_bLinkWithIndexes = ( nLinkageType != 0 ); 1759 return true; 1760 } 1761 1762 return OControlImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); 1763 } 1764 1765 //--------------------------------------------------------------------- implPushBackLabel(const::rtl::OUString & _rLabel)1766 void OListAndComboImport::implPushBackLabel(const ::rtl::OUString& _rLabel) 1767 { 1768 OSL_ENSURE(!m_nEmptyListItems, "OListAndComboImport::implPushBackValue: label list is already done!"); 1769 if (!m_nEmptyListItems) 1770 pushBackSequenceElement(m_aListSource, _rLabel); 1771 } 1772 1773 //--------------------------------------------------------------------- implPushBackValue(const::rtl::OUString & _rValue)1774 void OListAndComboImport::implPushBackValue(const ::rtl::OUString& _rValue) 1775 { 1776 OSL_ENSURE(!m_nEmptyValueItems, "OListAndComboImport::implPushBackValue: value list is already done!"); 1777 if (!m_nEmptyValueItems) 1778 { 1779 OSL_ENSURE( !m_bEncounteredLSAttrib, "OListAndComboImport::implPushBackValue: invalid structure! Did you save this document with a version prior SRC641 m?" ); 1780 // We already had the list-source attribute, which means that the ListSourceType is 1781 // not ValueList, which means that the ListSource should contain only one string in 1782 // the first element of the sequence 1783 // All other values in the file are invalid 1784 1785 pushBackSequenceElement( m_aValueList, _rValue ); 1786 } 1787 } 1788 1789 //--------------------------------------------------------------------- implEmptyLabelFound()1790 void OListAndComboImport::implEmptyLabelFound() 1791 { 1792 ++m_nEmptyListItems; 1793 } 1794 1795 //--------------------------------------------------------------------- implEmptyValueFound()1796 void OListAndComboImport::implEmptyValueFound() 1797 { 1798 ++m_nEmptyValueItems; 1799 } 1800 1801 //--------------------------------------------------------------------- implSelectCurrentItem()1802 void OListAndComboImport::implSelectCurrentItem() 1803 { 1804 OSL_ENSURE((m_aListSource.getLength() + m_nEmptyListItems) == (m_aValueList.getLength() + m_nEmptyValueItems), 1805 "OListAndComboImport::implSelectCurrentItem: inconsistence between labels and values!"); 1806 1807 sal_Int16 nItemNumber = (sal_Int16)(m_aListSource.getLength() - 1 + m_nEmptyListItems); 1808 pushBackSequenceElement(m_aSelectedSeq, nItemNumber); 1809 } 1810 1811 //--------------------------------------------------------------------- implDefaultSelectCurrentItem()1812 void OListAndComboImport::implDefaultSelectCurrentItem() 1813 { 1814 OSL_ENSURE((m_aListSource.getLength() + m_nEmptyListItems) == (m_aValueList.getLength() + m_nEmptyValueItems), 1815 "OListAndComboImport::implDefaultSelectCurrentItem: inconsistence between labels and values!"); 1816 1817 sal_Int16 nItemNumber = (sal_Int16)(m_aListSource.getLength() - 1 + m_nEmptyListItems); 1818 pushBackSequenceElement(m_aDefaultSelectedSeq, nItemNumber); 1819 } 1820 1821 //===================================================================== 1822 //= OListOptionImport 1823 //===================================================================== 1824 //--------------------------------------------------------------------- OListOptionImport(SvXMLImport & _rImport,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const OListAndComboImportRef & _rListBox)1825 OListOptionImport::OListOptionImport(SvXMLImport& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1826 const OListAndComboImportRef& _rListBox) 1827 :SvXMLImportContext(_rImport, _nPrefix, _rName) 1828 ,m_xListBoxImport(_rListBox) 1829 { 1830 } 1831 1832 //--------------------------------------------------------------------- StartElement(const Reference<sax::XAttributeList> & _rxAttrList)1833 void OListOptionImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1834 { 1835 // the label and the value 1836 const SvXMLNamespaceMap& rMap = GetImport().GetNamespaceMap(); 1837 const ::rtl::OUString sLabelAttribute = rMap.GetQNameByKey( 1838 GetPrefix(), ::rtl::OUString::createFromAscii("label")); 1839 const ::rtl::OUString sValueAttribute = rMap.GetQNameByKey( 1840 GetPrefix(), ::rtl::OUString::createFromAscii("value")); 1841 1842 // ------------------- 1843 // the label attribute 1844 ::rtl::OUString sValue = _rxAttrList->getValueByName(sLabelAttribute); 1845 sal_Bool bNonexistentAttribute = sal_False; 1846 if (!sValue.getLength()) 1847 if (0 == _rxAttrList->getTypeByName(sLabelAttribute).getLength()) 1848 // this attribute does not really exist 1849 bNonexistentAttribute = sal_True; 1850 1851 if (bNonexistentAttribute) 1852 m_xListBoxImport->implEmptyLabelFound(); 1853 else 1854 m_xListBoxImport->implPushBackLabel( sValue ); 1855 1856 // ------------------- 1857 // the value attribute 1858 sValue = _rxAttrList->getValueByName(sValueAttribute); 1859 bNonexistentAttribute = sal_False; 1860 if (!sValue.getLength()) 1861 if (0 == _rxAttrList->getTypeByName(sValueAttribute).getLength()) 1862 // this attribute does not really exist 1863 bNonexistentAttribute = sal_True; 1864 1865 if (bNonexistentAttribute) 1866 m_xListBoxImport->implEmptyValueFound(); 1867 else 1868 m_xListBoxImport->implPushBackValue( sValue ); 1869 1870 // the current-selected and selected 1871 const ::rtl::OUString sSelectedAttribute = rMap.GetQNameByKey( 1872 GetPrefix(), ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_SELECTED))); 1873 const ::rtl::OUString sDefaultSelectedAttribute = rMap.GetQNameByKey( 1874 GetPrefix(), ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_SELECTED))); 1875 1876 // propagate the selected flag 1877 sal_Bool bSelected; 1878 GetImport().GetMM100UnitConverter().convertBool(bSelected, _rxAttrList->getValueByName(sSelectedAttribute)); 1879 if (bSelected) 1880 m_xListBoxImport->implSelectCurrentItem(); 1881 1882 // same for the default selected 1883 sal_Bool bDefaultSelected; 1884 GetImport().GetMM100UnitConverter().convertBool(bDefaultSelected, _rxAttrList->getValueByName(sDefaultSelectedAttribute)); 1885 if (bDefaultSelected) 1886 m_xListBoxImport->implDefaultSelectCurrentItem(); 1887 1888 SvXMLImportContext::StartElement(_rxAttrList); 1889 } 1890 1891 //===================================================================== 1892 //= OComboItemImport 1893 //===================================================================== 1894 //--------------------------------------------------------------------- OComboItemImport(SvXMLImport & _rImport,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const OListAndComboImportRef & _rListBox)1895 OComboItemImport::OComboItemImport(SvXMLImport& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1896 const OListAndComboImportRef& _rListBox) 1897 :SvXMLImportContext(_rImport, _nPrefix, _rName) 1898 ,m_xListBoxImport(_rListBox) 1899 { 1900 } 1901 1902 //--------------------------------------------------------------------- StartElement(const Reference<sax::XAttributeList> & _rxAttrList)1903 void OComboItemImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1904 { 1905 const ::rtl::OUString sLabelAttributeName = GetImport().GetNamespaceMap().GetQNameByKey( 1906 GetPrefix(), ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL))); 1907 m_xListBoxImport->implPushBackLabel(_rxAttrList->getValueByName(sLabelAttributeName)); 1908 1909 SvXMLImportContext::StartElement(_rxAttrList); 1910 } 1911 1912 1913 //===================================================================== 1914 //= OColumnWrapperImport 1915 //===================================================================== 1916 //--------------------------------------------------------------------- OColumnWrapperImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer)1917 OColumnWrapperImport::OColumnWrapperImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1918 const Reference< XNameContainer >& _rxParentContainer) 1919 :SvXMLImportContext(_rImport.getGlobalContext(), _nPrefix, _rName) 1920 ,m_xParentContainer(_rxParentContainer) 1921 ,m_rFormImport(_rImport) 1922 ,m_rEventManager(_rEventManager) 1923 { 1924 } 1925 //--------------------------------------------------------------------- CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> &)1926 SvXMLImportContext* OColumnWrapperImport::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 1927 const Reference< sax::XAttributeList >&) 1928 { 1929 OControlImport* pReturn = implCreateChildContext(_nPrefix, _rLocalName, OElementNameMap::getElementType(_rLocalName)); 1930 if (pReturn) 1931 { 1932 OSL_ENSURE(m_xOwnAttributes.is(), "OColumnWrapperImport::CreateChildContext: had no form:column element!"); 1933 pReturn->addOuterAttributes(m_xOwnAttributes); 1934 } 1935 return pReturn; 1936 } 1937 //--------------------------------------------------------------------- StartElement(const Reference<sax::XAttributeList> & _rxAttrList)1938 void OColumnWrapperImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1939 { 1940 OSL_ENSURE(!m_xOwnAttributes.is(), "OColumnWrapperImport::StartElement: aready have the cloned list!"); 1941 1942 // clone the attributes 1943 Reference< XCloneable > xCloneList(_rxAttrList, UNO_QUERY); 1944 OSL_ENSURE(xCloneList.is(), "OColumnWrapperImport::StartElement: AttributeList not cloneable!"); 1945 if ( xCloneList.is() ) 1946 m_xOwnAttributes = Reference< sax::XAttributeList >(xCloneList->createClone(), UNO_QUERY); 1947 OSL_ENSURE(m_xOwnAttributes.is(), "OColumnWrapperImport::StartElement: no cloned list!"); 1948 } 1949 1950 //--------------------------------------------------------------------- implCreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,OControlElement::ElementType _eType)1951 OControlImport* OColumnWrapperImport::implCreateChildContext( 1952 sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 1953 OControlElement::ElementType _eType) 1954 { 1955 OSL_ENSURE( (OControlElement::TEXT == _eType) 1956 || (OControlElement::TEXT_AREA == _eType) 1957 || (OControlElement::FORMATTED_TEXT == _eType) 1958 || (OControlElement::CHECKBOX == _eType) 1959 || (OControlElement::LISTBOX == _eType) 1960 || (OControlElement::COMBOBOX == _eType) 1961 || (OControlElement::TIME == _eType) 1962 || (OControlElement::DATE == _eType), 1963 "OColumnWrapperImport::implCreateChildContext: invalid or unrecognized sub element!"); 1964 1965 switch (_eType) 1966 { 1967 case OControlElement::COMBOBOX: 1968 case OControlElement::LISTBOX: 1969 return new OColumnImport<OListAndComboImport>(m_rFormImport, m_rEventManager, _nPrefix, _rLocalName, m_xParentContainer, _eType ); 1970 1971 case OControlElement::PASSWORD: 1972 return new OColumnImport<OPasswordImport>(m_rFormImport, m_rEventManager, _nPrefix, _rLocalName, m_xParentContainer, _eType ); 1973 1974 case OControlElement::TEXT: 1975 case OControlElement::TEXT_AREA: 1976 case OControlElement::FORMATTED_TEXT: 1977 return new OColumnImport< OTextLikeImport >( m_rFormImport, m_rEventManager, _nPrefix, _rLocalName, m_xParentContainer, _eType ); 1978 1979 default: 1980 return new OColumnImport<OControlImport>(m_rFormImport, m_rEventManager, _nPrefix, _rLocalName, m_xParentContainer, _eType ); 1981 } 1982 } 1983 1984 //===================================================================== 1985 //= OGridImport 1986 //===================================================================== 1987 //--------------------------------------------------------------------- OGridImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer,OControlElement::ElementType _eType)1988 OGridImport::OGridImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1989 const Reference< XNameContainer >& _rxParentContainer, 1990 OControlElement::ElementType _eType) 1991 :OGridImport_Base(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, "column") 1992 { 1993 setElementType(_eType); 1994 } 1995 1996 //--------------------------------------------------------------------- implCreateControlWrapper(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName)1997 SvXMLImportContext* OGridImport::implCreateControlWrapper(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName) 1998 { 1999 return new OColumnWrapperImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer); 2000 } 2001 2002 //===================================================================== 2003 //= OFormImport 2004 //===================================================================== 2005 //--------------------------------------------------------------------- OFormImport(OFormLayerXMLImport_Impl & _rImport,IEventAttacherManager & _rEventManager,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const Reference<XNameContainer> & _rxParentContainer)2006 OFormImport::OFormImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 2007 const Reference< XNameContainer >& _rxParentContainer) 2008 :OFormImport_Base(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, "control") 2009 { 2010 enableTrackAttributes(); 2011 } 2012 2013 //--------------------------------------------------------------------- CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> & _rxAttrList)2014 SvXMLImportContext* OFormImport::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 2015 const Reference< sax::XAttributeList >& _rxAttrList) 2016 { 2017 if( token::IsXMLToken(_rLocalName, token::XML_FORM) ) 2018 return new OFormImport( m_rFormImport, *this, _nPrefix, _rLocalName, 2019 m_xMeAsContainer); 2020 else if ( token::IsXMLToken(_rLocalName, token::XML_CONNECTION_RESOURCE) ) 2021 return new OXMLDataSourceImport(GetImport(), _nPrefix, _rLocalName, _rxAttrList,m_xElement); 2022 else if( (token::IsXMLToken(_rLocalName, token::XML_EVENT_LISTENERS) && 2023 (XML_NAMESPACE_OFFICE == _nPrefix)) || 2024 token::IsXMLToken( _rLocalName, token::XML_PROPERTIES) ) 2025 return OElementImport::CreateChildContext( _nPrefix, _rLocalName, 2026 _rxAttrList ); 2027 else 2028 return implCreateChildContext( _nPrefix, _rLocalName, 2029 OElementNameMap::getElementType(_rLocalName) ); 2030 } 2031 2032 //--------------------------------------------------------------------- StartElement(const Reference<sax::XAttributeList> & _rxAttrList)2033 void OFormImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 2034 { 2035 m_rFormImport.enterEventContext(); 2036 OFormImport_Base::StartElement(_rxAttrList); 2037 2038 // handle the target-frame attribute 2039 simulateDefaultedAttribute(OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_FRAME), PROPERTY_TARGETFRAME, "_blank"); 2040 } 2041 2042 //--------------------------------------------------------------------- EndElement()2043 void OFormImport::EndElement() 2044 { 2045 OFormImport_Base::EndElement(); 2046 m_rFormImport.leaveEventContext(); 2047 } 2048 2049 //--------------------------------------------------------------------- implCreateControlWrapper(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName)2050 SvXMLImportContext* OFormImport::implCreateControlWrapper(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName) 2051 { 2052 OSL_ENSURE( !this, "illegal call to OFormImport::implCreateControlWrapper" ); 2053 return new SvXMLImportContext(GetImport(), _nPrefix, _rLocalName ); 2054 } 2055 2056 //--------------------------------------------------------------------- handleAttribute(sal_uInt16 _nNamespaceKey,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)2057 bool OFormImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 2058 { 2059 // handle the master/details field attributes (they're way too special to let the OPropertyImport handle them) 2060 static const ::rtl::OUString s_sMasterFieldsAttributeName = ::rtl::OUString::createFromAscii(OAttributeMetaData::getFormAttributeName(faMasterFields)); 2061 static const ::rtl::OUString s_sDetailFieldsAttributeName = ::rtl::OUString::createFromAscii(OAttributeMetaData::getFormAttributeName(faDetailFiels)); 2062 2063 if ( s_sMasterFieldsAttributeName == _rLocalName ) 2064 { 2065 implTranslateStringListProperty(PROPERTY_MASTERFIELDS, _rValue); 2066 return true; 2067 } 2068 2069 if ( s_sDetailFieldsAttributeName == _rLocalName ) 2070 { 2071 implTranslateStringListProperty(PROPERTY_DETAILFIELDS, _rValue); 2072 return true; 2073 } 2074 2075 return OFormImport_Base::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); 2076 } 2077 2078 //--------------------------------------------------------------------- implTranslateStringListProperty(const::rtl::OUString & _rPropertyName,const::rtl::OUString & _rValue)2079 void OFormImport::implTranslateStringListProperty(const ::rtl::OUString& _rPropertyName, const ::rtl::OUString& _rValue) 2080 { 2081 PropertyValue aProp; 2082 aProp.Name = _rPropertyName; 2083 2084 Sequence< ::rtl::OUString > aList; 2085 2086 // split up the value string 2087 if (_rValue.getLength()) 2088 { 2089 // For the moment, we build a vector instead of a Sequence. It's easier to handle because of it's 2090 // push_back method 2091 ::std::vector< ::rtl::OUString > aElements; 2092 // estimate the number of tokens 2093 sal_Int32 nEstimate = 0, nLength = _rValue.getLength(); 2094 const sal_Unicode* pChars = _rValue.getStr(); 2095 for (sal_Int32 i=0; i<nLength; ++i, ++pChars) 2096 if (*pChars == ',') 2097 ++nEstimate; 2098 aElements.reserve(nEstimate + 1); 2099 // that's the worst case. If the string contains the separator character _quoted_, we reserved to much ... 2100 2101 2102 sal_Int32 nElementStart = 0; 2103 sal_Int32 nNextSep = 0; 2104 sal_Int32 nElementLength; 2105 ::rtl::OUString sElement; 2106 do 2107 { 2108 // extract the current element 2109 nNextSep = SvXMLUnitConverter::indexOfComma( 2110 _rValue, nElementStart); 2111 if (-1 == nNextSep) 2112 nNextSep = nLength; 2113 sElement = _rValue.copy(nElementStart, nNextSep - nElementStart); 2114 2115 nElementLength = sElement.getLength(); 2116 // when writing the sequence, we quoted the single elements with " characters 2117 OSL_ENSURE( (nElementLength >= 2) 2118 && (sElement.getStr()[0] == '"') 2119 && (sElement.getStr()[nElementLength - 1] == '"'), 2120 "OFormImport::implTranslateStringListProperty: invalid quoted element name."); 2121 sElement = sElement.copy(1, nElementLength - 2); 2122 2123 aElements.push_back(sElement); 2124 2125 // swith to the next element 2126 nElementStart = 1 + nNextSep; 2127 } 2128 while (nElementStart < nLength); 2129 2130 ::rtl::OUString *pElements = aElements.empty() ? 0 : &aElements[0]; 2131 aList = Sequence< ::rtl::OUString >(pElements, aElements.size()); 2132 } 2133 else 2134 { 2135 OSL_ENSURE(sal_False, "OFormImport::implTranslateStringListProperty: invalid value (empty)!"); 2136 } 2137 2138 aProp.Value <<= aList; 2139 2140 // add the property to the base class' array 2141 implPushBackPropertyValue(aProp); 2142 } 2143 //===================================================================== 2144 //= OXMLDataSourceImport 2145 //===================================================================== OXMLDataSourceImport(SvXMLImport & _rImport,sal_uInt16 nPrfx,const::rtl::OUString & _sLocalName,const Reference<::com::sun::star::xml::sax::XAttributeList> & _xAttrList,const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & _xElement)2146 OXMLDataSourceImport::OXMLDataSourceImport( 2147 SvXMLImport& _rImport 2148 ,sal_uInt16 nPrfx 2149 , const ::rtl::OUString& _sLocalName 2150 ,const Reference< ::com::sun::star::xml::sax::XAttributeList > & _xAttrList 2151 ,const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _xElement) : 2152 SvXMLImportContext( _rImport, nPrfx, _sLocalName ) 2153 { 2154 OSL_ENSURE(_xAttrList.is(),"Attribute list is NULL!"); 2155 const SvXMLNamespaceMap& rMap = _rImport.GetNamespaceMap(); 2156 2157 sal_Int16 nLength = (_xElement.is() && _xAttrList.is()) ? _xAttrList->getLength() : 0; 2158 for(sal_Int16 i = 0; i < nLength; ++i) 2159 { 2160 ::rtl::OUString sLocalName; 2161 ::rtl::OUString sAttrName = _xAttrList->getNameByIndex( i ); 2162 sal_uInt16 nPrefix = rMap.GetKeyByAttrName( sAttrName, &sLocalName ); 2163 2164 if ( ( nPrefix == OAttributeMetaData::getCommonControlAttributeNamespace( CCA_TARGET_LOCATION ) ) 2165 && ( sLocalName.equalsAscii( OAttributeMetaData::getCommonControlAttributeName( CCA_TARGET_LOCATION ) ) ) 2166 ) 2167 { 2168 ::rtl::OUString sValue = _xAttrList->getValueByIndex( i ); 2169 2170 INetURLObject aURL(sValue); 2171 if ( aURL.GetProtocol() == INET_PROT_FILE ) 2172 _xElement->setPropertyValue(PROPERTY_DATASOURCENAME,makeAny(sValue)); 2173 else 2174 _xElement->setPropertyValue(PROPERTY_URL,makeAny(sValue)); // the url is the "sdbc:" string 2175 break; 2176 } 2177 } 2178 } 2179 //--------------------------------------------------------------------- implCreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,OControlElement::ElementType _eType)2180 OControlImport* OFormImport::implCreateChildContext( 2181 sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 2182 OControlElement::ElementType _eType ) 2183 { 2184 switch (_eType) 2185 { 2186 case OControlElement::TEXT: 2187 case OControlElement::TEXT_AREA: 2188 case OControlElement::FORMATTED_TEXT: 2189 return new OTextLikeImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2190 2191 case OControlElement::BUTTON: 2192 case OControlElement::IMAGE: 2193 case OControlElement::IMAGE_FRAME: 2194 return new OButtonImport( m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType ); 2195 2196 case OControlElement::COMBOBOX: 2197 case OControlElement::LISTBOX: 2198 return new OListAndComboImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2199 2200 case OControlElement::RADIO: 2201 return new ORadioImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2202 2203 case OControlElement::CHECKBOX: 2204 return new OImagePositionImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2205 2206 case OControlElement::PASSWORD: 2207 return new OPasswordImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2208 2209 case OControlElement::FRAME: 2210 case OControlElement::FIXED_TEXT: 2211 return new OReferredControlImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2212 2213 case OControlElement::GRID: 2214 return new OGridImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2215 2216 case OControlElement::VALUERANGE: 2217 return new OValueRangeImport( m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType ); 2218 2219 default: 2220 return new OControlImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2221 } 2222 } 2223 2224 //......................................................................... 2225 } // namespace xmloff 2226 //......................................................................... 2227 2228