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