merge the formfield patch from ooo-build
[ooovba.git] / extensions / source / propctrlr / xsdvalidationpropertyhandler.cxx
blob7bb323db207918108eaef22501eed1e2c9716b07
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xsdvalidationpropertyhandler.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
33 #include "xsdvalidationpropertyhandler.hxx"
34 #include "formstrings.hxx"
35 #include "formmetadata.hxx"
36 #include "xsddatatypes.hxx"
37 #ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_
38 #include "modulepcr.hxx"
39 #endif
40 #ifndef _EXTENSIONS_FORMCTRLR_PROPRESID_HRC_
41 #include "formresid.hrc"
42 #endif
43 #ifndef _EXTENSIONS_PROPCTRLR_FORMLOCALID_HRC_
44 #include "formlocalid.hrc"
45 #endif
46 #ifndef EXTENSIONS_INC_EXTENSIO_HRC
47 #include "extensio.hrc"
48 #endif
49 #include "newdatatype.hxx"
50 #include "xsdvalidationhelper.hxx"
51 #include "pcrcommon.hxx"
52 #include "handlerhelper.hxx"
54 /** === begin UNO includes === **/
55 #include <com/sun/star/beans/PropertyAttribute.hpp>
56 #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp>
57 #include <com/sun/star/xsd/DataTypeClass.hpp>
58 #include <com/sun/star/inspection/PropertyControlType.hpp>
59 #include <com/sun/star/beans/Optional.hpp>
60 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
61 #include <com/sun/star/inspection/PropertyLineElement.hpp>
62 /** === end UNO includes === **/
63 #include <vcl/msgbox.hxx>
64 #include <tools/debug.hxx>
65 #include <svtools/localresaccess.hxx>
67 #include <algorithm>
68 #include <functional>
69 #include <limits>
71 //------------------------------------------------------------------------
72 extern "C" void SAL_CALL createRegistryInfo_XSDValidationPropertyHandler()
74 ::pcr::XSDValidationPropertyHandler::registerImplementation();
77 //........................................................................
78 namespace pcr
80 //........................................................................
82 using namespace ::com::sun::star;
83 using namespace ::com::sun::star::uno;
84 using namespace ::com::sun::star::lang;
85 using namespace ::com::sun::star::beans;
86 using namespace ::com::sun::star::xforms;
87 using namespace ::com::sun::star::xsd;
88 using namespace ::com::sun::star::script;
89 using namespace ::com::sun::star::inspection;
91 using ::com::sun::star::beans::PropertyAttribute::MAYBEVOID;
93 //====================================================================
94 //= XSDValidationPropertyHandler
95 //====================================================================
96 DBG_NAME( XSDValidationPropertyHandler )
97 //--------------------------------------------------------------------
98 XSDValidationPropertyHandler::XSDValidationPropertyHandler( const Reference< XComponentContext >& _rxContext )
99 :XSDValidationPropertyHandler_Base( _rxContext )
101 DBG_CTOR( XSDValidationPropertyHandler, NULL );
104 //--------------------------------------------------------------------
105 XSDValidationPropertyHandler::~XSDValidationPropertyHandler()
107 DBG_DTOR( XSDValidationPropertyHandler, NULL );
110 //--------------------------------------------------------------------
111 ::rtl::OUString SAL_CALL XSDValidationPropertyHandler::getImplementationName_static( ) throw (RuntimeException)
113 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.XSDValidationPropertyHandler" ) );
116 //--------------------------------------------------------------------
117 Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getSupportedServiceNames_static( ) throw (RuntimeException)
119 Sequence< ::rtl::OUString > aSupported( 1 );
120 aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.XSDValidationPropertyHandler" ) );
121 return aSupported;
124 //--------------------------------------------------------------------
125 Any SAL_CALL XSDValidationPropertyHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
127 ::osl::MutexGuard aGuard( m_aMutex );
128 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
130 OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::getPropertyValue: inconsistency!" );
131 // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
133 Any aReturn;
134 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
135 switch ( nPropId )
137 // common facets
138 case PROPERTY_ID_XSD_DATA_TYPE: aReturn = pType.is() ? pType->getFacet( PROPERTY_NAME ) : makeAny( ::rtl::OUString() ); break;
139 case PROPERTY_ID_XSD_WHITESPACES:aReturn = pType.is() ? pType->getFacet( PROPERTY_XSD_WHITESPACES ) : makeAny( WhiteSpaceTreatment::Preserve ); break;
140 case PROPERTY_ID_XSD_PATTERN: aReturn = pType.is() ? pType->getFacet( PROPERTY_XSD_PATTERN ) : makeAny( ::rtl::OUString() ); break;
142 // all other properties are simply forwarded, if they exist at the given type
143 default:
145 if ( pType.is() && pType->hasFacet( _rPropertyName ) )
146 aReturn = pType->getFacet( _rPropertyName );
148 break;
151 return aReturn;
154 //--------------------------------------------------------------------
155 void SAL_CALL XSDValidationPropertyHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
157 ::osl::MutexGuard aGuard( m_aMutex );
158 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
160 OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::getPropertyValue: inconsistency!" );
161 // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
163 if ( PROPERTY_ID_XSD_DATA_TYPE == nPropId )
165 ::rtl::OUString sTypeName;
166 OSL_VERIFY( _rValue >>= sTypeName );
167 m_pHelper->setValidatingDataTypeByName( sTypeName );
168 impl_setContextDocumentModified_nothrow();
169 return;
172 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
173 if ( !pType.is() )
175 DBG_ERROR( "XSDValidationPropertyHandler::setPropertyValue: you're trying to set a type facet, without a current type!" );
176 return;
179 pType->setFacet( _rPropertyName, _rValue );
180 impl_setContextDocumentModified_nothrow();
183 //--------------------------------------------------------------------
184 void XSDValidationPropertyHandler::onNewComponent()
186 XSDValidationPropertyHandler_Base::onNewComponent();
188 Reference< frame::XModel > xDocument( impl_getContextDocument_nothrow() );
189 DBG_ASSERT( xDocument.is(), "XSDValidationPropertyHandler::onNewComponent: no document!" );
190 if ( EFormsHelper::isEForm( xDocument ) )
191 m_pHelper.reset( new XSDValidationHelper( m_aMutex, m_xComponent, xDocument ) );
192 else
193 m_pHelper.reset( NULL );
196 //--------------------------------------------------------------------
197 Sequence< Property > XSDValidationPropertyHandler::doDescribeSupportedProperties() const
199 ::std::vector< Property > aProperties;
201 if ( m_pHelper.get() )
203 bool bAllowBinding = m_pHelper->canBindToAnyDataType();
205 if ( bAllowBinding )
207 aProperties.reserve( 12 );
209 addStringPropertyDescription( aProperties, PROPERTY_XSD_DATA_TYPE );
210 addInt16PropertyDescription ( aProperties, PROPERTY_XSD_WHITESPACES );
211 addStringPropertyDescription( aProperties, PROPERTY_XSD_PATTERN );
213 // string facets
214 addInt32PropertyDescription( aProperties, PROPERTY_XSD_LENGTH, MAYBEVOID );
215 addInt32PropertyDescription( aProperties, PROPERTY_XSD_MIN_LENGTH, MAYBEVOID );
216 addInt32PropertyDescription( aProperties, PROPERTY_XSD_MAX_LENGTH, MAYBEVOID );
218 // decimal facets
219 addInt32PropertyDescription( aProperties, PROPERTY_XSD_TOTAL_DIGITS, MAYBEVOID );
220 addInt32PropertyDescription( aProperties, PROPERTY_XSD_FRACTION_DIGITS, MAYBEVOID );
222 // facets for different types
223 addInt16PropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_INT, MAYBEVOID );
224 addInt16PropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_INT, MAYBEVOID );
225 addInt16PropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_INT, MAYBEVOID );
226 addInt16PropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_INT, MAYBEVOID );
227 addDoublePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DOUBLE, MAYBEVOID );
228 addDoublePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DOUBLE, MAYBEVOID );
229 addDoublePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DOUBLE, MAYBEVOID );
230 addDoublePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DOUBLE, MAYBEVOID );
231 addDatePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DATE, MAYBEVOID );
232 addDatePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DATE, MAYBEVOID );
233 addDatePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DATE, MAYBEVOID );
234 addDatePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DATE, MAYBEVOID );
235 addTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_TIME, MAYBEVOID );
236 addTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_TIME, MAYBEVOID );
237 addTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_TIME, MAYBEVOID );
238 addTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_TIME, MAYBEVOID );
239 addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DATE_TIME, MAYBEVOID );
240 addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DATE_TIME, MAYBEVOID );
241 addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DATE_TIME, MAYBEVOID );
242 addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DATE_TIME, MAYBEVOID );
246 if ( aProperties.empty() )
247 return Sequence< Property >();
248 return Sequence< Property >( &(*aProperties.begin()), aProperties.size() );
251 //--------------------------------------------------------------------
252 Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getSupersededProperties( ) throw (RuntimeException)
254 ::osl::MutexGuard aGuard( m_aMutex );
256 ::std::vector< ::rtl::OUString > aSuperfluous;
257 if ( m_pHelper.get() )
259 aSuperfluous.push_back( PROPERTY_CONTROLSOURCE );
260 aSuperfluous.push_back( PROPERTY_EMPTY_IS_NULL );
261 aSuperfluous.push_back( PROPERTY_FILTERPROPOSAL );
262 aSuperfluous.push_back( PROPERTY_LISTSOURCETYPE );
263 aSuperfluous.push_back( PROPERTY_LISTSOURCE );
264 aSuperfluous.push_back( PROPERTY_BOUNDCOLUMN );
266 bool bAllowBinding = m_pHelper->canBindToAnyDataType();
268 if ( bAllowBinding )
270 aSuperfluous.push_back( PROPERTY_MAXTEXTLEN );
271 aSuperfluous.push_back( PROPERTY_VALUEMIN );
272 aSuperfluous.push_back( PROPERTY_VALUEMAX );
273 aSuperfluous.push_back( PROPERTY_DECIMAL_ACCURACY );
274 aSuperfluous.push_back( PROPERTY_TIMEMIN );
275 aSuperfluous.push_back( PROPERTY_TIMEMAX );
276 aSuperfluous.push_back( PROPERTY_DATEMIN );
277 aSuperfluous.push_back( PROPERTY_DATEMAX );
278 aSuperfluous.push_back( PROPERTY_EFFECTIVE_MIN );
279 aSuperfluous.push_back( PROPERTY_EFFECTIVE_MAX );
283 if ( aSuperfluous.empty() )
284 return Sequence< ::rtl::OUString >();
285 return Sequence< ::rtl::OUString >( &(*aSuperfluous.begin()), aSuperfluous.size() );
288 //--------------------------------------------------------------------
289 Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getActuatingProperties( ) throw (RuntimeException)
291 ::osl::MutexGuard aGuard( m_aMutex );
292 ::std::vector< ::rtl::OUString > aInterestedInActuations( 2 );
293 if ( m_pHelper.get() )
295 aInterestedInActuations.push_back( PROPERTY_XSD_DATA_TYPE );
296 aInterestedInActuations.push_back( PROPERTY_XML_DATA_MODEL );
298 if ( aInterestedInActuations.empty() )
299 return Sequence< ::rtl::OUString >();
300 return Sequence< ::rtl::OUString >( &(*aInterestedInActuations.begin()), aInterestedInActuations.size() );
303 //--------------------------------------------------------------------
304 namespace
306 void showPropertyUI( const Reference< XObjectInspectorUI >& _rxInspectorUI, const ::rtl::OUString& _rPropertyName, bool _bShow )
308 if ( _bShow )
309 _rxInspectorUI->showPropertyUI( _rPropertyName );
310 else
311 _rxInspectorUI->hidePropertyUI( _rPropertyName );
315 //--------------------------------------------------------------------
316 LineDescriptor SAL_CALL XSDValidationPropertyHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
317 const Reference< XPropertyControlFactory >& _rxControlFactory )
318 throw (UnknownPropertyException, NullPointerException, RuntimeException)
320 ::osl::MutexGuard aGuard( m_aMutex );
321 if ( !_rxControlFactory.is() )
322 throw NullPointerException();
323 if ( !m_pHelper.get() )
324 throw RuntimeException();
326 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
328 LineDescriptor aDescriptor;
329 if ( nPropId != PROPERTY_ID_XSD_DATA_TYPE )
330 aDescriptor.IndentLevel = 1;
332 // collect some information about the to-be-created control
333 sal_Int16 nControlType = PropertyControlType::TextField;
334 ::std::vector< ::rtl::OUString > aListEntries;
335 Optional< double > aMinValue( sal_False, 0 );
336 Optional< double > aMaxValue( sal_False, 0 );
338 switch ( nPropId )
340 case PROPERTY_ID_XSD_DATA_TYPE:
341 nControlType = PropertyControlType::ListBox;
343 implGetAvailableDataTypeNames( aListEntries );
345 aDescriptor.PrimaryButtonId = UID_PROP_ADD_DATA_TYPE;
346 aDescriptor.SecondaryButtonId = UID_PROP_REMOVE_DATA_TYPE;
347 aDescriptor.HasPrimaryButton = aDescriptor.HasSecondaryButton = sal_True;
348 aDescriptor.PrimaryButtonImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/extensions/res/buttonplus.png" ) );
349 aDescriptor.SecondaryButtonImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/extensions/res/buttonminus.png" ) );
350 break;
352 case PROPERTY_ID_XSD_WHITESPACES:
354 nControlType = PropertyControlType::ListBox;
355 aListEntries = m_pInfoService->getPropertyEnumRepresentations( PROPERTY_ID_XSD_WHITESPACES );
357 break;
359 case PROPERTY_ID_XSD_PATTERN:
360 nControlType = PropertyControlType::TextField;
361 break;
363 case PROPERTY_ID_XSD_LENGTH:
364 case PROPERTY_ID_XSD_MIN_LENGTH:
365 case PROPERTY_ID_XSD_MAX_LENGTH:
366 nControlType = PropertyControlType::NumericField;
367 break;
369 case PROPERTY_ID_XSD_TOTAL_DIGITS:
370 case PROPERTY_ID_XSD_FRACTION_DIGITS:
371 nControlType = PropertyControlType::NumericField;
372 break;
374 case PROPERTY_ID_XSD_MAX_INCLUSIVE_INT:
375 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_INT:
376 case PROPERTY_ID_XSD_MIN_INCLUSIVE_INT:
377 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_INT:
379 nControlType = PropertyControlType::NumericField;
381 // handle limits for various 'INT' types according to
382 // their actual semantics (year, month, day)
384 ::rtl::Reference< XSDDataType > xDataType( m_pHelper->getValidatingDataType() );
385 sal_Int16 nTypeClass = xDataType.is() ? xDataType->classify() : DataTypeClass::STRING;
387 aMinValue.IsPresent = aMaxValue.IsPresent = sal_True;
388 aMinValue.Value = DataTypeClass::gYear == nTypeClass ? 0 : 1;
389 aMaxValue.Value = ::std::numeric_limits< sal_Int32 >::max();
390 if ( DataTypeClass::gMonth == nTypeClass )
391 aMaxValue.Value = 12;
392 else if ( DataTypeClass::gDay == nTypeClass )
393 aMaxValue.Value = 31;
395 break;
397 case PROPERTY_ID_XSD_MAX_INCLUSIVE_DOUBLE:
398 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DOUBLE:
399 case PROPERTY_ID_XSD_MIN_INCLUSIVE_DOUBLE:
400 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DOUBLE:
401 nControlType = PropertyControlType::NumericField;
402 // TODO/eForms: do we have "auto-digits"?
403 break;
405 case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE:
406 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE:
407 case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE:
408 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE:
409 nControlType = PropertyControlType::DateField;
410 break;
412 case PROPERTY_ID_XSD_MAX_INCLUSIVE_TIME:
413 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_TIME:
414 case PROPERTY_ID_XSD_MIN_INCLUSIVE_TIME:
415 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_TIME:
416 nControlType = PropertyControlType::TimeField;
417 break;
419 case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE_TIME:
420 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE_TIME:
421 case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE_TIME:
422 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE_TIME:
423 nControlType = PropertyControlType::DateTimeField;
424 break;
426 default:
427 DBG_ERROR( "XSDValidationPropertyHandler::describePropertyLine: cannot handle this property!" );
428 break;
431 switch ( nControlType )
433 case PropertyControlType::ListBox:
434 aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
435 break;
436 case PropertyControlType::NumericField:
437 aDescriptor.Control = PropertyHandlerHelper::createNumericControl( _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
438 break;
439 default:
440 aDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, sal_False );
441 break;
444 aDescriptor.Category = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Data" ) );
445 aDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( nPropId );
446 aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) );
448 return aDescriptor;
451 //--------------------------------------------------------------------
452 InteractiveSelectionResult SAL_CALL XSDValidationPropertyHandler::onInteractivePropertySelection( const ::rtl::OUString& _rPropertyName, sal_Bool _bPrimary, Any& /*_rData*/, const Reference< XObjectInspectorUI >& _rxInspectorUI ) throw (UnknownPropertyException, NullPointerException, RuntimeException)
454 if ( !_rxInspectorUI.is() )
455 throw NullPointerException();
457 ::osl::MutexGuard aGuard( m_aMutex );
458 OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::onInteractivePropertySelection: we don't have any SupportedProperties!" );
459 if ( !m_pHelper.get() )
460 return InteractiveSelectionResult_Cancelled;
462 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
464 switch ( nPropId )
466 case PROPERTY_ID_XSD_DATA_TYPE:
468 if ( _bPrimary )
470 ::rtl::OUString sNewDataTypeName;
471 if ( implPrepareCloneDataCurrentType( sNewDataTypeName ) )
473 implDoCloneCurrentDataType( sNewDataTypeName );
474 return InteractiveSelectionResult_Success;
477 else
478 return implPrepareRemoveCurrentDataType() && implDoRemoveCurrentDataType() ? InteractiveSelectionResult_Success : InteractiveSelectionResult_Cancelled;
480 break;
482 default:
483 DBG_ERROR( "XSDValidationPropertyHandler::onInteractivePropertySelection: unexpected property to build a dedicated UI!" );
484 break;
486 return InteractiveSelectionResult_Cancelled;
489 //--------------------------------------------------------------------
490 void SAL_CALL XSDValidationPropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
492 ::osl::MutexGuard aGuard( m_aMutex );
493 XSDValidationPropertyHandler_Base::addPropertyChangeListener( _rxListener );
494 if ( m_pHelper.get() )
495 m_pHelper->registerBindingListener( _rxListener );
498 //--------------------------------------------------------------------
499 void SAL_CALL XSDValidationPropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
501 ::osl::MutexGuard aGuard( m_aMutex );
502 if ( m_pHelper.get() )
503 m_pHelper->revokeBindingListener( _rxListener );
504 XSDValidationPropertyHandler_Base::removePropertyChangeListener( _rxListener );
507 //--------------------------------------------------------------------
508 bool XSDValidationPropertyHandler::implPrepareCloneDataCurrentType( ::rtl::OUString& _rNewName ) SAL_THROW(())
510 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implPrepareCloneDataCurrentType: this will crash!" );
512 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
513 if ( !pType.is() )
515 DBG_ERROR( "XSDValidationPropertyHandler::implPrepareCloneDataCurrentType: invalid current data type!" );
516 return false;
519 ::std::vector< ::rtl::OUString > aExistentNames;
520 m_pHelper->getAvailableDataTypeNames( aExistentNames );
522 NewDataTypeDialog aDialog( NULL, pType->getName(), aExistentNames ); // TODO/eForms: proper parent
523 if ( aDialog.Execute() != RET_OK )
524 return false;
526 _rNewName = aDialog.GetName();
527 return true;
530 //--------------------------------------------------------------------
531 bool XSDValidationPropertyHandler::implDoCloneCurrentDataType( const ::rtl::OUString& _rNewName ) SAL_THROW(())
533 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implDoCloneCurrentDataType: this will crash!" );
535 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
536 if ( !pType.is() )
537 return false;
539 if ( !m_pHelper->cloneDataType( pType, _rNewName ) )
540 return false;
542 m_pHelper->setValidatingDataTypeByName( _rNewName );
543 return true;
546 //--------------------------------------------------------------------
547 bool XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType() SAL_THROW(())
549 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType: this will crash!" );
551 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
552 if ( !pType.is() )
554 DBG_ERROR( "XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType: invalid current data type!" );
555 return false;
558 // confirmation message
559 String sConfirmation( PcrRes( RID_STR_CONFIRM_DELETE_DATA_TYPE ) );
560 sConfirmation.SearchAndReplaceAscii( "#type#", pType->getName() );
561 QueryBox aQuery( NULL, WB_YES_NO, sConfirmation ); // TODO/eForms: proper parent
562 if ( aQuery.Execute() != RET_YES )
563 return false;
565 return true;
568 //--------------------------------------------------------------------
569 bool XSDValidationPropertyHandler::implDoRemoveCurrentDataType() SAL_THROW(())
571 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implDoRemoveCurrentDataType: this will crash!" );
573 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
574 if ( !pType.is() )
575 return false;
577 // set a new data type at the binding, which is the "basic" type for the one
578 // we are going to delete
579 // (do this before the actual deletion, so the old type is still valid for property change
580 // notifications)
581 m_pHelper->setValidatingDataTypeByName( m_pHelper->getBasicTypeNameForClass( pType->classify() ) );
582 // now remove the type
583 m_pHelper->removeDataTypeFromRepository( pType->getName() );
585 return true;
588 //--------------------------------------------------------------------
589 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)
591 if ( !_rxInspectorUI.is() )
592 throw NullPointerException();
594 ::osl::MutexGuard aGuard( m_aMutex );
595 PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) );
596 if ( !m_pHelper.get() )
597 throw RuntimeException();
598 // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
600 switch ( nActuatingPropId )
602 case PROPERTY_ID_XSD_DATA_TYPE:
604 ::rtl::Reference< XSDDataType > xDataType( m_pHelper->getValidatingDataType() );
606 // is removal of this type possible?
607 sal_Bool bIsBasicType = xDataType.is() && xDataType->isBasicType();
608 _rxInspectorUI->enablePropertyUIElements( PROPERTY_XSD_DATA_TYPE, PropertyLineElement::PrimaryButton, xDataType.is() );
609 _rxInspectorUI->enablePropertyUIElements( PROPERTY_XSD_DATA_TYPE, PropertyLineElement::SecondaryButton, xDataType.is() && !bIsBasicType );
611 //------------------------------------------------------------
612 // show the facets which are available at the data type
613 ::rtl::OUString aFacets[] = {
614 PROPERTY_XSD_WHITESPACES, PROPERTY_XSD_PATTERN,
615 PROPERTY_XSD_LENGTH, PROPERTY_XSD_MIN_LENGTH, PROPERTY_XSD_MAX_LENGTH, PROPERTY_XSD_TOTAL_DIGITS,
616 PROPERTY_XSD_FRACTION_DIGITS,
617 PROPERTY_XSD_MAX_INCLUSIVE_INT,
618 PROPERTY_XSD_MAX_EXCLUSIVE_INT,
619 PROPERTY_XSD_MIN_INCLUSIVE_INT,
620 PROPERTY_XSD_MIN_EXCLUSIVE_INT,
621 PROPERTY_XSD_MAX_INCLUSIVE_DOUBLE,
622 PROPERTY_XSD_MAX_EXCLUSIVE_DOUBLE,
623 PROPERTY_XSD_MIN_INCLUSIVE_DOUBLE,
624 PROPERTY_XSD_MIN_EXCLUSIVE_DOUBLE,
625 PROPERTY_XSD_MAX_INCLUSIVE_DATE,
626 PROPERTY_XSD_MAX_EXCLUSIVE_DATE,
627 PROPERTY_XSD_MIN_INCLUSIVE_DATE,
628 PROPERTY_XSD_MIN_EXCLUSIVE_DATE,
629 PROPERTY_XSD_MAX_INCLUSIVE_TIME,
630 PROPERTY_XSD_MAX_EXCLUSIVE_TIME,
631 PROPERTY_XSD_MIN_INCLUSIVE_TIME,
632 PROPERTY_XSD_MIN_EXCLUSIVE_TIME,
633 PROPERTY_XSD_MAX_INCLUSIVE_DATE_TIME,
634 PROPERTY_XSD_MAX_EXCLUSIVE_DATE_TIME,
635 PROPERTY_XSD_MIN_INCLUSIVE_DATE_TIME,
636 PROPERTY_XSD_MIN_EXCLUSIVE_DATE_TIME
639 size_t i=0;
640 const ::rtl::OUString* pLoop = NULL;
641 for ( i = 0, pLoop = aFacets;
642 i < sizeof( aFacets ) / sizeof( aFacets[0] );
643 ++i, ++pLoop
646 showPropertyUI( _rxInspectorUI, *pLoop, xDataType.is() && xDataType->hasFacet( *pLoop ) );
647 _rxInspectorUI->enablePropertyUI( *pLoop, !bIsBasicType );
650 break;
652 case PROPERTY_ID_XML_DATA_MODEL:
654 // The data type which the current binding works with may not be present in the
655 // new model. Thus, transfer it.
656 ::rtl::OUString sOldModelName; _rOldValue >>= sOldModelName;
657 ::rtl::OUString sNewModelName; _rNewValue >>= sNewModelName;
658 ::rtl::OUString sDataType = m_pHelper->getValidatingDataTypeName();
659 m_pHelper->copyDataType( sOldModelName, sNewModelName, sDataType );
661 // the list of available data types depends on the chosen model, so update this
662 if ( !_bFirstTimeInit )
663 _rxInspectorUI->rebuildPropertyUI( PROPERTY_XSD_DATA_TYPE );
665 break;
667 default:
668 DBG_ERROR( "XSDValidationPropertyHandler::actuatingPropertyChanged: cannot handle this property!" );
669 return;
672 // in both cases, we need to care for the current value of the XSD_DATA_TYPE property,
673 // and update the FormatKey of the formatted field we're inspecting (if any)
674 if ( !_bFirstTimeInit && m_pHelper->isInspectingFormattedField() )
675 m_pHelper->findDefaultFormatForIntrospectee();
678 //--------------------------------------------------------------------
679 void XSDValidationPropertyHandler::implGetAvailableDataTypeNames( ::std::vector< ::rtl::OUString >& /* [out] */ _rNames ) const SAL_THROW(())
681 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implGetAvailableDataTypeNames: this will crash!" );
682 // start with *all* types which are available at the model
683 ::std::vector< ::rtl::OUString > aAllTypes;
684 m_pHelper->getAvailableDataTypeNames( aAllTypes );
685 _rNames.clear();
686 _rNames.reserve( aAllTypes.size() );
688 // then allow only those which are "compatible" with our control
689 for ( ::std::vector< ::rtl::OUString >::const_iterator dataType = aAllTypes.begin();
690 dataType != aAllTypes.end();
691 ++dataType
694 ::rtl::Reference< XSDDataType > pType = m_pHelper->getDataTypeByName( *dataType );
695 if ( pType.is() && m_pHelper->canBindToDataType( pType->classify() ) )
696 _rNames.push_back( *dataType );
700 //........................................................................
701 } // namespace pcr
702 //........................................................................