Avoid potential negative array index access to cached text.
[LibreOffice.git] / extensions / source / propctrlr / xsdvalidationpropertyhandler.cxx
blob08eb6d7e847bd86f322f56b08d88d65e4ff6b404
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include "xsdvalidationpropertyhandler.hxx"
23 #include "formstrings.hxx"
24 #include "formmetadata.hxx"
25 #include "xsddatatypes.hxx"
26 #include "modulepcr.hxx"
27 #include <strings.hrc>
28 #include <propctrlr.h>
29 #include "newdatatype.hxx"
30 #include "xsdvalidationhelper.hxx"
31 #include "pcrcommon.hxx"
32 #include "handlerhelper.hxx"
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <com/sun/star/lang/NullPointerException.hpp>
36 #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp>
37 #include <com/sun/star/xsd/DataTypeClass.hpp>
38 #include <com/sun/star/inspection/PropertyControlType.hpp>
39 #include <com/sun/star/beans/Optional.hpp>
40 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
41 #include <com/sun/star/inspection/PropertyLineElement.hpp>
42 #include <vcl/svapp.hxx>
43 #include <vcl/weld.hxx>
44 #include <tools/debug.hxx>
45 #include <sal/macros.h>
47 #include <algorithm>
48 #include <limits>
51 namespace pcr
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::uno;
57 using namespace ::com::sun::star::lang;
58 using namespace ::com::sun::star::beans;
59 using namespace ::com::sun::star::xforms;
60 using namespace ::com::sun::star::xsd;
61 using namespace ::com::sun::star::script;
62 using namespace ::com::sun::star::inspection;
64 using ::com::sun::star::beans::PropertyAttribute::MAYBEVOID;
67 //= XSDValidationPropertyHandler
69 XSDValidationPropertyHandler::XSDValidationPropertyHandler( const Reference< XComponentContext >& _rxContext )
70 :PropertyHandlerComponent( _rxContext )
75 XSDValidationPropertyHandler::~XSDValidationPropertyHandler()
80 OUString XSDValidationPropertyHandler::getImplementationName( )
82 return "com.sun.star.comp.extensions.XSDValidationPropertyHandler";
86 Sequence< OUString > XSDValidationPropertyHandler::getSupportedServiceNames( )
88 return{ "com.sun.star.form.inspection.XSDValidationPropertyHandler" };
92 Any SAL_CALL XSDValidationPropertyHandler::getPropertyValue( const OUString& _rPropertyName )
94 ::osl::MutexGuard aGuard( m_aMutex );
95 PropertyId nPropId( impl_getPropertyId_throwUnknownProperty( _rPropertyName ) );
97 OSL_ENSURE(m_pHelper, "XSDValidationPropertyHandler::getPropertyValue: inconsistency!");
98 // if we survived impl_getPropertyId_throwUnknownProperty, we should have a helper, since no helper implies no properties
100 Any aReturn;
101 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
102 switch ( nPropId )
104 // common facets
105 case PROPERTY_ID_XSD_DATA_TYPE: aReturn = pType.is() ? pType->getFacet( PROPERTY_NAME ) : Any( OUString() ); break;
106 case PROPERTY_ID_XSD_WHITESPACES:aReturn = pType.is() ? pType->getFacet( PROPERTY_XSD_WHITESPACES ) : Any( WhiteSpaceTreatment::Preserve ); break;
107 case PROPERTY_ID_XSD_PATTERN: aReturn = pType.is() ? pType->getFacet( PROPERTY_XSD_PATTERN ) : Any( OUString() ); break;
109 // all other properties are simply forwarded, if they exist at the given type
110 default:
112 if ( pType.is() && pType->hasFacet( _rPropertyName ) )
113 aReturn = pType->getFacet( _rPropertyName );
115 break;
118 return aReturn;
122 void SAL_CALL XSDValidationPropertyHandler::setPropertyValue( const OUString& _rPropertyName, const Any& _rValue )
124 ::osl::MutexGuard aGuard( m_aMutex );
125 PropertyId nPropId( impl_getPropertyId_throwUnknownProperty( _rPropertyName ) );
127 OSL_ENSURE(m_pHelper, "XSDValidationPropertyHandler::getPropertyValue: inconsistency!");
128 // if we survived impl_getPropertyId_throwUnknownProperty, we should have a helper, since no helper implies no properties
130 if ( PROPERTY_ID_XSD_DATA_TYPE == nPropId )
132 OUString sTypeName;
133 OSL_VERIFY( _rValue >>= sTypeName );
134 m_pHelper->setValidatingDataTypeByName( sTypeName );
135 impl_setContextDocumentModified_nothrow();
136 return;
139 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
140 if ( !pType.is() )
142 OSL_FAIL( "XSDValidationPropertyHandler::setPropertyValue: you're trying to set a type facet, without a current type!" );
143 return;
146 pType->setFacet( _rPropertyName, _rValue );
147 impl_setContextDocumentModified_nothrow();
151 void XSDValidationPropertyHandler::onNewComponent()
153 PropertyHandlerComponent::onNewComponent();
155 Reference< frame::XModel > xDocument( impl_getContextDocument_nothrow() );
156 DBG_ASSERT( xDocument.is(), "XSDValidationPropertyHandler::onNewComponent: no document!" );
157 if ( EFormsHelper::isEForm( xDocument ) )
158 m_pHelper.reset( new XSDValidationHelper( m_aMutex, m_xComponent, xDocument ) );
159 else
160 m_pHelper.reset();
164 Sequence< Property > XSDValidationPropertyHandler::doDescribeSupportedProperties() const
166 std::vector< Property > aProperties;
168 if (m_pHelper)
170 bool bAllowBinding = m_pHelper->canBindToAnyDataType();
172 if ( bAllowBinding )
174 aProperties.reserve( 28 );
176 addStringPropertyDescription( aProperties, PROPERTY_XSD_DATA_TYPE );
177 addInt16PropertyDescription ( aProperties, PROPERTY_XSD_WHITESPACES );
178 addStringPropertyDescription( aProperties, PROPERTY_XSD_PATTERN );
180 // string facets
181 addInt32PropertyDescription( aProperties, PROPERTY_XSD_LENGTH, MAYBEVOID );
182 addInt32PropertyDescription( aProperties, PROPERTY_XSD_MIN_LENGTH, MAYBEVOID );
183 addInt32PropertyDescription( aProperties, PROPERTY_XSD_MAX_LENGTH, MAYBEVOID );
185 // decimal facets
186 addInt32PropertyDescription( aProperties, PROPERTY_XSD_TOTAL_DIGITS, MAYBEVOID );
187 addInt32PropertyDescription( aProperties, PROPERTY_XSD_FRACTION_DIGITS, MAYBEVOID );
189 // facets for different types
190 addInt16PropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_INT, MAYBEVOID );
191 addInt16PropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_INT, MAYBEVOID );
192 addInt16PropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_INT, MAYBEVOID );
193 addInt16PropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_INT, MAYBEVOID );
194 addDoublePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DOUBLE, MAYBEVOID );
195 addDoublePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DOUBLE, MAYBEVOID );
196 addDoublePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DOUBLE, MAYBEVOID );
197 addDoublePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DOUBLE, MAYBEVOID );
198 addDatePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DATE, MAYBEVOID );
199 addDatePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DATE, MAYBEVOID );
200 addDatePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DATE, MAYBEVOID );
201 addDatePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DATE, MAYBEVOID );
202 addTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_TIME, MAYBEVOID );
203 addTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_TIME, MAYBEVOID );
204 addTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_TIME, MAYBEVOID );
205 addTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_TIME, MAYBEVOID );
206 addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DATE_TIME, MAYBEVOID );
207 addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DATE_TIME, MAYBEVOID );
208 addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DATE_TIME, MAYBEVOID );
209 addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DATE_TIME, MAYBEVOID );
213 return comphelper::containerToSequence( aProperties );
217 Sequence< OUString > SAL_CALL XSDValidationPropertyHandler::getSupersededProperties( )
219 ::osl::MutexGuard aGuard( m_aMutex );
221 std::vector< OUString > aSuperfluous;
222 if (m_pHelper)
224 aSuperfluous.push_back( PROPERTY_CONTROLSOURCE );
225 aSuperfluous.push_back( PROPERTY_EMPTY_IS_NULL );
226 aSuperfluous.push_back( PROPERTY_FILTERPROPOSAL );
227 aSuperfluous.push_back( PROPERTY_LISTSOURCETYPE );
228 aSuperfluous.push_back( PROPERTY_LISTSOURCE );
229 aSuperfluous.push_back( PROPERTY_BOUNDCOLUMN );
231 bool bAllowBinding = m_pHelper->canBindToAnyDataType();
233 if ( bAllowBinding )
235 aSuperfluous.push_back( PROPERTY_MAXTEXTLEN );
236 aSuperfluous.push_back( PROPERTY_VALUEMIN );
237 aSuperfluous.push_back( PROPERTY_VALUEMAX );
238 aSuperfluous.push_back( PROPERTY_DECIMAL_ACCURACY );
239 aSuperfluous.push_back( PROPERTY_TIMEMIN );
240 aSuperfluous.push_back( PROPERTY_TIMEMAX );
241 aSuperfluous.push_back( PROPERTY_DATEMIN );
242 aSuperfluous.push_back( PROPERTY_DATEMAX );
243 aSuperfluous.push_back( PROPERTY_EFFECTIVE_MIN );
244 aSuperfluous.push_back( PROPERTY_EFFECTIVE_MAX );
248 return comphelper::containerToSequence( aSuperfluous );
252 Sequence< OUString > SAL_CALL XSDValidationPropertyHandler::getActuatingProperties( )
254 ::osl::MutexGuard aGuard( m_aMutex );
255 std::vector< OUString > aInterestedInActuations;
256 if (m_pHelper)
258 aInterestedInActuations.push_back( PROPERTY_XSD_DATA_TYPE );
259 aInterestedInActuations.push_back( PROPERTY_XML_DATA_MODEL );
261 return comphelper::containerToSequence( aInterestedInActuations );
265 namespace
267 void showPropertyUI( const Reference< XObjectInspectorUI >& _rxInspectorUI, const OUString& _rPropertyName, bool _bShow )
269 if ( _bShow )
270 _rxInspectorUI->showPropertyUI( _rPropertyName );
271 else
272 _rxInspectorUI->hidePropertyUI( _rPropertyName );
277 LineDescriptor SAL_CALL XSDValidationPropertyHandler::describePropertyLine( const OUString& _rPropertyName,
278 const Reference< XPropertyControlFactory >& _rxControlFactory )
280 ::osl::MutexGuard aGuard( m_aMutex );
281 if ( !_rxControlFactory.is() )
282 throw NullPointerException();
283 if (!m_pHelper)
284 throw RuntimeException();
286 PropertyId nPropId( impl_getPropertyId_throwUnknownProperty( _rPropertyName ) );
288 LineDescriptor aDescriptor;
289 if ( nPropId != PROPERTY_ID_XSD_DATA_TYPE )
290 aDescriptor.IndentLevel = 1;
292 // collect some information about the to-be-created control
293 sal_Int16 nControlType = PropertyControlType::TextField;
294 std::vector< OUString > aListEntries;
295 Optional< double > aMinValue( false, 0 );
296 Optional< double > aMaxValue( false, 0 );
298 switch ( nPropId )
300 case PROPERTY_ID_XSD_DATA_TYPE:
301 nControlType = PropertyControlType::ListBox;
303 implGetAvailableDataTypeNames( aListEntries );
305 aDescriptor.PrimaryButtonId = UID_PROP_ADD_DATA_TYPE;
306 aDescriptor.SecondaryButtonId = UID_PROP_REMOVE_DATA_TYPE;
307 aDescriptor.HasPrimaryButton = aDescriptor.HasSecondaryButton = true;
308 aDescriptor.PrimaryButtonImageURL = "private:graphicrepository/extensions/res/buttonplus.png";
309 aDescriptor.SecondaryButtonImageURL = "private:graphicrepository/extensions/res/buttonminus.png";
310 break;
312 case PROPERTY_ID_XSD_WHITESPACES:
314 nControlType = PropertyControlType::ListBox;
315 aListEntries = m_pInfoService->getPropertyEnumRepresentations( PROPERTY_ID_XSD_WHITESPACES );
317 break;
319 case PROPERTY_ID_XSD_PATTERN:
320 nControlType = PropertyControlType::TextField;
321 break;
323 case PROPERTY_ID_XSD_LENGTH:
324 case PROPERTY_ID_XSD_MIN_LENGTH:
325 case PROPERTY_ID_XSD_MAX_LENGTH:
326 nControlType = PropertyControlType::NumericField;
327 break;
329 case PROPERTY_ID_XSD_TOTAL_DIGITS:
330 case PROPERTY_ID_XSD_FRACTION_DIGITS:
331 nControlType = PropertyControlType::NumericField;
332 break;
334 case PROPERTY_ID_XSD_MAX_INCLUSIVE_INT:
335 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_INT:
336 case PROPERTY_ID_XSD_MIN_INCLUSIVE_INT:
337 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_INT:
339 nControlType = PropertyControlType::NumericField;
341 // handle limits for various 'INT' types according to
342 // their actual semantics (year, month, day)
344 ::rtl::Reference< XSDDataType > xDataType( m_pHelper->getValidatingDataType() );
345 sal_Int16 nTypeClass = xDataType.is() ? xDataType->classify() : DataTypeClass::STRING;
347 aMinValue.IsPresent = aMaxValue.IsPresent = true;
348 aMinValue.Value = DataTypeClass::gYear == nTypeClass ? 0 : 1;
349 aMaxValue.Value = std::numeric_limits< sal_Int32 >::max();
350 if ( DataTypeClass::gMonth == nTypeClass )
351 aMaxValue.Value = 12;
352 else if ( DataTypeClass::gDay == nTypeClass )
353 aMaxValue.Value = 31;
355 break;
357 case PROPERTY_ID_XSD_MAX_INCLUSIVE_DOUBLE:
358 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DOUBLE:
359 case PROPERTY_ID_XSD_MIN_INCLUSIVE_DOUBLE:
360 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DOUBLE:
361 nControlType = PropertyControlType::NumericField;
362 // TODO/eForms: do we have "auto-digits"?
363 break;
365 case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE:
366 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE:
367 case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE:
368 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE:
369 nControlType = PropertyControlType::DateField;
370 break;
372 case PROPERTY_ID_XSD_MAX_INCLUSIVE_TIME:
373 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_TIME:
374 case PROPERTY_ID_XSD_MIN_INCLUSIVE_TIME:
375 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_TIME:
376 nControlType = PropertyControlType::TimeField;
377 break;
379 case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE_TIME:
380 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE_TIME:
381 case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE_TIME:
382 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE_TIME:
383 nControlType = PropertyControlType::DateTimeField;
384 break;
386 default:
387 OSL_FAIL( "XSDValidationPropertyHandler::describePropertyLine: cannot handle this property!" );
388 break;
391 switch ( nControlType )
393 case PropertyControlType::ListBox:
394 aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, std::move(aListEntries), false, false );
395 break;
396 case PropertyControlType::NumericField:
397 aDescriptor.Control = PropertyHandlerHelper::createNumericControl( _rxControlFactory, 0, aMinValue, aMaxValue );
398 break;
399 default:
400 aDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, false );
401 break;
404 aDescriptor.Category = "Data";
405 aDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( nPropId );
406 aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) );
408 return aDescriptor;
412 InteractiveSelectionResult SAL_CALL XSDValidationPropertyHandler::onInteractivePropertySelection( const OUString& _rPropertyName, sal_Bool _bPrimary, Any& /*_rData*/, const Reference< XObjectInspectorUI >& _rxInspectorUI )
414 if ( !_rxInspectorUI.is() )
415 throw NullPointerException();
417 ::osl::MutexGuard aGuard( m_aMutex );
418 OSL_ENSURE(m_pHelper, "XSDValidationPropertyHandler::onInteractivePropertySelection: we "
419 "don't have any SupportedProperties!");
420 if (!m_pHelper)
421 return InteractiveSelectionResult_Cancelled;
423 PropertyId nPropId( impl_getPropertyId_throwUnknownProperty( _rPropertyName ) );
425 switch ( nPropId )
427 case PROPERTY_ID_XSD_DATA_TYPE:
429 if ( _bPrimary )
431 OUString sNewDataTypeName;
432 if ( implPrepareCloneDataCurrentType( sNewDataTypeName ) )
434 implDoCloneCurrentDataType( sNewDataTypeName );
435 return InteractiveSelectionResult_Success;
438 else
439 return implPrepareRemoveCurrentDataType() && implDoRemoveCurrentDataType() ? InteractiveSelectionResult_Success : InteractiveSelectionResult_Cancelled;
441 break;
443 default:
444 OSL_FAIL( "XSDValidationPropertyHandler::onInteractivePropertySelection: unexpected property to build a dedicated UI!" );
445 break;
447 return InteractiveSelectionResult_Cancelled;
451 void SAL_CALL XSDValidationPropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener )
453 ::osl::MutexGuard aGuard( m_aMutex );
454 PropertyHandlerComponent::addPropertyChangeListener( _rxListener );
455 if (m_pHelper)
456 m_pHelper->registerBindingListener( _rxListener );
460 void SAL_CALL XSDValidationPropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener )
462 ::osl::MutexGuard aGuard( m_aMutex );
463 if (m_pHelper)
464 m_pHelper->revokeBindingListener( _rxListener );
465 PropertyHandlerComponent::removePropertyChangeListener( _rxListener );
469 bool XSDValidationPropertyHandler::implPrepareCloneDataCurrentType( OUString& _rNewName )
471 OSL_PRECOND(
472 m_pHelper,
473 "XSDValidationPropertyHandler::implPrepareCloneDataCurrentType: this will crash!");
475 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
476 if ( !pType.is() )
478 OSL_FAIL( "XSDValidationPropertyHandler::implPrepareCloneDataCurrentType: invalid current data type!" );
479 return false;
482 std::vector< OUString > aExistentNames;
483 m_pHelper->getAvailableDataTypeNames( aExistentNames );
485 NewDataTypeDialog aDialog( nullptr, pType->getName(), aExistentNames ); // TODO/eForms: proper parent
486 if (aDialog.run() != RET_OK)
487 return false;
489 _rNewName = aDialog.GetName();
490 return true;
494 void XSDValidationPropertyHandler::implDoCloneCurrentDataType( const OUString& _rNewName )
496 OSL_PRECOND(m_pHelper,
497 "XSDValidationPropertyHandler::implDoCloneCurrentDataType: this will crash!");
499 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
500 if ( !pType.is() )
501 return;
503 if ( !m_pHelper->cloneDataType( pType, _rNewName ) )
504 return;
506 m_pHelper->setValidatingDataTypeByName( _rNewName );
509 bool XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType()
511 OSL_PRECOND(
512 m_pHelper,
513 "XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType: this will crash!");
515 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
516 if ( !pType.is() )
518 OSL_FAIL( "XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType: invalid current data type!" );
519 return false;
522 // confirmation message
523 OUString sConfirmation( PcrRes( RID_STR_CONFIRM_DELETE_DATA_TYPE ) );
524 sConfirmation = sConfirmation.replaceFirst( "#type#", pType->getName() );
526 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(nullptr, // TODO/eForms: proper parent
527 VclMessageType::Question, VclButtonsType::YesNo,
528 sConfirmation));
529 return xQueryBox->run() == RET_YES;
532 bool XSDValidationPropertyHandler::implDoRemoveCurrentDataType()
534 OSL_PRECOND(m_pHelper,
535 "XSDValidationPropertyHandler::implDoRemoveCurrentDataType: this will crash!");
537 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
538 if ( !pType.is() )
539 return false;
541 // set a new data type at the binding, which is the "basic" type for the one
542 // we are going to delete
543 // (do this before the actual deletion, so the old type is still valid for property change
544 // notifications)
545 m_pHelper->setValidatingDataTypeByName( m_pHelper->getBasicTypeNameForClass( pType->classify() ) );
546 // now remove the type
547 m_pHelper->removeDataTypeFromRepository( pType->getName() );
549 return true;
553 void SAL_CALL XSDValidationPropertyHandler::actuatingPropertyChanged( const OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& _rOldValue, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit )
555 if ( !_rxInspectorUI.is() )
556 throw NullPointerException();
558 ::osl::MutexGuard aGuard( m_aMutex );
559 PropertyId nActuatingPropId( impl_getPropertyId_throwRuntime( _rActuatingPropertyName ) );
560 if (!m_pHelper)
561 throw RuntimeException();
562 // if we survived impl_getPropertyId_throwRuntime, we should have a helper, since no helper implies no properties
564 switch ( nActuatingPropId )
566 case PROPERTY_ID_XSD_DATA_TYPE:
568 ::rtl::Reference< XSDDataType > xDataType( m_pHelper->getValidatingDataType() );
570 // is removal of this type possible?
571 bool bIsBasicType = xDataType.is() && xDataType->isBasicType();
572 _rxInspectorUI->enablePropertyUIElements( PROPERTY_XSD_DATA_TYPE, PropertyLineElement::PrimaryButton, xDataType.is() );
573 _rxInspectorUI->enablePropertyUIElements( PROPERTY_XSD_DATA_TYPE, PropertyLineElement::SecondaryButton, xDataType.is() && !bIsBasicType );
576 // show the facets which are available at the data type
577 OUString aFacets[] = {
578 PROPERTY_XSD_WHITESPACES, PROPERTY_XSD_PATTERN,
579 PROPERTY_XSD_LENGTH, PROPERTY_XSD_MIN_LENGTH, PROPERTY_XSD_MAX_LENGTH, PROPERTY_XSD_TOTAL_DIGITS,
580 PROPERTY_XSD_FRACTION_DIGITS,
581 PROPERTY_XSD_MAX_INCLUSIVE_INT,
582 PROPERTY_XSD_MAX_EXCLUSIVE_INT,
583 PROPERTY_XSD_MIN_INCLUSIVE_INT,
584 PROPERTY_XSD_MIN_EXCLUSIVE_INT,
585 PROPERTY_XSD_MAX_INCLUSIVE_DOUBLE,
586 PROPERTY_XSD_MAX_EXCLUSIVE_DOUBLE,
587 PROPERTY_XSD_MIN_INCLUSIVE_DOUBLE,
588 PROPERTY_XSD_MIN_EXCLUSIVE_DOUBLE,
589 PROPERTY_XSD_MAX_INCLUSIVE_DATE,
590 PROPERTY_XSD_MAX_EXCLUSIVE_DATE,
591 PROPERTY_XSD_MIN_INCLUSIVE_DATE,
592 PROPERTY_XSD_MIN_EXCLUSIVE_DATE,
593 PROPERTY_XSD_MAX_INCLUSIVE_TIME,
594 PROPERTY_XSD_MAX_EXCLUSIVE_TIME,
595 PROPERTY_XSD_MIN_INCLUSIVE_TIME,
596 PROPERTY_XSD_MIN_EXCLUSIVE_TIME,
597 PROPERTY_XSD_MAX_INCLUSIVE_DATE_TIME,
598 PROPERTY_XSD_MAX_EXCLUSIVE_DATE_TIME,
599 PROPERTY_XSD_MIN_INCLUSIVE_DATE_TIME,
600 PROPERTY_XSD_MIN_EXCLUSIVE_DATE_TIME
603 size_t i=0;
604 const OUString* pLoop = nullptr;
605 for ( i = 0, pLoop = aFacets;
606 i < SAL_N_ELEMENTS( aFacets );
607 ++i, ++pLoop
610 showPropertyUI( _rxInspectorUI, *pLoop, xDataType.is() && xDataType->hasFacet( *pLoop ) );
611 _rxInspectorUI->enablePropertyUI( *pLoop, !bIsBasicType );
614 break;
616 case PROPERTY_ID_XML_DATA_MODEL:
618 // The data type which the current binding works with may not be present in the
619 // new model. Thus, transfer it.
620 OUString sOldModelName; _rOldValue >>= sOldModelName;
621 OUString sNewModelName; _rNewValue >>= sNewModelName;
622 OUString sDataType = m_pHelper->getValidatingDataTypeName();
623 m_pHelper->copyDataType( sOldModelName, sNewModelName, sDataType );
625 // the list of available data types depends on the chosen model, so update this
626 if ( !_bFirstTimeInit )
627 _rxInspectorUI->rebuildPropertyUI( PROPERTY_XSD_DATA_TYPE );
629 break;
631 default:
632 OSL_FAIL( "XSDValidationPropertyHandler::actuatingPropertyChanged: cannot handle this property!" );
633 return;
636 // in both cases, we need to care for the current value of the XSD_DATA_TYPE property,
637 // and update the FormatKey of the formatted field we're inspecting (if any)
638 if ( !_bFirstTimeInit && m_pHelper->isInspectingFormattedField() )
639 m_pHelper->findDefaultFormatForIntrospectee();
643 void XSDValidationPropertyHandler::implGetAvailableDataTypeNames( std::vector< OUString >& /* [out] */ _rNames ) const
645 OSL_PRECOND(
646 m_pHelper,
647 "XSDValidationPropertyHandler::implGetAvailableDataTypeNames: this will crash!");
648 // start with *all* types which are available at the model
649 std::vector< OUString > aAllTypes;
650 m_pHelper->getAvailableDataTypeNames( aAllTypes );
651 _rNames.clear();
652 _rNames.reserve( aAllTypes.size() );
654 // then allow only those which are "compatible" with our control
655 for (auto const& dataType : aAllTypes)
657 ::rtl::Reference< XSDDataType > pType = m_pHelper->getDataTypeByName(dataType);
658 if ( pType.is() && m_pHelper->canBindToDataType( pType->classify() ) )
659 _rNames.push_back(dataType);
664 } // namespace pcr
666 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
667 extensions_propctrlr_XSDValidationPropertyHandler_get_implementation(
668 css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any> const&)
670 return cppu::acquire(new pcr::XSDValidationPropertyHandler(context));
673 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */