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( ) throw (RuntimeException)
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( ) 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 //--------------------------------------------------------------------
getPropertyValue(const::rtl::OUString & _rPropertyName)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 //--------------------------------------------------------------------
setPropertyValue(const::rtl::OUString & _rPropertyName,const Any & _rValue)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 //--------------------------------------------------------------------
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( ) 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 //--------------------------------------------------------------------
getActuatingProperties()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 {
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 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 //--------------------------------------------------------------------
onInteractivePropertySelection(const::rtl::OUString & _rPropertyName,sal_Bool _bPrimary,Any &,const Reference<XObjectInspectorUI> & _rxInspectorUI)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 //--------------------------------------------------------------------
addPropertyChangeListener(const Reference<XPropertyChangeListener> & _rxListener)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 //--------------------------------------------------------------------
removePropertyChangeListener(const Reference<XPropertyChangeListener> & _rxListener)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 //--------------------------------------------------------------------
implPrepareCloneDataCurrentType(::rtl::OUString & _rNewName)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 //--------------------------------------------------------------------
implDoCloneCurrentDataType(const::rtl::OUString & _rNewName)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 //--------------------------------------------------------------------
implPrepareRemoveCurrentDataType()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 //--------------------------------------------------------------------
implDoRemoveCurrentDataType()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 //--------------------------------------------------------------------
actuatingPropertyChanged(const::rtl::OUString & _rActuatingPropertyName,const Any & _rNewValue,const Any & _rOldValue,const Reference<XObjectInspectorUI> & _rxInspectorUI,sal_Bool _bFirstTimeInit)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 //--------------------------------------------------------------------
implGetAvailableDataTypeNames(::std::vector<::rtl::OUString> & _rNames) const664 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