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