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 //------------------------------------------------------------------------
createRegistryInfo_XSDValidationPropertyHandler()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 //====================================================================
DBG_NAME(XSDValidationPropertyHandler)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 //--------------------------------------------------------------------
~XSDValidationPropertyHandler()90 XSDValidationPropertyHandler::~XSDValidationPropertyHandler()
91 {
92 DBG_DTOR( XSDValidationPropertyHandler, NULL );
93 }
94
95 //--------------------------------------------------------------------
getImplementationName_static()96 ::rtl::OUString SAL_CALL XSDValidationPropertyHandler::getImplementationName_static( )
97 {
98 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.XSDValidationPropertyHandler" ) );
99 }
100
101 //--------------------------------------------------------------------
getSupportedServiceNames_static()102 Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getSupportedServiceNames_static( )
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 //--------------------------------------------------------------------
getPropertyValue(const::rtl::OUString & _rPropertyName)110 Any SAL_CALL XSDValidationPropertyHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName )
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 //--------------------------------------------------------------------
setPropertyValue(const::rtl::OUString & _rPropertyName,const Any & _rValue)140 void SAL_CALL XSDValidationPropertyHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue )
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 //--------------------------------------------------------------------
onNewComponent()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();
179 }
180
181 //--------------------------------------------------------------------
doDescribeSupportedProperties() const182 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 //--------------------------------------------------------------------
getSupersededProperties()237 Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getSupersededProperties( )
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 //--------------------------------------------------------------------
getActuatingProperties()274 Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getActuatingProperties( )
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 {
showPropertyUI(const Reference<XObjectInspectorUI> & _rxInspectorUI,const::rtl::OUString & _rPropertyName,bool _bShow)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 //--------------------------------------------------------------------
describePropertyLine(const::rtl::OUString & _rPropertyName,const Reference<XPropertyControlFactory> & _rxControlFactory)301 LineDescriptor SAL_CALL XSDValidationPropertyHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
302 const Reference< XPropertyControlFactory >& _rxControlFactory )
303 {
304 ::osl::MutexGuard aGuard( m_aMutex );
305 if ( !_rxControlFactory.is() )
306 throw NullPointerException();
307 if ( !m_pHelper.get() )
308 throw RuntimeException();
309
310 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
311
312 LineDescriptor aDescriptor;
313 if ( nPropId != PROPERTY_ID_XSD_DATA_TYPE )
314 aDescriptor.IndentLevel = 1;
315
316 // collect some information about the to-be-created control
317 sal_Int16 nControlType = PropertyControlType::TextField;
318 ::std::vector< ::rtl::OUString > aListEntries;
319 Optional< double > aMinValue( sal_False, 0 );
320 Optional< double > aMaxValue( sal_False, 0 );
321
322 switch ( nPropId )
323 {
324 case PROPERTY_ID_XSD_DATA_TYPE:
325 nControlType = PropertyControlType::ListBox;
326
327 implGetAvailableDataTypeNames( aListEntries );
328
329 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_ADD_DATA_TYPE);
330 aDescriptor.SecondaryButtonId = rtl::OUString::createFromAscii(UID_PROP_REMOVE_DATA_TYPE);
331 aDescriptor.HasPrimaryButton = aDescriptor.HasSecondaryButton = sal_True;
332 aDescriptor.PrimaryButtonImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/extensions/res/buttonplus.png" ) );
333 aDescriptor.SecondaryButtonImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/extensions/res/buttonminus.png" ) );
334 break;
335
336 case PROPERTY_ID_XSD_WHITESPACES:
337 {
338 nControlType = PropertyControlType::ListBox;
339 aListEntries = m_pInfoService->getPropertyEnumRepresentations( PROPERTY_ID_XSD_WHITESPACES );
340 }
341 break;
342
343 case PROPERTY_ID_XSD_PATTERN:
344 nControlType = PropertyControlType::TextField;
345 break;
346
347 case PROPERTY_ID_XSD_LENGTH:
348 case PROPERTY_ID_XSD_MIN_LENGTH:
349 case PROPERTY_ID_XSD_MAX_LENGTH:
350 nControlType = PropertyControlType::NumericField;
351 break;
352
353 case PROPERTY_ID_XSD_TOTAL_DIGITS:
354 case PROPERTY_ID_XSD_FRACTION_DIGITS:
355 nControlType = PropertyControlType::NumericField;
356 break;
357
358 case PROPERTY_ID_XSD_MAX_INCLUSIVE_INT:
359 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_INT:
360 case PROPERTY_ID_XSD_MIN_INCLUSIVE_INT:
361 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_INT:
362 {
363 nControlType = PropertyControlType::NumericField;
364
365 // handle limits for various 'INT' types according to
366 // their actual semantics (year, month, day)
367
368 ::rtl::Reference< XSDDataType > xDataType( m_pHelper->getValidatingDataType() );
369 sal_Int16 nTypeClass = xDataType.is() ? xDataType->classify() : DataTypeClass::STRING;
370
371 aMinValue.IsPresent = aMaxValue.IsPresent = sal_True;
372 aMinValue.Value = DataTypeClass::gYear == nTypeClass ? 0 : 1;
373 aMaxValue.Value = ::std::numeric_limits< sal_Int32 >::max();
374 if ( DataTypeClass::gMonth == nTypeClass )
375 aMaxValue.Value = 12;
376 else if ( DataTypeClass::gDay == nTypeClass )
377 aMaxValue.Value = 31;
378 }
379 break;
380
381 case PROPERTY_ID_XSD_MAX_INCLUSIVE_DOUBLE:
382 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DOUBLE:
383 case PROPERTY_ID_XSD_MIN_INCLUSIVE_DOUBLE:
384 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DOUBLE:
385 nControlType = PropertyControlType::NumericField;
386 // TODO/eForms: do we have "auto-digits"?
387 break;
388
389 case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE:
390 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE:
391 case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE:
392 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE:
393 nControlType = PropertyControlType::DateField;
394 break;
395
396 case PROPERTY_ID_XSD_MAX_INCLUSIVE_TIME:
397 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_TIME:
398 case PROPERTY_ID_XSD_MIN_INCLUSIVE_TIME:
399 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_TIME:
400 nControlType = PropertyControlType::TimeField;
401 break;
402
403 case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE_TIME:
404 case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE_TIME:
405 case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE_TIME:
406 case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE_TIME:
407 nControlType = PropertyControlType::DateTimeField;
408 break;
409
410 default:
411 DBG_ERROR( "XSDValidationPropertyHandler::describePropertyLine: cannot handle this property!" );
412 break;
413 }
414
415 switch ( nControlType )
416 {
417 case PropertyControlType::ListBox:
418 aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
419 break;
420 case PropertyControlType::NumericField:
421 aDescriptor.Control = PropertyHandlerHelper::createNumericControl( _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
422 break;
423 default:
424 aDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, sal_False );
425 break;
426 }
427
428 aDescriptor.Category = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Data" ) );
429 aDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( nPropId );
430 aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) );
431
432 return aDescriptor;
433 }
434
435 //--------------------------------------------------------------------
onInteractivePropertySelection(const::rtl::OUString & _rPropertyName,sal_Bool _bPrimary,Any &,const Reference<XObjectInspectorUI> & _rxInspectorUI)436 InteractiveSelectionResult SAL_CALL XSDValidationPropertyHandler::onInteractivePropertySelection( const ::rtl::OUString& _rPropertyName, sal_Bool _bPrimary, Any& /*_rData*/, const Reference< XObjectInspectorUI >& _rxInspectorUI )
437 {
438 if ( !_rxInspectorUI.is() )
439 throw NullPointerException();
440
441 ::osl::MutexGuard aGuard( m_aMutex );
442 OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::onInteractivePropertySelection: we don't have any SupportedProperties!" );
443 if ( !m_pHelper.get() )
444 return InteractiveSelectionResult_Cancelled;
445
446 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
447
448 switch ( nPropId )
449 {
450 case PROPERTY_ID_XSD_DATA_TYPE:
451 {
452 if ( _bPrimary )
453 {
454 ::rtl::OUString sNewDataTypeName;
455 if ( implPrepareCloneDataCurrentType( sNewDataTypeName ) )
456 {
457 implDoCloneCurrentDataType( sNewDataTypeName );
458 return InteractiveSelectionResult_Success;
459 }
460 }
461 else
462 return implPrepareRemoveCurrentDataType() && implDoRemoveCurrentDataType() ? InteractiveSelectionResult_Success : InteractiveSelectionResult_Cancelled;
463 }
464 break;
465
466 default:
467 DBG_ERROR( "XSDValidationPropertyHandler::onInteractivePropertySelection: unexpected property to build a dedicated UI!" );
468 break;
469 }
470 return InteractiveSelectionResult_Cancelled;
471 }
472
473 //--------------------------------------------------------------------
addPropertyChangeListener(const Reference<XPropertyChangeListener> & _rxListener)474 void SAL_CALL XSDValidationPropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener )
475 {
476 ::osl::MutexGuard aGuard( m_aMutex );
477 XSDValidationPropertyHandler_Base::addPropertyChangeListener( _rxListener );
478 if ( m_pHelper.get() )
479 m_pHelper->registerBindingListener( _rxListener );
480 }
481
482 //--------------------------------------------------------------------
removePropertyChangeListener(const Reference<XPropertyChangeListener> & _rxListener)483 void SAL_CALL XSDValidationPropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener )
484 {
485 ::osl::MutexGuard aGuard( m_aMutex );
486 if ( m_pHelper.get() )
487 m_pHelper->revokeBindingListener( _rxListener );
488 XSDValidationPropertyHandler_Base::removePropertyChangeListener( _rxListener );
489 }
490
491 //--------------------------------------------------------------------
implPrepareCloneDataCurrentType(::rtl::OUString & _rNewName)492 bool XSDValidationPropertyHandler::implPrepareCloneDataCurrentType( ::rtl::OUString& _rNewName ) SAL_THROW(())
493 {
494 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implPrepareCloneDataCurrentType: this will crash!" );
495
496 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
497 if ( !pType.is() )
498 {
499 DBG_ERROR( "XSDValidationPropertyHandler::implPrepareCloneDataCurrentType: invalid current data type!" );
500 return false;
501 }
502
503 ::std::vector< ::rtl::OUString > aExistentNames;
504 m_pHelper->getAvailableDataTypeNames( aExistentNames );
505
506 NewDataTypeDialog aDialog( NULL, pType->getName(), aExistentNames ); // TODO/eForms: proper parent
507 if ( aDialog.Execute() != RET_OK )
508 return false;
509
510 _rNewName = aDialog.GetName();
511 return true;
512 }
513
514 //--------------------------------------------------------------------
implDoCloneCurrentDataType(const::rtl::OUString & _rNewName)515 bool XSDValidationPropertyHandler::implDoCloneCurrentDataType( const ::rtl::OUString& _rNewName ) SAL_THROW(())
516 {
517 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implDoCloneCurrentDataType: this will crash!" );
518
519 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
520 if ( !pType.is() )
521 return false;
522
523 if ( !m_pHelper->cloneDataType( pType, _rNewName ) )
524 return false;
525
526 m_pHelper->setValidatingDataTypeByName( _rNewName );
527 return true;
528 }
529
530 //--------------------------------------------------------------------
implPrepareRemoveCurrentDataType()531 bool XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType() SAL_THROW(())
532 {
533 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType: this will crash!" );
534
535 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
536 if ( !pType.is() )
537 {
538 DBG_ERROR( "XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType: invalid current data type!" );
539 return false;
540 }
541
542 // confirmation message
543 String sConfirmation( PcrRes( RID_STR_CONFIRM_DELETE_DATA_TYPE ) );
544 sConfirmation.SearchAndReplaceAscii( "#type#", pType->getName() );
545 QueryBox aQuery( NULL, WB_YES_NO, sConfirmation ); // TODO/eForms: proper parent
546 if ( aQuery.Execute() != RET_YES )
547 return false;
548
549 return true;
550 }
551
552 //--------------------------------------------------------------------
implDoRemoveCurrentDataType()553 bool XSDValidationPropertyHandler::implDoRemoveCurrentDataType() SAL_THROW(())
554 {
555 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implDoRemoveCurrentDataType: this will crash!" );
556
557 ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
558 if ( !pType.is() )
559 return false;
560
561 // set a new data type at the binding, which is the "basic" type for the one
562 // we are going to delete
563 // (do this before the actual deletion, so the old type is still valid for property change
564 // notifications)
565 m_pHelper->setValidatingDataTypeByName( m_pHelper->getBasicTypeNameForClass( pType->classify() ) );
566 // now remove the type
567 m_pHelper->removeDataTypeFromRepository( pType->getName() );
568
569 return true;
570 }
571
572 //--------------------------------------------------------------------
actuatingPropertyChanged(const::rtl::OUString & _rActuatingPropertyName,const Any & _rNewValue,const Any & _rOldValue,const Reference<XObjectInspectorUI> & _rxInspectorUI,sal_Bool _bFirstTimeInit)573 void SAL_CALL XSDValidationPropertyHandler::actuatingPropertyChanged( const ::rtl::OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& _rOldValue, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit )
574 {
575 if ( !_rxInspectorUI.is() )
576 throw NullPointerException();
577
578 ::osl::MutexGuard aGuard( m_aMutex );
579 PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) );
580 if ( !m_pHelper.get() )
581 throw RuntimeException();
582 // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
583
584 switch ( nActuatingPropId )
585 {
586 case PROPERTY_ID_XSD_DATA_TYPE:
587 {
588 ::rtl::Reference< XSDDataType > xDataType( m_pHelper->getValidatingDataType() );
589
590 // is removal of this type possible?
591 sal_Bool bIsBasicType = xDataType.is() && xDataType->isBasicType();
592 _rxInspectorUI->enablePropertyUIElements( PROPERTY_XSD_DATA_TYPE, PropertyLineElement::PrimaryButton, xDataType.is() );
593 _rxInspectorUI->enablePropertyUIElements( PROPERTY_XSD_DATA_TYPE, PropertyLineElement::SecondaryButton, xDataType.is() && !bIsBasicType );
594
595 //------------------------------------------------------------
596 // show the facets which are available at the data type
597 ::rtl::OUString aFacets[] = {
598 PROPERTY_XSD_WHITESPACES, PROPERTY_XSD_PATTERN,
599 PROPERTY_XSD_LENGTH, PROPERTY_XSD_MIN_LENGTH, PROPERTY_XSD_MAX_LENGTH, PROPERTY_XSD_TOTAL_DIGITS,
600 PROPERTY_XSD_FRACTION_DIGITS,
601 PROPERTY_XSD_MAX_INCLUSIVE_INT,
602 PROPERTY_XSD_MAX_EXCLUSIVE_INT,
603 PROPERTY_XSD_MIN_INCLUSIVE_INT,
604 PROPERTY_XSD_MIN_EXCLUSIVE_INT,
605 PROPERTY_XSD_MAX_INCLUSIVE_DOUBLE,
606 PROPERTY_XSD_MAX_EXCLUSIVE_DOUBLE,
607 PROPERTY_XSD_MIN_INCLUSIVE_DOUBLE,
608 PROPERTY_XSD_MIN_EXCLUSIVE_DOUBLE,
609 PROPERTY_XSD_MAX_INCLUSIVE_DATE,
610 PROPERTY_XSD_MAX_EXCLUSIVE_DATE,
611 PROPERTY_XSD_MIN_INCLUSIVE_DATE,
612 PROPERTY_XSD_MIN_EXCLUSIVE_DATE,
613 PROPERTY_XSD_MAX_INCLUSIVE_TIME,
614 PROPERTY_XSD_MAX_EXCLUSIVE_TIME,
615 PROPERTY_XSD_MIN_INCLUSIVE_TIME,
616 PROPERTY_XSD_MIN_EXCLUSIVE_TIME,
617 PROPERTY_XSD_MAX_INCLUSIVE_DATE_TIME,
618 PROPERTY_XSD_MAX_EXCLUSIVE_DATE_TIME,
619 PROPERTY_XSD_MIN_INCLUSIVE_DATE_TIME,
620 PROPERTY_XSD_MIN_EXCLUSIVE_DATE_TIME
621 };
622
623 size_t i=0;
624 const ::rtl::OUString* pLoop = NULL;
625 for ( i = 0, pLoop = aFacets;
626 i < sizeof( aFacets ) / sizeof( aFacets[0] );
627 ++i, ++pLoop
628 )
629 {
630 showPropertyUI( _rxInspectorUI, *pLoop, xDataType.is() && xDataType->hasFacet( *pLoop ) );
631 _rxInspectorUI->enablePropertyUI( *pLoop, !bIsBasicType );
632 }
633 }
634 break;
635
636 case PROPERTY_ID_XML_DATA_MODEL:
637 {
638 // The data type which the current binding works with may not be present in the
639 // new model. Thus, transfer it.
640 ::rtl::OUString sOldModelName; _rOldValue >>= sOldModelName;
641 ::rtl::OUString sNewModelName; _rNewValue >>= sNewModelName;
642 ::rtl::OUString sDataType = m_pHelper->getValidatingDataTypeName();
643 m_pHelper->copyDataType( sOldModelName, sNewModelName, sDataType );
644
645 // the list of available data types depends on the chosen model, so update this
646 if ( !_bFirstTimeInit )
647 _rxInspectorUI->rebuildPropertyUI( PROPERTY_XSD_DATA_TYPE );
648 }
649 break;
650
651 default:
652 DBG_ERROR( "XSDValidationPropertyHandler::actuatingPropertyChanged: cannot handle this property!" );
653 return;
654 }
655
656 // in both cases, we need to care for the current value of the XSD_DATA_TYPE property,
657 // and update the FormatKey of the formatted field we're inspecting (if any)
658 if ( !_bFirstTimeInit && m_pHelper->isInspectingFormattedField() )
659 m_pHelper->findDefaultFormatForIntrospectee();
660 }
661
662 //--------------------------------------------------------------------
implGetAvailableDataTypeNames(::std::vector<::rtl::OUString> & _rNames) const663 void XSDValidationPropertyHandler::implGetAvailableDataTypeNames( ::std::vector< ::rtl::OUString >& /* [out] */ _rNames ) const SAL_THROW(())
664 {
665 OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implGetAvailableDataTypeNames: this will crash!" );
666 // start with *all* types which are available at the model
667 ::std::vector< ::rtl::OUString > aAllTypes;
668 m_pHelper->getAvailableDataTypeNames( aAllTypes );
669 _rNames.clear();
670 _rNames.reserve( aAllTypes.size() );
671
672 // then allow only those which are "compatible" with our control
673 for ( ::std::vector< ::rtl::OUString >::const_iterator dataType = aAllTypes.begin();
674 dataType != aAllTypes.end();
675 ++dataType
676 )
677 {
678 ::rtl::Reference< XSDDataType > pType = m_pHelper->getDataTypeByName( *dataType );
679 if ( pType.is() && m_pHelper->canBindToDataType( pType->classify() ) )
680 _rNames.push_back( *dataType );
681 }
682 }
683
684 //........................................................................
685 } // namespace pcr
686 //........................................................................
687