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_extensions.hxx" 30 #include "xsdvalidationpropertyhandler.hxx" 31 #include "formstrings.hxx" 32 #include "formmetadata.hxx" 33 #include "xsddatatypes.hxx" 34 #include "modulepcr.hxx" 35 #include "formresid.hrc" 36 #include "formlocalid.hrc" 37 #include "propctrlr.hrc" 38 #include "newdatatype.hxx" 39 #include "xsdvalidationhelper.hxx" 40 #include "pcrcommon.hxx" 41 #include "handlerhelper.hxx" 42 43 /** === begin UNO includes === **/ 44 #include <com/sun/star/beans/PropertyAttribute.hpp> 45 #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp> 46 #include <com/sun/star/xsd/DataTypeClass.hpp> 47 #include <com/sun/star/inspection/PropertyControlType.hpp> 48 #include <com/sun/star/beans/Optional.hpp> 49 #include <com/sun/star/inspection/XObjectInspectorUI.hpp> 50 #include <com/sun/star/inspection/PropertyLineElement.hpp> 51 /** === end UNO includes === **/ 52 #include <vcl/msgbox.hxx> 53 #include <tools/debug.hxx> 54 #include <svtools/localresaccess.hxx> 55 56 #include <algorithm> 57 #include <functional> 58 #include <limits> 59 60 //------------------------------------------------------------------------ 61 extern "C" void SAL_CALL createRegistryInfo_XSDValidationPropertyHandler() 62 { 63 ::pcr::XSDValidationPropertyHandler::registerImplementation(); 64 } 65 66 //........................................................................ 67 namespace pcr 68 { 69 //........................................................................ 70 71 using namespace ::com::sun::star; 72 using namespace ::com::sun::star::uno; 73 using namespace ::com::sun::star::lang; 74 using namespace ::com::sun::star::beans; 75 using namespace ::com::sun::star::xforms; 76 using namespace ::com::sun::star::xsd; 77 using namespace ::com::sun::star::script; 78 using namespace ::com::sun::star::inspection; 79 80 using ::com::sun::star::beans::PropertyAttribute::MAYBEVOID; 81 82 //==================================================================== 83 //= XSDValidationPropertyHandler 84 //==================================================================== 85 DBG_NAME( XSDValidationPropertyHandler ) 86 //-------------------------------------------------------------------- 87 XSDValidationPropertyHandler::XSDValidationPropertyHandler( const Reference< XComponentContext >& _rxContext ) 88 :XSDValidationPropertyHandler_Base( _rxContext ) 89 { 90 DBG_CTOR( XSDValidationPropertyHandler, NULL ); 91 } 92 93 //-------------------------------------------------------------------- 94 XSDValidationPropertyHandler::~XSDValidationPropertyHandler() 95 { 96 DBG_DTOR( XSDValidationPropertyHandler, NULL ); 97 } 98 99 //-------------------------------------------------------------------- 100 ::rtl::OUString SAL_CALL XSDValidationPropertyHandler::getImplementationName_static( ) throw (RuntimeException) 101 { 102 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.XSDValidationPropertyHandler" ) ); 103 } 104 105 //-------------------------------------------------------------------- 106 Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getSupportedServiceNames_static( ) throw (RuntimeException) 107 { 108 Sequence< ::rtl::OUString > aSupported( 1 ); 109 aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.XSDValidationPropertyHandler" ) ); 110 return aSupported; 111 } 112 113 //-------------------------------------------------------------------- 114 Any SAL_CALL XSDValidationPropertyHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException) 115 { 116 ::osl::MutexGuard aGuard( m_aMutex ); 117 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) ); 118 119 OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::getPropertyValue: inconsistency!" ); 120 // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties 121 122 Any aReturn; 123 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType(); 124 switch ( nPropId ) 125 { 126 // common facets 127 case PROPERTY_ID_XSD_DATA_TYPE: aReturn = pType.is() ? pType->getFacet( PROPERTY_NAME ) : makeAny( ::rtl::OUString() ); break; 128 case PROPERTY_ID_XSD_WHITESPACES:aReturn = pType.is() ? pType->getFacet( PROPERTY_XSD_WHITESPACES ) : makeAny( WhiteSpaceTreatment::Preserve ); break; 129 case PROPERTY_ID_XSD_PATTERN: aReturn = pType.is() ? pType->getFacet( PROPERTY_XSD_PATTERN ) : makeAny( ::rtl::OUString() ); break; 130 131 // all other properties are simply forwarded, if they exist at the given type 132 default: 133 { 134 if ( pType.is() && pType->hasFacet( _rPropertyName ) ) 135 aReturn = pType->getFacet( _rPropertyName ); 136 } 137 break; 138 } 139 140 return aReturn; 141 } 142 143 //-------------------------------------------------------------------- 144 void SAL_CALL XSDValidationPropertyHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException) 145 { 146 ::osl::MutexGuard aGuard( m_aMutex ); 147 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) ); 148 149 OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::getPropertyValue: inconsistency!" ); 150 // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties 151 152 if ( PROPERTY_ID_XSD_DATA_TYPE == nPropId ) 153 { 154 ::rtl::OUString sTypeName; 155 OSL_VERIFY( _rValue >>= sTypeName ); 156 m_pHelper->setValidatingDataTypeByName( sTypeName ); 157 impl_setContextDocumentModified_nothrow(); 158 return; 159 } 160 161 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType(); 162 if ( !pType.is() ) 163 { 164 DBG_ERROR( "XSDValidationPropertyHandler::setPropertyValue: you're trying to set a type facet, without a current type!" ); 165 return; 166 } 167 168 pType->setFacet( _rPropertyName, _rValue ); 169 impl_setContextDocumentModified_nothrow(); 170 } 171 172 //-------------------------------------------------------------------- 173 void XSDValidationPropertyHandler::onNewComponent() 174 { 175 XSDValidationPropertyHandler_Base::onNewComponent(); 176 177 Reference< frame::XModel > xDocument( impl_getContextDocument_nothrow() ); 178 DBG_ASSERT( xDocument.is(), "XSDValidationPropertyHandler::onNewComponent: no document!" ); 179 if ( EFormsHelper::isEForm( xDocument ) ) 180 m_pHelper.reset( new XSDValidationHelper( m_aMutex, m_xComponent, xDocument ) ); 181 else 182 m_pHelper.reset( NULL ); 183 } 184 185 //-------------------------------------------------------------------- 186 Sequence< Property > XSDValidationPropertyHandler::doDescribeSupportedProperties() const 187 { 188 ::std::vector< Property > aProperties; 189 190 if ( m_pHelper.get() ) 191 { 192 bool bAllowBinding = m_pHelper->canBindToAnyDataType(); 193 194 if ( bAllowBinding ) 195 { 196 aProperties.reserve( 12 ); 197 198 addStringPropertyDescription( aProperties, PROPERTY_XSD_DATA_TYPE ); 199 addInt16PropertyDescription ( aProperties, PROPERTY_XSD_WHITESPACES ); 200 addStringPropertyDescription( aProperties, PROPERTY_XSD_PATTERN ); 201 202 // string facets 203 addInt32PropertyDescription( aProperties, PROPERTY_XSD_LENGTH, MAYBEVOID ); 204 addInt32PropertyDescription( aProperties, PROPERTY_XSD_MIN_LENGTH, MAYBEVOID ); 205 addInt32PropertyDescription( aProperties, PROPERTY_XSD_MAX_LENGTH, MAYBEVOID ); 206 207 // decimal facets 208 addInt32PropertyDescription( aProperties, PROPERTY_XSD_TOTAL_DIGITS, MAYBEVOID ); 209 addInt32PropertyDescription( aProperties, PROPERTY_XSD_FRACTION_DIGITS, MAYBEVOID ); 210 211 // facets for different types 212 addInt16PropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_INT, MAYBEVOID ); 213 addInt16PropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_INT, MAYBEVOID ); 214 addInt16PropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_INT, MAYBEVOID ); 215 addInt16PropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_INT, MAYBEVOID ); 216 addDoublePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DOUBLE, MAYBEVOID ); 217 addDoublePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DOUBLE, MAYBEVOID ); 218 addDoublePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DOUBLE, MAYBEVOID ); 219 addDoublePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DOUBLE, MAYBEVOID ); 220 addDatePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DATE, MAYBEVOID ); 221 addDatePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DATE, MAYBEVOID ); 222 addDatePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DATE, MAYBEVOID ); 223 addDatePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DATE, MAYBEVOID ); 224 addTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_TIME, MAYBEVOID ); 225 addTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_TIME, MAYBEVOID ); 226 addTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_TIME, MAYBEVOID ); 227 addTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_TIME, MAYBEVOID ); 228 addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DATE_TIME, MAYBEVOID ); 229 addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DATE_TIME, MAYBEVOID ); 230 addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DATE_TIME, MAYBEVOID ); 231 addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DATE_TIME, MAYBEVOID ); 232 } 233 } 234 235 if ( aProperties.empty() ) 236 return Sequence< Property >(); 237 return Sequence< Property >( &(*aProperties.begin()), aProperties.size() ); 238 } 239 240 //-------------------------------------------------------------------- 241 Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getSupersededProperties( ) throw (RuntimeException) 242 { 243 ::osl::MutexGuard aGuard( m_aMutex ); 244 245 ::std::vector< ::rtl::OUString > aSuperfluous; 246 if ( m_pHelper.get() ) 247 { 248 aSuperfluous.push_back( PROPERTY_CONTROLSOURCE ); 249 aSuperfluous.push_back( PROPERTY_EMPTY_IS_NULL ); 250 aSuperfluous.push_back( PROPERTY_FILTERPROPOSAL ); 251 aSuperfluous.push_back( PROPERTY_LISTSOURCETYPE ); 252 aSuperfluous.push_back( PROPERTY_LISTSOURCE ); 253 aSuperfluous.push_back( PROPERTY_BOUNDCOLUMN ); 254 255 bool bAllowBinding = m_pHelper->canBindToAnyDataType(); 256 257 if ( bAllowBinding ) 258 { 259 aSuperfluous.push_back( PROPERTY_MAXTEXTLEN ); 260 aSuperfluous.push_back( PROPERTY_VALUEMIN ); 261 aSuperfluous.push_back( PROPERTY_VALUEMAX ); 262 aSuperfluous.push_back( PROPERTY_DECIMAL_ACCURACY ); 263 aSuperfluous.push_back( PROPERTY_TIMEMIN ); 264 aSuperfluous.push_back( PROPERTY_TIMEMAX ); 265 aSuperfluous.push_back( PROPERTY_DATEMIN ); 266 aSuperfluous.push_back( PROPERTY_DATEMAX ); 267 aSuperfluous.push_back( PROPERTY_EFFECTIVE_MIN ); 268 aSuperfluous.push_back( PROPERTY_EFFECTIVE_MAX ); 269 } 270 } 271 272 if ( aSuperfluous.empty() ) 273 return Sequence< ::rtl::OUString >(); 274 return Sequence< ::rtl::OUString >( &(*aSuperfluous.begin()), aSuperfluous.size() ); 275 } 276 277 //-------------------------------------------------------------------- 278 Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getActuatingProperties( ) throw (RuntimeException) 279 { 280 ::osl::MutexGuard aGuard( m_aMutex ); 281 ::std::vector< ::rtl::OUString > aInterestedInActuations( 2 ); 282 if ( m_pHelper.get() ) 283 { 284 aInterestedInActuations.push_back( PROPERTY_XSD_DATA_TYPE ); 285 aInterestedInActuations.push_back( PROPERTY_XML_DATA_MODEL ); 286 } 287 if ( aInterestedInActuations.empty() ) 288 return Sequence< ::rtl::OUString >(); 289 return Sequence< ::rtl::OUString >( &(*aInterestedInActuations.begin()), aInterestedInActuations.size() ); 290 } 291 292 //-------------------------------------------------------------------- 293 namespace 294 { 295 void showPropertyUI( const Reference< XObjectInspectorUI >& _rxInspectorUI, const ::rtl::OUString& _rPropertyName, bool _bShow ) 296 { 297 if ( _bShow ) 298 _rxInspectorUI->showPropertyUI( _rPropertyName ); 299 else 300 _rxInspectorUI->hidePropertyUI( _rPropertyName ); 301 } 302 } 303 304 //-------------------------------------------------------------------- 305 LineDescriptor SAL_CALL XSDValidationPropertyHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName, 306 const Reference< XPropertyControlFactory >& _rxControlFactory ) 307 throw (UnknownPropertyException, NullPointerException, RuntimeException) 308 { 309 ::osl::MutexGuard aGuard( m_aMutex ); 310 if ( !_rxControlFactory.is() ) 311 throw NullPointerException(); 312 if ( !m_pHelper.get() ) 313 throw RuntimeException(); 314 315 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) ); 316 317 LineDescriptor aDescriptor; 318 if ( nPropId != PROPERTY_ID_XSD_DATA_TYPE ) 319 aDescriptor.IndentLevel = 1; 320 321 // collect some information about the to-be-created control 322 sal_Int16 nControlType = PropertyControlType::TextField; 323 ::std::vector< ::rtl::OUString > aListEntries; 324 Optional< double > aMinValue( sal_False, 0 ); 325 Optional< double > aMaxValue( sal_False, 0 ); 326 327 switch ( nPropId ) 328 { 329 case PROPERTY_ID_XSD_DATA_TYPE: 330 nControlType = PropertyControlType::ListBox; 331 332 implGetAvailableDataTypeNames( aListEntries ); 333 334 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_ADD_DATA_TYPE); 335 aDescriptor.SecondaryButtonId = rtl::OUString::createFromAscii(UID_PROP_REMOVE_DATA_TYPE);; 336 aDescriptor.HasPrimaryButton = aDescriptor.HasSecondaryButton = sal_True; 337 aDescriptor.PrimaryButtonImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/extensions/res/buttonplus.png" ) ); 338 aDescriptor.SecondaryButtonImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/extensions/res/buttonminus.png" ) ); 339 break; 340 341 case PROPERTY_ID_XSD_WHITESPACES: 342 { 343 nControlType = PropertyControlType::ListBox; 344 aListEntries = m_pInfoService->getPropertyEnumRepresentations( PROPERTY_ID_XSD_WHITESPACES ); 345 } 346 break; 347 348 case PROPERTY_ID_XSD_PATTERN: 349 nControlType = PropertyControlType::TextField; 350 break; 351 352 case PROPERTY_ID_XSD_LENGTH: 353 case PROPERTY_ID_XSD_MIN_LENGTH: 354 case PROPERTY_ID_XSD_MAX_LENGTH: 355 nControlType = PropertyControlType::NumericField; 356 break; 357 358 case PROPERTY_ID_XSD_TOTAL_DIGITS: 359 case PROPERTY_ID_XSD_FRACTION_DIGITS: 360 nControlType = PropertyControlType::NumericField; 361 break; 362 363 case PROPERTY_ID_XSD_MAX_INCLUSIVE_INT: 364 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_INT: 365 case PROPERTY_ID_XSD_MIN_INCLUSIVE_INT: 366 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_INT: 367 { 368 nControlType = PropertyControlType::NumericField; 369 370 // handle limits for various 'INT' types according to 371 // their actual semantics (year, month, day) 372 373 ::rtl::Reference< XSDDataType > xDataType( m_pHelper->getValidatingDataType() ); 374 sal_Int16 nTypeClass = xDataType.is() ? xDataType->classify() : DataTypeClass::STRING; 375 376 aMinValue.IsPresent = aMaxValue.IsPresent = sal_True; 377 aMinValue.Value = DataTypeClass::gYear == nTypeClass ? 0 : 1; 378 aMaxValue.Value = ::std::numeric_limits< sal_Int32 >::max(); 379 if ( DataTypeClass::gMonth == nTypeClass ) 380 aMaxValue.Value = 12; 381 else if ( DataTypeClass::gDay == nTypeClass ) 382 aMaxValue.Value = 31; 383 } 384 break; 385 386 case PROPERTY_ID_XSD_MAX_INCLUSIVE_DOUBLE: 387 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DOUBLE: 388 case PROPERTY_ID_XSD_MIN_INCLUSIVE_DOUBLE: 389 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DOUBLE: 390 nControlType = PropertyControlType::NumericField; 391 // TODO/eForms: do we have "auto-digits"? 392 break; 393 394 case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE: 395 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE: 396 case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE: 397 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE: 398 nControlType = PropertyControlType::DateField; 399 break; 400 401 case PROPERTY_ID_XSD_MAX_INCLUSIVE_TIME: 402 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_TIME: 403 case PROPERTY_ID_XSD_MIN_INCLUSIVE_TIME: 404 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_TIME: 405 nControlType = PropertyControlType::TimeField; 406 break; 407 408 case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE_TIME: 409 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE_TIME: 410 case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE_TIME: 411 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE_TIME: 412 nControlType = PropertyControlType::DateTimeField; 413 break; 414 415 default: 416 DBG_ERROR( "XSDValidationPropertyHandler::describePropertyLine: cannot handle this property!" ); 417 break; 418 } 419 420 switch ( nControlType ) 421 { 422 case PropertyControlType::ListBox: 423 aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False ); 424 break; 425 case PropertyControlType::NumericField: 426 aDescriptor.Control = PropertyHandlerHelper::createNumericControl( _rxControlFactory, 0, aMinValue, aMaxValue, sal_False ); 427 break; 428 default: 429 aDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, sal_False ); 430 break; 431 } 432 433 aDescriptor.Category = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Data" ) ); 434 aDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( nPropId ); 435 aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) ); 436 437 return aDescriptor; 438 } 439 440 //-------------------------------------------------------------------- 441 InteractiveSelectionResult SAL_CALL XSDValidationPropertyHandler::onInteractivePropertySelection( const ::rtl::OUString& _rPropertyName, sal_Bool _bPrimary, Any& /*_rData*/, const Reference< XObjectInspectorUI >& _rxInspectorUI ) throw (UnknownPropertyException, NullPointerException, RuntimeException) 442 { 443 if ( !_rxInspectorUI.is() ) 444 throw NullPointerException(); 445 446 ::osl::MutexGuard aGuard( m_aMutex ); 447 OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::onInteractivePropertySelection: we don't have any SupportedProperties!" ); 448 if ( !m_pHelper.get() ) 449 return InteractiveSelectionResult_Cancelled; 450 451 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) ); 452 453 switch ( nPropId ) 454 { 455 case PROPERTY_ID_XSD_DATA_TYPE: 456 { 457 if ( _bPrimary ) 458 { 459 ::rtl::OUString sNewDataTypeName; 460 if ( implPrepareCloneDataCurrentType( sNewDataTypeName ) ) 461 { 462 implDoCloneCurrentDataType( sNewDataTypeName ); 463 return InteractiveSelectionResult_Success; 464 } 465 } 466 else 467 return implPrepareRemoveCurrentDataType() && implDoRemoveCurrentDataType() ? InteractiveSelectionResult_Success : InteractiveSelectionResult_Cancelled; 468 } 469 break; 470 471 default: 472 DBG_ERROR( "XSDValidationPropertyHandler::onInteractivePropertySelection: unexpected property to build a dedicated UI!" ); 473 break; 474 } 475 return InteractiveSelectionResult_Cancelled; 476 } 477 478 //-------------------------------------------------------------------- 479 void SAL_CALL XSDValidationPropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException) 480 { 481 ::osl::MutexGuard aGuard( m_aMutex ); 482 XSDValidationPropertyHandler_Base::addPropertyChangeListener( _rxListener ); 483 if ( m_pHelper.get() ) 484 m_pHelper->registerBindingListener( _rxListener ); 485 } 486 487 //-------------------------------------------------------------------- 488 void SAL_CALL XSDValidationPropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException) 489 { 490 ::osl::MutexGuard aGuard( m_aMutex ); 491 if ( m_pHelper.get() ) 492 m_pHelper->revokeBindingListener( _rxListener ); 493 XSDValidationPropertyHandler_Base::removePropertyChangeListener( _rxListener ); 494 } 495 496 //-------------------------------------------------------------------- 497 bool XSDValidationPropertyHandler::implPrepareCloneDataCurrentType( ::rtl::OUString& _rNewName ) SAL_THROW(()) 498 { 499 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implPrepareCloneDataCurrentType: this will crash!" ); 500 501 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType(); 502 if ( !pType.is() ) 503 { 504 DBG_ERROR( "XSDValidationPropertyHandler::implPrepareCloneDataCurrentType: invalid current data type!" ); 505 return false; 506 } 507 508 ::std::vector< ::rtl::OUString > aExistentNames; 509 m_pHelper->getAvailableDataTypeNames( aExistentNames ); 510 511 NewDataTypeDialog aDialog( NULL, pType->getName(), aExistentNames ); // TODO/eForms: proper parent 512 if ( aDialog.Execute() != RET_OK ) 513 return false; 514 515 _rNewName = aDialog.GetName(); 516 return true; 517 } 518 519 //-------------------------------------------------------------------- 520 bool XSDValidationPropertyHandler::implDoCloneCurrentDataType( const ::rtl::OUString& _rNewName ) SAL_THROW(()) 521 { 522 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implDoCloneCurrentDataType: this will crash!" ); 523 524 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType(); 525 if ( !pType.is() ) 526 return false; 527 528 if ( !m_pHelper->cloneDataType( pType, _rNewName ) ) 529 return false; 530 531 m_pHelper->setValidatingDataTypeByName( _rNewName ); 532 return true; 533 } 534 535 //-------------------------------------------------------------------- 536 bool XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType() SAL_THROW(()) 537 { 538 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType: this will crash!" ); 539 540 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType(); 541 if ( !pType.is() ) 542 { 543 DBG_ERROR( "XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType: invalid current data type!" ); 544 return false; 545 } 546 547 // confirmation message 548 String sConfirmation( PcrRes( RID_STR_CONFIRM_DELETE_DATA_TYPE ) ); 549 sConfirmation.SearchAndReplaceAscii( "#type#", pType->getName() ); 550 QueryBox aQuery( NULL, WB_YES_NO, sConfirmation ); // TODO/eForms: proper parent 551 if ( aQuery.Execute() != RET_YES ) 552 return false; 553 554 return true; 555 } 556 557 //-------------------------------------------------------------------- 558 bool XSDValidationPropertyHandler::implDoRemoveCurrentDataType() SAL_THROW(()) 559 { 560 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implDoRemoveCurrentDataType: this will crash!" ); 561 562 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType(); 563 if ( !pType.is() ) 564 return false; 565 566 // set a new data type at the binding, which is the "basic" type for the one 567 // we are going to delete 568 // (do this before the actual deletion, so the old type is still valid for property change 569 // notifications) 570 m_pHelper->setValidatingDataTypeByName( m_pHelper->getBasicTypeNameForClass( pType->classify() ) ); 571 // now remove the type 572 m_pHelper->removeDataTypeFromRepository( pType->getName() ); 573 574 return true; 575 } 576 577 //-------------------------------------------------------------------- 578 void SAL_CALL XSDValidationPropertyHandler::actuatingPropertyChanged( const ::rtl::OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& _rOldValue, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit ) throw (NullPointerException, RuntimeException) 579 { 580 if ( !_rxInspectorUI.is() ) 581 throw NullPointerException(); 582 583 ::osl::MutexGuard aGuard( m_aMutex ); 584 PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) ); 585 if ( !m_pHelper.get() ) 586 throw RuntimeException(); 587 // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties 588 589 switch ( nActuatingPropId ) 590 { 591 case PROPERTY_ID_XSD_DATA_TYPE: 592 { 593 ::rtl::Reference< XSDDataType > xDataType( m_pHelper->getValidatingDataType() ); 594 595 // is removal of this type possible? 596 sal_Bool bIsBasicType = xDataType.is() && xDataType->isBasicType(); 597 _rxInspectorUI->enablePropertyUIElements( PROPERTY_XSD_DATA_TYPE, PropertyLineElement::PrimaryButton, xDataType.is() ); 598 _rxInspectorUI->enablePropertyUIElements( PROPERTY_XSD_DATA_TYPE, PropertyLineElement::SecondaryButton, xDataType.is() && !bIsBasicType ); 599 600 //------------------------------------------------------------ 601 // show the facets which are available at the data type 602 ::rtl::OUString aFacets[] = { 603 PROPERTY_XSD_WHITESPACES, PROPERTY_XSD_PATTERN, 604 PROPERTY_XSD_LENGTH, PROPERTY_XSD_MIN_LENGTH, PROPERTY_XSD_MAX_LENGTH, PROPERTY_XSD_TOTAL_DIGITS, 605 PROPERTY_XSD_FRACTION_DIGITS, 606 PROPERTY_XSD_MAX_INCLUSIVE_INT, 607 PROPERTY_XSD_MAX_EXCLUSIVE_INT, 608 PROPERTY_XSD_MIN_INCLUSIVE_INT, 609 PROPERTY_XSD_MIN_EXCLUSIVE_INT, 610 PROPERTY_XSD_MAX_INCLUSIVE_DOUBLE, 611 PROPERTY_XSD_MAX_EXCLUSIVE_DOUBLE, 612 PROPERTY_XSD_MIN_INCLUSIVE_DOUBLE, 613 PROPERTY_XSD_MIN_EXCLUSIVE_DOUBLE, 614 PROPERTY_XSD_MAX_INCLUSIVE_DATE, 615 PROPERTY_XSD_MAX_EXCLUSIVE_DATE, 616 PROPERTY_XSD_MIN_INCLUSIVE_DATE, 617 PROPERTY_XSD_MIN_EXCLUSIVE_DATE, 618 PROPERTY_XSD_MAX_INCLUSIVE_TIME, 619 PROPERTY_XSD_MAX_EXCLUSIVE_TIME, 620 PROPERTY_XSD_MIN_INCLUSIVE_TIME, 621 PROPERTY_XSD_MIN_EXCLUSIVE_TIME, 622 PROPERTY_XSD_MAX_INCLUSIVE_DATE_TIME, 623 PROPERTY_XSD_MAX_EXCLUSIVE_DATE_TIME, 624 PROPERTY_XSD_MIN_INCLUSIVE_DATE_TIME, 625 PROPERTY_XSD_MIN_EXCLUSIVE_DATE_TIME 626 }; 627 628 size_t i=0; 629 const ::rtl::OUString* pLoop = NULL; 630 for ( i = 0, pLoop = aFacets; 631 i < sizeof( aFacets ) / sizeof( aFacets[0] ); 632 ++i, ++pLoop 633 ) 634 { 635 showPropertyUI( _rxInspectorUI, *pLoop, xDataType.is() && xDataType->hasFacet( *pLoop ) ); 636 _rxInspectorUI->enablePropertyUI( *pLoop, !bIsBasicType ); 637 } 638 } 639 break; 640 641 case PROPERTY_ID_XML_DATA_MODEL: 642 { 643 // The data type which the current binding works with may not be present in the 644 // new model. Thus, transfer it. 645 ::rtl::OUString sOldModelName; _rOldValue >>= sOldModelName; 646 ::rtl::OUString sNewModelName; _rNewValue >>= sNewModelName; 647 ::rtl::OUString sDataType = m_pHelper->getValidatingDataTypeName(); 648 m_pHelper->copyDataType( sOldModelName, sNewModelName, sDataType ); 649 650 // the list of available data types depends on the chosen model, so update this 651 if ( !_bFirstTimeInit ) 652 _rxInspectorUI->rebuildPropertyUI( PROPERTY_XSD_DATA_TYPE ); 653 } 654 break; 655 656 default: 657 DBG_ERROR( "XSDValidationPropertyHandler::actuatingPropertyChanged: cannot handle this property!" ); 658 return; 659 } 660 661 // in both cases, we need to care for the current value of the XSD_DATA_TYPE property, 662 // and update the FormatKey of the formatted field we're inspecting (if any) 663 if ( !_bFirstTimeInit && m_pHelper->isInspectingFormattedField() ) 664 m_pHelper->findDefaultFormatForIntrospectee(); 665 } 666 667 //-------------------------------------------------------------------- 668 void XSDValidationPropertyHandler::implGetAvailableDataTypeNames( ::std::vector< ::rtl::OUString >& /* [out] */ _rNames ) const SAL_THROW(()) 669 { 670 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implGetAvailableDataTypeNames: this will crash!" ); 671 // start with *all* types which are available at the model 672 ::std::vector< ::rtl::OUString > aAllTypes; 673 m_pHelper->getAvailableDataTypeNames( aAllTypes ); 674 _rNames.clear(); 675 _rNames.reserve( aAllTypes.size() ); 676 677 // then allow only those which are "compatible" with our control 678 for ( ::std::vector< ::rtl::OUString >::const_iterator dataType = aAllTypes.begin(); 679 dataType != aAllTypes.end(); 680 ++dataType 681 ) 682 { 683 ::rtl::Reference< XSDDataType > pType = m_pHelper->getDataTypeByName( *dataType ); 684 if ( pType.is() && m_pHelper->canBindToDataType( pType->classify() ) ) 685 _rNames.push_back( *dataType ); 686 } 687 } 688 689 //........................................................................ 690 } // namespace pcr 691 //........................................................................ 692 693