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