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 { 90 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 { 99 bool operator() (const PropertyValue& lhs, const ::rtl::OUString& rhs) const 100 { 101 return lhs.Name == rhs; 102 } 103 bool operator() (const ::rtl::OUString& lhs, const PropertyValue& rhs) const 104 { 105 return lhs == rhs.Name; 106 } 107 }; 108 109 //===================================================================== 110 template <class ELEMENT> 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 165 OElementImport::~OElementImport() 166 { 167 } 168 169 //--------------------------------------------------------------------- 170 ::rtl::OUString OElementImport::determineDefaultServiceName() const 171 { 172 return ::rtl::OUString(); 173 } 174 175 //--------------------------------------------------------------------- 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 m_sServiceName = 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 487 ::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 //--------------------------------------------------------------------- 520 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 694 ::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::VALUERANGE: pServiceName = "com.sun.star.form.component.ScrollBar"; break; 716 case OControlElement::TIME: pServiceName = "com.sun.star.form.component.DateField"; break; 717 case OControlElement::DATE: pServiceName = "com.sun.star.form.component.TimeField"; break; 718 default: break; 719 } 720 if ( pServiceName != NULL ) 721 return ::rtl::OUString::createFromAscii( pServiceName ); 722 return ::rtl::OUString(); 723 } 724 725 //--------------------------------------------------------------------- 726 void OControlImport::addOuterAttributes(const Reference< sax::XAttributeList >& _rxOuterAttribs) 727 { 728 OSL_ENSURE(!m_xOuterAttributes.is(), "OControlImport::addOuterAttributes: already have these attributes!"); 729 m_xOuterAttributes = _rxOuterAttribs; 730 } 731 732 //--------------------------------------------------------------------- 733 bool OControlImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 734 { 735 static const sal_Char* pLinkedCellAttributeName = OAttributeMetaData::getBindingAttributeName(BA_LINKED_CELL); 736 737 if (IsXMLToken(_rLocalName, XML_ID)) 738 { // it's the control id 739 if (XML_NAMESPACE_XML == _nNamespaceKey) 740 { 741 m_sControlId = _rValue; 742 } 743 else if (XML_NAMESPACE_FORM == _nNamespaceKey) 744 { 745 if (!m_sControlId.getLength()) 746 { 747 m_sControlId = _rValue; 748 } 749 } 750 return true; 751 } 752 753 if ( _rLocalName.equalsAscii( pLinkedCellAttributeName ) ) 754 { // it's the address of a spreadsheet cell 755 m_sBoundCellAddress = _rValue; 756 return true; 757 } 758 759 if ( _nNamespaceKey == XML_NAMESPACE_XFORMS && IsXMLToken( _rLocalName, XML_BIND ) ) 760 { 761 m_sBindingID = _rValue; 762 return true; 763 } 764 765 if ( _nNamespaceKey == XML_NAMESPACE_FORM && IsXMLToken( _rLocalName, XML_XFORMS_LIST_SOURCE ) ) 766 { 767 m_sListBindingID = _rValue; 768 return true; 769 } 770 771 if ( ( ( _nNamespaceKey == XML_NAMESPACE_FORM ) 772 && IsXMLToken( _rLocalName, XML_XFORMS_SUBMISSION ) 773 ) 774 || ( ( _nNamespaceKey == XML_NAMESPACE_XFORMS ) 775 && IsXMLToken( _rLocalName, XML_SUBMISSION ) 776 ) 777 ) 778 { 779 m_sSubmissionID = _rValue; 780 return true; 781 } 782 783 if ( OElementImport::tryGenericAttribute( _nNamespaceKey, _rLocalName, _rValue ) ) 784 return true; 785 786 static const sal_Char* pValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_VALUE); 787 static const sal_Char* pCurrentValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_VALUE); 788 static const sal_Char* pMinValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MIN_VALUE); 789 static const sal_Char* pMaxValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MAX_VALUE); 790 static const sal_Char* pRepeatDelayAttributeName = OAttributeMetaData::getSpecialAttributeName( SCA_REPEAT_DELAY ); 791 792 sal_Int32 nHandle = -1; 793 if ( _rLocalName.equalsAscii( pValueAttributeName ) ) 794 nHandle = PROPID_VALUE; 795 else if ( _rLocalName.equalsAscii( pCurrentValueAttributeName ) ) 796 nHandle = PROPID_CURRENT_VALUE; 797 else if ( _rLocalName.equalsAscii( pMinValueAttributeName ) ) 798 nHandle = PROPID_MIN_VALUE; 799 else if ( _rLocalName.equalsAscii( pMaxValueAttributeName ) ) 800 nHandle = PROPID_MAX_VALUE; 801 if ( nHandle != -1 ) 802 { 803 // for the moment, simply remember the name and the value 804 PropertyValue aProp; 805 aProp.Name = _rLocalName; 806 aProp.Handle = nHandle; 807 aProp.Value <<= _rValue; 808 m_aValueProperties.push_back(aProp); 809 return true; 810 } 811 812 if ( _rLocalName.equalsAscii( pRepeatDelayAttributeName ) ) 813 { 814 ::Time aTime; 815 sal_Int32 nFractions = 0; 816 if ( SvXMLUnitConverter::convertTimeDuration( _rValue, aTime, &nFractions ) ) 817 { 818 PropertyValue aProp; 819 aProp.Name = PROPERTY_REPEAT_DELAY; 820 aProp.Value <<= (sal_Int32)( ( ( aTime.GetMSFromTime() / 1000 ) * 1000 ) + nFractions ); 821 822 implPushBackPropertyValue(aProp); 823 } 824 return true; 825 } 826 827 return OElementImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); 828 } 829 830 //--------------------------------------------------------------------- 831 void OControlImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 832 { 833 ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > xAttributes; 834 if( m_xOuterAttributes.is() ) 835 { 836 // merge the attribute lists 837 OAttribListMerger* pMerger = new OAttribListMerger; 838 // our own one 839 pMerger->addList(_rxAttrList); 840 // and the ones of our enclosing element 841 pMerger->addList(m_xOuterAttributes); 842 xAttributes = pMerger; 843 } 844 else 845 { 846 xAttributes = _rxAttrList; 847 } 848 849 // let the base class handle all the attributes 850 OElementImport::StartElement(xAttributes); 851 852 if ( !m_aValueProperties.empty() && m_xElement.is()) 853 { 854 // get the property set info 855 if (!m_xInfo.is()) 856 { 857 OSL_ENSURE(sal_False, "OControlImport::StartElement: no PropertySetInfo!"); 858 return; 859 } 860 861 const sal_Char* pValueProperty = NULL; 862 const sal_Char* pCurrentValueProperty = NULL; 863 const sal_Char* pMinValueProperty = NULL; 864 const sal_Char* pMaxValueProperty = NULL; 865 866 sal_Bool bRetrievedValues = sal_False; 867 sal_Bool bRetrievedValueLimits = sal_False; 868 869 // get the class id of our element 870 sal_Int16 nClassId = FormComponentType::CONTROL; 871 m_xElement->getPropertyValue(PROPERTY_CLASSID) >>= nClassId; 872 873 // translate the value properties we collected in handleAttributes 874 PropertyValueArray::iterator aEnd = m_aValueProperties.end(); 875 for ( PropertyValueArray::iterator aValueProps = m_aValueProperties.begin(); 876 aValueProps != aEnd; 877 ++aValueProps 878 ) 879 { 880 bool bSuccess = false; 881 switch (aValueProps->Handle) 882 { 883 case PROPID_VALUE: 884 case PROPID_CURRENT_VALUE: 885 { 886 // get the property names 887 if (!bRetrievedValues) 888 { 889 getValuePropertyNames(m_eElementType, nClassId, pCurrentValueProperty, pValueProperty); 890 ENSURE_OR_BREAK( pValueProperty, "OControlImport::StartElement: illegal value property names!" ); 891 bRetrievedValues = sal_True; 892 } 893 ENSURE_OR_BREAK((PROPID_VALUE != aValueProps->Handle) || pValueProperty, 894 "OControlImport::StartElement: the control does not have a value property!"); 895 ENSURE_OR_BREAK((PROPID_CURRENT_VALUE != aValueProps->Handle) || pCurrentValueProperty, 896 "OControlImport::StartElement: the control does not have a current-value property!"); 897 898 // transfer the name 899 if (PROPID_VALUE == aValueProps->Handle) 900 aValueProps->Name = ::rtl::OUString::createFromAscii(pValueProperty); 901 else 902 aValueProps->Name = ::rtl::OUString::createFromAscii(pCurrentValueProperty); 903 bSuccess = true; 904 } 905 break; 906 case PROPID_MIN_VALUE: 907 case PROPID_MAX_VALUE: 908 { 909 // get the property names 910 if (!bRetrievedValueLimits) 911 { 912 getValueLimitPropertyNames(nClassId, pMinValueProperty, pMaxValueProperty); 913 ENSURE_OR_BREAK( pMinValueProperty && pMaxValueProperty, "OControlImport::StartElement: illegal value limit property names!" ); 914 bRetrievedValueLimits = sal_True; 915 } 916 OSL_ENSURE((PROPID_MIN_VALUE != aValueProps->Handle) || pMinValueProperty, 917 "OControlImport::StartElement: the control does not have a value property!"); 918 OSL_ENSURE((PROPID_MAX_VALUE != aValueProps->Handle) || pMaxValueProperty, 919 "OControlImport::StartElement: the control does not have a current-value property!"); 920 921 // transfer the name 922 if (PROPID_MIN_VALUE == aValueProps->Handle) 923 aValueProps->Name = ::rtl::OUString::createFromAscii(pMinValueProperty); 924 else 925 aValueProps->Name = ::rtl::OUString::createFromAscii(pMaxValueProperty); 926 bSuccess = true; 927 } 928 break; 929 } 930 931 if ( !bSuccess ) 932 continue; 933 934 // translate the value 935 implTranslateValueProperty(m_xInfo, *aValueProps); 936 // add the property to the base class' array 937 implPushBackPropertyValue(*aValueProps); 938 } 939 } 940 } 941 942 //--------------------------------------------------------------------- 943 void OControlImport::implTranslateValueProperty(const Reference< XPropertySetInfo >& _rxPropInfo, 944 PropertyValue& _rPropValue) 945 { 946 OSL_ENSURE(_rxPropInfo->hasPropertyByName(_rPropValue.Name), 947 "OControlImport::implTranslateValueProperty: invalid property name!"); 948 949 // retrieve the type of the property 950 Property aProp = _rxPropInfo->getPropertyByName(_rPropValue.Name); 951 // the untranslated string value as read in handleAttribute 952 ::rtl::OUString sValue; 953 #if OSL_DEBUG_LEVEL > 0 954 sal_Bool bSuccess = 955 #endif 956 _rPropValue.Value >>= sValue; 957 OSL_ENSURE(bSuccess, "OControlImport::implTranslateValueProperty: supposed to be called with non-translated string values!"); 958 959 if (TypeClass_ANY == aProp.Type.getTypeClass()) 960 { 961 // we have exactly 2 properties where this type class is allowed: 962 OSL_ENSURE( 963 (0 == _rPropValue.Name.compareToAscii(PROPERTY_EFFECTIVE_VALUE)) 964 || (0 == _rPropValue.Name.compareToAscii(PROPERTY_EFFECTIVE_DEFAULT)), 965 "OControlImport::implTranslateValueProperty: invalid property type/name combination!"); 966 967 // Both properties are allowed to have a double or a string value, 968 // so first try to convert the string into a number 969 double nValue; 970 if (GetImport().GetMM100UnitConverter().convertDouble(nValue, sValue)) 971 _rPropValue.Value <<= nValue; 972 else 973 _rPropValue.Value <<= sValue; 974 } 975 else 976 _rPropValue.Value = PropertyConversion::convertString(GetImport(), aProp.Type, sValue); 977 } 978 979 //--------------------------------------------------------------------- 980 void OControlImport::EndElement() 981 { 982 OSL_ENSURE(m_xElement.is(), "OControlImport::EndElement: invalid control!"); 983 if ( !m_xElement.is() ) 984 return; 985 986 // register our control with it's id 987 if (m_sControlId.getLength()) 988 m_rFormImport.registerControlId(m_xElement, m_sControlId); 989 // it's allowed to have no control id. In this case we're importing a column 990 991 // one more pre-work to do: 992 // when we set default values, then by definition the respective value is set 993 // to this default value, too. This means if the sequence contains for example 994 // a DefaultText value, then the Text will be affected by this, too. 995 // In case the Text is not part of the property sequence (or occurs _before_ 996 // the DefaultText, which can happen for other value/default-value property names), 997 // this means that the Text (the value property) is incorrectly imported. 998 // #102475# - 04.09.2002 - fs@openoffice.org 999 1000 sal_Bool bRestoreValuePropertyValue = sal_False; 1001 Any aValuePropertyValue; 1002 1003 sal_Int16 nClassId = FormComponentType::CONTROL; 1004 try 1005 { 1006 // get the class id of our element 1007 m_xElement->getPropertyValue(PROPERTY_CLASSID) >>= nClassId; 1008 } 1009 catch( const Exception& ) 1010 { 1011 OSL_ENSURE( sal_False, "OControlImport::EndElement: caught an exception while retrieving the class id!" ); 1012 } 1013 1014 const sal_Char* pValueProperty = NULL; 1015 const sal_Char* pDefaultValueProperty = NULL; 1016 getRuntimeValuePropertyNames(m_eElementType, nClassId, pValueProperty, pDefaultValueProperty); 1017 if ( pDefaultValueProperty && pValueProperty ) 1018 { 1019 sal_Bool bNonDefaultValuePropertyValue = sal_False; 1020 // is the "value property" part of the sequence? 1021 1022 // look up this property in our sequence 1023 PropertyValueArray::iterator aEnd = m_aValues.end(); 1024 for ( PropertyValueArray::iterator aCheck = m_aValues.begin(); 1025 ( aCheck != aEnd ); 1026 ++aCheck 1027 ) 1028 { 1029 if ( aCheck->Name.equalsAscii( pDefaultValueProperty ) ) 1030 bRestoreValuePropertyValue = sal_True; 1031 else if ( aCheck->Name.equalsAscii( pValueProperty ) ) 1032 { 1033 bNonDefaultValuePropertyValue = sal_True; 1034 // we need to restore the value property we found here, nothing else 1035 aValuePropertyValue = aCheck->Value; 1036 } 1037 } 1038 1039 if ( bRestoreValuePropertyValue && !bNonDefaultValuePropertyValue ) 1040 { 1041 // found it -> need to remember (and restore) the "value property value", which is not set explicitly 1042 try 1043 { 1044 aValuePropertyValue = m_xElement->getPropertyValue( ::rtl::OUString::createFromAscii( pValueProperty ) ); 1045 } 1046 catch( const Exception& ) 1047 { 1048 OSL_ENSURE( sal_False, "OControlImport::EndElement: caught an exception while retrieving the current value property!" ); 1049 } 1050 } 1051 } 1052 1053 // let the base class set all the values 1054 OElementImport::EndElement(); 1055 1056 // restore the "value property value", if necessary 1057 if ( bRestoreValuePropertyValue && pValueProperty ) 1058 { 1059 try 1060 { 1061 m_xElement->setPropertyValue( ::rtl::OUString::createFromAscii( pValueProperty ), aValuePropertyValue ); 1062 } 1063 catch( const Exception& ) 1064 { 1065 OSL_ENSURE( sal_False, "OControlImport::EndElement: caught an exception while restoring the value property!" ); 1066 } 1067 } 1068 1069 // the external cell binding, if applicable 1070 if ( m_xElement.is() && m_sBoundCellAddress.getLength() ) 1071 doRegisterCellValueBinding( m_sBoundCellAddress ); 1072 1073 // XForms binding, if applicable 1074 if ( m_xElement.is() && m_sBindingID.getLength() ) 1075 doRegisterXFormsValueBinding( m_sBindingID ); 1076 1077 // XForms list binding, if applicable 1078 if ( m_xElement.is() && m_sListBindingID.getLength() ) 1079 doRegisterXFormsListBinding( m_sListBindingID ); 1080 1081 // XForms submission, if applicable 1082 if ( m_xElement.is() && m_sSubmissionID.getLength() ) 1083 doRegisterXFormsSubmission( m_sSubmissionID ); 1084 } 1085 1086 //--------------------------------------------------------------------- 1087 void OControlImport::doRegisterCellValueBinding( const ::rtl::OUString& _rBoundCellAddress ) 1088 { 1089 OSL_PRECOND( m_xElement.is(), "OControlImport::doRegisterCellValueBinding: invalid element!" ); 1090 OSL_PRECOND( _rBoundCellAddress.getLength(), 1091 "OControlImport::doRegisterCellValueBinding: invalid address!" ); 1092 1093 m_rContext.registerCellValueBinding( m_xElement, _rBoundCellAddress ); 1094 } 1095 1096 //--------------------------------------------------------------------- 1097 void OControlImport::doRegisterXFormsValueBinding( const ::rtl::OUString& _rBindingID ) 1098 { 1099 OSL_PRECOND( m_xElement.is(), "need element" ); 1100 OSL_PRECOND( _rBindingID.getLength() > 0, "binding ID is not valid" ); 1101 1102 m_rContext.registerXFormsValueBinding( m_xElement, _rBindingID ); 1103 } 1104 1105 //--------------------------------------------------------------------- 1106 void OControlImport::doRegisterXFormsListBinding( const ::rtl::OUString& _rBindingID ) 1107 { 1108 OSL_PRECOND( m_xElement.is(), "need element" ); 1109 OSL_PRECOND( _rBindingID.getLength() > 0, "binding ID is not valid" ); 1110 1111 m_rContext.registerXFormsListBinding( m_xElement, _rBindingID ); 1112 } 1113 1114 //--------------------------------------------------------------------- 1115 void OControlImport::doRegisterXFormsSubmission( const ::rtl::OUString& _rSubmissionID ) 1116 { 1117 OSL_PRECOND( m_xElement.is(), "need element" ); 1118 OSL_PRECOND( _rSubmissionID.getLength() > 0, "binding ID is not valid" ); 1119 1120 m_rContext.registerXFormsSubmission( m_xElement, _rSubmissionID ); 1121 } 1122 1123 //--------------------------------------------------------------------- 1124 //added by BerryJia for fixing bug102407 2002-11-5 1125 Reference< XPropertySet > OControlImport::createElement() 1126 { 1127 const Reference<XPropertySet> xPropSet = OElementImport::createElement(); 1128 if ( xPropSet.is() ) 1129 { 1130 m_xInfo = xPropSet->getPropertySetInfo(); 1131 if ( m_xInfo.is() && m_xInfo->hasPropertyByName(PROPERTY_ALIGN) ) 1132 { 1133 Any aValue; 1134 xPropSet->setPropertyValue(PROPERTY_ALIGN,aValue); 1135 } 1136 } 1137 return xPropSet; 1138 } 1139 1140 //===================================================================== 1141 //= OImagePositionImport 1142 //===================================================================== 1143 //--------------------------------------------------------------------- 1144 OImagePositionImport::OImagePositionImport( OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, 1145 sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, const Reference< XNameContainer >& _rxParentContainer, 1146 OControlElement::ElementType _eType ) 1147 :OControlImport( _rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType ) 1148 ,m_nImagePosition( -1 ) 1149 ,m_nImageAlign( 0 ) 1150 ,m_bHaveImagePosition( sal_False ) 1151 { 1152 } 1153 1154 //--------------------------------------------------------------------- 1155 bool OImagePositionImport::handleAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, 1156 const ::rtl::OUString& _rValue ) 1157 { 1158 if ( _rLocalName == GetXMLToken( XML_IMAGE_POSITION ) ) 1159 { 1160 OSL_VERIFY( PropertyConversion::convertString( 1161 m_rContext.getGlobalContext(), ::getCppuType( &m_nImagePosition ), 1162 _rValue, OEnumMapper::getEnumMap( OEnumMapper::epImagePosition ) 1163 ) >>= m_nImagePosition ); 1164 m_bHaveImagePosition = sal_True; 1165 return true; 1166 } 1167 1168 if ( _rLocalName == GetXMLToken( XML_IMAGE_ALIGN ) ) 1169 { 1170 OSL_VERIFY( PropertyConversion::convertString( 1171 m_rContext.getGlobalContext(), ::getCppuType( &m_nImageAlign ), 1172 _rValue, OEnumMapper::getEnumMap( OEnumMapper::epImageAlign ) 1173 ) >>= m_nImageAlign ); 1174 return true; 1175 } 1176 1177 return OControlImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); 1178 } 1179 1180 //--------------------------------------------------------------------- 1181 void OImagePositionImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1182 { 1183 OControlImport::StartElement( _rxAttrList ); 1184 1185 if ( m_bHaveImagePosition ) 1186 { 1187 sal_Int16 nUnoImagePosition = ImagePosition::Centered; 1188 if ( m_nImagePosition >= 0 ) 1189 { 1190 OSL_ENSURE( ( m_nImagePosition <= 3 ) && ( m_nImageAlign >= 0 ) && ( m_nImageAlign < 3 ), 1191 "OImagePositionImport::StartElement: unknown image align and/or position!" ); 1192 nUnoImagePosition = m_nImagePosition * 3 + m_nImageAlign; 1193 } 1194 1195 PropertyValue aImagePosition; 1196 aImagePosition.Name = PROPERTY_IMAGE_POSITION; 1197 aImagePosition.Value <<= nUnoImagePosition; 1198 implPushBackPropertyValue( aImagePosition ); 1199 } 1200 } 1201 1202 //===================================================================== 1203 //= OReferredControlImport 1204 //===================================================================== 1205 //--------------------------------------------------------------------- 1206 OReferredControlImport::OReferredControlImport( 1207 OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1208 const Reference< XNameContainer >& _rxParentContainer, 1209 OControlElement::ElementType ) 1210 :OControlImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer) 1211 { 1212 } 1213 1214 //--------------------------------------------------------------------- 1215 void OReferredControlImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1216 { 1217 OControlImport::StartElement(_rxAttrList); 1218 1219 // the base class should have created the control, so we can register it 1220 if ( m_sReferringControls.getLength() ) 1221 m_rFormImport.registerControlReferences(m_xElement, m_sReferringControls); 1222 } 1223 1224 //--------------------------------------------------------------------- 1225 bool OReferredControlImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, 1226 const ::rtl::OUString& _rValue) 1227 { 1228 static const ::rtl::OUString s_sReferenceAttributeName = ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_FOR)); 1229 if (_rLocalName == s_sReferenceAttributeName) 1230 { 1231 m_sReferringControls = _rValue; 1232 return true; 1233 } 1234 return OControlImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); 1235 } 1236 1237 //===================================================================== 1238 //= OPasswordImport 1239 //===================================================================== 1240 //--------------------------------------------------------------------- 1241 OPasswordImport::OPasswordImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1242 const Reference< XNameContainer >& _rxParentContainer, OControlElement::ElementType _eType) 1243 :OControlImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType) 1244 { 1245 } 1246 1247 //--------------------------------------------------------------------- 1248 bool OPasswordImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 1249 { 1250 static const ::rtl::OUString s_sEchoCharAttributeName = ::rtl::OUString::createFromAscii(OAttributeMetaData::getSpecialAttributeName(SCA_ECHO_CHAR)); 1251 if (_rLocalName == s_sEchoCharAttributeName) 1252 { 1253 // need a special handling for the EchoChar property 1254 PropertyValue aEchoChar; 1255 aEchoChar.Name = PROPERTY_ECHOCHAR; 1256 OSL_ENSURE(_rValue.getLength() == 1, "OPasswordImport::handleAttribute: invalid echo char attribute!"); 1257 // we ourself should not have written values other than of length 1 1258 if (_rValue.getLength() >= 1) 1259 aEchoChar.Value <<= (sal_Int16)_rValue.getStr()[0]; 1260 else 1261 aEchoChar.Value <<= (sal_Int16)0; 1262 implPushBackPropertyValue(aEchoChar); 1263 return true; 1264 } 1265 return OControlImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); 1266 } 1267 1268 //===================================================================== 1269 //= ORadioImport 1270 //===================================================================== 1271 //--------------------------------------------------------------------- 1272 ORadioImport::ORadioImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1273 const Reference< XNameContainer >& _rxParentContainer, OControlElement::ElementType _eType) 1274 :OImagePositionImport( _rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType ) 1275 { 1276 } 1277 1278 //--------------------------------------------------------------------- 1279 bool ORadioImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 1280 { 1281 // need special handling for the State & CurrentState properties: 1282 // they're stored as booleans, but expected to be int16 properties 1283 static const sal_Char* pCurrentSelectedAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_SELECTED); 1284 static const sal_Char* pSelectedAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_SELECTED); 1285 if ( _rLocalName.equalsAscii( pCurrentSelectedAttributeName ) 1286 || _rLocalName.equalsAscii( pSelectedAttributeName ) 1287 ) 1288 { 1289 const OAttribute2Property::AttributeAssignment* pProperty = m_rContext.getAttributeMap().getAttributeTranslation(_rLocalName); 1290 OSL_ENSURE(pProperty, "ORadioImport::handleAttribute: invalid property map!"); 1291 if (pProperty) 1292 { 1293 const Any aBooleanValue( PropertyConversion::convertString(m_rContext.getGlobalContext(), pProperty->aPropertyType, _rValue, pProperty->pEnumMap) ); 1294 1295 // create and store a new PropertyValue 1296 PropertyValue aNewValue; 1297 aNewValue.Name = pProperty->sPropertyName; 1298 aNewValue.Value <<= (sal_Int16)::cppu::any2bool(aBooleanValue); 1299 1300 implPushBackPropertyValue(aNewValue); 1301 } 1302 return true; 1303 } 1304 return OImagePositionImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); 1305 } 1306 1307 //===================================================================== 1308 //= OURLReferenceImport 1309 //===================================================================== 1310 OURLReferenceImport::OURLReferenceImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1311 const Reference< XNameContainer >& _rxParentContainer, 1312 OControlElement::ElementType _eType) 1313 :OImagePositionImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType) 1314 { 1315 } 1316 1317 //--------------------------------------------------------------------- 1318 bool OURLReferenceImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 1319 { 1320 static const sal_Char* s_pTargetLocationAttributeName = OAttributeMetaData::getCommonControlAttributeName( CCA_TARGET_LOCATION ); 1321 static const sal_Char* s_pImageDataAttributeName = OAttributeMetaData::getCommonControlAttributeName( CCA_IMAGE_DATA ); 1322 1323 // need to make the URL absolute if 1324 // * it's the image-data attribute 1325 // * it's the target-location attribute, and we're dealign with an object which has the respective property 1326 sal_Bool bMakeAbsolute = 1327 ( 0 == _rLocalName.compareToAscii( s_pImageDataAttributeName ) ) 1328 || ( ( 0 == _rLocalName.compareToAscii( s_pTargetLocationAttributeName ) ) 1329 && ( ( OControlElement::BUTTON == m_eElementType ) 1330 || ( OControlElement::IMAGE == m_eElementType ) 1331 ) 1332 ); 1333 1334 if ( bMakeAbsolute && ( _rValue.getLength() > 0 ) ) 1335 { 1336 // make a global URL out of the local one 1337 ::rtl::OUString sAdjustedValue; 1338 // only resolve image related url 1339 // we don't want say form url targets to be resolved 1340 // using ResolveGraphicObjectURL 1341 if ( 0 == _rLocalName.compareToAscii( s_pImageDataAttributeName ) ) 1342 sAdjustedValue = m_rContext.getGlobalContext().ResolveGraphicObjectURL( _rValue, sal_False ); 1343 else 1344 sAdjustedValue = m_rContext.getGlobalContext().GetAbsoluteReference( _rValue ); 1345 return OImagePositionImport::handleAttribute( _nNamespaceKey, _rLocalName, sAdjustedValue ); 1346 } 1347 1348 return OImagePositionImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); 1349 } 1350 1351 //===================================================================== 1352 //= OButtonImport 1353 //===================================================================== 1354 //--------------------------------------------------------------------- 1355 OButtonImport::OButtonImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1356 const Reference< XNameContainer >& _rxParentContainer, 1357 OControlElement::ElementType _eType) 1358 :OURLReferenceImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType) 1359 { 1360 enableTrackAttributes(); 1361 } 1362 1363 //--------------------------------------------------------------------- 1364 void OButtonImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1365 { 1366 OURLReferenceImport::StartElement(_rxAttrList); 1367 1368 // handle the target-frame attribute 1369 simulateDefaultedAttribute(OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_FRAME), PROPERTY_TARGETFRAME, "_blank"); 1370 } 1371 1372 //===================================================================== 1373 //= OValueRangeImport 1374 //===================================================================== 1375 //--------------------------------------------------------------------- 1376 OValueRangeImport::OValueRangeImport( OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1377 const Reference< XNameContainer >& _rxParentContainer, OControlElement::ElementType _eType ) 1378 :OControlImport( _rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType ) 1379 ,m_nStepSizeValue( 1 ) 1380 { 1381 1382 } 1383 1384 //--------------------------------------------------------------------- 1385 bool OValueRangeImport::handleAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue ) 1386 { 1387 if ( _rLocalName.equalsAscii( OAttributeMetaData::getSpecialAttributeName( SCA_STEP_SIZE ) ) ) 1388 { 1389 GetImport().GetMM100UnitConverter().convertNumber( m_nStepSizeValue, _rValue ); 1390 return true; 1391 } 1392 return OControlImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); 1393 } 1394 1395 //--------------------------------------------------------------------- 1396 void OValueRangeImport::StartElement( const Reference< sax::XAttributeList >& _rxAttrList ) 1397 { 1398 OControlImport::StartElement( _rxAttrList ); 1399 1400 if ( m_xInfo.is() ) 1401 { 1402 if ( m_xInfo->hasPropertyByName( PROPERTY_SPIN_INCREMENT ) ) 1403 m_xElement->setPropertyValue( PROPERTY_SPIN_INCREMENT, makeAny( m_nStepSizeValue ) ); 1404 else if ( m_xInfo->hasPropertyByName( PROPERTY_LINE_INCREMENT ) ) 1405 m_xElement->setPropertyValue( PROPERTY_LINE_INCREMENT, makeAny( m_nStepSizeValue ) ); 1406 } 1407 } 1408 1409 //===================================================================== 1410 //= OTextLikeImport 1411 //===================================================================== 1412 //--------------------------------------------------------------------- 1413 OTextLikeImport::OTextLikeImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1414 const Reference< XNameContainer >& _rxParentContainer, 1415 OControlElement::ElementType _eType) 1416 :OControlImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType) 1417 ,m_bEncounteredTextPara( false ) 1418 { 1419 enableTrackAttributes(); 1420 } 1421 1422 //--------------------------------------------------------------------- 1423 SvXMLImportContext* OTextLikeImport::CreateChildContext( sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 1424 const Reference< sax::XAttributeList >& _rxAttrList ) 1425 { 1426 if ( ( XML_NAMESPACE_TEXT == _nPrefix ) && _rLocalName.equalsIgnoreAsciiCaseAscii( "p" ) ) 1427 { 1428 OSL_ENSURE( m_eElementType == OControlElement::TEXT_AREA, 1429 "OTextLikeImport::CreateChildContext: text paragraphs in a non-text-area?" ); 1430 1431 if ( m_eElementType == OControlElement::TEXT_AREA ) 1432 { 1433 Reference< XText > xTextElement( m_xElement, UNO_QUERY ); 1434 if ( xTextElement.is() ) 1435 { 1436 UniReference < XMLTextImportHelper > xTextImportHelper( m_rContext.getGlobalContext().GetTextImport() ); 1437 1438 if ( !m_xCursor.is() ) 1439 { 1440 m_xOldCursor = xTextImportHelper->GetCursor(); 1441 m_xCursor = xTextElement->createTextCursor(); 1442 1443 if ( m_xCursor.is() ) 1444 xTextImportHelper->SetCursor( m_xCursor ); 1445 } 1446 if ( m_xCursor.is() ) 1447 { 1448 m_bEncounteredTextPara = true; 1449 return xTextImportHelper->CreateTextChildContext( m_rContext.getGlobalContext(), _nPrefix, _rLocalName, _rxAttrList ); 1450 } 1451 } 1452 else 1453 { 1454 // in theory, we could accumulate all the text portions (without formatting), 1455 // and set it as Text property at the model ... 1456 } 1457 } 1458 } 1459 1460 return OControlImport::CreateChildContext( _nPrefix, _rLocalName, _rxAttrList ); 1461 } 1462 1463 //--------------------------------------------------------------------- 1464 void OTextLikeImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1465 { 1466 OControlImport::StartElement(_rxAttrList); 1467 1468 // handle the convert-empty-to-null attribute, whose default is different from the property default 1469 // unfortunately, different classes are imported by this class ('cause they're represented by the 1470 // same XML element), though not all of them know this property. 1471 // So we have to do a check ... 1472 if (m_xElement.is() && m_xInfo.is() && m_xInfo->hasPropertyByName(PROPERTY_EMPTY_IS_NULL) ) 1473 simulateDefaultedAttribute(OAttributeMetaData::getDatabaseAttributeName(DA_CONVERT_EMPTY), PROPERTY_EMPTY_IS_NULL, "false"); 1474 } 1475 1476 //--------------------------------------------------------------------- 1477 struct EqualHandle : public ::std::unary_function< PropertyValue, bool > 1478 { 1479 const sal_Int32 m_nHandle; 1480 EqualHandle( sal_Int32 _nHandle ) : m_nHandle( _nHandle ) { } 1481 1482 inline bool operator()( const PropertyValue& _rProp ) 1483 { 1484 return _rProp.Handle == m_nHandle; 1485 } 1486 }; 1487 1488 //--------------------------------------------------------------------- 1489 void OTextLikeImport::removeRedundantCurrentValue() 1490 { 1491 if ( m_bEncounteredTextPara ) 1492 { 1493 // In case the text is written in the text:p elements, we need to ignore what we read as 1494 // current-value attribute, since it's redundant. 1495 // fortunately, OElementImport tagged the value property with the PROPID_CURRENT_VALUE 1496 // handle, so we do not need to determine the name of our value property here 1497 // (normally, it should be "Text", since no other controls than the edit field should 1498 // have the text:p elements) 1499 PropertyValueArray::iterator aValuePropertyPos = ::std::find_if( 1500 m_aValues.begin(), 1501 m_aValues.end(), 1502 EqualHandle( PROPID_CURRENT_VALUE ) 1503 ); 1504 if ( aValuePropertyPos != m_aValues.end() ) 1505 { 1506 OSL_ENSURE( aValuePropertyPos->Name == PROPERTY_TEXT, "OTextLikeImport::EndElement: text:p was present, but our value property is *not* 'Text'!" ); 1507 if ( aValuePropertyPos->Name == PROPERTY_TEXT ) 1508 { 1509 ::std::copy( 1510 aValuePropertyPos + 1, 1511 m_aValues.end(), 1512 aValuePropertyPos 1513 ); 1514 m_aValues.resize( m_aValues.size() - 1 ); 1515 } 1516 } 1517 1518 // additionally, we need to set the "RichText" property of our element to sal_True 1519 // (the presence of the text:p is used as indicator for the value of the RichText property) 1520 sal_Bool bHasRichTextProperty = sal_False; 1521 if ( m_xInfo.is() ) 1522 bHasRichTextProperty = m_xInfo->hasPropertyByName( PROPERTY_RICH_TEXT ); 1523 OSL_ENSURE( bHasRichTextProperty, "OTextLikeImport::EndElement: text:p, but no rich text control?" ); 1524 if ( bHasRichTextProperty ) 1525 m_xElement->setPropertyValue( PROPERTY_RICH_TEXT, makeAny( (sal_Bool)sal_True ) ); 1526 } 1527 // Note that we do *not* set the RichText property (in case our element has one) to sal_False here 1528 // since this is the default of this property, anyway. 1529 } 1530 1531 //--------------------------------------------------------------------- 1532 struct EqualName : public ::std::unary_function< PropertyValue, bool > 1533 { 1534 const ::rtl::OUString m_sName; 1535 EqualName( const ::rtl::OUString& _rName ) : m_sName( _rName ) { } 1536 1537 inline bool operator()( const PropertyValue& _rProp ) 1538 { 1539 return _rProp.Name == m_sName; 1540 } 1541 }; 1542 1543 //--------------------------------------------------------------------- 1544 void OTextLikeImport::adjustDefaultControlProperty() 1545 { 1546 // In OpenOffice.org 2.0, we changed the implementation of the css.form.component.TextField (the model of a text field control), 1547 // so that it now uses another default control. So if we encounter a text field where the *old* default 1548 // control property is writting, we are not allowed to use it 1549 PropertyValueArray::iterator aDefaultControlPropertyPos = ::std::find_if( 1550 m_aValues.begin(), 1551 m_aValues.end(), 1552 EqualName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultControl" ) ) ) 1553 ); 1554 if ( aDefaultControlPropertyPos != m_aValues.end() ) 1555 { 1556 ::rtl::OUString sDefaultControl; 1557 OSL_VERIFY( aDefaultControlPropertyPos->Value >>= sDefaultControl ); 1558 if ( sDefaultControl.equalsAscii( "stardiv.one.form.control.Edit" ) ) 1559 { 1560 // complete remove this property value from the array. Today's "default value" of the "DefaultControl" 1561 // property is sufficient 1562 ::std::copy( 1563 aDefaultControlPropertyPos + 1, 1564 m_aValues.end(), 1565 aDefaultControlPropertyPos 1566 ); 1567 m_aValues.resize( m_aValues.size() - 1 ); 1568 } 1569 } 1570 } 1571 1572 //--------------------------------------------------------------------- 1573 void OTextLikeImport::EndElement() 1574 { 1575 removeRedundantCurrentValue(); 1576 adjustDefaultControlProperty(); 1577 1578 // let the base class do the stuff 1579 OControlImport::EndElement(); 1580 1581 // some cleanups 1582 UniReference < XMLTextImportHelper > xTextImportHelper( m_rContext.getGlobalContext().GetTextImport() ); 1583 if ( m_xCursor.is() ) 1584 { 1585 // delete the newline which has been imported errornously 1586 // TODO (fs): stole this code somewhere - why don't we fix the text import?? 1587 m_xCursor->gotoEnd( sal_False ); 1588 m_xCursor->goLeft( 1, sal_True ); 1589 m_xCursor->setString( ::rtl::OUString() ); 1590 1591 // reset cursor 1592 xTextImportHelper->ResetCursor(); 1593 } 1594 1595 if ( m_xOldCursor.is() ) 1596 xTextImportHelper->SetCursor( m_xOldCursor ); 1597 1598 } 1599 1600 //===================================================================== 1601 //= OListAndComboImport 1602 //===================================================================== 1603 //--------------------------------------------------------------------- 1604 OListAndComboImport::OListAndComboImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1605 const Reference< XNameContainer >& _rxParentContainer, 1606 OControlElement::ElementType _eType) 1607 :OControlImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, _eType) 1608 ,m_nEmptyListItems( 0 ) 1609 ,m_nEmptyValueItems( 0 ) 1610 ,m_bEncounteredLSAttrib( sal_False ) 1611 ,m_bLinkWithIndexes( sal_False ) 1612 { 1613 if (OControlElement::COMBOBOX == m_eElementType) 1614 enableTrackAttributes(); 1615 } 1616 1617 //--------------------------------------------------------------------- 1618 SvXMLImportContext* OListAndComboImport::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 1619 const Reference< sax::XAttributeList >& _rxAttrList) 1620 { 1621 // is it the "option" sub tag of a listbox ? 1622 static const ::rtl::OUString s_sOptionElementName = ::rtl::OUString::createFromAscii("option"); 1623 if (s_sOptionElementName == _rLocalName) 1624 return new OListOptionImport(GetImport(), _nPrefix, _rLocalName, this); 1625 1626 // is it the "item" sub tag of a combobox ? 1627 static const ::rtl::OUString s_sItemElementName = ::rtl::OUString::createFromAscii("item"); 1628 if (s_sItemElementName == _rLocalName) 1629 return new OComboItemImport(GetImport(), _nPrefix, _rLocalName, this); 1630 1631 // everything else 1632 return OControlImport::CreateChildContext(_nPrefix, _rLocalName, _rxAttrList); 1633 } 1634 1635 //--------------------------------------------------------------------- 1636 void OListAndComboImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1637 { 1638 m_bLinkWithIndexes = sal_False; 1639 1640 OControlImport::StartElement(_rxAttrList); 1641 1642 if (OControlElement::COMBOBOX == m_eElementType) 1643 { 1644 // for the auto-completion 1645 // the attribute default does not equal the property default, so in case we did not read this attribute, 1646 // we have to simulate it 1647 simulateDefaultedAttribute( OAttributeMetaData::getSpecialAttributeName( SCA_AUTOMATIC_COMPLETION ), PROPERTY_AUTOCOMPLETE, "false"); 1648 1649 // same for the convert-empty-to-null attribute, which's default is different from the property default 1650 simulateDefaultedAttribute( OAttributeMetaData::getDatabaseAttributeName( DA_CONVERT_EMPTY ), PROPERTY_EMPTY_IS_NULL, "false"); 1651 } 1652 } 1653 1654 //--------------------------------------------------------------------- 1655 void OListAndComboImport::EndElement() 1656 { 1657 // append the list source property the the properties sequence of our importer 1658 // the string item list 1659 PropertyValue aItemList; 1660 aItemList.Name = PROPERTY_STRING_ITEM_LIST; 1661 aItemList.Value <<= m_aListSource; 1662 implPushBackPropertyValue(aItemList); 1663 1664 if (OControlElement::LISTBOX == m_eElementType) 1665 { 1666 OSL_ENSURE((m_aListSource.getLength() + m_nEmptyListItems) == (m_aValueList.getLength() + m_nEmptyValueItems), 1667 "OListAndComboImport::EndElement: inconsistence between labels and values!"); 1668 1669 if ( !m_bEncounteredLSAttrib ) 1670 { 1671 // the value sequence 1672 PropertyValue aValueList; 1673 aValueList.Name = PROPERTY_LISTSOURCE; 1674 aValueList.Value <<= m_aValueList; 1675 implPushBackPropertyValue(aValueList); 1676 } 1677 1678 // the select sequence 1679 PropertyValue aSelected; 1680 aSelected.Name = PROPERTY_SELECT_SEQ; 1681 aSelected.Value <<= m_aSelectedSeq; 1682 implPushBackPropertyValue(aSelected); 1683 1684 // the default select sequence 1685 PropertyValue aDefaultSelected; 1686 aDefaultSelected.Name = PROPERTY_DEFAULT_SELECT_SEQ; 1687 aDefaultSelected.Value <<= m_aDefaultSelectedSeq; 1688 implPushBackPropertyValue(aDefaultSelected); 1689 } 1690 1691 OControlImport::EndElement(); 1692 1693 // the external list source, if applicable 1694 if ( m_xElement.is() && m_sCellListSource.getLength() ) 1695 m_rContext.registerCellRangeListSource( m_xElement, m_sCellListSource ); 1696 } 1697 1698 //--------------------------------------------------------------------- 1699 void OListAndComboImport::doRegisterCellValueBinding( const ::rtl::OUString& _rBoundCellAddress ) 1700 { 1701 ::rtl::OUString sBoundCellAddress( _rBoundCellAddress ); 1702 if ( m_bLinkWithIndexes ) 1703 { 1704 // This is a HACK. We register a string which is no valid address, but allows 1705 // (somewhere else) to determine that a non-standard binding should be created. 1706 // This hack is acceptable for OOo 1.1.1, since the file format for value 1707 // bindings of form controls is to be changed afterwards, anyway. 1708 sBoundCellAddress += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":index" ) ); 1709 } 1710 1711 OControlImport::doRegisterCellValueBinding( sBoundCellAddress ); 1712 } 1713 1714 //--------------------------------------------------------------------- 1715 bool OListAndComboImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 1716 { 1717 static const sal_Char* pListSourceAttributeName = OAttributeMetaData::getDatabaseAttributeName(DA_LIST_SOURCE); 1718 if ( _rLocalName.equalsAscii(pListSourceAttributeName) ) 1719 { 1720 PropertyValue aListSource; 1721 aListSource.Name = PROPERTY_LISTSOURCE; 1722 1723 // it's the ListSource attribute 1724 m_bEncounteredLSAttrib = sal_True; 1725 if ( OControlElement::COMBOBOX == m_eElementType ) 1726 { 1727 aListSource.Value <<= _rValue; 1728 } 1729 else 1730 { 1731 // a listbox which has a list-source attribute must have a list-source-type of something 1732 // not equal to ValueList. 1733 // In this case, the list-source value is simply the one and only element of the ListSource property. 1734 Sequence< ::rtl::OUString > aListSourcePropValue( 1 ); 1735 aListSourcePropValue[0] = _rValue; 1736 aListSource.Value <<= aListSourcePropValue; 1737 } 1738 1739 implPushBackPropertyValue( aListSource ); 1740 return true; 1741 } 1742 1743 if ( _rLocalName.equalsAscii( OAttributeMetaData::getBindingAttributeName( BA_LIST_CELL_RANGE ) ) ) 1744 { 1745 m_sCellListSource = _rValue; 1746 return true; 1747 } 1748 1749 if ( _rLocalName.equalsAscii( OAttributeMetaData::getBindingAttributeName( BA_LIST_LINKING_TYPE ) ) ) 1750 { 1751 sal_Int16 nLinkageType = 0; 1752 PropertyConversion::convertString( 1753 m_rContext.getGlobalContext(), 1754 ::getCppuType( static_cast< sal_Int16* >( NULL ) ), 1755 _rValue, 1756 OEnumMapper::getEnumMap( OEnumMapper::epListLinkageType ) 1757 ) >>= nLinkageType; 1758 1759 m_bLinkWithIndexes = ( nLinkageType != 0 ); 1760 return true; 1761 } 1762 1763 return OControlImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); 1764 } 1765 1766 //--------------------------------------------------------------------- 1767 void OListAndComboImport::implPushBackLabel(const ::rtl::OUString& _rLabel) 1768 { 1769 OSL_ENSURE(!m_nEmptyListItems, "OListAndComboImport::implPushBackValue: label list is already done!"); 1770 if (!m_nEmptyListItems) 1771 pushBackSequenceElement(m_aListSource, _rLabel); 1772 } 1773 1774 //--------------------------------------------------------------------- 1775 void OListAndComboImport::implPushBackValue(const ::rtl::OUString& _rValue) 1776 { 1777 OSL_ENSURE(!m_nEmptyValueItems, "OListAndComboImport::implPushBackValue: value list is already done!"); 1778 if (!m_nEmptyValueItems) 1779 { 1780 OSL_ENSURE( !m_bEncounteredLSAttrib, "OListAndComboImport::implPushBackValue: invalid structure! Did you save this document with a version prior SRC641 m?" ); 1781 // We already had the list-source attribute, which means that the ListSourceType is 1782 // not ValueList, which means that the ListSource should contain only one string in 1783 // the first element of the sequence 1784 // All other values in the file are invalid 1785 1786 pushBackSequenceElement( m_aValueList, _rValue ); 1787 } 1788 } 1789 1790 //--------------------------------------------------------------------- 1791 void OListAndComboImport::implEmptyLabelFound() 1792 { 1793 ++m_nEmptyListItems; 1794 } 1795 1796 //--------------------------------------------------------------------- 1797 void OListAndComboImport::implEmptyValueFound() 1798 { 1799 ++m_nEmptyValueItems; 1800 } 1801 1802 //--------------------------------------------------------------------- 1803 void OListAndComboImport::implSelectCurrentItem() 1804 { 1805 OSL_ENSURE((m_aListSource.getLength() + m_nEmptyListItems) == (m_aValueList.getLength() + m_nEmptyValueItems), 1806 "OListAndComboImport::implSelectCurrentItem: inconsistence between labels and values!"); 1807 1808 sal_Int16 nItemNumber = (sal_Int16)(m_aListSource.getLength() - 1 + m_nEmptyListItems); 1809 pushBackSequenceElement(m_aSelectedSeq, nItemNumber); 1810 } 1811 1812 //--------------------------------------------------------------------- 1813 void OListAndComboImport::implDefaultSelectCurrentItem() 1814 { 1815 OSL_ENSURE((m_aListSource.getLength() + m_nEmptyListItems) == (m_aValueList.getLength() + m_nEmptyValueItems), 1816 "OListAndComboImport::implDefaultSelectCurrentItem: inconsistence between labels and values!"); 1817 1818 sal_Int16 nItemNumber = (sal_Int16)(m_aListSource.getLength() - 1 + m_nEmptyListItems); 1819 pushBackSequenceElement(m_aDefaultSelectedSeq, nItemNumber); 1820 } 1821 1822 //===================================================================== 1823 //= OListOptionImport 1824 //===================================================================== 1825 //--------------------------------------------------------------------- 1826 OListOptionImport::OListOptionImport(SvXMLImport& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1827 const OListAndComboImportRef& _rListBox) 1828 :SvXMLImportContext(_rImport, _nPrefix, _rName) 1829 ,m_xListBoxImport(_rListBox) 1830 { 1831 } 1832 1833 //--------------------------------------------------------------------- 1834 void OListOptionImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1835 { 1836 // the label and the value 1837 const SvXMLNamespaceMap& rMap = GetImport().GetNamespaceMap(); 1838 const ::rtl::OUString sLabelAttribute = rMap.GetQNameByKey( 1839 GetPrefix(), ::rtl::OUString::createFromAscii("label")); 1840 const ::rtl::OUString sValueAttribute = rMap.GetQNameByKey( 1841 GetPrefix(), ::rtl::OUString::createFromAscii("value")); 1842 1843 // ------------------- 1844 // the label attribute 1845 ::rtl::OUString sValue = _rxAttrList->getValueByName(sLabelAttribute); 1846 sal_Bool bNonexistentAttribute = sal_False; 1847 if (!sValue.getLength()) 1848 if (0 == _rxAttrList->getTypeByName(sLabelAttribute).getLength()) 1849 // this attribute does not really exist 1850 bNonexistentAttribute = sal_True; 1851 1852 if (bNonexistentAttribute) 1853 m_xListBoxImport->implEmptyLabelFound(); 1854 else 1855 m_xListBoxImport->implPushBackLabel( sValue ); 1856 1857 // ------------------- 1858 // the value attribute 1859 sValue = _rxAttrList->getValueByName(sValueAttribute); 1860 bNonexistentAttribute = sal_False; 1861 if (!sValue.getLength()) 1862 if (0 == _rxAttrList->getTypeByName(sValueAttribute).getLength()) 1863 // this attribute does not really exist 1864 bNonexistentAttribute = sal_True; 1865 1866 if (bNonexistentAttribute) 1867 m_xListBoxImport->implEmptyValueFound(); 1868 else 1869 m_xListBoxImport->implPushBackValue( sValue ); 1870 1871 // the current-selected and selected 1872 const ::rtl::OUString sSelectedAttribute = rMap.GetQNameByKey( 1873 GetPrefix(), ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_SELECTED))); 1874 const ::rtl::OUString sDefaultSelectedAttribute = rMap.GetQNameByKey( 1875 GetPrefix(), ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_SELECTED))); 1876 1877 // propagate the selected flag 1878 sal_Bool bSelected; 1879 GetImport().GetMM100UnitConverter().convertBool(bSelected, _rxAttrList->getValueByName(sSelectedAttribute)); 1880 if (bSelected) 1881 m_xListBoxImport->implSelectCurrentItem(); 1882 1883 // same for the default selected 1884 sal_Bool bDefaultSelected; 1885 GetImport().GetMM100UnitConverter().convertBool(bDefaultSelected, _rxAttrList->getValueByName(sDefaultSelectedAttribute)); 1886 if (bDefaultSelected) 1887 m_xListBoxImport->implDefaultSelectCurrentItem(); 1888 1889 SvXMLImportContext::StartElement(_rxAttrList); 1890 } 1891 1892 //===================================================================== 1893 //= OComboItemImport 1894 //===================================================================== 1895 //--------------------------------------------------------------------- 1896 OComboItemImport::OComboItemImport(SvXMLImport& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1897 const OListAndComboImportRef& _rListBox) 1898 :SvXMLImportContext(_rImport, _nPrefix, _rName) 1899 ,m_xListBoxImport(_rListBox) 1900 { 1901 } 1902 1903 //--------------------------------------------------------------------- 1904 void OComboItemImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1905 { 1906 const ::rtl::OUString sLabelAttributeName = GetImport().GetNamespaceMap().GetQNameByKey( 1907 GetPrefix(), ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL))); 1908 m_xListBoxImport->implPushBackLabel(_rxAttrList->getValueByName(sLabelAttributeName)); 1909 1910 SvXMLImportContext::StartElement(_rxAttrList); 1911 } 1912 1913 1914 //===================================================================== 1915 //= OColumnWrapperImport 1916 //===================================================================== 1917 //--------------------------------------------------------------------- 1918 OColumnWrapperImport::OColumnWrapperImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1919 const Reference< XNameContainer >& _rxParentContainer) 1920 :SvXMLImportContext(_rImport.getGlobalContext(), _nPrefix, _rName) 1921 ,m_xParentContainer(_rxParentContainer) 1922 ,m_rFormImport(_rImport) 1923 ,m_rEventManager(_rEventManager) 1924 { 1925 } 1926 //--------------------------------------------------------------------- 1927 SvXMLImportContext* OColumnWrapperImport::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 1928 const Reference< sax::XAttributeList >&) 1929 { 1930 OControlImport* pReturn = implCreateChildContext(_nPrefix, _rLocalName, OElementNameMap::getElementType(_rLocalName)); 1931 if (pReturn) 1932 { 1933 OSL_ENSURE(m_xOwnAttributes.is(), "OColumnWrapperImport::CreateChildContext: had no form:column element!"); 1934 pReturn->addOuterAttributes(m_xOwnAttributes); 1935 } 1936 return pReturn; 1937 } 1938 //--------------------------------------------------------------------- 1939 void OColumnWrapperImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 1940 { 1941 OSL_ENSURE(!m_xOwnAttributes.is(), "OColumnWrapperImport::StartElement: already have the cloned list!"); 1942 1943 // clone the attributes 1944 Reference< XCloneable > xCloneList(_rxAttrList, UNO_QUERY); 1945 OSL_ENSURE(xCloneList.is(), "OColumnWrapperImport::StartElement: AttributeList not cloneable!"); 1946 if ( xCloneList.is() ) 1947 m_xOwnAttributes = Reference< sax::XAttributeList >(xCloneList->createClone(), UNO_QUERY); 1948 OSL_ENSURE(m_xOwnAttributes.is(), "OColumnWrapperImport::StartElement: no cloned list!"); 1949 } 1950 1951 //--------------------------------------------------------------------- 1952 OControlImport* OColumnWrapperImport::implCreateChildContext( 1953 sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 1954 OControlElement::ElementType _eType) 1955 { 1956 OSL_ENSURE( (OControlElement::TEXT == _eType) 1957 || (OControlElement::TEXT_AREA == _eType) 1958 || (OControlElement::FORMATTED_TEXT == _eType) 1959 || (OControlElement::CHECKBOX == _eType) 1960 || (OControlElement::LISTBOX == _eType) 1961 || (OControlElement::COMBOBOX == _eType) 1962 || (OControlElement::TIME == _eType) 1963 || (OControlElement::DATE == _eType), 1964 "OColumnWrapperImport::implCreateChildContext: invalid or unrecognized sub element!"); 1965 1966 switch (_eType) 1967 { 1968 case OControlElement::COMBOBOX: 1969 case OControlElement::LISTBOX: 1970 return new OColumnImport<OListAndComboImport>(m_rFormImport, m_rEventManager, _nPrefix, _rLocalName, m_xParentContainer, _eType ); 1971 1972 case OControlElement::PASSWORD: 1973 return new OColumnImport<OPasswordImport>(m_rFormImport, m_rEventManager, _nPrefix, _rLocalName, m_xParentContainer, _eType ); 1974 1975 case OControlElement::TEXT: 1976 case OControlElement::TEXT_AREA: 1977 case OControlElement::FORMATTED_TEXT: 1978 return new OColumnImport< OTextLikeImport >( m_rFormImport, m_rEventManager, _nPrefix, _rLocalName, m_xParentContainer, _eType ); 1979 1980 default: 1981 return new OColumnImport<OControlImport>(m_rFormImport, m_rEventManager, _nPrefix, _rLocalName, m_xParentContainer, _eType ); 1982 } 1983 } 1984 1985 //===================================================================== 1986 //= OGridImport 1987 //===================================================================== 1988 //--------------------------------------------------------------------- 1989 OGridImport::OGridImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 1990 const Reference< XNameContainer >& _rxParentContainer, 1991 OControlElement::ElementType _eType) 1992 :OGridImport_Base(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, "column") 1993 { 1994 setElementType(_eType); 1995 } 1996 1997 //--------------------------------------------------------------------- 1998 SvXMLImportContext* OGridImport::implCreateControlWrapper(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName) 1999 { 2000 return new OColumnWrapperImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer); 2001 } 2002 2003 //===================================================================== 2004 //= OFormImport 2005 //===================================================================== 2006 //--------------------------------------------------------------------- 2007 OFormImport::OFormImport(OFormLayerXMLImport_Impl& _rImport, IEventAttacherManager& _rEventManager, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, 2008 const Reference< XNameContainer >& _rxParentContainer) 2009 :OFormImport_Base(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer, "control") 2010 { 2011 enableTrackAttributes(); 2012 } 2013 2014 //--------------------------------------------------------------------- 2015 SvXMLImportContext* OFormImport::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 2016 const Reference< sax::XAttributeList >& _rxAttrList) 2017 { 2018 if( token::IsXMLToken(_rLocalName, token::XML_FORM) ) 2019 return new OFormImport( m_rFormImport, *this, _nPrefix, _rLocalName, 2020 m_xMeAsContainer); 2021 else if ( token::IsXMLToken(_rLocalName, token::XML_CONNECTION_RESOURCE) ) 2022 return new OXMLDataSourceImport(GetImport(), _nPrefix, _rLocalName, _rxAttrList,m_xElement); 2023 else if( (token::IsXMLToken(_rLocalName, token::XML_EVENT_LISTENERS) && 2024 (XML_NAMESPACE_OFFICE == _nPrefix)) || 2025 token::IsXMLToken( _rLocalName, token::XML_PROPERTIES) ) 2026 return OElementImport::CreateChildContext( _nPrefix, _rLocalName, 2027 _rxAttrList ); 2028 else 2029 return implCreateChildContext( _nPrefix, _rLocalName, 2030 OElementNameMap::getElementType(_rLocalName) ); 2031 } 2032 2033 //--------------------------------------------------------------------- 2034 void OFormImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) 2035 { 2036 m_rFormImport.enterEventContext(); 2037 OFormImport_Base::StartElement(_rxAttrList); 2038 2039 // handle the target-frame attribute 2040 simulateDefaultedAttribute(OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_FRAME), PROPERTY_TARGETFRAME, "_blank"); 2041 } 2042 2043 //--------------------------------------------------------------------- 2044 void OFormImport::EndElement() 2045 { 2046 OFormImport_Base::EndElement(); 2047 m_rFormImport.leaveEventContext(); 2048 } 2049 2050 //--------------------------------------------------------------------- 2051 SvXMLImportContext* OFormImport::implCreateControlWrapper(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName) 2052 { 2053 OSL_ENSURE( !this, "illegal call to OFormImport::implCreateControlWrapper" ); 2054 return new SvXMLImportContext(GetImport(), _nPrefix, _rLocalName ); 2055 } 2056 2057 //--------------------------------------------------------------------- 2058 bool OFormImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) 2059 { 2060 // handle the master/details field attributes (they're way too special to let the OPropertyImport handle them) 2061 static const ::rtl::OUString s_sMasterFieldsAttributeName = ::rtl::OUString::createFromAscii(OAttributeMetaData::getFormAttributeName(faMasterFields)); 2062 static const ::rtl::OUString s_sDetailFieldsAttributeName = ::rtl::OUString::createFromAscii(OAttributeMetaData::getFormAttributeName(faDetailFiels)); 2063 2064 if ( s_sMasterFieldsAttributeName == _rLocalName ) 2065 { 2066 implTranslateStringListProperty(PROPERTY_MASTERFIELDS, _rValue); 2067 return true; 2068 } 2069 2070 if ( s_sDetailFieldsAttributeName == _rLocalName ) 2071 { 2072 implTranslateStringListProperty(PROPERTY_DETAILFIELDS, _rValue); 2073 return true; 2074 } 2075 2076 return OFormImport_Base::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); 2077 } 2078 2079 //--------------------------------------------------------------------- 2080 void OFormImport::implTranslateStringListProperty(const ::rtl::OUString& _rPropertyName, const ::rtl::OUString& _rValue) 2081 { 2082 PropertyValue aProp; 2083 aProp.Name = _rPropertyName; 2084 2085 Sequence< ::rtl::OUString > aList; 2086 2087 // split up the value string 2088 if (_rValue.getLength()) 2089 { 2090 // For the moment, we build a vector instead of a Sequence. It's easier to handle because of it's 2091 // push_back method 2092 ::std::vector< ::rtl::OUString > aElements; 2093 // estimate the number of tokens 2094 sal_Int32 nEstimate = 0, nLength = _rValue.getLength(); 2095 const sal_Unicode* pChars = _rValue.getStr(); 2096 for (sal_Int32 i=0; i<nLength; ++i, ++pChars) 2097 if (*pChars == ',') 2098 ++nEstimate; 2099 aElements.reserve(nEstimate + 1); 2100 // that's the worst case. If the string contains the separator character _quoted_, we reserved to much ... 2101 2102 2103 sal_Int32 nElementStart = 0; 2104 sal_Int32 nNextSep = 0; 2105 sal_Int32 nElementLength; 2106 ::rtl::OUString sElement; 2107 do 2108 { 2109 // extract the current element 2110 nNextSep = SvXMLUnitConverter::indexOfComma( 2111 _rValue, nElementStart); 2112 if (-1 == nNextSep) 2113 nNextSep = nLength; 2114 sElement = _rValue.copy(nElementStart, nNextSep - nElementStart); 2115 2116 nElementLength = sElement.getLength(); 2117 // when writing the sequence, we quoted the single elements with " characters 2118 OSL_ENSURE( (nElementLength >= 2) 2119 && (sElement.getStr()[0] == '"') 2120 && (sElement.getStr()[nElementLength - 1] == '"'), 2121 "OFormImport::implTranslateStringListProperty: invalid quoted element name."); 2122 sElement = sElement.copy(1, nElementLength - 2); 2123 2124 aElements.push_back(sElement); 2125 2126 // swith to the next element 2127 nElementStart = 1 + nNextSep; 2128 } 2129 while (nElementStart < nLength); 2130 2131 ::rtl::OUString *pElements = aElements.empty() ? 0 : &aElements[0]; 2132 aList = Sequence< ::rtl::OUString >(pElements, aElements.size()); 2133 } 2134 else 2135 { 2136 OSL_ENSURE(sal_False, "OFormImport::implTranslateStringListProperty: invalid value (empty)!"); 2137 } 2138 2139 aProp.Value <<= aList; 2140 2141 // add the property to the base class' array 2142 implPushBackPropertyValue(aProp); 2143 } 2144 //===================================================================== 2145 //= OXMLDataSourceImport 2146 //===================================================================== 2147 OXMLDataSourceImport::OXMLDataSourceImport( 2148 SvXMLImport& _rImport 2149 ,sal_uInt16 nPrfx 2150 , const ::rtl::OUString& _sLocalName 2151 ,const Reference< ::com::sun::star::xml::sax::XAttributeList > & _xAttrList 2152 ,const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _xElement) : 2153 SvXMLImportContext( _rImport, nPrfx, _sLocalName ) 2154 { 2155 OSL_ENSURE(_xAttrList.is(),"Attribute list is NULL!"); 2156 const SvXMLNamespaceMap& rMap = _rImport.GetNamespaceMap(); 2157 2158 sal_Int16 nLength = (_xElement.is() && _xAttrList.is()) ? _xAttrList->getLength() : 0; 2159 for(sal_Int16 i = 0; i < nLength; ++i) 2160 { 2161 ::rtl::OUString sLocalName; 2162 ::rtl::OUString sAttrName = _xAttrList->getNameByIndex( i ); 2163 sal_uInt16 nPrefix = rMap.GetKeyByAttrName( sAttrName, &sLocalName ); 2164 2165 if ( ( nPrefix == OAttributeMetaData::getCommonControlAttributeNamespace( CCA_TARGET_LOCATION ) ) 2166 && ( sLocalName.equalsAscii( OAttributeMetaData::getCommonControlAttributeName( CCA_TARGET_LOCATION ) ) ) 2167 ) 2168 { 2169 ::rtl::OUString sValue = _xAttrList->getValueByIndex( i ); 2170 2171 INetURLObject aURL(sValue); 2172 if ( aURL.GetProtocol() == INET_PROT_FILE ) 2173 _xElement->setPropertyValue(PROPERTY_DATASOURCENAME,makeAny(sValue)); 2174 else 2175 _xElement->setPropertyValue(PROPERTY_URL,makeAny(sValue)); // the url is the "sdbc:" string 2176 break; 2177 } 2178 } 2179 } 2180 //--------------------------------------------------------------------- 2181 OControlImport* OFormImport::implCreateChildContext( 2182 sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, 2183 OControlElement::ElementType _eType ) 2184 { 2185 switch (_eType) 2186 { 2187 case OControlElement::TEXT: 2188 case OControlElement::TEXT_AREA: 2189 case OControlElement::FORMATTED_TEXT: 2190 return new OTextLikeImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2191 2192 case OControlElement::BUTTON: 2193 case OControlElement::IMAGE: 2194 case OControlElement::IMAGE_FRAME: 2195 return new OButtonImport( m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType ); 2196 2197 case OControlElement::COMBOBOX: 2198 case OControlElement::LISTBOX: 2199 return new OListAndComboImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2200 2201 case OControlElement::RADIO: 2202 return new ORadioImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2203 2204 case OControlElement::CHECKBOX: 2205 return new OImagePositionImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2206 2207 case OControlElement::PASSWORD: 2208 return new OPasswordImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2209 2210 case OControlElement::FRAME: 2211 case OControlElement::FIXED_TEXT: 2212 return new OReferredControlImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2213 2214 case OControlElement::GRID: 2215 return new OGridImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2216 2217 case OControlElement::VALUERANGE: 2218 return new OValueRangeImport( m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType ); 2219 2220 default: 2221 return new OControlImport(m_rFormImport, *this, _nPrefix, _rLocalName, m_xMeAsContainer, _eType); 2222 } 2223 } 2224 2225 //--------------------------------------------------------------------- 2226 ::rtl::OUString OFormImport::determineDefaultServiceName() const 2227 { 2228 return ::rtl::OUString::createFromAscii( "com.sun.star.form.component.Form" ); 2229 } 2230 2231 //......................................................................... 2232 } // namespace xmloff 2233 //......................................................................... 2234 2235